diff --git a/.coderabbit.yaml b/.coderabbit.yaml deleted file mode 100644 index ab02b02657..0000000000 --- a/.coderabbit.yaml +++ /dev/null @@ -1,70 +0,0 @@ -# yaml-language-server: $schema=https://storage.googleapis.com/coderabbit_public_assets/schema.v2.json -# CodeRabbit configuration for opencodex. -# This file is the single source of truth for CodeRabbit behavior; prefer editing -# this file over the dashboard so settings are versioned and reviewable. - -language: en-US -tone_instructions: >- - Always review in English. Be very detailed and specific: cite exact files and - lines, explain the failure mode, and propose a concrete fix. Prefer - evidence-backed findings over style nitpicks. - -reviews: - profile: assertive - high_level_summary: true - auto_review: - enabled: true - drafts: false - # Default branch (main) is included automatically; these are additional - # base branches (anchored regex). - base_branches: - - "^dev$" - - "^preview$" - path_instructions: - - path: "src/**" - instructions: >- - Runtime is Bun-native TypeScript (no separate compile step). Flag - Node-only APIs that break under Bun, provider/adapter contract drift, - and changes that bypass the shared routing/config layers. Watch for - credential handling: tokens and OAuth material must never be logged or - serialized into responses. - - path: "tests/**" - instructions: >- - Tests are flat Bun tests under tests/. A behavior change in src/ should - come with a focused regression test near the existing tests for that - subsystem. Flag PRs that change shared routing, adapters, config, or - server behavior without touching tests. - - path: "gui/**" - instructions: >- - React dashboard built with Vite. Check that GUI state changes stay - consistent with the management API responses and that user-visible - strings go through the i18n locale files rather than hardcoded text. - - path: ".github/**" - instructions: >- - Security boundary. Workflow changes, release automation, and dependency - installation steps require explicit security review per MAINTAINERS.md. - Flag any new secret usage, permission escalation, or third-party action - pinned to a mutable ref. - - path: "scripts/**" - instructions: >- - scripts/release.ts is the release authority and a security boundary. - Flag changes that weaken CI gating, alter npm publish behavior, or - bypass the release workflow's dry-run default. - - path: "docs-site/**" - instructions: >- - Astro + Starlight docs site. Check that user-facing docs stay in sync - with actual CLI/API behavior and that translated locale pages (ja, ko, - ru, zh-cn) are not left contradicting the English source. - -issue_enrichment: - auto_enrich: - enabled: true - planning: - enabled: true - auto_planning: - enabled: true - labels: - - plan-me - -chat: - auto_reply: true diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 1b2418c7fb..01da865adf 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,31 +1,5 @@ -# Default reviewer +# Single-owner repository: every path defaults to the owner. CODEOWNERS here +# requests review; it is not a merge gate. Merge requirements live in the +# GitHub ruleset on `main`, which must list repository admins as Always-allow +# bypass actors (see MAINTAINERS.md). * @pavelhov - -# High-impact runtime behavior -/src/adapters/ @lidge-jun @Ingwannu @Wibias -/src/providers/ @lidge-jun @Ingwannu @Wibias -/src/codex/ @lidge-jun @Ingwannu @Wibias -/src/server/ @lidge-jun @Ingwannu @Wibias - -# Repository automation and release security -/.github/ @pavelhov -/scripts/release.ts @pavelhov -/scripts/build-macos-app.sh @pavelhov -/scripts/package-macos-release.sh @pavelhov -/package.json @pavelhov -/bun.lock @pavelhov - -# Authentication, credentials, and management API -/src/oauth/ @pavelhov -/src/codex/auth-context.ts @pavelhov -/src/server/auth-cors.ts @pavelhov -/src/server/management-api.ts @pavelhov -/app/Sources/MenuBarCore/Discovery.swift @pavelhov -/app/Sources/MenuBarCore/ProxyClient.swift @pavelhov -/app/Info.plist @pavelhov - -# Governance and security policy -/AGENTS.md @pavelhov -**/AGENTS.md @pavelhov -/MAINTAINERS.md @pavelhov -/SECURITY.md @pavelhov diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 4a2503137e..c731707599 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -19,7 +19,7 @@ body: - Codex SDK - Claude Code - Direct HTTP/API client - - OpenCodex dashboard + - CodexCommander dashboard - Other validations: required: true @@ -28,7 +28,7 @@ body: id: area attributes: label: Area - description: Which part of OpenCodex is affected? + description: Which part of CodexCommander is affected? options: - CLI - Proxy and routing @@ -62,7 +62,7 @@ body: description: | Exact commands, steps, configuration shape, and inputs. If the problem is intermittent or not yet consistently reproducible, explain what you have observed and under which conditions. placeholder: | - 1. ocx start --port 10100 + 1. ccx start --port 10100 2. Send a request to /v1/responses with ... 3. Observe ... validations: @@ -72,8 +72,8 @@ body: id: version attributes: label: Version - description: Installed `@bitkyc08/opencodex` version or commit SHA. - placeholder: "2.7.31" + description: Installed `codexcommander` version or commit SHA. + placeholder: "0.1.0" validations: required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 07fd1d1cf6..d587207795 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,11 +1,11 @@ blank_issues_enabled: false contact_links: - name: Report a security vulnerability (private) - url: https://github.com/lidge-jun/opencodex/security/advisories/new + url: https://github.com/pavelhov/CodexCommander/security/advisories/new about: Report undisclosed vulnerabilities privately to the maintainers. Do not open a public issue. - name: Security policy - url: https://github.com/lidge-jun/opencodex/blob/main/SECURITY.md + url: https://github.com/pavelhov/CodexCommander/blob/main/SECURITY.md about: Read the supported-version and reporting guidance before sharing security-sensitive details. - name: Contributing guide - url: https://opencodex.me/contributing/ + url: https://github.com/pavelhov/CodexCommander/blob/main/CONTRIBUTING.md about: Review setup, build, and verification guidance for contributors. diff --git a/.github/ISSUE_TEMPLATE/documentation.yml b/.github/ISSUE_TEMPLATE/documentation.yml index 358e5e889b..53c7cd8574 100644 --- a/.github/ISSUE_TEMPLATE/documentation.yml +++ b/.github/ISSUE_TEMPLATE/documentation.yml @@ -28,7 +28,7 @@ body: attributes: label: Documentation location description: Public documentation URL or repository path. - placeholder: "https://opencodex.me/providers/ or docs/providers.md" + placeholder: "docs-site/src/content/docs/guides/providers.md" validations: required: true diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 5ac7b510c3..3215665552 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,18 +1,18 @@ name: Feature proposal -description: Propose a new capability or workflow improvement for OpenCodex. +description: Propose a new capability or workflow improvement for CodexCommander. labels: - enhancement body: - type: markdown attributes: value: | - Describe the workflow you need and what OpenCodex should do. Concrete examples help us evaluate and implement your proposal faster. + Describe the workflow you need and what CodexCommander should do. Concrete examples help us evaluate and implement your proposal faster. - type: dropdown id: area attributes: label: Area - description: Which part of OpenCodex does this proposal affect? + description: Which part of CodexCommander does this proposal affect? options: - CLI - Proxy and routing @@ -52,7 +52,7 @@ body: - type: textarea id: behaviour attributes: - label: What should OpenCodex do? + label: What should CodexCommander do? description: Describe the observable behaviour you expect, not internal implementation details. placeholder: When I send ... the proxy should ... validations: @@ -66,7 +66,7 @@ body: Provide at least one concrete example: a CLI command, configuration fragment, API exchange, UI workflow, or before/after comparison. placeholder: | ```bash - ocx config set routing.fallback_provider anthropic + ccx config set routing.fallback_provider anthropic ``` validations: required: true @@ -90,7 +90,7 @@ body: options: - label: I searched existing issues and documentation. required: true - - label: This request describes a concrete OpenCodex workflow rather than merely naming a desired technology. + - label: This request describes a concrete CodexCommander workflow rather than merely naming a desired technology. required: true - label: I removed secrets and personal data. required: true diff --git a/.github/ISSUE_TEMPLATE/provider_compatibility.yml b/.github/ISSUE_TEMPLATE/provider_compatibility.yml index ab02cf3791..d071abfd08 100644 --- a/.github/ISSUE_TEMPLATE/provider_compatibility.yml +++ b/.github/ISSUE_TEMPLATE/provider_compatibility.yml @@ -7,7 +7,7 @@ body: - type: markdown attributes: value: | - Use this form when a provider endpoint, request format, response format, or client integration does not work correctly through the OpenCodex proxy. + Use this form when a provider endpoint, request format, response format, or client integration does not work correctly through the CodexCommander proxy. - type: dropdown id: client @@ -37,9 +37,9 @@ body: - type: input id: version attributes: - label: OpenCodex version - description: Installed `@bitkyc08/opencodex` version or commit SHA. - placeholder: "2.7.31" + label: CodexCommander version + description: Installed `codexcommander` version or commit SHA. + placeholder: "0.1.0" validations: required: true diff --git a/.github/release.yml b/.github/release.yml deleted file mode 100644 index 7ecd38fb37..0000000000 --- a/.github/release.yml +++ /dev/null @@ -1,20 +0,0 @@ -changelog: - exclude: - labels: - - skip-changelog - categories: - - title: New Features - labels: - - enhancement - - title: Bug Fixes - labels: - - bug - - title: Documentation - labels: - - documentation - - title: Chores - labels: - - chore - - title: Other Changes - labels: - - "*" diff --git a/.github/scripts/copilot-workflows.test.cjs b/.github/scripts/copilot-workflows.test.cjs deleted file mode 100644 index 607911542d..0000000000 --- a/.github/scripts/copilot-workflows.test.cjs +++ /dev/null @@ -1,82 +0,0 @@ -const test = require('node:test'); -const assert = require('node:assert/strict'); -const fs = require('node:fs'); -const path = require('node:path'); - -const ROOT = path.resolve(__dirname, '..', '..'); -const AI_ACTION = 'actions/ai-inference@2c43c91ae16266ca159d311430343c67a5ffa222'; -const CLI_INSTALL = 'npm install --global @github/copilot@1.0.74'; -const SETUP_NODE = 'actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e'; - -function readWorkflow(name) { - return fs.readFileSync(path.join(ROOT, '.github', 'workflows', name), 'utf8'); -} - -function count(text, fragment) { - return text.split(fragment).length - 1; -} - -test('issue automation uses pinned Copilot inference without tool access', () => { - const quality = readWorkflow('enforce-issue-quality.yml'); - const triage = readWorkflow('issue-triage.yml'); - const combined = quality + '\n' + triage; - - assert.equal(count(quality, AI_ACTION), 2); - assert.equal(count(triage, AI_ACTION), 1); - assert.equal(count(quality, SETUP_NODE), 2); - assert.equal(count(triage, SETUP_NODE), 1); - assert.equal(count(quality, CLI_INSTALL), 2); - assert.equal(count(triage, CLI_INSTALL), 1); - assert.equal(count(quality, 'copilot-requests: write'), 2); - assert.equal(count(triage, 'copilot-requests: write'), 1); - assert.equal(count(quality, 'GITHUB_TOKEN: ${{ github.token }}'), 2); - assert.equal(count(triage, 'GITHUB_TOKEN: ${{ github.token }}'), 1); - assert.equal(count(quality, 'model: ""'), 2); - assert.equal(count(triage, 'model: ""'), 1); - - assert.doesNotMatch(combined, /\bmodels:\s*read\b/); - assert.doesNotMatch(combined, /max-tokens:/); - assert.doesNotMatch(combined, /copilot-allow-tools:/); - assert.doesNotMatch(combined, /--allow-tool/); - assert.doesNotMatch(combined, /GitHub Models/); -}); - -test('Copilot failures leave issue enforcement and triage retryable', () => { - const quality = readWorkflow('enforce-issue-quality.yml'); - const triage = readWorkflow('issue-triage.yml'); - - assert.equal(count(quality, 'continue-on-error: true'), 6); - assert.equal(count(triage, 'continue-on-error: true'), 3); - - assert.equal( - count( - quality, - "if: steps.prepare.outputs.should_translate == 'true' && steps.copilot.outcome == 'success'", - ), - 2, - ); - assert.equal( - count( - quality, - "if: steps.prepare.outputs.should_translate == 'true' && steps.ai.outcome == 'success'", - ), - 2, - ); - assert.equal(count(quality, "steps.ai.outcome == 'success' &&"), 2); - assert.equal(count(quality, "steps.parse.outcome == 'success' &&"), 2); - assert.match(quality, /leaving the issue unchanged and retryable/); - assert.match(quality, /leaving the comment unchanged and retryable/); - - assert.equal( - count(quality, "if: steps.prepare.outputs.should_translate == 'true' && steps.node.outcome == 'success'"), - 2, - ); - assert.match(triage, /if: steps\.node\.outcome == 'success'/); - assert.match(triage, /if: steps\.copilot\.outcome == 'success'/); - assert.match(triage, /if: steps\.infer\.outcome == 'success'/); - assert.match(triage, /skipping duplicate suggestions for this issue/); - - // The deterministic quality gate must still run when translation fails. - assert.match(quality, /needs: translate/); - assert.match(quality, /always\(\) &&\n\s+needs\.translate\.result != 'cancelled'/); -}); diff --git a/.github/scripts/enforce-pr-target.test.cjs b/.github/scripts/enforce-pr-target.test.cjs deleted file mode 100644 index 5fc9455a7c..0000000000 --- a/.github/scripts/enforce-pr-target.test.cjs +++ /dev/null @@ -1,185 +0,0 @@ -"use strict"; - -const fs = require("node:fs"); -const path = require("node:path"); -const { describe, it } = require("node:test"); -const assert = require("node:assert/strict"); - -describe("enforce-pr-target workflow", () => { - const workflowPath = path.join(__dirname, "../workflows/enforce-pr-target.yml"); - const workflow = fs.readFileSync(workflowPath, "utf8"); - - it("uses pull_request_target without checking out PR head code", () => { - assert.match(workflow, /pull_request_target:/); - assert.doesNotMatch( - workflow, - /ref:\s*\$\{\{\s*github\.event\.pull_request\.head/, - "enforcer must not check out untrusted PR head code", - ); - }); - - it("grants contents:write so draft GraphQL mutations work with GITHUB_TOKEN", () => { - // convertPullRequestToDraft / markPullRequestReadyForReview fail with - // "Resource not accessible by integration" when contents stays unset/read - // (seen on #626). Assert the real permissions block, not comment text - // that also mentions these scopes. - const permissionsBlock = workflow.match(/^permissions:\n((?:[ \t]+.+\n)+)/m); - assert.ok(permissionsBlock, "workflow must declare a top-level permissions block"); - const lines = permissionsBlock[1] - .split("\n") - .map((line) => line.trim()) - .filter(Boolean) - .sort(); - assert.deepEqual(lines, ["contents: write", "pull-requests: write"]); - }); - - it("fails the required check on a wrong base even if draft conversion fails", () => { - assert.match(workflow, /core\.setFailed\(/); - assert.match(workflow, /draftConversionFailed/); - assert.match(workflow, /Could not convert pull request to draft/); - }); - - it("soft-fails ready-for-review restoration the same way", () => { - assert.match(workflow, /readyConversionFailed/); - assert.match(workflow, /Could not mark pull request ready for review/); - }); - - it("listens for synchronize so rebase can clear ancestry failures", () => { - assert.match(workflow, /synchronize/); - }); - - it("re-runs on issue_comment so a maintainer GUI waiver takes effect", () => { - // The GUI-screenshot gate is waived by a maintainer issue comment - // ("not touching gui"). `pull_request_target` types do not include issue - // comments, so without this trigger the waiver sits unread until a PR - // edit or push re-runs the gate. - assert.match(workflow, /^ issue_comment:/m); - assert.match(workflow, /- created/); - assert.match(workflow, /- edited/); - // The script resolves the PR number from the issue payload, which is what - // an issue_comment event delivers instead of a pull_request object. - assert.match(workflow, /context\.payload\.issue\?\.number/); - }); - - it("does not add review events that would break the trusted-base model", () => { - // `pull_request_review` / `pull_request_review_comment` load the workflow - // from the PR head branch (like `pull_request`), while this workflow's - // checkout pins the base SHA — head YAML + base scripts mismatch, so the - // gate crashes (`parseGateState is not a function`) and the head controls - // the workflow definition under a write token. The findings claim runs on - // every `pull_request_target` event instead (opened/edited/synchronize/ - // ready_for_review). - assert.doesNotMatch(workflow, /^ pull_request_review:/m); - assert.doesNotMatch(workflow, /^ pull_request_review_comment:/m); - }); - - it("queries review threads and feeds them to the findings claim check", () => { - // Paginated read: `after: $cursor` + `pageInfo.hasNextPage`, so a busy PR - // with more than 100 threads cannot hide unresolved bot threads (fail-open - // gap in a fail-closed check). - assert.match(workflow, /reviewThreads\(first: 100, after: \$cursor\)/); - assert.match(workflow, /hasNextPage/); - assert.match(workflow, /unresolvedFindingsClaim/); - assert.match(workflow, /findingsClaim\.byBot/); - assert.match(workflow, /review_findings/); - }); - - it("fails closed when review threads cannot be read", () => { - assert.match(workflow, /findingsUnverifiable/); - assert.match(workflow, /findings claim could not be verified/); - }); - - it("writes exactly one consolidated comment via a single upsert helper", () => { - assert.match(workflow, /GATE_MARKER,/); - assert.match(workflow, /comment\.body\?\.includes\(GATE_MARKER\)/); - assert.match(workflow, /upsertGateComment/); - assert.match(workflow, /buildGateCommentBody/); - // No legacy two-comment write path remains. - assert.doesNotMatch(workflow, /upsertReadinessComment/); - assert.doesNotMatch(workflow, /buildReadinessCommentBody/); - // No intermediate checkpoint comment writes. - assert.doesNotMatch(workflow, /Draft conversion pending/); - assert.doesNotMatch(workflow, /Recording ownership state/); - }); - - it("manages the review-ready status label at the ready moment", () => { - assert.match(workflow, /REVIEW_READY_LABEL\s*=\s*"review-ready"/); - assert.match(workflow, /github\.rest\.issues\.addLabels/); - assert.match(workflow, /github\.rest\.issues\.removeLabel/); - assert.match(workflow, /reviewReadyDesired/); - }); - - it("keeps CodeRabbit auto-review unfiltered so maintainer PRs are not starved", () => { - // A positive `labels:` filter under `reviews.auto_review` in - // `.coderabbit.yaml` would restrict ALL automatic reviews to PRs carrying - // that label. Maintainer PRs never carry `review-ready` (no checklist), so - // such a filter would silently stop CodeRabbit from reviewing maintainer - // PRs. The label is a status marker only; assert the reviewer config - // directly, since the workflow never writes a labels block. - const coderabbit = fs.readFileSync( - path.join(__dirname, "../../.coderabbit.yaml"), - "utf8", - ); - const autoReview = coderabbit.match(/auto_review:[\s\S]*?(?=\n\S|\n\s{2}\S)/); - assert.ok(autoReview, ".coderabbit.yaml must declare auto_review"); - assert.doesNotMatch(autoReview[0], /labels:/); - }); - - it("migrates legacy two-comment PRs and deletes the old comments", () => { - assert.match(workflow, /migrateLegacyCommentsIfNeeded/); - assert.match(workflow, /migrateLegacyGateState/); - assert.match(workflow, /github\.rest\.issues\.deleteComment/); - assert.match(workflow, /legacyEnforcerComment/); - assert.match(workflow, /legacyReadinessComment/); - }); - - it("checks out trusted base-branch scripts only (never PR head)", () => { - // Scope the assertions to the checkout step itself, so a stray `ref:` on - // another step cannot satisfy the pin while the checkout stays mutable. - const checkoutStep = workflow - .split("- name: Checkout trusted PR-quality scripts")[1] - .split(/\n {6}- name:/)[0]; - assert.match(checkoutStep, /actions\/checkout@[0-9a-f]{40}/); - // `pull_request_target` pins the PR's base SHA so the scripts match the - // event's base revision. An `issue_comment` event has no PR payload, so - // the ref falls back to the integration branch `dev` (the gate's only - // allowed base) — still trusted, and never the PR head. - assert.match( - checkoutStep, - /ref:\s*\$\{\{\s*github\.event\.pull_request\.base\.sha\s*\|\|\s*'dev'\s*\}\}/, - ); - // The readiness ping reads MAINTAINERS.md from the same trusted checkout. - assert.match(checkoutStep, /sparse-checkout:\s*\|\s*\n\s*\.github\/scripts\n\s*MAINTAINERS\.md/); - assert.match(checkoutStep, /persist-credentials:\s*false/); - assert.doesNotMatch(workflow, /ref:\s*\$\{\{\s*github\.event\.pull_request\.head/); - }); - - it("loads pr-quality via require from the checked-out scripts", () => { - assert.match(workflow, /pr-quality\.cjs/); - assert.match(workflow, /collectPrQualityFailures/); - }); - - it("checks stacked bases via open PR heads before wrong_base enforcement", () => { - assert.match(workflow, /stackedBase/); - assert.match(workflow, /github\.rest\.pulls\.list/); - assert.match(workflow, /treating as stacked/); - assert.match(workflow, /other\.base\?\.repo\?\.owner/); - const qualityCall = workflow.match( - /collectPrQualityFailures\(\{([\s\S]*?)\}\);/, - ); - assert.ok(qualityCall, "must call collectPrQualityFailures"); - assert.match(qualityCall[1], /stackedBase/); - }); - - it("strips stale WRONG BRANCH prefix on failure when base is corrected", () => { - const failureBlock = workflow.match( - /if \(mustDraft\) \{([\s\S]*?)core\.setFailed\(/, - ); - assert.ok(failureBlock, "workflow must have a draft path"); - const failurePath = failureBlock[1]; - assert.match(failurePath, /shouldStripTitlePrefix/); - assert.match(failurePath, /!hasWrongBase/); - assert.match(failurePath, /titlePrefixedByBot = false/); - assert.match(failurePath, /pr\.title\.slice\(TITLE_PREFIX\.length\)/); - }); -}); diff --git a/.github/scripts/issue-quality.cjs b/.github/scripts/issue-quality.cjs deleted file mode 100644 index 1c0a6430a7..0000000000 --- a/.github/scripts/issue-quality.cjs +++ /dev/null @@ -1,1649 +0,0 @@ -"use strict"; - -// --------------------------------------------------------------------------- -// Pure issue-quality validation for OpenCodex. -// CommonJS, zero runtime dependencies. No GitHub API calls. -// --------------------------------------------------------------------------- - -/** - * True when the entire meaningful value is a placeholder-only token. - * Supports harmless Markdown emphasis/code markers and trailing punctuation. - * Sentences that merely contain a placeholder phrase are not matches. - */ -const PLACEHOLDER_ONLY_RE = - /^[\s_*~`]*(?:no\s+response|n\/?a|not\s+applicable|not\s+available|none|todo|tbd)[\s_*~`]*[.!?]*$/i; - -/** - * If `text` is exactly one enclosing fenced code block (``` or ~~~), return the - * inner body; otherwise null. Real multi-statement fences are left alone by - * the placeholder matcher after unwrap. - */ -function unwrapSingleEnclosingFence(text) { - const trimmed = text.trim(); - const match = trimmed.match(/^(```|~~~)[^\n]*\r?\n([\s\S]*?)\r?\n\1[ \t]*$/); - if (!match) return null; - return match[2]; -} - -/** - * Shared strip/trim/unwrap used by placeholder and unusable-stand-in matchers. - * Returns null when the value is absent after normalisation. - */ -function normalizeRawSectionValue(raw) { - if (typeof raw !== "string") return null; - let value = raw.replace(//g, "").trim(); - if (!value) return null; - - // A lone fenced block whose entire body is a stand-in is still a stand-in - // (e.g. ```text\nN/A\n```), not a real example. - const unwrapped = unwrapSingleEnclosingFence(value); - if (unwrapped !== null) { - value = unwrapped.trim(); - if (!value) return null; - } - - return value; -} - -function isPlaceholderOnlyValue(raw) { - const value = normalizeRawSectionValue(raw); - if (value === null) return false; - return PLACEHOLDER_ONLY_RE.test(value); -} - -/** - * Strip image/media-only content from a markdown or HTML fragment so that a - * section whose only content is a screenshot or media embed is treated as - * empty by the validators. - * - * Handles: - * - Markdown images: `![alt](url)`, `![alt](url "title")` - * - HTML and ... blocks - * - Common media embeds (video/audio) when they are the only content - * - * Text mixed with media (for example a caption or repro steps around an - * image) is preserved; only the media tokens themselves are removed. - */ -function stripMediaTokens(text) { - if (typeof text !== "string") return ""; - // Indented code lines render as literal code in GitHub Markdown. Protect - // them first so neither the HTML nor the Markdown media stripper can - // remove example syntax; restore the lines afterwards. - const protectedText = protectIndentedCodeLines(text); - const markdownStripped = stripMarkdownImages(stripHtmlMedia(protectedText.text)); - const referenceStripped = stripReferenceImages(markdownStripped); - return restoreIndentedCodeLines(referenceStripped, protectedText.lines); -} - -/** - * Replace every indented code line (4+ leading spaces or a tab) with a - * placeholder of equal length so media stripping cannot touch it. Returns the - * masked text plus the original lines for restoration. - */ -function protectIndentedCodeLines(text) { - const lines = []; - const masked = text.split("\n").map((line) => { - if (/^(?: {4,}|\t)/.test(line)) { - lines.push(line); - return "\u0000" + line.replace(/[^\n]/g, " ").slice(1); - } - lines.push(null); - return line; - }); - return { text: masked.join("\n"), lines }; -} - -/** - * Restore masked indented-code lines from their original content. Placeholder - * lines are identified by the leading \u0000 marker and matched positionally. - */ -function restoreIndentedCodeLines(text, lines) { - const out = text.split("\n").map((line, i) => { - if (lines[i] !== null && line.startsWith("\u0000")) { - return lines[i]; - } - return line; - }); - return out.join("\n"); -} - -/** - * Strip HTML media blocks whose entire inner content is media markup (no - * substantive text). A block that contains fallback/caption prose — for - * example `` - * — is left untouched so the prose survives the empty-section check. - * - * Handles , ..., , and - * . - */ -function stripHtmlMedia(text) { - if (typeof text !== "string") return ""; - let s = text - .replace(/]*>/gi, " ") - .replace(//g, " "); - - // Whole media blocks: replace only when the inner content is not - // substantive text (no word characters outside tags). - s = s.replace( - /<(picture|video|audio)\b[^>]*>([\s\S]*?)<\/\1>/gi, - (match, tag, inner) => { - const innerStripped = inner - .replace(/<[^>]+>/g, " ") - .replace(/[\s_*~`]+/g, " ") - .trim(); - return innerStripped.length === 0 ? " " : match; - }, - ); - return s; -} - -/** - * Remove Markdown image tokens `![alt](dest "title")` using a small - * balanced scanner instead of a regex, because destinations may contain - * balanced parentheses (for example `image_(final).png`) and alt text may - * contain balanced brackets (`![Image [screenshot]](url)`). - * - * A token is matched only when: - * - it starts with `![` (not escaped); - * - the alt text is balanced with respect to `[` / `]`; - * - the destination is balanced with respect to `(`, `)` and `"` (an - * optional title may follow); and - * - the token closes with a `)`. - * - * Malformed tokens (unbalanced destination, e.g. `a)b.png)`) are left in - * place — they are not valid Markdown images and must not be silently - * dropped. - */ -function stripMarkdownImages(text) { - if (typeof text !== "string") return ""; - const out = []; - let i = 0; - while (i < text.length) { - // Inside an indented code block (4+ leading spaces or a tab), image - // syntax is literal code, not a rendered image. Leave it untouched so a - // section that documents example syntax is not emptied. - if (isInsideIndentedCode(text, i)) { - out.push(text[i]); - i += 1; - continue; - } - // A backslash-escaped or code-fenced `![` is not an image token. We only - // guard the common `\!` escape here; fenced blocks are handled by the - // section extractor upstream, which does not include them in sections. - if (text[i] === "!" && text[i + 1] === "[") { - const end = scanMarkdownImage(text, i); - if (end !== -1) { - out.push(" "); - i = end; - continue; - } - } - out.push(text[i]); - i += 1; - } - return out.join(""); -} - -/** - * True when `index` sits inside an indented code block, i.e. on a line that - * starts with four or more spaces or a tab. Such lines render as literal - * code in GitHub Markdown. - */ -function isInsideIndentedCode(text, index) { - const lineStart = text.lastIndexOf("\n", index - 1) + 1; - const prefix = text.slice(lineStart, index); - return /^(?: {4,}|\t)/.test(prefix); -} - -/** - * Strip reference-style Markdown images: inline references `![alt][ref]` - * and the reference definitions `[ref]: https://...` they point at. These - * are valid image syntax that a media-only section may use to embed a - * screenshot. - */ -function stripReferenceImages(text) { - if (typeof text !== "string") return ""; - // Inline reference: ![alt][ref] or ![alt][] (implicit). Alt may contain - // balanced brackets, so a balanced scan is used for the label part. - let s = stripInlineReferences(text); - // Reference definitions: [ref]: url "title" — only when the reference is - // actually used by an image in the same text. A definition alone (or one - // used by a text link) is not media and must stay. - const refs = new Set(); - for (const ref of collectInlineReferenceLabels(text)) { - refs.add(ref.toLowerCase()); - } - if (refs.size > 0) { - s = s.replace( - /^\s*\[([^\]]+)\]:\s*\S+(?:\s+["'(][^"')]*["')])?\s*$/gm, - (line, ref) => (refs.has(ref.toLowerCase()) ? " " : line), - ); - } - return s; -} - -/** - * Strip inline reference-style image tokens `![alt][ref]` / `![alt][]` - * using a balanced scan for the alt text (which may contain nested brackets). - */ -function stripInlineReferences(text) { - const out = []; - let i = 0; - while (i < text.length) { - if (text[i] === "!" && text[i + 1] === "[") { - const end = scanReferenceImage(text, i); - if (end !== -1) { - out.push(" "); - i = end; - continue; - } - } - out.push(text[i]); - i += 1; - } - return out.join(""); -} - -/** - * Scan an inline reference-style image `![alt][ref]` or `![alt][]` starting - * at `start`. Returns the index just past the closing `]` on success, or -1. - */ -function scanReferenceImage(text, start) { - const altEnd = scanBalancedBrackets(text, start + 2); - if (altEnd === -1 || text[altEnd] !== "]") return -1; - if (text[altEnd + 1] !== "[") return -1; - const refEnd = scanBalancedBrackets(text, altEnd + 2); - if (refEnd === -1 || text[refEnd] !== "]") return -1; - return refEnd + 1; -} - -/** - * Scan balanced bracket content starting at `start` (inside the opening `[`). - * Returns the index of the matching closing `]`, or -1 when unbalanced. - */ -function scanBalancedBrackets(text, start) { - let depth = 0; - for (let i = start; i < text.length; i += 1) { - const ch = text[i]; - if (ch === "\\") { - i += 1; - continue; - } - if (ch === "[") { - depth += 1; - } else if (ch === "]") { - if (depth === 0) return i; - depth -= 1; - } - } - return -1; -} - -/** - * Collect the reference labels used by inline reference-style images. For an - * explicit `![alt][ref]` the label is `ref`; for an implicit `![alt][]` the - * label is the alt text. - */ -function collectInlineReferenceLabels(text) { - const labels = []; - let i = 0; - while (i < text.length) { - if (text[i] === "!" && text[i + 1] === "[") { - const altStart = i + 2; - const altEnd = scanBalancedBrackets(text, altStart); - if (altEnd !== -1 && text[altEnd] === "]") { - const alt = text.slice(altStart, altEnd); - if (text[altEnd + 1] === "[") { - const refStart = altEnd + 2; - const refEnd = scanBalancedBrackets(text, refStart); - if (refEnd !== -1 && text[refEnd] === "]") { - const ref = text.slice(refStart, refEnd); - labels.push(ref ? ref : alt); - i = refEnd + 1; - continue; - } - } - } - } - i += 1; - } - return labels; -} - -/** - * Scan a Markdown image token starting at `start` (which points at `!`). - * Returns the index just past the closing `)` on success, or -1 when the - * token is malformed. - */ -function scanMarkdownImage(text, start) { - // Alt text: `![` ... `]` with balanced nested brackets. - let i = start + 2; - let bracketDepth = 0; - for (; i < text.length; i += 1) { - const ch = text[i]; - if (ch === "\\") { - i += 1; // skip escaped character - continue; - } - if (ch === "[") { - bracketDepth += 1; - } else if (ch === "]") { - if (bracketDepth === 0) break; - bracketDepth -= 1; - } - } - if (i >= text.length || text[i] !== "]") return -1; - - // Destination: `(` ... `)` with balanced parentheses. An optional - // whitespace-separated `"title"` may follow the destination. - if (text[i + 1] !== "(") return -1; - i += 2; - let parenDepth = 1; - let inQuotes = false; - for (; i < text.length; i += 1) { - const ch = text[i]; - if (ch === "\\") { - i += 1; // skip escaped character - continue; - } - if (ch === '"') { - inQuotes = !inQuotes; - continue; - } - if (inQuotes) continue; - if (ch === "(") { - parenDepth += 1; - } else if (ch === ")") { - parenDepth -= 1; - if (parenDepth === 0) return i + 1; - } - } - return -1; -} - -/** - * True when a section contains no substantive text after removing media - * tokens and whitespace. Used to decide whether a media-only section should - * count as empty for quality validation. - */ -function isMediaOnly(text) { - if (typeof text !== "string") return false; - const stripped = stripMediaTokens(text); - return stripped.replace(/\s+/g, "").length === 0; -} - -/** - * Strip HTML comments, placeholder-only values, and trim whitespace. - */ -function clean(raw) { - if (typeof raw !== "string") return ""; - let s = raw.replace(//g, ""); - // Media-only sections (a lone screenshot or embed) carry no reportable - // text. Strip the media tokens so the section participates in emptiness and - // duplicate detection like any other blank section. This closes the - // image-only-section bypass (see #1098: an ``-only goal hid repeated - // prose in the other sections from duplicate detection). - if (isMediaOnly(s)) { - s = stripMediaTokens(s).replace(/\s+/g, " ").trim(); - } - // Whole-value placeholders first (including a single enclosing fence), so - // line-by-line stripping cannot leave bare fence markers behind. - if (isPlaceholderOnlyValue(s)) return ""; - // Treat placeholder-only lines (GitHub "No response", N/A, etc.) as empty. - s = s - .split("\n") - .map((line) => (isPlaceholderOnlyValue(line) ? "" : line)) - .join("\n"); - if (isPlaceholderOnlyValue(s)) return ""; - return s.trim(); -} - -/** - * Lowercase, strip punctuation (Unicode-aware), collapse whitespace. - */ -function normalise(raw) { - return clean(raw) - .toLowerCase() - .replace(/[^\p{L}\p{N}\s]/gu, "") - .replace(/\s+/g, " ") - .trim(); -} - -/** - * Canonical form for duplicate detection: normalise + strip common filler - * phrases that do not add semantic content. - */ -function canonicalise(raw) { - let s = normalise(raw); - const fillers = [ - /^i want to\s+/, - /^we need to\s+/, - /^would like to\s+/, - /^i would like to\s+/, - /^we would like to\s+/, - /^please\s+/, - ]; - for (const re of fillers) s = s.replace(re, ""); - return s.trim(); -} - -/** - * Extract the text content of a markdown ### section by heading name. - * Returns null when the heading is absent. - */ -function extractSection(body, heading) { - if (typeof body !== "string") return null; - const lines = body.split("\n"); - const headingLower = heading.toLowerCase().trim(); - let capturing = false; - let sectionDepth = 0; - let fence = null; - const out = []; - for (const line of lines) { - if (fence) { - if (new RegExp(`^[ \\t]{0,3}${fence.marker}{${fence.length},}[ \\t]*$`).test(line)) { - fence = null; - } - if (capturing) out.push(line); - continue; - } - - const fenceMatch = line.match(/^[ \t]{0,3}(`{3,}|~{3,})/); - if (fenceMatch) { - fence = { marker: fenceMatch[1][0], length: fenceMatch[1].length }; - if (capturing) out.push(line); - continue; - } - - const m = line.match(/^(#{2,4})\s+(.*)/); - if (m) { - const depth = m[1].length; - if (capturing && depth <= sectionDepth) break; - if (!capturing && m[2].toLowerCase().trim() === headingLower) { - capturing = true; - sectionDepth = depth; - continue; - } - } - if (capturing) out.push(line); - } - if (!capturing) return null; - return out.join("\n").trim(); -} - -/** - * Resolve a logical section from the first matching heading. - * Prefers the first non-empty match; if every present heading is empty, - * returns that empty string so callers can distinguish "missing" (null) - * from "present but blank". - */ -function resolveSection(body, headings) { - let firstPresent = null; - for (const heading of headings) { - const section = extractSection(body, heading); - if (section === null) continue; - if (firstPresent === null) firstPresent = section; - if (!isEmpty(section)) return section; - } - return firstPresent; -} - -/** - * True when the body has multiple non-empty h2–h4 sections with enough detail. - * Soft-pass only — unstructured length alone is not enough, and a single - * arbitrary heading must not bypass the quality gate (Codex on #564). - */ -function hasSubstantialStructuredContent(body, minSectionLen = 40, minRichSections = 2) { - if (typeof body !== "string") return false; - const lines = body.split("\n"); - let capturing = false; - let bucket = []; - let richSections = 0; - const flush = () => { - if (clean(bucket.join("\n")).length >= minSectionLen) richSections += 1; - bucket = []; - }; - for (const line of lines) { - const m = line.match(/^#{2,4}\s+(.*)/); - if (m) { - if (capturing) flush(); - capturing = true; - continue; - } - if (capturing) bucket.push(line); - } - if (capturing) flush(); - return richSections >= minRichSections; -} - -// --------------------------------------------------------------------------- -// Issue kind detection -// --------------------------------------------------------------------------- - -const FEATURE_NEW_HEADINGS = [ - "What are you trying to accomplish?", - "What prevents this today?", - "What should OpenCodex do?", -]; -const FEATURE_LEGACY_HEADINGS = ["Problem to solve", "Proposed solution"]; -const FEATURE_GOAL_HEADINGS = [ - "What are you trying to accomplish?", - "Goal / Problem", - "Goal/Problem", - "Problem to solve", -]; -const FEATURE_BLOCKER_HEADINGS = [ - "What prevents this today?", - "Current limitation", - "Current workaround", -]; -const FEATURE_BEHAVIOUR_HEADINGS = [ - "What should OpenCodex do?", - "Expected behaviour", - "Expected behavior", - "Proposed solution", -]; -const FEATURE_EXAMPLE_HEADINGS = [ - "Example usage or interface", - "Example usage", - "Example", -]; -const FEATURE_ALIAS_DETECT_HEADINGS = [ - "Goal / Problem", - "Goal/Problem", - "Expected behaviour", - "Expected behavior", - "Current limitation", - "Current workaround", - "Example usage", - // Intentionally omit bare "Example" — too common in freeform/bug reports. -]; -const BUG_NEW_HEADINGS = ["Client or integration", "Summary", "Reproduction"]; -const BUG_LEGACY_HEADINGS = ["Summary", "Reproduction"]; -const PROVIDER_HEADINGS = [ - "Provider or upstream service", - "Endpoint or capability", - "Current behaviour", - "Expected behaviour", -]; -const DOCS_HEADINGS = [ - "Documentation problem type", - "Documentation location", - "What is wrong or missing?", -]; - -const KIND_TO_LABEL = { - bug: "bug", - feature: "enhancement", - documentation: "documentation", - "provider-compatibility": "provider-compatibility", -}; - -/** - * Orthogonal product-area labels (additive beside kind/process labels). - * Colors/descriptions are used when the workflow ensures labels exist. - */ -const AREA_LABELS = { - provider: { - color: "1D76DB", - description: "Provider adapters, OpenAI-compat presets, upstream API quirks", - }, - "account-pool": { - color: "5319E7", - description: "OAuth, credentials, Codex pool, quota, failover, plans", - }, - catalog: { - color: "006B75", - description: "Model catalog, slugs, visibility, routed entries", - }, - gui: { - color: "D93F0B", - description: "Dashboard, tray, settings UI", - }, - cli: { - color: "FBCA04", - description: "CLI, config inject, packaging flags", - }, - proxy: { - color: "0E8A16", - description: "HTTP proxy, routing, reverse-proxy / management auth", - }, - platform: { - color: "BFDADC", - description: "OS/service/tray/ACL (Windows-heavy, not Windows-only)", - }, - streaming: { - color: "C5DEF5", - description: "SSE, WebSocket, terminal stream frames", - }, - tools: { - color: "F9D0C4", - description: "tool_calls, MCP, web-search / sidecar tools", - }, - install: { - color: "EDEDED", - description: "Installation or packaging", - }, - service: { - color: "EDEDED", - description: "Service lifecycle (WinSW/launchd/scheduler)", - }, -}; - -/** Canonical Area dropdown text → area label(s). Keys are lowercased. */ -const AREA_FIELD_TO_LABELS = { - cli: ["cli"], - "proxy and routing": ["proxy"], - dashboard: ["gui"], - "provider adapter": ["provider"], - "provider adapters": ["provider"], - "authentication and account pool": ["account-pool"], - "catalog / models": ["catalog"], - streaming: ["streaming"], - "tools / mcp / web search": ["tools"], - "installation or packaging": ["install"], - "service lifecycle": ["service"], - "service lifecycle (config injection)": ["service"], - "platform (windows / macos / linux)": ["platform"], - // Do not map to kind label `documentation` — that collides with labelBasedKind - // when a feature/bug form picks Area: Documentation. Docs form already seeds - // the kind label; Area selection alone does not add an area tag. - documentation: [], - // No dedicated label; heuristics still run in detectAreaLabels. - "multiple areas": [], - other: [], -}; - -/** Body headings used for area heuristics (excludes Environment / OS metadata). */ -const AREA_HEURISTIC_BODY_HEADINGS = [ - "Summary", - "Reproduction", - "What are you trying to accomplish?", - "What prevents this today?", - "What should OpenCodex do?", - "Example usage or interface", - "Current behaviour", - "Expected behaviour", - "Minimal redacted request or reproduction", - "What is wrong or missing?", - "Documentation problem type", - "Documentation location", -]; - -/** - * Heuristic rules. `scope: "title"` avoids false hits from template Environment / - * OS fields in the body; `scope: "full"` is for distinctive technical tokens. - */ -const AREA_HEURISTICS = [ - { - label: "account-pool", - scope: "full", - re: /\b(oauth|reauth|needsreauth|account pool|codex.?auth|auto[- ]?switch|account failover|refresh token|plan_type|chatgpt[- ]account|reset credit)\b/i, - }, - { - label: "account-pool", - scope: "title", - re: /\b(quota|failover|pool account|account switch)\b/i, - }, - { - label: "catalog", - scope: "full", - re: /\b(model catalog|opencodex-catalog|model list|model visibility|virtual model|routed (catalog|entries|slug)|model slug)\b/i, - }, - { - label: "catalog", - scope: "title", - re: /\bcatalog\b/i, - }, - { - label: "gui", - scope: "title", - re: /\b(dashboard|\bgui\b|tray|sidebar|settings (page|tab|ui))\b/i, - }, - { - label: "cli", - scope: "title", - re: /\b(ocx\b|config\.toml|config inject)\b/i, - }, - { - label: "proxy", - scope: "full", - re: /\b(reverse[- ]proxy|management api|admin[- ]token|\/api\/\*|bind(s)? the (old )?port)\b/i, - }, - { - label: "proxy", - scope: "title", - re: /\b(reverse[- ]proxy|management api|admin[- ]token)\b/i, - }, - { - label: "platform", - scope: "full", - re: /\b(winsw|launchd|schtasks|icacls|windows-latest|tray host|scheduler backend)\b/i, - }, - { - label: "platform", - scope: "title", - re: /\b(\[windows\]|\[macos\]|windows|macos|darwin|win32|wsl)\b/i, - }, - { - label: "streaming", - scope: "full", - re: /\b(sse|websocket|\bws\b|stream(ing)?\b.{0,40}\btruncat\w*|stream(ing)?\b.{0,40}\bterminal\b|terminal (sse )?frame|without a terminal)\b/i, - }, - { - label: "tools", - scope: "full", - re: /\b(tool_calls?|tool[- ]calls?|\bmcp\b|web[- ]search|tool[- ]recall)\b/i, - }, - { - label: "install", - scope: "full", - re: /\b(npm (global )?install|packaging|release asset|npx ocx)\b/i, - }, - { - label: "service", - scope: "full", - re: /\b(ocx service|winsw|scheduler backend|launchd service)\b/i, - }, - { - label: "provider", - scope: "full", - re: /\b(provider adapter|openai[- ]compatible|provider[- ]compat|adapter quirk|built[- ]in provider|provider preset)\b/i, - }, - { - label: "provider", - scope: "title", - re: /\b(\[provider\]|provider compat|openai[- ]compatible)\b/i, - }, -]; - -/** - * Map a detected issue kind to its triage label. Returns null when unknown. - */ -function labelForKind(kind) { - if (!kind || typeof kind !== "string") return null; - return KIND_TO_LABEL[kind] || null; -} - -/** - * Map a template Area dropdown value to orthogonal area label names. - * Returns [] for Other / Multiple areas / unknown / empty. - * - * @param {unknown} areaText - * @returns {string[]} - */ -function mapAreaFieldToLabels(areaText) { - if (typeof areaText !== "string") return []; - const key = areaText.replace(/\s+/g, " ").trim().toLowerCase(); - if (!key) return []; - return AREA_FIELD_TO_LABELS[key] ? [...AREA_FIELD_TO_LABELS[key]] : []; -} - -/** - * Build heuristic text from title-relevant semantic sections only — never from - * Operating system / Version / Checks metadata that every template includes. - * - * @param {string} body - * @returns {string} - */ -function bodyForAreaHeuristics(body) { - if (typeof body !== "string" || !body.trim()) return ""; - const parts = []; - for (const heading of AREA_HEURISTIC_BODY_HEADINGS) { - const section = extractSection(body, heading); - if (section) parts.push(section); - } - return parts.join("\n\n"); -} - -/** - * Conservative title/body heuristics for orthogonal area labels. - * - * @param {string} title - * @param {string} body semantic body text (already filtered) - * @returns {string[]} - */ -function heuristicAreaLabels(title, body) { - const titleText = title || ""; - const fullText = `${titleText}\n${body || ""}`; - const seen = new Set(); - const out = []; - for (const { label, re, scope } of AREA_HEURISTICS) { - const text = scope === "title" ? titleText : fullText; - if (!re.test(text) || seen.has(label)) continue; - seen.add(label); - out.push(label); - } - return out; -} - -/** - * Detect additive product-area labels from Area field, form defaults, and - * title/body heuristics. Never invents per-provider labels. - * - * @param {{ - * title?: string, - * body?: string, - * labels?: string[], - * heuristicBody?: string, - * }} issue - * `body` is the source form (for Area / provider headings). - * `heuristicBody` may include English translation text for heuristics only. - * @returns {string[]} - */ -function detectAreaLabels(issue) { - const title = typeof issue?.title === "string" ? issue.title : ""; - const body = typeof issue?.body === "string" ? issue.body : ""; - const labels = Array.isArray(issue?.labels) ? issue.labels : []; - const heuristicSource = typeof issue?.heuristicBody === "string" ? issue.heuristicBody : body; - - const areaSection = extractSection(body, "Area"); - const fromArea = mapAreaFieldToLabels(areaSection); - const fromHeur = heuristicAreaLabels(title, bodyForAreaHeuristics(heuristicSource)); - const fromForm = []; - if (labels.includes("provider-compatibility")) fromForm.push("provider"); - // Provider-compat form uses this heading instead of Area. - if (extractSection(body, "Provider or upstream service") !== null) { - fromForm.push("provider"); - } - - const seen = new Set(); - const out = []; - for (const label of [...fromArea, ...fromForm, ...fromHeur]) { - if (!label || seen.has(label)) continue; - if (!AREA_LABELS[label]) continue; - seen.add(label); - out.push(label); - } - return out; -} - -function countHeadings(body, headings) { - let n = 0; - for (const h of headings) { - if (extractSection(body, h) !== null) n++; - } - return n; -} - -/** - * Detect the issue kind from body headings, title prefix, labels, and - * optional stored bot kind. - * - * @param {{ title: string, body: string, labels: string[], storedKind?: string|null }} issue - * @returns {"feature"|"bug"|"provider-compatibility"|"documentation"|null} - */ -function detectIssueKindFromContent(issue) { - const { title = "", body = "", labels = [] } = issue; - const titleLower = title.toLowerCase(); - - // Provider compatibility: distinct headings. - if (countHeadings(body, PROVIDER_HEADINGS) >= 3) return "provider-compatibility"; - - // Documentation: distinct headings. - if (countHeadings(body, DOCS_HEADINGS) >= 2) return "documentation"; - - // New feature form: at least 2 of the 3 core headings. - if (countHeadings(body, FEATURE_NEW_HEADINGS) >= 2) return "feature"; - - // Translated / alternate feature headings (e.g. after issue-triage). - // Require a feature-specific goal heading so common headings like - // "Expected behaviour" cannot reclassify bug/freeform reports as features. - // ([Feature]: prefix and enhancement labels are handled elsewhere.) - if ( - countHeadings(body, FEATURE_ALIAS_DETECT_HEADINGS) >= 2 && - countHeadings(body, FEATURE_GOAL_HEADINGS) >= 1 - ) { - return "feature"; - } - - // New bug form: Client or integration + Summary + Reproduction. - if ( - extractSection(body, "Client or integration") !== null && - extractSection(body, "Summary") !== null && - extractSection(body, "Reproduction") !== null - ) { - return "bug"; - } - - // Legacy feature form: title prefix or old headings. - if (titleLower.startsWith("[feature]:") || countHeadings(body, FEATURE_LEGACY_HEADINGS) >= 2) { - return "feature"; - } - - // Legacy bug form: title prefix or old headings (Summary + Reproduction). - if (titleLower.startsWith("[bug]:") || countHeadings(body, BUG_LEGACY_HEADINGS) >= 2) { - // Only classify as bug when there is supporting evidence (label or prefix) - // to avoid false positives on generic issues that happen to have those words. - if (titleLower.startsWith("[bug]:") || labels.includes("bug")) return "bug"; - } - - return null; -} - -/** - * True when body evidence for `kind` is a full structured form, not merely a - * title prefix or leftover label. Used to decide whether detected kind may - * override a stored bot kind. - */ -function hasStrongKindEvidence(kind, issue) { - const { body = "" } = issue; - switch (kind) { - case "provider-compatibility": - return countHeadings(body, PROVIDER_HEADINGS) >= 3; - case "documentation": - return countHeadings(body, DOCS_HEADINGS) >= 2; - case "feature": - return ( - countHeadings(body, FEATURE_NEW_HEADINGS) >= 2 || - countHeadings(body, FEATURE_LEGACY_HEADINGS) >= 2 || - (countHeadings(body, FEATURE_ALIAS_DETECT_HEADINGS) >= 2 && - countHeadings(body, FEATURE_GOAL_HEADINGS) >= 1) - ); - case "bug": - return ( - extractSection(body, "Client or integration") !== null && - extractSection(body, "Summary") !== null && - extractSection(body, "Reproduction") !== null - ); - default: - return false; - } -} - -/** - * Detect the issue kind from body headings, title prefix, labels, and - * optional stored bot kind. - * - * Stored kind survives heading removal (bypass protection). A different - * detected kind overrides it only when the body has strong form evidence. - * - * @param {{ title: string, body: string, labels: string[], storedKind?: string|null }} issue - * @returns {"feature"|"bug"|"provider-compatibility"|"documentation"|null} - */ -function detectIssueKind(issue) { - const { storedKind } = issue; - const detected = detectIssueKindFromContent(issue); - - if (storedKind) { - if ( - detected && - detected !== storedKind && - hasStrongKindEvidence(detected, issue) - ) { - return detected; - } - return storedKind; - } - - return detected; -} - -// --------------------------------------------------------------------------- -// Validation -// --------------------------------------------------------------------------- - -function isEmpty(text) { - const c = clean(text); - if (c.length === 0) return true; - // Stand-ins like "...", "…", "---" are not actionable report content. - return /^[\p{P}\p{S}\s]+$/u.test(c); -} - -function allSameCanonical(sections) { - const cans = sections.map(canonicalise).filter(Boolean); - if (cans.length < 2) return false; - return cans.every((c) => c === cans[0]); -} - -function allRepeatTitle(sections, title) { - const titleCan = canonicalise(title); - if (!titleCan) return false; - const cans = sections.map(canonicalise).filter(Boolean); - if (cans.length === 0) return false; - return cans.every((c) => c === titleCan); -} - -function isPlaceholder(text) { - return isPlaceholderOnlyValue(text); -} - -/** - * True when Version is an "I don't know" stand-in rather than an install id. - * Kept separate from PLACEHOLDER_ONLY_RE so legacy N/A / No response soft-pass - * behaviour is unchanged. - */ -const UNUSABLE_VERSION_RE = - /^[\s_*~`]*(?:unknown|unkown|uknown|don'?t\s+know|do\s+not\s+know|idk|dunno|not\s+sure|unsure|\?+|모름|잘\s*모름|모르겠(?:습니다|음)?|不明|わからない|分からない|不知道|不清楚|keine\s+ahnung|wei[sß]{1,2}\s+nicht)[\s_*~`]*[.!?]*$/i; - -function isUnusableVersion(raw) { - const value = normalizeRawSectionValue(raw); - if (value === null) return false; - return UNUSABLE_VERSION_RE.test(value); -} - -const CJK_RE = - /[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}]/gu; - -function countWords(text) { - const c = clean(text); - if (!c) return 0; - - // Count each CJK character as one unit, and non-CJK scripts as Unicode - // word tokens. Mixing one CJK glyph into a Latin/Cyrillic word must not - // inflate the count to letter-length. - const cjkChars = c.match(CJK_RE) || []; - const nonCjkText = c.replace(CJK_RE, " "); - const nonCjkTokens = nonCjkText.match(/[\p{L}\p{N}']+/gu) || []; - - return cjkChars.length + nonCjkTokens.length; -} - -function hasConcreteDetail(text) { - const c = clean(text); - if (!c) return false; - return ( - /\d/.test(c) || - /[`{}\[\]<>/\\]/.test(c) || - /\b(ocx|config|api|cli|dashboard|provider|proxy|route|endpoint|workflow|command)\b/i.test(c) - ); -} - -function isTooTerseFeatureSection(text) { - if (isEmpty(text) || isPlaceholder(text)) return false; - const words = countWords(text); - if (words >= 8) return false; - if (words >= 6 && hasConcreteDetail(text)) return false; - return true; -} - -/** - * Bug Reproduction needs concrete signals that let a maintainer reproduce the - * failure. Product keywords alone (e.g. "choose model deepseek" or "send a - * message in the codex plugin") are not actionable: the report must name a - * command, an error, a file/config path, or an exact observed output. - */ -// Commands and exact technical actions, e.g. "ocx start", "run bun", -// "send a streaming request", "curl https://...". -const REPRO_COMMAND_RE = new RegExp([ - "\\b(?:run|start|stop|restart|install|launch|execute|reproduce|trigger|invoke)\\s+(?:(?:the|an|a)\\s+)?(?:ocx|bun|npm|pnpm|yarn|curl|node|codex|proxy|server|dashboard|plugin)\\b", - "\\b(?:ocx|bun|npm|pnpm|yarn|curl|node|codex)\\s+(?:start|run|stop|restart|install|config|--[a-z-]+)\\b", - "\\b(?:send|issue|make|post)\\s+(?:a|an|any)\\s+(?:streaming|api|http|json|completion|chat|config|auth|embedding|post|graphql|grpc)\\s+(?:request|call|command|prompt|query)\\b", - "\\b(?:send|issue|make|post)\\s+(?:a|an|any)\\s+(?:api|curl|endpoint|url)\\b", - "\\b(?:send|issue|make|post)\\s+(?:a|an|any)\\s+[\\w.-]+\\s+request\\s+to\\s+(?:the\\s+)?(?:endpoint|url|api|server|proxy|\\S+/\\S+)\\b", - "\\b(?:pip|npm|bun)\\s+install\\b", - "\\b(?:curl|wget)\\s+[^\\s]+", -].join("|"), "i"); - -// Error, exception, and failure tokens, plus status codes in status context -// (bare 3-digit numbers can be ports or version numbers). -const REPRO_FAILURE_RE = new RegExp([ - "\\b(?:segfault|sigsegv|panic|abort|exception|traceback|stack\\s*trace|timeout|timed\\s*out|refused|reset|denied|failed?|error|crash|hang|hangs?|stuck|spinning|empty\\s*response)\\b", - "\\b(?:status\\s*(?:code\\s*)?|code\\s*|http\\s*)(?:is|of|:)?\\s*[1-5]\\d\\d\\b", -].join("|"), "i"); - -// File, config, and log paths such as ~/.codex/config.toml or C:\\logs\\ocx.log. -const REPRO_PATH_RE = new RegExp([ - "~?/[\\w.@-]+(?:/[\\w.@-]+)+", - "[A-Za-z]:\\\\(?:[\\w.@-]+\\\\)+[\\w.@-]+", - "~?/[\\w.@-]+/[\\w.@-]+\\.(?:json|yaml|yml|toml|conf|log|env|txt|ts|js|tsx|jsx|sh|ps1|py)", - "[\\w.@-]+\\.(?:json|yaml|yml|toml|conf|log|env)\\b", -].join("|")); -const ACTIONABLE_REPRO_RE = new RegExp( - [REPRO_COMMAND_RE.source, REPRO_FAILURE_RE.source, REPRO_PATH_RE.source].join("|"), - "i", -); - -// Sigil-only fences with no body content are never actionable. -const EMPTY_FENCE_RE = /^[ \t]{0,3}(?:```+|~~~+)\s*\n\s*\n[ \t]{0,3}(?:```+|~~~+)\s*$/; - -/** - * True when a bug Reproduction names commands, error tokens, file/config - * paths, or exact technical actions. Product/model mentions without any of - * those signals (e.g. #977) are treated as unactionable. Fenced blocks only - * count as actionable when their body contains non-whitespace content. - */ -function hasActionableReproductionDetail(text) { - const c = clean(text); - if (!c) return false; - if (ACTIONABLE_REPRO_RE.test(c)) return true; - // Fenced blocks: only count when the body has non-whitespace content. - if (/```|~~~/.test(c)) { - const parts = stripFencedActionableContent(c); - if (parts) return true; - } - return false; -} - -/** - * Walk the text looking for a fenced code block whose body contains - * non-whitespace content. Returns the non-empty body or null. - */ -function stripFencedActionableContent(text) { - const fenceRe = /^[ \t]{0,3}(`{3,}|~{3,})/; - const lines = text.split("\n"); - let i = 0; - while (i < lines.length) { - const m = lines[i].match(fenceRe); - if (!m) { i++; continue; } - const marker = m[1]; - const markerLen = marker.length; - // Find the closing fence on a later line. - let j = i + 1; - const endRe = new RegExp( - `^[ \\t]{0,3}${marker[0] === "`" ? "`" : "~"}{${markerLen},}[ \\t]*$`, - ); - while (j < lines.length && !endRe.test(lines[j])) j++; - if (j > i + 1) { - const body = lines.slice(i + 1, j).join("\n"); - if (body.trim()) return body; - } - i = j + 1; - } - return null; -} - -function isTooTerseBugReproduction(text) { - if (isEmpty(text) || isPlaceholder(text)) return false; - if (hasActionableReproductionDetail(text)) return false; - return countWords(text) < 12; -} - -/** - * Check if raw section text is a placeholder-only variant without relying on - * clean() first. Used to distinguish intentionally blank optional fields - * (legacy "No response" / N/A) from actively cleared required fields. - */ -function isRawPlaceholder(raw) { - if (raw === null) return false; - return isPlaceholderOnlyValue(raw); -} - -/** - * Near-miss freeform headings that often appear in API-opened or copy-pasted - * bug reports instead of the Bug report template (e.g. Description / Log entry). - */ -const FREEFORM_BUG_NEAR_MISS_HEADINGS = [ - "Description", - "Steps to reproduce", - "Steps to Reproduce", - "How to reproduce", - "Log", - "Logs", - "Log entry", - "Error", - "Error output", - "Stack trace", -]; - -/** - * True when an unclassified body looks like a bug report that skipped the - * template (near-miss headings and/or repro/error signals). - * - * @param {{ title?: string, body?: string }} issue - * @returns {boolean} - */ -function looksLikeUntemplatedBugReport(issue) { - const body = typeof issue?.body === "string" ? issue.body : ""; - if (!body.trim()) return false; - - const nearMissCount = countHeadings(body, FREEFORM_BUG_NEAR_MISS_HEADINGS); - const hasReproduction = - extractSection(body, "Reproduction") !== null || - extractSection(body, "Steps to reproduce") !== null || - extractSection(body, "Steps to Reproduce") !== null || - extractSection(body, "How to reproduce") !== null; - const hasDescription = extractSection(body, "Description") !== null; - const hasLogOrError = - extractSection(body, "Log") !== null || - extractSection(body, "Logs") !== null || - extractSection(body, "Log entry") !== null || - extractSection(body, "Logs or error output") !== null || - extractSection(body, "Error") !== null || - extractSection(body, "Error output") !== null || - extractSection(body, "Stack trace") !== null; - - if (hasDescription && (hasReproduction || hasLogOrError)) return true; - if (hasReproduction && hasLogOrError) return true; - if (nearMissCount >= 2) return true; - - // Body-level signals for heading-free freeform dumps. - const signalRe = - /\b(repro(?:duce|duction| steps)?|stack\s*traces?|traceback|segfault|panic|exception|error\s*output|ECONNREFUSED|SIGSEGV)\b/i; - if (signalRe.test(body) && (hasDescription || hasReproduction || hasLogOrError || nearMissCount >= 1)) { - return true; - } - return false; -} - -/** - * Reasons/guidance when no structured issue kind was detected. - * - * @param {{ title?: string, body?: string }} issue - * @returns {{ reasons: string[], guidance: string[] }} - */ -function untemplatedIssueFailure(issue) { - if (looksLikeUntemplatedBugReport(issue)) { - return { - reasons: [ - "This looks like a bug report but it does not use the Bug report template headings (for example Description/Log entry instead of Summary).", - ], - guidance: [ - "Use the Bug report template, or edit this issue to include: Client or integration, Summary, Reproduction, Version, and Operating system.", - "Retitling with `[Bug]:` and applying the `bug` label alone is not enough without those section headings filled in.", - ], - }; - } - return { - reasons: [ - "This issue does not use a recognized issue template.", - ], - guidance: [ - "Open a new issue with the Bug report, Feature request, Documentation, or Provider compatibility template.", - "Or edit this issue so the body uses the template section headings for the kind of report you are filing.", - ], - }; -} - -/** - * Validate an issue body for its detected kind. - * - * Unclassified (freeform / non-template) issues are invalid so API-opened - * reports cannot skip the quality gate. Trusted-author exemption is enforced - * by the workflow, not here. - * - * @param {{ title: string, body: string, labels: string[], storedKind?: string|null }} issue - * @returns {{ kind: string|null, valid: boolean, softPass: boolean, reasons: string[], guidance: string[] }} - */ -function validateIssue(issue) { - const { title = "", body = "" } = issue; - const kind = detectIssueKind(issue); - const reasons = []; - const guidance = []; - let softPass = false; - - if (!kind) { - const failure = untemplatedIssueFailure(issue); - return { - kind: null, - valid: false, - softPass: false, - reasons: failure.reasons, - guidance: failure.guidance, - }; - } - - if (kind === "feature") { - const goal = resolveSection(body, FEATURE_GOAL_HEADINGS); - const blocker = resolveSection(body, FEATURE_BLOCKER_HEADINGS); - const behaviour = resolveSection(body, FEATURE_BEHAVIOUR_HEADINGS); - const example = resolveSection(body, FEATURE_EXAMPLE_HEADINGS); - - const coreSections = [goal, blocker, behaviour, example]; - const emptyCore = []; - if (isEmpty(goal)) emptyCore.push("goal / problem"); - // blocker and example are only required when those headings exist. - // On the legacy / translated forms these sections may be absent (null). - if (blocker !== null && isEmpty(blocker)) emptyCore.push("current limitation"); - if (isEmpty(behaviour)) emptyCore.push("expected behaviour"); - if (example !== null && isPlaceholder(example)) { - reasons.push("Example usage or interface contains placeholder text instead of a concrete example."); - guidance.push("Add a real CLI command, config snippet, API exchange, or before/after workflow example."); - } else if (example !== null && isEmpty(example)) { - emptyCore.push("example usage"); - } - - const mappedHeadingPresent = - goal !== null || blocker !== null || behaviour !== null || example !== null; - - if (emptyCore.length > 0) { - // Soft-pass rich non-template bodies once kind is already feature (title - // prefix, enhancement label, or stored kind). Do not require the title to - // keep a `[Feature]:` prefix — maintainer retitles must not re-arm closure. - const canSoftPass = - !mappedHeadingPresent && - hasSubstantialStructuredContent(body); - if (canSoftPass) { - softPass = true; - } else { - reasons.push(`Required sections are missing or empty: ${emptyCore.join(", ")}.`); - guidance.push("Fill in each required section with specific detail about your workflow."); - } - } - - if (!softPass) { - const nonEmpty = coreSections.filter((s) => !isEmpty(s)); - if (nonEmpty.length >= 2 && allSameCanonical(nonEmpty)) { - reasons.push("All core sections contain the same content."); - guidance.push("Each section should describe a different aspect: goal, limitation, expected behaviour, and a concrete example."); - } - - if (nonEmpty.length >= 2 && allRepeatTitle(nonEmpty, title)) { - reasons.push("All core sections merely repeat the issue title."); - guidance.push("Expand each section with details beyond the title."); - } - - if (nonEmpty.length > 0 && nonEmpty.every(isPlaceholder)) { - reasons.push("Required sections contain only placeholder text."); - guidance.push("Replace placeholder text with your actual proposal."); - } - } - - const terseSections = []; - if (goal !== null && isTooTerseFeatureSection(goal)) terseSections.push("goal / problem"); - if (blocker !== null && isTooTerseFeatureSection(blocker)) terseSections.push("current limitation"); - if (behaviour !== null && isTooTerseFeatureSection(behaviour)) terseSections.push("expected behaviour"); - if (terseSections.length > 0) { - reasons.push(`Required sections are too vague to act on: ${terseSections.join(", ")}.`); - guidance.push("Describe the workflow, limitation, and expected behaviour with enough detail for someone to implement or evaluate the request."); - } - } - - if (kind === "bug") { - const summary = extractSection(body, "Summary"); - const repro = extractSection(body, "Reproduction"); - const version = extractSection(body, "Version"); - const os = extractSection(body, "Operating system") ?? extractSection(body, "OS"); - // New Bug report template always includes Client or integration. - const isNewBugForm = extractSection(body, "Client or integration") !== null; - - if (isEmpty(summary) && isEmpty(repro)) { - // Soft-pass substantial non-English / freeform structured reports once - // kind is already bug (label, stored kind, or prior `[Bug]:` detection). - // Requiring the title to keep a `[Bug]:` prefix caused #545: a maintainer - // retitle of an already detailed report was treated as empty Summary/ - // Reproduction and auto-closed. - const canSoftPass = - summary === null && - repro === null && - hasSubstantialStructuredContent(body); - if (canSoftPass) { - softPass = true; - } else { - reasons.push("Both Summary and Reproduction are empty."); - guidance.push("Describe what happened and how to reproduce it."); - } - } else { - // Each mapped field is required on its own — a filled Summary with an - // empty / ellipsis Reproduction (e.g. #598) must not pass. - if (isEmpty(summary)) { - reasons.push("Summary is empty."); - guidance.push("Describe what happened (the symptom or error)."); - } - if (isEmpty(repro)) { - reasons.push("Reproduction is empty."); - guidance.push("List the exact steps to reproduce the problem."); - } else if (!softPass && isTooTerseBugReproduction(repro)) { - reasons.push("Reproduction is too vague to act on."); - guidance.push("List exact steps, commands, and the observed failure — not only a short phrase."); - } - } - - // Version "Unknown" / "모름" / "idk" is never actionable, on any form. - if (!softPass && version !== null && isUnusableVersion(version)) { - reasons.push("Version is missing or unknown."); - guidance.push("Report the installed `@bitkyc08/opencodex` version (for example `2.7.42`) or a commit SHA from `ocx --version`."); - } else if ( - !softPass && - isNewBugForm && - (version === null || isEmpty(version) || isRawPlaceholder(version)) - ) { - // New form requires Version (including when the heading was removed). - // Legacy N/A / No response soft-pass stays only for bodies without - // Client or integration. - reasons.push("Version is missing."); - guidance.push("Add your OpenCodex version so we can reproduce the environment."); - } - - if (!softPass && isNewBugForm && os !== null && isUnusableVersion(os)) { - reasons.push("Operating system is missing or unknown."); - guidance.push("Add your OS name and version (for example Windows 11 24H2)."); - } else if ( - !softPass && - isNewBugForm && - (os === null || isEmpty(os) || isRawPlaceholder(os)) - ) { - reasons.push("Operating system is missing."); - guidance.push("Add your OS name and version (for example Windows 11 24H2)."); - } - - // Required environment fields removed after submission on bodies that are - // not the new form (no Client or integration). Legacy reports never had - // Version or OS fields, so null means absent, not removed. Skip when the - // raw value is a "No response" placeholder — the old form had both fields - // as optional. Only close when the field was actively cleared. - if ( - !softPass && - !isNewBugForm && - version !== null && - os !== null && - isEmpty(version) && - isEmpty(os) && - !isRawPlaceholder(version) && - !isRawPlaceholder(os) - ) { - reasons.push("Version and Operating system are both missing."); - guidance.push("Add your OpenCodex version and OS so we can reproduce the environment."); - } - - if (!softPass) { - const nonEmpty = [summary, repro].filter((s) => !isEmpty(s)); - if (nonEmpty.length >= 2 && allSameCanonical(nonEmpty)) { - reasons.push("Summary and Reproduction contain the same content."); - guidance.push("Summary should describe the symptom; Reproduction should list the exact steps."); - } - - if (nonEmpty.length >= 1 && allRepeatTitle(nonEmpty, title)) { - reasons.push("Summary and Reproduction merely repeat the title."); - guidance.push("Add detail beyond the title: what you observed, what you expected, and the exact steps."); - } - - if (nonEmpty.length > 0 && nonEmpty.every(isPlaceholder)) { - reasons.push("Required sections contain only placeholder text."); - guidance.push("Replace placeholder text with your actual report."); - } - } - } - - if (kind === "provider-compatibility") { - const current = extractSection(body, "Current behaviour"); - const expected = extractSection(body, "Expected behaviour"); - const repro = extractSection(body, "Minimal redacted request or reproduction"); - const response = extractSection(body, "Actual response or error"); - const docs = extractSection(body, "Upstream documentation"); - - const emptyCore = []; - if (isEmpty(current)) emptyCore.push("current behaviour"); - if (isEmpty(expected)) emptyCore.push("expected behaviour"); - // Metadata fields: provider, version, endpoint are required on the form. - const provider = extractSection(body, "Provider or upstream service"); - const version = extractSection(body, "OpenCodex version"); - const endpoint = extractSection(body, "Endpoint or capability"); - if (provider !== null && isEmpty(provider)) emptyCore.push("provider or upstream service"); - if (version !== null && isRawPlaceholder(version) === false && isEmpty(version)) emptyCore.push("OpenCodex version"); - if (endpoint !== null && isEmpty(endpoint)) emptyCore.push("endpoint or capability"); - if (emptyCore.length > 0) { - // Same soft-pass as bug/feature: label- or maintainer-scoped provider - // reports often use non-English structured headings after a retitle. - const mappedHeadingPresent = - current !== null || expected !== null || repro !== null || response !== null || docs !== null || - provider !== null || version !== null || endpoint !== null; - const canSoftPass = - !mappedHeadingPresent && - hasSubstantialStructuredContent(body); - if (canSoftPass) { - softPass = true; - } else { - reasons.push(`Required sections are missing or empty: ${emptyCore.join(", ")}.`); - guidance.push("Describe both the current and expected behaviour."); - } - } - - if (!softPass && !isEmpty(current) && !isEmpty(expected) && canonicalise(current) === canonicalise(expected)) { - reasons.push("Current and expected behaviour are effectively identical."); - guidance.push("Explain the difference between what happens now and what should happen."); - } - - const allSections = [current, expected, repro, response].filter((s) => !isEmpty(s)); - if (!softPass && allSections.length >= 2 && allRepeatTitle(allSections, title)) { - reasons.push("All sections merely repeat the issue title."); - guidance.push("Add specific detail in each section."); - } - - if (!softPass && isEmpty(repro) && isEmpty(response)) { - reasons.push("Both the request/reproduction and the actual response/error are absent."); - guidance.push("Include at least a minimal redacted request or the actual error output."); - } - - if (!softPass && isEmpty(docs)) { - reasons.push("Upstream documentation is empty without stating that no public specification exists."); - guidance.push("Add a URL to the provider specification, or state that no public spec exists."); - } - } - - if (kind === "documentation") { - const location = extractSection(body, "Documentation location"); - const problem = extractSection(body, "What is wrong or missing?"); - const expected = extractSection(body, "What should the documentation explain instead?"); - - if (isEmpty(location) && isEmpty(problem)) { - reasons.push("Documentation location and problem description are both missing."); - guidance.push("Point to the exact documentation page and describe what is wrong."); - } - - const nonEmpty = [location, problem, expected].filter((s) => !isEmpty(s)); - if (nonEmpty.length >= 1 && allRepeatTitle(nonEmpty, title)) { - reasons.push("The body merely repeats the title."); - guidance.push("Add detail: the exact URL or path, what is wrong, and what it should say."); - } - - if (nonEmpty.length > 0 && nonEmpty.every(isPlaceholder)) { - reasons.push("Required sections contain only placeholder text."); - guidance.push("Replace placeholder text with the actual documentation problem."); - } - } - - return { - kind, - valid: reasons.length === 0 && !softPass, - softPass, - reasons, - guidance, - }; -} - -// --------------------------------------------------------------------------- -// Closure ownership -// --------------------------------------------------------------------------- - -/** - * Decide whether the bot may auto-close an invalid issue. - * - * After a maintainer reopens and deactivates enforcement, later `edited` - * events must not close the issue again. - * - * @param {{ active?: boolean, maintainerOverride?: boolean }|null|undefined} botState - * @returns {boolean} - */ -function shouldEnforceClosure(botState) { - if (botState && botState.maintainerOverride === true) return false; - return true; -} - -/** - * Decide whether the bot may reopen a closed issue. - * - * @param {{ active: boolean, closedAt: string|null, stateReason: string }} botState - * @param {{ state: string, closed_at: string|null, state_reason: string|null, closed_by?: string|null }} issue - * @param {boolean} maintainerOverride True when a maintainer changed the issue state after the bot. - * @returns {boolean} - */ -function shouldReopen(botState, issue, maintainerOverride) { - if (!botState || !botState.active) return false; - if (issue.state !== "closed") return false; - if (maintainerOverride) return false; - if (issue.closed_at !== botState.closedAt) return false; - if (issue.state_reason !== botState.stateReason) return false; - // Only reopen if the bot itself was the last actor to close the issue. - // A human closing it (even with the same timestamp) means intentional closure. - if (issue.closed_by && issue.closed_by !== "github-actions[bot]") return false; - return true; -} - -/** - * workflow_dispatch accepts a bare issue number, but GitHub reuses the same - * number namespace for issues and pull requests. Reject PR targets before any - * validation or mutation runs. - * - * @param {{ pull_request?: unknown }} issue - * @param {number|string} issueNumber - * @param {string} eventName - * @returns {string|null} - */ -function rejectsWorkflowDispatchPullRequest(issue, issueNumber, eventName) { - if (eventName !== "workflow_dispatch") return null; - if (!issue?.pull_request) return null; - return `#${issueNumber} is a pull request. This workflow only accepts issue numbers.`; -} - -/** - * workflow_dispatch can be started from a selected branch. Reject runs whose - * selected ref is not the repository default branch so untrusted branch code - * cannot drive issue mutations with issues:write. - * - * @param {string} eventName - * @param {string|null|undefined} ref - * @param {string|null|undefined} defaultBranch - * @returns {string|null} - */ -function rejectsWorkflowDispatchNonDefaultBranch(eventName, ref, defaultBranch) { - if (eventName !== "workflow_dispatch") return null; - if (!defaultBranch || typeof defaultBranch !== "string") { - return "workflow_dispatch requires repository.default_branch to be available."; - } - const expected = `refs/heads/${defaultBranch}`; - if (ref !== expected) { - return ( - `workflow_dispatch must run from the default branch (${defaultBranch}); ` + - `selected ref was ${ref || "(empty)"}.` - ); - } - return null; -} - -// --------------------------------------------------------------------------- -// Exports -// --------------------------------------------------------------------------- - -module.exports = { - clean, - normalise, - canonicalise, - stripMediaTokens, - isMediaOnly, - extractSection, - resolveSection, - detectIssueKind, - validateIssue, - looksLikeUntemplatedBugReport, - shouldReopen, - shouldEnforceClosure, - isPlaceholderOnlyValue, - isPlaceholder, - isRawPlaceholder, - isUnusableVersion, - countWords, - hasConcreteDetail, - hasActionableReproductionDetail, - labelForKind, - KIND_TO_LABEL, - AREA_LABELS, - AREA_FIELD_TO_LABELS, - mapAreaFieldToLabels, - bodyForAreaHeuristics, - heuristicAreaLabels, - detectAreaLabels, - hasSubstantialStructuredContent, - rejectsWorkflowDispatchPullRequest, - rejectsWorkflowDispatchNonDefaultBranch, -}; diff --git a/.github/scripts/issue-quality.test.cjs b/.github/scripts/issue-quality.test.cjs deleted file mode 100644 index 4f22c4247c..0000000000 --- a/.github/scripts/issue-quality.test.cjs +++ /dev/null @@ -1,2028 +0,0 @@ -"use strict"; - -const { describe, it } = require("node:test"); -const assert = require("node:assert/strict"); -const { - clean, - normalise, - canonicalise, - extractSection, - detectIssueKind, - validateIssue, - looksLikeUntemplatedBugReport, - shouldReopen, - shouldEnforceClosure, - labelForKind, - AREA_LABELS, - mapAreaFieldToLabels, - detectAreaLabels, - isPlaceholderOnlyValue, - isPlaceholder, - isRawPlaceholder, - isUnusableVersion, - stripMediaTokens, - isMediaOnly, - countWords, - hasConcreteDetail, - hasActionableReproductionDetail, - rejectsWorkflowDispatchPullRequest, - rejectsWorkflowDispatchNonDefaultBranch, -} = require("./issue-quality.cjs"); - -function featureBodyWithGoal(goal) { - return [ - "### Area", - "CLI", - "### What are you trying to accomplish?", - goal, - "### What prevents this today?", - "Port resets to 10100 after every ocx stop command.", - "### What should OpenCodex do?", - "Persist the last used port in config across restarts.", - "### Example usage or interface", - "ocx start --port 8080 && ocx stop && ocx start", - ].join("\n"); -} - -function featureBodyWithExample(example) { - return [ - "### What are you trying to accomplish?", - "Route voice requests to a configured fallback provider when the primary quota is exhausted.", - "### What prevents this today?", - "Voice mode is hard-wired to the primary Codex quota and cannot switch providers.", - "### What should OpenCodex do?", - "Expose a setting to choose the fallback voice model and provider.", - "### Example usage or interface", - example, - ].join("\n"); -} - -// --------------------------------------------------------------------------- -// Detection -// --------------------------------------------------------------------------- - -describe("detectIssueKind", () => { - it("detects new feature form without [Feature]: prefix", () => { - const body = [ - "### Area", - "Proxy and routing", - "### What are you trying to accomplish?", - "Route requests to a fallback provider.", - "### What prevents this today?", - "No fallback support.", - "### What should OpenCodex do?", - "Fall back automatically.", - "### Example usage or interface", - "ocx config set routing.fallback anthropic", - ].join("\n"); - assert.equal(detectIssueKind({ title: "Add fallback routing", body, labels: ["enhancement"] }), "feature"); - }); - - it("detects legacy feature form with [Feature]: prefix", () => { - const body = [ - "### Problem to solve", - "I want opencodex to support streaming.", - "### Proposed solution", - "Add SSE passthrough.", - ].join("\n"); - assert.equal(detectIssueKind({ title: "[Feature]: streaming support", body, labels: ["enhancement"] }), "feature"); - }); - - it("detects new bug form without [Bug]: prefix", () => { - const body = [ - "### Client or integration", - "Codex CLI", - "### Area", - "Proxy and routing", - "### Summary", - "Proxy crashes on startup.", - "### Reproduction", - "1. ocx start", - "### Version", - "2.7.31", - "### Operating system", - "Windows 11", - ].join("\n"); - assert.equal(detectIssueKind({ title: "Proxy crashes", body, labels: ["bug"] }), "bug"); - }); - - it("detects legacy bug form with [Bug]: prefix", () => { - const body = [ - "### Summary", - "The proxy returns 502.", - "### Reproduction", - "Send a request to /v1/responses.", - ].join("\n"); - assert.equal(detectIssueKind({ title: "[Bug]: 502 on responses", body, labels: ["bug"] }), "bug"); - }); - - it("detects provider compatibility form", () => { - const body = [ - "### Client or integration", - "Codex CLI", - "### Provider or upstream service", - "anthropic", - "### OpenCodex version", - "2.7.31", - "### Endpoint or capability", - "/v1/messages", - "### Current behaviour", - "Returns 400.", - "### Expected behaviour", - "Returns 200 with a message.", - "### Minimal redacted request or reproduction", - "curl ...", - "### Actual response or error", - "400 Bad Request", - "### Upstream documentation", - "https://docs.anthropic.com/en/api/messages", - ].join("\n"); - assert.equal(detectIssueKind({ title: "Anthropic messages 400", body, labels: ["enhancement"] }), "provider-compatibility"); - }); - - it("detects documentation form", () => { - const body = [ - "### Documentation problem type", - "Missing documentation", - "### Documentation location", - "docs/providers.md", - "### What is wrong or missing?", - "No mention of the xai provider.", - "### What should the documentation explain instead?", - "How to configure xai.", - ].join("\n"); - assert.equal(detectIssueKind({ title: "Missing xai docs", body, labels: ["documentation"] }), "documentation"); - }); - - it("returns null for unrelated issue with manually applied enhancement label", () => { - const body = "Just a random question about setup."; - assert.equal(detectIssueKind({ title: "How do I configure?", body, labels: ["enhancement"] }), null); - }); - - it("uses stored bot kind when headings are removed", () => { - const body = "Some edited text without headings."; - assert.equal(detectIssueKind({ title: "My issue", body, labels: [], storedKind: "feature" }), "feature"); - }); -}); - -// --------------------------------------------------------------------------- -// Validation: feature -// --------------------------------------------------------------------------- - -describe("validateIssue - feature", () => { - it("keeps nested sub-headings and fenced heading text inside a section (#541)", () => { - const body = [ - "### What are you trying to accomplish?", - "Route Studio models through the user's WordPress.com account.", - "### What prevents this today?", - "The provider needs two wire formats and one shared OAuth identity.", - "### What should OpenCodex do?", - "Add a first-class provider with model-specific transport selection.", - "### Example usage or interface", - "#### CLI flow", - "```bash", - "# This heading-shaped shell comment must stay inside the fence", - "ocx login wordpress-studio", - "```", - "#### Dashboard flow", - "Providers -> WordPress Studio Code -> Log in", - "### Alternatives or workarounds", - "Use Studio directly.", - ].join("\n"); - - const example = extractSection(body, "Example usage or interface"); - assert.match(example, /^#### CLI flow/); - assert.match(example, /# This heading-shaped shell comment/); - assert.match(example, /#### Dashboard flow/); - assert.doesNotMatch(example, /Alternatives or workarounds/); - - const result = validateIssue({ title: "Add WordPress Studio provider", body, labels: ["enhancement"] }); - assert.equal(result.kind, "feature"); - assert.equal(result.valid, true, `Expected valid but got reasons: ${result.reasons.join(", ")}`); - }); - - it("ignores markdown headings inside backtick and tilde fences when finding section boundaries (#541)", () => { - for (const fence of ["```", "~~~~"]) { - const body = [ - "### Example usage or interface", - fence, - "### pasted heading", - "real example content", - fence, - "### Next sibling", - "outside", - ].join("\n"); - assert.equal( - extractSection(body, "Example usage or interface"), - [fence, "### pasted heading", "real example content", fence].join("\n"), - ); - } - }); - - it("rejects issue #208-style duplicate content", () => { - const repeated = "Add support for streaming responses in the proxy"; - const body = [ - "### What are you trying to accomplish?", - repeated, - "### What prevents this today?", - repeated, - "### What should OpenCodex do?", - repeated, - "### Example usage or interface", - repeated, - ].join("\n"); - const result = validateIssue({ title: repeated, body, labels: ["enhancement"] }); - assert.equal(result.kind, "feature"); - assert.equal(result.valid, false); - assert.ok(result.reasons.length > 0); - }); - - it("rejects an image-only goal section that hides repeated prose (#1098)", () => { - // Regression for #1098: an HTML in the goal section made the goal - // look non-empty, so the repeated identical sentences in the other three - // sections were not caught as duplicates and the issue passed validation. - const repeated = - "It is hoped that the usage query will support time-based queries and statistics, as well as key-based queries and statistics"; - const img = - 'Image'; - const body = [ - "### Area", - "CLI", - "### What are you trying to accomplish?", - img, - "### What prevents this today?", - repeated, - "### What should OpenCodex do?", - repeated, - "### Example usage or interface", - repeated, - ].join("\n"); - const result = validateIssue({ title: repeated, body, labels: ["enhancement"] }); - assert.equal(result.kind, "feature"); - assert.equal(result.valid, false); - assert.ok( - result.reasons.some((r) => /missing or empty/i.test(r)), - `Expected missing/empty reason, got: ${result.reasons.join("; ")}`, - ); - assert.ok( - result.reasons.some((r) => /same content/i.test(r)), - `Expected duplicate-content reason, got: ${result.reasons.join("; ")}`, - ); - assert.ok( - result.reasons.some((r) => /repeat the issue title/i.test(r)), - `Expected repeated-title reason, got: ${result.reasons.join("; ")}`, - ); - }); - - it("rejects a markdown-image-only goal section with repeated prose (#1098)", () => { - const repeated = - "It is hoped that the usage query will support time-based queries and statistics, as well as key-based queries and statistics"; - const mdImg = "![Image](https://github.com/user-attachments/assets/17ea27a8-cec6-4591-aa09-a0ce36f1211f)"; - const body = [ - "### What are you trying to accomplish?", - mdImg, - "### What prevents this today?", - repeated, - "### What should OpenCodex do?", - repeated, - "### Example usage or interface", - repeated, - ].join("\n"); - const result = validateIssue({ title: repeated, body, labels: ["enhancement"] }); - assert.equal(result.kind, "feature"); - assert.equal(result.valid, false); - assert.ok( - result.reasons.some((r) => /missing or empty/i.test(r)), - `Expected missing/empty reason, got: ${result.reasons.join("; ")}`, - ); - }); - - it("rejects a markdown image with bracketed alt text in the goal (#1098)", () => { - const repeated = - "It is hoped that the usage query will support time-based queries and statistics, as well as key-based queries and statistics"; - // GitHub permits balanced brackets inside image alt text, e.g. - // ![Image [screenshot]](url). The stripper must still treat it as - // media-only so it cannot hide repeated prose. - const mdImg = "![Image [screenshot]](https://example.com/x.png)"; - const body = [ - "### What are you trying to accomplish?", - mdImg, - "### What prevents this today?", - repeated, - "### What should OpenCodex do?", - repeated, - "### Example usage or interface", - repeated, - ].join("\n"); - const result = validateIssue({ title: repeated, body, labels: ["enhancement"] }); - assert.equal(result.kind, "feature"); - assert.equal(result.valid, false); - assert.ok( - result.reasons.some((r) => /missing or empty/i.test(r)), - `Expected missing/empty reason, got: ${result.reasons.join("; ")}`, - ); - }); - - it("rejects a markdown image whose URL contains balanced parentheses (#1098)", () => { - const repeated = - "It is hoped that the usage query will support time-based queries and statistics, as well as key-based queries and statistics"; - // Markdown destinations may contain balanced parentheses, e.g. - // ![diagram](https://example.com/image_(final).png). The stripper must - // still treat it as media-only so it cannot hide repeated prose. - const mdImg = "![diagram](https://example.com/image_(final).png)"; - const body = [ - "### What are you trying to accomplish?", - mdImg, - "### What prevents this today?", - repeated, - "### What should OpenCodex do?", - repeated, - "### Example usage or interface", - repeated, - ].join("\n"); - const result = validateIssue({ title: repeated, body, labels: ["enhancement"] }); - assert.equal(result.kind, "feature"); - assert.equal(result.valid, false); - assert.ok( - result.reasons.some((r) => /missing or empty/i.test(r)), - `Expected missing/empty reason, got: ${result.reasons.join("; ")}`, - ); - }); - - it("preserves a goal section that mixes an image with real text", () => { - const goal = [ - "![Screenshot](https://example.com/shot.png)", - "Route voice requests to a configured fallback provider when the primary quota is exhausted.", - ].join("\n"); - const result = validateIssue({ - title: "Voice fallback routing", - body: featureBodyWithGoal(goal), - labels: ["enhancement"], - }); - assert.equal(result.kind, "feature"); - assert.equal(result.valid, true); - }); - - it("treats image/media-only sections as empty via isMediaOnly", () => { - assert.equal(isMediaOnly(''), true); - assert.equal(isMediaOnly("![alt](https://example.com/x.png)"), true); - assert.equal(isMediaOnly("![alt [with bracket]](https://example.com/x.png)"), true); - assert.equal(isMediaOnly("![diagram](https://example.com/image_(final).png)"), true); - assert.equal(isMediaOnly('![alt](https://example.com/image_(final).png "title")'), true); - assert.equal(isMediaOnly("![bad](https://example.com/a)b.png)"), false); - assert.equal(isMediaOnly("\\![escaped](url)"), false); - // Reference-style images (Codex bot finding): inline ref + definition. - assert.equal(isMediaOnly("![Image][shot]\n\n[shot]: https://example.com/x.png"), true); - assert.equal(isMediaOnly("![Image][]\n\n[Image]: https://example.com/x.png"), true); - assert.equal(isMediaOnly("![Image][shot]\n\n[shot]: https://example.com/x.png\ncaption"), false); - // Fallback prose inside media blocks is preserved (Codex bot finding). - assert.equal( - isMediaOnly(""), - false, - ); - assert.equal(isMediaOnly(''), true); - assert.equal(isMediaOnly("Fallback image description"), false); - // Indented code blocks render as literal code, not images (Codex bot finding). - assert.equal(isMediaOnly(" ![provider status](https://example.com/status.png)"), false); - assert.equal(isMediaOnly("\t![provider status](https://example.com/status.png)"), false); - // HTML media inside indented code is also literal code (CodeRabbit finding). - assert.equal(isMediaOnly(' '), false); - assert.equal(isMediaOnly(' '), false); - assert.equal(isMediaOnly('\t'), false); - // Reference labels with nested alt brackets (CodeRabbit finding). - assert.equal(isMediaOnly("![Image [screenshot]][shot]\n\n[shot]: https://example.com/x.png"), true); - assert.equal( - isMediaOnly("![Image [screenshot]][shot]\n\n[shot]: https://example.com/x.png\ncaption"), - false, - ); - assert.equal(isMediaOnly(''), true); - assert.equal(isMediaOnly(''), true); - assert.equal(isMediaOnly('\nCaption text'), false); - assert.equal(isMediaOnly("Some real description."), false); - assert.equal(stripMediaTokens('').trim(), ""); - assert.equal(stripMediaTokens('![alt](url "title")').trim(), ""); - assert.equal(stripMediaTokens('before ![alt](url) after').replace(/\s+/g, " ").trim(), "before after"); - }); - - it("accepts a concise but actionable feature", () => { - const body = [ - "### Area", - "CLI", - "### What are you trying to accomplish?", - "Pin the proxy port across restarts.", - "### What prevents this today?", - "Port resets to 10100 after ocx stop.", - "### What should OpenCodex do?", - "Remember the last used port in config.", - "### Example usage or interface", - "ocx start --port 8080 && ocx stop && ocx start # still 8080", - ].join("\n"); - const result = validateIssue({ title: "Persist port across restarts", body, labels: ["enhancement"] }); - assert.equal(result.kind, "feature"); - assert.equal(result.valid, true); - }); - - it("rejects issue #401-style low-effort feature with placeholder example", () => { - const body = [ - "### Area", - "Proxy and routing", - "### What are you trying to accomplish?", - "Quota for Chatgpt running out that can no longer use voice mode. Would like to change other model for that", - "### What prevents this today?", - "No usage without codex quota", - "### What should OpenCodex do?", - "Change another voice model", - "### Example usage or interface", - "NA", - ].join("\n"); - const result = validateIssue({ - title: "Change voice chat to different model", - body, - labels: ["enhancement"], - }); - assert.equal(result.kind, "feature"); - assert.equal(result.valid, false); - assert.ok(result.reasons.some((r) => r.includes("placeholder"))); - assert.ok(result.reasons.some((r) => r.includes("expected behaviour"))); - }); - - it("rejects feature reports with placeholder example variants", () => { - const placeholders = [ - "NA", - "N/A", - "_N/A_", - "NA.", - "N/A.", - "Not applicable", - "Not applicable.", - "Not available!", - ]; - for (const example of placeholders) { - const body = [ - "### What are you trying to accomplish?", - "Route voice requests to a configured fallback provider when the primary quota is exhausted.", - "### What prevents this today?", - "Voice mode is hard-wired to the primary Codex quota and cannot switch providers.", - "### What should OpenCodex do?", - "Expose a setting to choose the fallback voice model and provider.", - "### Example usage or interface", - example, - ].join("\n"); - const result = validateIssue({ title: "Voice fallback routing", body, labels: ["enhancement"] }); - assert.equal(result.valid, false, `Expected placeholder example "${example}" to be invalid`); - assert.ok( - result.reasons.some((r) => r.includes("placeholder")), - `Expected placeholder reason for "${example}", got: ${result.reasons.join("; ")}`, - ); - assert.ok(!result.reasons.some((r) => r.includes("example usage"))); - } - }); - - it("reports blank example usage as missing, not placeholder", () => { - const body = [ - "### What are you trying to accomplish?", - "Route voice requests to a configured fallback provider when the primary quota is exhausted.", - "### What prevents this today?", - "Voice mode is hard-wired to the primary Codex quota and cannot switch providers.", - "### What should OpenCodex do?", - "Expose a setting to choose the fallback voice model and provider.", - "### Example usage or interface", - "", - ].join("\n"); - const result = validateIssue({ title: "Voice fallback routing", body, labels: ["enhancement"] }); - assert.equal(result.valid, false); - assert.ok(result.reasons.some((r) => r.includes("example usage"))); - assert.ok(!result.reasons.some((r) => r.includes("placeholder"))); - }); - - it("accepts a valid legacy feature request without blocker/example headings", () => { - const body = [ - "### Problem to solve", - "No way to set a custom timeout per provider in the proxy config.", - "### Proposed solution", - "Add a per-provider timeout field in the config JSON.", - ].join("\n"); - const result = validateIssue({ title: "[Feature]: per-provider timeout", body, labels: ["enhancement"] }); - assert.equal(result.kind, "feature"); - assert.equal(result.valid, true, `Expected valid but got reasons: ${result.reasons.join(", ")}`); - }); - - it("accepts a detailed CJK submission", () => { - const body = [ - "### Area", - "Proxy and routing", - "### What are you trying to accomplish?", - "\u4ee3\u7406\u670d\u52a1\u5668\u9700\u8981\u652f\u6301\u591a\u4e2a\u4e0a\u6e38\u63d0\u4f9b\u5546\u7684\u81ea\u52a8\u6545\u969c\u8f6c\u79fb\uff0c\u5f53\u4e3b\u63d0\u4f9b\u5546\u8fd4\u56de\u9519\u8bef\u65f6\u81ea\u52a8\u5207\u6362\u5230\u5907\u7528\u63d0\u4f9b\u5546\u3002", - "### What prevents this today?", - "\u76ee\u524d\u4ee3\u7406\u4e0d\u652f\u6301\u6545\u969c\u8f6c\u79fb\uff0c\u9700\u8981\u624b\u52a8\u91cd\u542f\u5e76\u66f4\u6539\u914d\u7f6e\u3002", - "### What should OpenCodex do?", - "\u5f53\u4e3b\u63d0\u4f9b\u5546\u8fd4\u56de 5xx \u6216\u8d85\u65f6\u65f6\uff0c\u81ea\u52a8\u5c06\u8bf7\u6c42\u8f6c\u53d1\u5230\u914d\u7f6e\u7684\u5907\u7528\u63d0\u4f9b\u5546\u3002", - "### Example usage or interface", - "```json\n{\"routing\":{\"fallback_provider\":\"anthropic\"}}\n```", - ].join("\n"); - const result = validateIssue({ title: "\u652f\u6301\u591a\u63d0\u4f9b\u5546\u6545\u969c\u8f6c\u79fb", body, labels: ["enhancement"] }); - assert.equal(result.kind, "feature"); - assert.equal(result.valid, true); - }); - - it("rejects terse goal sections that only contain a keyword, digit, or punctuation", () => { - const terseGoals = ["API", "provider", "1", "/", "use CLI", "route 1"]; - for (const goal of terseGoals) { - const result = validateIssue({ - title: "Improve feature request quality", - body: featureBodyWithGoal(goal), - labels: ["enhancement"], - }); - assert.equal(result.kind, "feature"); - assert.equal(result.valid, false, `Expected terse goal "${goal}" to be invalid`); - assert.ok( - result.reasons.some((r) => r.includes("too vague") || /missing or empty/i.test(r)), - `Expected too vague or empty reason for "${goal}", got: ${result.reasons.join(", ")}`, - ); - } - }); - - it("rejects a single long non-CJK word as overly terse", () => { - const terseGoals = [ - "провайдер", - "маршрут", - "πάροχος", - "واجهة", - ]; - for (const goal of terseGoals) { - assert.equal(countWords(goal), 1, `Expected "${goal}" to count as one word`); - const result = validateIssue({ - title: "Improve feature request quality", - body: featureBodyWithGoal(goal), - labels: ["enhancement"], - }); - assert.equal(result.kind, "feature"); - assert.equal(result.valid, false, `Expected terse goal "${goal}" to be invalid`); - assert.ok( - result.reasons.some((r) => r.includes("too vague")), - `Expected too vague reason for "${goal}", got: ${result.reasons.join(", ")}`, - ); - } - }); - - it("counts mixed-script CJK text without inflating non-CJK letter length", () => { - assert.equal(countWords("provider中"), 2); - assert.equal(countWords("провайдер中"), 2); - assert.equal(countWords("configuration中"), 2); - assert.equal(countWords("中provider文"), 3); - }); - - it("rejects mixed-script CJK stubs that only inflate letter counts", () => { - const terseGoals = ["provider中", "провайдер中", "configuration中"]; - for (const goal of terseGoals) { - assert.ok(countWords(goal) < 8, `Expected "${goal}" to stay under 8 units`); - const result = validateIssue({ - title: "Improve feature request quality", - body: featureBodyWithGoal(goal), - labels: ["enhancement"], - }); - assert.equal(result.kind, "feature"); - assert.equal(result.valid, false, `Expected terse goal "${goal}" to be invalid`); - assert.ok( - result.reasons.some((r) => r.includes("too vague")), - `Expected too vague reason for "${goal}", got: ${result.reasons.join(", ")}`, - ); - } - }); - - it("accepts sufficiently detailed goal sections", () => { - const detailedGoal = - "Expose a dashboard setting to choose the fallback voice model and provider."; - const detailedResult = validateIssue({ - title: "Voice fallback routing", - body: featureBodyWithGoal(detailedGoal), - labels: ["enhancement"], - }); - assert.equal(detailedResult.kind, "feature"); - assert.equal(detailedResult.valid, true); - assert.ok(countWords(detailedGoal) >= 8); - }); - - it("accepts a 6-7 word goal when it includes concrete technical detail", () => { - const concreteGoal = "Route requests through the configured API provider."; - assert.equal(countWords(concreteGoal), 7); - assert.ok(countWords(concreteGoal) < 8); - assert.ok(countWords(concreteGoal) >= 6); - assert.equal(hasConcreteDetail(concreteGoal), true); - - const concreteResult = validateIssue({ - title: "Voice fallback routing", - body: featureBodyWithGoal(concreteGoal), - labels: ["enhancement"], - }); - assert.equal(concreteResult.kind, "feature"); - assert.equal(concreteResult.valid, true); - }); - - it("rejects a 6-7 word goal that lacks concrete technical detail", () => { - // Avoid keywords that count as concrete detail (api/provider/workflow/…). - const vagueGoal = "Make this process easier for all users."; - assert.equal(countWords(vagueGoal), 7); - assert.equal(hasConcreteDetail(vagueGoal), false); - - const vagueResult = validateIssue({ - title: "Voice fallback routing", - body: featureBodyWithGoal(vagueGoal), - labels: ["enhancement"], - }); - assert.equal(vagueResult.kind, "feature"); - assert.equal(vagueResult.valid, false); - assert.ok(vagueResult.reasons.some((r) => r.includes("too vague"))); - }); - - it("treats only commands, errors, paths, or exact actions as actionable reproduction detail", () => { - assert.equal(hasActionableReproductionDetail("1. choose model deepseek\n2. send a message in codex plugin"), false); - assert.equal(hasActionableReproductionDetail("I want to work with deepseek in VSCode, but it dont reply"), false); - assert.equal(hasActionableReproductionDetail("1. ocx start --port 10100\n2. Send a request"), true); - assert.equal(hasActionableReproductionDetail("Run ocx start and send any streaming request."), true); - assert.equal(hasActionableReproductionDetail("ocx start on Raspberry Pi 4, send any streaming request."), true); - assert.equal(hasActionableReproductionDetail("send a request"), false); - assert.equal(hasActionableReproductionDetail("make a call"), false); - assert.equal(hasActionableReproductionDetail("post a command"), false); - assert.equal(hasActionableReproductionDetail("make an API call"), true); - assert.equal(hasActionableReproductionDetail("send an HTTP request"), true); - assert.equal(hasActionableReproductionDetail("send a request to /v1/responses"), true); - assert.equal(hasActionableReproductionDetail("The proxy returns HTTP 502 after the first streaming chunk."), true); - assert.equal(hasActionableReproductionDetail("Paste ~/.codex/config.toml, then restart the proxy."), true); - assert.equal(hasActionableReproductionDetail("```\n\n```"), false); - assert.equal(hasActionableReproductionDetail("~~~\n\n~~~"), false); - assert.equal(hasActionableReproductionDetail("```\nSIGSEGV at 0x0000\n```"), true); - }); - - it("rejects fenced placeholder-only examples", () => { - const fencedPlaceholders = [ - "```\nN/A\n```", - "```text\nN/A\n```", - "```json\nNot applicable.\n```", - "~~~text\nN/A\n~~~", - ]; - for (const example of fencedPlaceholders) { - assert.equal( - isPlaceholderOnlyValue(example), - true, - `Expected fenced placeholder to match: ${JSON.stringify(example)}`, - ); - const result = validateIssue({ - title: "Voice fallback routing", - body: featureBodyWithExample(example), - labels: ["enhancement"], - }); - assert.equal(result.valid, false, `Expected fenced placeholder to be invalid: ${JSON.stringify(example)}`); - assert.ok( - result.reasons.some((r) => r.includes("placeholder")), - `Expected placeholder reason for ${JSON.stringify(example)}, got: ${result.reasons.join("; ")}`, - ); - } - }); - - it("accepts real fenced examples that merely mention N/A", () => { - const realExamples = [ - "```text\nThe API returns N/A when no provider is configured.\n```", - '```json\n{"provider":"N/A","fallback":"anthropic"}\n```', - ]; - for (const example of realExamples) { - assert.equal( - isPlaceholderOnlyValue(example), - false, - `Expected real example not to be placeholder-only: ${JSON.stringify(example)}`, - ); - const result = validateIssue({ - title: "Voice fallback routing", - body: featureBodyWithExample(example), - labels: ["enhancement"], - }); - assert.equal( - result.valid, - true, - `Expected real fenced example to remain valid, got: ${result.reasons.join("; ")}`, - ); - } - }); -}); -// --------------------------------------------------------------------------- -// Validation: bug -// --------------------------------------------------------------------------- - -describe("validateIssue - bug", () => { - it("rejects an empty bug report", () => { - const body = [ - "### Client or integration", - "Codex CLI", - "### Area", - "CLI", - "### Summary", - "No response", - "### Reproduction", - "No response", - "### Version", - "No response", - "### Operating system", - "No response", - ].join("\n"); - const result = validateIssue({ title: "Bug", body, labels: ["bug"] }); - assert.equal(result.kind, "bug"); - assert.equal(result.valid, false); - }); - - it("rejects a bug with Summary filled but Reproduction empty", () => { - const body = [ - "### Client or integration", - "Codex CLI", - "### Area", - "CLI", - "### Summary", - "The 'gpt-5.6-sol' model is not supported when using Codex with a ChatGPT account.", - "### Reproduction", - "No response", - "### Version", - "2.7.42", - "### Operating system", - "macOS", - ].join("\n"); - const result = validateIssue({ title: "Open Codex Error", body, labels: ["bug"] }); - assert.equal(result.kind, "bug"); - assert.equal(result.valid, false); - assert.ok(result.reasons.some((r) => /Reproduction is empty/i.test(r))); - assert.ok(!result.reasons.some((r) => /Summary is empty/i.test(r))); - }); - - it("rejects a bug whose Reproduction is only an ellipsis (#598)", () => { - const body = [ - "### Client or integration", - "Codex CLI", - "### Area", - "CLI", - "### Summary", - "{\"detail\":\"The 'gpt-5.6-sol' model is not supported when using Codex with a ChatGPT account.\"}", - "### Reproduction", - "...", - "### Version", - "2.7.42", - "### Operating system", - "mac os", - ].join("\n"); - const result = validateIssue({ title: "Open Codex Error", body, labels: ["bug"] }); - assert.equal(result.kind, "bug"); - assert.equal(result.valid, false); - assert.ok(result.reasons.some((r) => /Reproduction is empty/i.test(r))); - }); - - it("rejects a bug with Reproduction filled but Summary empty", () => { - const body = [ - "### Client or integration", - "Codex CLI", - "### Area", - "CLI", - "### Summary", - "", - "### Reproduction", - "1. Run ocx start\n2. Send a request", - "### Version", - "2.7.42", - "### Operating system", - "macOS", - ].join("\n"); - const result = validateIssue({ title: "Crash", body, labels: ["bug"] }); - assert.equal(result.kind, "bug"); - assert.equal(result.valid, false); - assert.ok(result.reasons.some((r) => /Summary is empty/i.test(r))); - }); - - it("accepts a terse real crash report", () => { - const body = [ - "### Client or integration", - "Codex CLI", - "### Area", - "Proxy and routing", - "### Summary", - "Proxy segfaults on ARM64 when streaming is enabled.", - "### Reproduction", - "ocx start on Raspberry Pi 4, send any streaming request.", - "### Version", - "2.7.30", - "### Operating system", - "Debian 12 aarch64", - "### Logs or error output", - "```", - "SIGSEGV at 0x0000 in bun_runtime", - "```", - ].join("\n"); - const result = validateIssue({ title: "Segfault on ARM64 streaming", body, labels: ["bug"] }); - assert.equal(result.kind, "bug"); - assert.equal(result.valid, true); - }); - - it("accepts a valid legacy bug report without version/OS headings", () => { - const body = [ - "### Summary", - "The proxy crashes when streaming is enabled.", - "### Reproduction", - "Run ocx start and send a streaming request.", - ].join("\n"); - const result = validateIssue({ title: "[Bug]: crash on streaming", body, labels: ["bug"] }); - assert.equal(result.kind, "bug"); - assert.equal(result.valid, true, `Expected valid but got reasons: ${result.reasons.join(", ")}`); - }); - - it("accepts a legacy bug with _No response_ in old optional env fields", () => { - const body = [ - "### Summary", - "Proxy crashes on startup.", - "### Reproduction", - "Run ocx start.", - "### Version", - "_No response_", - "### OS", - "_No response_", - ].join("\n"); - const result = validateIssue({ title: "[Bug]: crash", body, labels: ["bug"] }); - assert.equal(result.kind, "bug"); - assert.equal(result.valid, true, `Expected valid but got: ${result.reasons.join(", ")}`); - }); - - it("accepts a legacy bug with N/A-style placeholders in Version and Operating system", () => { - for (const placeholder of ["N/A", "NA", "Not applicable.", "Not available!"]) { - const body = [ - "### Summary", - "Proxy crashes on startup when streaming is enabled.", - "### Reproduction", - "Run ocx start and send any streaming request.", - "### Version", - placeholder, - "### Operating system", - placeholder, - ].join("\n"); - const result = validateIssue({ title: "[Bug]: crash", body, labels: ["bug"] }); - assert.equal(result.kind, "bug"); - assert.equal( - result.valid, - true, - `Expected legacy env placeholder "${placeholder}" to remain valid, got: ${result.reasons.join(", ")}`, - ); - assert.ok(!result.reasons.some((r) => r.includes("Version"))); - } - }); - - it("rejects a new-form bug where env fields were actively cleared", () => { - const body = [ - "### Client or integration", - "Codex CLI", - "### Summary", - "Proxy crashes.", - "### Reproduction", - "Run ocx start.", - "### Version", - "", - "### Operating system", - "", - ].join("\n"); - const result = validateIssue({ title: "Crash", body, labels: ["bug"] }); - assert.equal(result.kind, "bug"); - assert.equal(result.valid, false); - assert.ok(result.reasons.some((r) => r.includes("Version"))); - }); - - it("rejects unknown / don't-know Version values (#624)", () => { - const versions = [ - "Unknown", - "Uknown", - "unkown", - "Don't know", - "dont know", - "idk", - "모름", - "잘 모름", - "?", - "???", - ]; - for (const version of versions) { - const body = [ - "### Client or integration", - "Codex CLI", - "### Area", - "CLI", - "### Summary", - "The OpenCodex proxy keeps dropping the Codex CLI connection mid-request.", - "### Reproduction", - "1. ocx start --port 10100", - "2. Send any Codex CLI request through the proxy", - "3. Observe the connection drop", - "### Version", - version, - "### Operating system", - "Windows 11", - ].join("\n"); - const result = validateIssue({ - title: "Unexpected interruption continues to occur", - body, - labels: ["bug"], - }); - assert.equal(result.kind, "bug"); - assert.equal( - result.valid, - false, - `Expected unusable Version "${version}" to be invalid, got: ${result.reasons.join("; ")}`, - ); - assert.ok( - result.reasons.some((r) => /Version/i.test(r) && /unknown|missing/i.test(r)), - `Expected Version unknown/missing reason for "${version}", got: ${result.reasons.join("; ")}`, - ); - } - }); - - it("rejects issue #624-style low-effort new-form bug", () => { - const body = [ - "### Client or integration", - "Codex CLI", - "### Area", - "CLI", - "### Summary", - "CLI로 확인해봤는데 오픈코덱스 프록시가 중간에 자꾸 연결이 끊어져서 그런거라고 합니다.", - "", - "수정 바랍니다.", - "### Reproduction", - "예기치않게중단됨", - "### Version", - "모름", - "### Operating system", - "윈11", - "### Provider and model", - "_No response_", - "### Logs or error output", - "```shell", - "", - "```", - ].join("\n"); - const result = validateIssue({ - title: "Unexpected interruption continues to occur", - body, - labels: ["bug"], - }); - assert.equal(result.kind, "bug"); - assert.equal(result.valid, false); - assert.ok(result.reasons.some((r) => /Version/i.test(r))); - assert.ok(result.reasons.some((r) => /Reproduction/i.test(r) && /vague|empty/i.test(r))); - }); - - it("rejects a new-form bug with a usable Version but placeholder OS", () => { - const body = [ - "### Client or integration", - "Codex CLI", - "### Area", - "CLI", - "### Summary", - "Proxy returns 502 when streaming is enabled on Windows.", - "### Reproduction", - "1. ocx start", - "2. Send a streaming /v1/responses request", - "### Version", - "2.7.42", - "### Operating system", - "No response", - ].join("\n"); - const result = validateIssue({ title: "Streaming 502", body, labels: ["bug"] }); - assert.equal(result.kind, "bug"); - assert.equal(result.valid, false); - assert.ok(result.reasons.some((r) => /Operating system/i.test(r))); - }); - - it("rejects a new-form bug when the Version heading was removed", () => { - const body = [ - "### Client or integration", - "Codex CLI", - "### Area", - "CLI", - "### Summary", - "Proxy returns 502 when streaming is enabled on Windows.", - "### Reproduction", - "1. ocx start", - "2. Send a streaming /v1/responses request", - "### Operating system", - "Windows 11", - ].join("\n"); - const result = validateIssue({ title: "Streaming 502", body, labels: ["bug"] }); - assert.equal(result.kind, "bug"); - assert.equal(result.valid, false); - assert.ok(result.reasons.some((r) => /Version/i.test(r) && /missing/i.test(r))); - }); - - it("rejects a new-form bug when the Operating system heading was removed", () => { - const body = [ - "### Client or integration", - "Codex CLI", - "### Area", - "CLI", - "### Summary", - "Proxy returns 502 when streaming is enabled on Windows.", - "### Reproduction", - "1. ocx start", - "2. Send a streaming /v1/responses request", - "### Version", - "2.7.42", - ].join("\n"); - const result = validateIssue({ title: "Streaming 502", body, labels: ["bug"] }); - assert.equal(result.kind, "bug"); - assert.equal(result.valid, false); - assert.ok(result.reasons.some((r) => /Operating system/i.test(r) && /missing/i.test(r))); - }); - - it("rejects a new-form bug whose Reproduction is only a vague phrase", () => { - const body = [ - "### Client or integration", - "Codex CLI", - "### Area", - "CLI", - "### Summary", - "The OpenCodex proxy keeps dropping the Codex CLI connection mid-request.", - "### Reproduction", - "Unexpected interruption", - "### Version", - "2.7.42", - "### Operating system", - "Windows 11", - ].join("\n"); - const result = validateIssue({ - title: "Unexpected interruption continues to occur", - body, - labels: ["bug"], - }); - assert.equal(result.kind, "bug"); - assert.equal(result.valid, false); - assert.ok(result.reasons.some((r) => /Reproduction/i.test(r) && /vague/i.test(r))); - }); - - it("rejects a #977-shaped bug with product keywords but no actionable reproduction", () => { - const body = [ - "### Client or integration", - "Other", - "### Area", - "Proxy and routing", - "### Summary", - "I want to work with deepseek in VSCode, but it dont reply,just thinking", - "### Reproduction", - "1.choose model deepseek", - "2.send a message in codex plugin", - "### Version", - "2.10.0", - "### Operating system", - "Ubuntu 24.04", - "### Provider and model", - "deepseek", - ].join("\n"); - const result = validateIssue({ - title: "Dont work in VSCode Codex plugin", - body, - labels: ["bug", "proxy"], - }); - assert.equal(result.kind, "bug"); - assert.equal(result.valid, false); - assert.ok( - result.reasons.some((r) => /Reproduction/i.test(r) && /vague/i.test(r)), - `Expected a vague Reproduction reason, got: ${result.reasons.join("; ")}`, - ); - assert.ok( - result.guidance.some((g) => /commands|steps/i.test(g)), - `Expected reproduction guidance, got: ${result.guidance.join("; ")}`, - ); - }); - - it("rejects unknown Operating system stand-ins on the new bug form", () => { - const body = [ - "### Client or integration", - "Codex CLI", - "### Area", - "CLI", - "### Summary", - "The OpenCodex proxy keeps dropping the Codex CLI connection mid-request.", - "### Reproduction", - "1. ocx start --port 10100", - "2. Send any Codex CLI request through the proxy", - "3. Observe the connection drop", - "### Version", - "2.7.42", - "### Operating system", - "Unknown", - ].join("\n"); - const result = validateIssue({ - title: "Unexpected interruption continues to occur", - body, - labels: ["bug"], - }); - assert.equal(result.kind, "bug"); - assert.equal(result.valid, false); - assert.ok(result.reasons.some((r) => /Operating system/i.test(r))); - }); -}); - -// --------------------------------------------------------------------------- -// Validation: provider-compatibility -// --------------------------------------------------------------------------- - -describe("validateIssue - provider-compatibility", () => { - it("rejects when request and response are both absent", () => { - const body = [ - "### Client or integration", - "Codex CLI", - "### Provider or upstream service", - "mistral", - "### OpenCodex version", - "2.7.31", - "### Endpoint or capability", - "/v1/chat/completions", - "### Current behaviour", - "Returns 500.", - "### Expected behaviour", - "Returns 200.", - "### Minimal redacted request or reproduction", - "No response", - "### Actual response or error", - "No response", - "### Upstream documentation", - "https://docs.mistral.ai/api/", - ].join("\n"); - const result = validateIssue({ title: "Mistral 500", body, labels: ["enhancement"] }); - assert.equal(result.kind, "provider-compatibility"); - assert.equal(result.valid, false); - }); - - it("accepts a complete provider compatibility report", () => { - const body = [ - "### Client or integration", - "Codex CLI", - "### Provider or upstream service", - "anthropic", - "### OpenCodex version", - "2.7.31", - "### Endpoint or capability", - "/v1/messages", - "### Current behaviour", - "Proxy strips the system field from the request.", - "### Expected behaviour", - "Proxy preserves the system field as documented.", - "### Minimal redacted request or reproduction", - "curl -X POST http://localhost:10100/v1/messages -d '{\"model\":\"claude-sonnet-4-20250514\",\"system\":\"You are helpful.\",\"messages\":[]}'", - "### Actual response or error", - "400: system is required", - "### Upstream documentation", - "https://docs.anthropic.com/en/api/messages", - ].join("\n"); - const result = validateIssue({ title: "System field stripped", body, labels: ["enhancement"] }); - assert.equal(result.kind, "provider-compatibility"); - assert.equal(result.valid, true); - }); - - it("rejects provider compat report when provider/endpoint fields are cleared", () => { - const body = [ - "### Client or integration", - "Codex CLI", - "### Provider or upstream service", - "", - "### OpenCodex version", - "2.7.31", - "### Endpoint or capability", - "", - "### Current behaviour", - "Returns 400.", - "### Expected behaviour", - "Returns 200.", - "### Minimal redacted request or reproduction", - "curl ...", - "### Actual response or error", - "400 Bad Request", - "### Upstream documentation", - "https://docs.example.com", - ].join("\n"); - const result = validateIssue({ title: "400 error", body, labels: ["provider-compatibility"] }); - assert.equal(result.kind, "provider-compatibility"); - assert.equal(result.valid, false); - assert.ok(result.reasons.some((r) => r.includes("provider"))); - }); -}); - -// --------------------------------------------------------------------------- -// Validation: documentation -// --------------------------------------------------------------------------- - -describe("validateIssue - documentation", () => { - it("rejects an empty documentation report", () => { - const body = [ - "### Documentation problem type", - "Missing documentation", - "### Documentation location", - "No response", - "### What is wrong or missing?", - "No response", - "### What should the documentation explain instead?", - "No response", - ].join("\n"); - const result = validateIssue({ title: "Docs", body, labels: ["documentation"] }); - assert.equal(result.kind, "documentation"); - assert.equal(result.valid, false); - }); - - it("accepts a complete documentation correction", () => { - const body = [ - "### Documentation problem type", - "Incorrect documentation", - "### Documentation location", - "https://lidge-jun.github.io/opencodex/providers/", - "### What is wrong or missing?", - "The page says kimi uses /v1/chat/completions but it actually uses /v1/responses.", - "### What should the documentation explain instead?", - "Update the endpoint to /v1/responses and add a note about the model discovery step.", - ].join("\n"); - const result = validateIssue({ title: "Wrong kimi endpoint in docs", body, labels: ["documentation"] }); - assert.equal(result.kind, "documentation"); - assert.equal(result.valid, true); - }); -}); - -// --------------------------------------------------------------------------- -// Normalisation -// --------------------------------------------------------------------------- - -describe("normalisation", () => { - it("treats 'No response' as empty", () => { - assert.equal(clean("No response"), ""); - assert.equal(clean("_No response_"), ""); - }); - - it("treats NA and not applicable as placeholders", () => { - assert.equal(clean("NA"), ""); - assert.equal(clean("N/A"), ""); - assert.equal(clean("_N/A_"), ""); - assert.equal(clean("NA."), ""); - assert.equal(clean("N/A."), ""); - assert.equal(clean("not applicable"), ""); - assert.equal(clean("Not applicable."), ""); - assert.equal(clean("Not available!"), ""); - }); - - it("detects unusable Version stand-ins without treating them as generic placeholders", () => { - for (const value of ["Unknown", "Uknown", "모름", "idk", "don't know"]) { - assert.equal(isUnusableVersion(value), true, value); - assert.equal(isPlaceholderOnlyValue(value), false, value); - } - for (const value of ["2.7.42", "N/A", "No response", "main@abc1234"]) { - assert.equal(isUnusableVersion(value), false, value); - } - }); - - it("does not treat sentences containing placeholder phrases as empty", () => { - assert.equal(clean("This is N/A for voice mode today."), "This is N/A for voice mode today."); - assert.equal(clean("Not applicable to Claude Code."), "Not applicable to Claude Code."); - }); - - it("shares one placeholder matcher across clean, isPlaceholder, and isRawPlaceholder", () => { - const placeholders = [ - "No response", - "NA", - "N/A", - "_N/A_", - "NA.", - "N/A.", - "None", - "Todo", - "TBD", - "Not applicable", - "Not applicable.", - "Not available!", - "```\nN/A\n```", - "```text\nN/A\n```", - "```json\nNot applicable.\n```", - "~~~text\nN/A\n~~~", - ]; - for (const value of placeholders) { - assert.equal(isPlaceholderOnlyValue(value), true, value); - assert.equal(isPlaceholder(value), true, value); - assert.equal(isRawPlaceholder(value), true, value); - assert.equal(clean(value), "", value); - } - assert.equal(isPlaceholderOnlyValue("Route voice traffic to provider N/A fallback"), false); - assert.equal(isPlaceholderOnlyValue("```text\nThe API returns N/A when no provider is configured.\n```"), false); - assert.equal(isPlaceholderOnlyValue('```json\n{"provider":"N/A","fallback":"anthropic"}\n```'), false); - assert.equal(isPlaceholder("use CLI"), false); - assert.equal(isRawPlaceholder(""), false); - assert.equal(isRawPlaceholder(null), false); - }); - - it("strips HTML comments", () => { - assert.equal(clean("Hello world"), "Hello world"); - }); - - it("normalises punctuation and capitalisation", () => { - assert.equal(normalise("Hello, World!"), normalise("hello world")); - }); - - it("removes filler phrases", () => { - const a = canonicalise("I want to add streaming support"); - const b = canonicalise("add streaming support"); - assert.equal(a, b); - }); -}); - -// --------------------------------------------------------------------------- -// extractSection -// --------------------------------------------------------------------------- - -describe("extractSection", () => { - it("extracts content between headings", () => { - const body = "### Summary\nProxy crashes.\n### Reproduction\nRun ocx start."; - assert.equal(extractSection(body, "Summary"), "Proxy crashes."); - assert.equal(extractSection(body, "Reproduction"), "Run ocx start."); - }); - - it("returns null for missing sections", () => { - assert.equal(extractSection("### Summary\nHello", "Reproduction"), null); - }); -}); - -// --------------------------------------------------------------------------- -// Closure ownership (shouldReopen) -// --------------------------------------------------------------------------- - -describe("shouldReopen", () => { - const baseBotState = { - version: 2, - active: true, - kind: "feature", - closedAt: "2026-07-20T10:00:00Z", - stateReason: "not_planned", - }; - - it("allows reopen when timestamps and state match", () => { - const issue = { state: "closed", closed_at: "2026-07-20T10:00:00Z", state_reason: "not_planned" }; - assert.equal(shouldReopen(baseBotState, issue, false), true); - }); - - it("forbids reopen when timestamp differs", () => { - const issue = { state: "closed", closed_at: "2026-07-21T12:00:00Z", state_reason: "not_planned" }; - assert.equal(shouldReopen(baseBotState, issue, false), false); - }); - - it("forbids reopen when state reason differs", () => { - const issue = { state: "closed", closed_at: "2026-07-20T10:00:00Z", state_reason: "completed" }; - assert.equal(shouldReopen(baseBotState, issue, false), false); - }); - - it("forbids reopen when bot state is inactive", () => { - const inactive = { ...baseBotState, active: false }; - const issue = { state: "closed", closed_at: "2026-07-20T10:00:00Z", state_reason: "not_planned" }; - assert.equal(shouldReopen(inactive, issue, false), false); - }); - - it("returns false when issue is already open", () => { - const issue = { state: "open", closed_at: null, state_reason: null }; - assert.equal(shouldReopen(baseBotState, issue, false), false); - }); - - it("forbids reopen on maintainer override", () => { - const issue = { state: "closed", closed_at: "2026-07-20T10:00:00Z", state_reason: "not_planned" }; - assert.equal(shouldReopen(baseBotState, issue, true), false); - }); - - it("forbids reopen when a human closed the issue (closed_by is not the bot)", () => { - const issue = { - state: "closed", - closed_at: "2026-07-20T10:00:00Z", - state_reason: "not_planned", - closed_by: "lidge-jun", - }; - assert.equal(shouldReopen(baseBotState, issue, false), false); - }); - - it("allows reopen when the bot is the recorded closer", () => { - const issue = { - state: "closed", - closed_at: "2026-07-20T10:00:00Z", - state_reason: "not_planned", - closed_by: "github-actions[bot]", - }; - assert.equal(shouldReopen(baseBotState, issue, false), true); - }); -}); - -describe("shouldEnforceClosure", () => { - it("enforces when there is no bot state yet", () => { - assert.equal(shouldEnforceClosure(null), true); - }); - - it("enforces while the bot still owns an active closure", () => { - assert.equal( - shouldEnforceClosure({ - version: 2, - active: true, - kind: "feature", - closedAt: "2026-07-20T10:00:00Z", - stateReason: "not_planned", - }), - true, - ); - }); - - it("does not enforce after a maintainer override", () => { - assert.equal( - shouldEnforceClosure({ - version: 2, - active: false, - kind: "feature", - closedAt: "2026-07-20T10:00:00Z", - stateReason: "not_planned", - maintainerOverride: true, - }), - false, - ); - }); - - it("still enforces after a normal active:false without maintainer override", () => { - assert.equal( - shouldEnforceClosure({ - version: 2, - active: false, - kind: "feature", - closedAt: "2026-07-20T10:00:00Z", - stateReason: "not_planned", - }), - true, - ); - }); -}); - -// --------------------------------------------------------------------------- -// Translated / soft-pass / labels -// --------------------------------------------------------------------------- - -describe("translated feature headings and soft-pass", () => { - it("accepts Goal / Problem + Expected behaviour as a valid feature", () => { - const body = [ - "### Goal / Problem", - "Codex App rejects image paste for noVisionModels before the vision sidecar can run.", - "### Expected behaviour", - "Catalog should advertise image input when the vision sidecar covers the model.", - "### Environment", - "opencodex 2.7.36 on macOS with Codex App.", - ].join("\n"); - const result = validateIssue({ - title: "[Feature]: Auto-advertise image inputModalities for noVisionModels", - body, - labels: [], - }); - assert.equal(result.kind, "feature"); - assert.equal(result.valid, true, `Expected valid but got: ${result.reasons.join("; ")}`); - assert.equal(result.softPass, false); - }); - - it("soft-passes [Feature]: with rich custom headings outside the alias map", () => { - const body = [ - "### Concrete user workflow that fails", - "User pastes an image in Codex App while a text-only routed model is selected and the App blocks upload.", - "### Why this matters", - "Vision sidecar is advertised but never reached from the App client path.", - "### Verification", - "Same proxy config works end-to-end in Claude Code with the sidecar describing the image.", - ].join("\n"); - const result = validateIssue({ - title: "[Feature]: Vision sidecar unusable from Codex App", - body, - labels: [], - }); - assert.equal(result.kind, "feature"); - assert.equal(result.softPass, true); - assert.equal(result.valid, false); - }); - - it("soft-passes retitled feature reports that drop the [Feature]: prefix", () => { - const body = [ - "### Concrete user workflow that fails", - "User pastes an image in Codex App while a text-only routed model is selected and the App blocks upload.", - "### Why this matters", - "Vision sidecar is advertised but never reached from the App client path.", - "### Verification", - "Same proxy config works end-to-end in Claude Code with the sidecar describing the image.", - ].join("\n"); - const result = validateIssue({ - title: "Vision sidecar unusable from Codex App", - body, - labels: ["enhancement"], - storedKind: "feature", - }); - assert.equal(result.kind, "feature"); - assert.equal(result.softPass, true); - }); - - it("soft-passes retitled bug reports with substantial non-English structure (#545)", () => { - // Maintainer retitle removed `[Bug]:`; Korean structured body has no English - // Summary/Reproduction headings but is clearly actionable. - const body = [ - "## 환경", - "- opencodex 2.7.41 (launchd, port 10100)", - "- Claude Desktop 3P + Anthropic OAuth (Pro/Max)", - "- Auto Mode classifier model = `claude-sonnet-5`", - "", - "## 증상", - "Auto Mode classifier requests truncate at outputTokens=64 with max_output_tokens,", - "then retry the same payload up to 5 times. Dashboard previously showed 502.", - "", - "## 재현", - "1. `ocx login anthropic` and enable Claude Desktop 3P gateway key mode", - "2. Enable Auto Mode and trigger a tool permission classifier turn", - "3. Observe five identical 64-token incomplete terminals for one approval", - "", - "## 증거", - "Inbound+outbound correlated captures show max_tokens:64 and stop_sequences preserved.", - ].join("\n"); - const result = validateIssue({ - title: "Claude Desktop 3P Auto Mode classifier retries after 64-token Anthropic OAuth outputs", - body, - labels: ["bug", "provider-compatibility"], - storedKind: "bug", - }); - assert.equal(result.kind, "bug"); - assert.equal(result.softPass, true, `Expected soft-pass but got: ${result.reasons.join("; ")}`); - assert.equal(result.valid, false); - }); - - it("does not soft-pass a single arbitrary rich heading (Codex #564)", () => { - const result = validateIssue({ - title: "Something broke after upgrade", - body: [ - "## Notes", - "x".repeat(80), - ].join("\n"), - labels: ["bug"], - storedKind: "bug", - }); - assert.equal(result.kind, "bug"); - assert.equal(result.softPass, false); - assert.equal(result.valid, false); - assert.match(result.reasons.join(" "), /Summary and Reproduction are empty/); - }); - - it("does not soft-pass provider reports that only fill mapped metadata headings", () => { - const result = validateIssue({ - title: "Provider X fails on Responses", - body: [ - "### Provider or upstream service", - "custom-openai-compatible gateway hosted on our internal mesh", - "### OpenCodex version", - "2.7.41", - "### Endpoint or capability", - "`POST /v1/responses` with streaming tool calls", - "## Extra notes", - "We see intermittent 502s after rotating the upstream API key for this gateway.", - ].join("\n"), - labels: ["provider-compatibility"], - storedKind: "provider-compatibility", - }); - assert.equal(result.kind, "provider-compatibility"); - assert.equal(result.softPass, false); - assert.equal(result.valid, false); - assert.match(result.reasons.join(" "), /current behaviour|expected behaviour/i); - }); - - it("still rejects empty [Feature]: bodies", () => { - const result = validateIssue({ - title: "[Feature]: do something cool", - body: "please add this", - labels: [], - }); - assert.equal(result.kind, "feature"); - assert.equal(result.valid, false); - assert.equal(result.softPass, false); - }); - - it("does not treat a title containing problem as a bug", () => { - assert.equal( - detectIssueKind({ - title: "Problem with documentation wording", - body: "The docs are confusing about install.", - labels: [], - }), - null, - ); - }); - - it("does not soft-pass long unstructured bodies without headings", () => { - const result = validateIssue({ - title: "[Feature]: please add thing", - body: "x".repeat(250), - labels: [], - }); - assert.equal(result.kind, "feature"); - assert.equal(result.softPass, false); - assert.equal(result.valid, false); - }); - - it("does not classify Expected behaviour + Example as feature without a feature hint", () => { - assert.equal( - detectIssueKind({ - title: "Something broke in the proxy", - body: [ - "### Expected behaviour", - "Proxy should return 200.", - "### Example", - "curl localhost:10100/v1/responses", - ].join("\n"), - labels: [], - }), - null, - ); - }); - - it("classifies alias headings as feature when a goal heading is present", () => { - assert.equal( - detectIssueKind({ - title: "Advertise image input for sidecar models", - body: [ - "### Goal / Problem", - "App blocks images before the sidecar runs.", - "### Expected behaviour", - "Catalog should advertise image input.", - ].join("\n"), - labels: [], - }), - "feature", - ); - }); - - it("lets a strong bug form override a stale stored feature kind", () => { - const result = validateIssue({ - title: "Crash on start", - body: [ - "### Client or integration", - "Codex CLI", - "### Summary", - "Proxy segfaults on ARM64 when streaming is enabled.", - "### Reproduction", - "ocx start on Raspberry Pi 4, send any streaming request.", - "### Version", - "2.7.36", - "### Operating system", - "Linux", - ].join("\n"), - labels: ["bug"], - storedKind: "feature", - }); - assert.equal(result.kind, "bug"); - assert.equal(result.valid, true, `Expected valid bug but got: ${result.reasons.join("; ")}`); - }); - - it("accepts US spelling Expected behavior as a behaviour alias", () => { - const result = validateIssue({ - title: "[Feature]: Auto-advertise image inputModalities", - body: [ - "### Goal / Problem", - "App blocks images before the vision sidecar can run.", - "### Expected behavior", - "Catalog should advertise image input when the sidecar covers the model.", - ].join("\n"), - labels: [], - }); - assert.equal(result.kind, "feature"); - assert.equal(result.valid, true, `Expected valid but got: ${result.reasons.join("; ")}`); - }); - - it("does not treat enhancement + non-goal aliases as a feature detect hit", () => { - assert.equal( - detectIssueKind({ - title: "Something odd in the proxy", - body: [ - "### Current limitation", - "No fallback provider today for upstream 5xx responses.", - "### Expected behaviour", - "Auto failover to a backup provider.", - ].join("\n"), - labels: ["enhancement"], - }), - null, - ); - }); - - it("does not let a weak title-prefix detection override stored documentation kind", () => { - assert.equal( - detectIssueKind({ - title: "[Feature]: rewrite the docs", - body: "Still working on the write-up.", - labels: [], - storedKind: "documentation", - }), - "documentation", - ); - }); -}); - -describe("labelForKind", () => { - it("maps kinds to triage labels", () => { - assert.equal(labelForKind("bug"), "bug"); - assert.equal(labelForKind("feature"), "enhancement"); - assert.equal(labelForKind("documentation"), "documentation"); - assert.equal(labelForKind("provider-compatibility"), "provider-compatibility"); - assert.equal(labelForKind(null), null); - assert.equal(labelForKind("unknown"), null); - }); -}); - -// --------------------------------------------------------------------------- -// Freeform / non-template bypass (e.g. issue #521) -// --------------------------------------------------------------------------- - -describe("validateIssue - freeform / non-template", () => { - it("rejects a plain freeform body that previously skipped validation", () => { - const result = validateIssue({ - title: "How do I configure?", - body: "Just a random question about setup.", - labels: [], - }); - assert.equal(result.kind, null); - assert.equal(result.valid, false); - assert.equal(result.softPass, false); - assert.ok(result.reasons.some((r) => /recognized issue template/i.test(r))); - assert.ok(result.guidance.some((g) => /Bug report|Feature request/i.test(g))); - }); - - it("rejects a #521-shaped Description/Reproduction/Log entry body with a clear message", () => { - const body = [ - "### Description", - "Proxy returns 502 when streaming is enabled on Windows.", - "### Reproduction", - "1. ocx start", - "2. Send a streaming request", - "3. Observe 502", - "### Log entry", - "```", - "upstream connect error or disconnect/reset before headers", - "```", - ].join("\n"); - assert.equal( - detectIssueKind({ title: "Proxy 502 on streaming", body, labels: [] }), - null, - "near-miss headings must not silently classify as a structured bug", - ); - assert.equal(looksLikeUntemplatedBugReport({ title: "Proxy 502 on streaming", body }), true); - - const result = validateIssue({ - title: "Proxy 502 on streaming", - body, - labels: [], - }); - assert.equal(result.kind, null); - assert.equal(result.valid, false); - assert.ok( - result.reasons.some((r) => /bug report/i.test(r) && /template/i.test(r)), - `Expected bug-template reason, got: ${result.reasons.join("; ")}`, - ); - assert.ok( - result.guidance.some((g) => /Client or integration|Summary|Reproduction/i.test(g)), - `Expected template-heading guidance, got: ${result.guidance.join("; ")}`, - ); - }); - - it("still detects and validates a real structured bug as before", () => { - const body = [ - "### Client or integration", - "Codex CLI", - "### Summary", - "Proxy segfaults on ARM64 when streaming is enabled.", - "### Reproduction", - "ocx start on Raspberry Pi 4, send any streaming request.", - "### Version", - "2.7.30", - "### Operating system", - "Debian 12 aarch64", - ].join("\n"); - const result = validateIssue({ - title: "Segfault on ARM64 streaming", - body, - labels: ["bug"], - }); - assert.equal(result.kind, "bug"); - assert.equal(result.valid, true); - }); - - it("does not treat Summary+Reproduction alone as a bug without prefix or label", () => { - // Existing anti-false-positive rule; freeform gate still fails these as untemplated. - const body = [ - "### Summary", - "Something went wrong in the proxy.", - "### Reproduction", - "Run ocx start.", - ].join("\n"); - assert.equal(detectIssueKind({ title: "Something went wrong", body, labels: [] }), null); - const result = validateIssue({ title: "Something went wrong", body, labels: [] }); - assert.equal(result.kind, null); - assert.equal(result.valid, false); - }); - - it("keeps label-backed storedKind validation for enhancement freeform", () => { - // Workflow passes storedKind from the enhancement label; empty feature form still fails. - const result = validateIssue({ - title: "How do I configure?", - body: "Just a random question about setup.", - labels: ["enhancement"], - storedKind: "feature", - }); - assert.equal(result.kind, "feature"); - assert.equal(result.valid, false); - assert.ok(result.reasons.some((r) => /missing or empty/i.test(r))); - }); -}); - -// --------------------------------------------------------------------------- -// workflow_dispatch guards -// --------------------------------------------------------------------------- - -describe("rejectsWorkflowDispatchPullRequest", () => { - it("rejects pull request numbers on workflow_dispatch", () => { - assert.equal( - rejectsWorkflowDispatchPullRequest({ pull_request: {} }, 423, "workflow_dispatch"), - "#423 is a pull request. This workflow only accepts issue numbers.", - ); - }); - - it("allows issues and non-dispatch events", () => { - assert.equal(rejectsWorkflowDispatchPullRequest({ pull_request: {} }, 423, "issues"), null); - assert.equal(rejectsWorkflowDispatchPullRequest({}, 42, "workflow_dispatch"), null); - }); -}); - -describe("rejectsWorkflowDispatchNonDefaultBranch", () => { - it("rejects workflow_dispatch runs that are not on the default branch", () => { - assert.equal( - rejectsWorkflowDispatchNonDefaultBranch( - "workflow_dispatch", - "refs/heads/fix/issue-quality-low-effort-reports", - "main", - ), - "workflow_dispatch must run from the default branch (main); selected ref was refs/heads/fix/issue-quality-low-effort-reports.", - ); - }); - - it("allows default-branch dispatches and normal issue events", () => { - assert.equal( - rejectsWorkflowDispatchNonDefaultBranch("workflow_dispatch", "refs/heads/main", "main"), - null, - ); - assert.equal( - rejectsWorkflowDispatchNonDefaultBranch( - "issues", - "refs/heads/fix/issue-quality-low-effort-reports", - "main", - ), - null, - ); - }); -}); - -// --------------------------------------------------------------------------- -// Orthogonal area labels -// --------------------------------------------------------------------------- - -describe("mapAreaFieldToLabels", () => { - it("maps canonical Area dropdown values", () => { - assert.deepEqual(mapAreaFieldToLabels("CLI"), ["cli"]); - assert.deepEqual(mapAreaFieldToLabels("Proxy and routing"), ["proxy"]); - assert.deepEqual(mapAreaFieldToLabels("Dashboard"), ["gui"]); - assert.deepEqual(mapAreaFieldToLabels("Provider adapter"), ["provider"]); - assert.deepEqual(mapAreaFieldToLabels("Provider adapters"), ["provider"]); - assert.deepEqual(mapAreaFieldToLabels("Authentication and account pool"), ["account-pool"]); - assert.deepEqual(mapAreaFieldToLabels("Catalog / models"), ["catalog"]); - assert.deepEqual(mapAreaFieldToLabels("Streaming"), ["streaming"]); - assert.deepEqual(mapAreaFieldToLabels("Tools / MCP / web search"), ["tools"]); - assert.deepEqual(mapAreaFieldToLabels("Installation or packaging"), ["install"]); - assert.deepEqual(mapAreaFieldToLabels("Service lifecycle"), ["service"]); - assert.deepEqual(mapAreaFieldToLabels("Platform (Windows / macOS / Linux)"), ["platform"]); - assert.deepEqual(mapAreaFieldToLabels("Documentation"), []); - }); - - it("maps legacy Service lifecycle wording and ignores Other / Multiple areas", () => { - assert.deepEqual(mapAreaFieldToLabels("Service lifecycle (config injection)"), ["service"]); - assert.deepEqual(mapAreaFieldToLabels("Other"), []); - assert.deepEqual(mapAreaFieldToLabels("Multiple areas"), []); - assert.deepEqual(mapAreaFieldToLabels(""), []); - assert.deepEqual(mapAreaFieldToLabels(null), []); - }); - - it("exposes metadata for every non-documentation area label", () => { - for (const name of Object.keys(AREA_LABELS)) { - assert.ok(AREA_LABELS[name].color, name); - assert.ok(AREA_LABELS[name].description, name); - } - }); -}); - -describe("detectAreaLabels", () => { - it("applies Area mapping plus orthogonal heuristics", () => { - const labels = detectAreaLabels({ - title: "Pool failover stalls on SSE without terminal frame", - body: [ - "### Area", - "Authentication and account pool", - "### Summary", - "Account pool failover waits forever when the upstream SSE stream ends without a terminal frame.", - ].join("\n"), - labels: ["bug"], - }); - assert.ok(labels.includes("account-pool")); - assert.ok(labels.includes("streaming")); - }); - - it("adds provider for provider-compatibility form and label", () => { - const fromLabel = detectAreaLabels({ - title: "AgentRouter Anthropic streams can end without terminal SSE frames", - body: "### Summary\nStream ends early.", - labels: ["provider-compatibility"], - }); - assert.ok(fromLabel.includes("provider")); - assert.ok(fromLabel.includes("streaming")); - - const fromHeading = detectAreaLabels({ - title: "Custom relay rejects tool_calls", - body: [ - "### Provider or upstream service", - "Volcengine Ark", - "### Current behaviour", - "tool_calls with empty content return 400.", - ].join("\n"), - labels: [], - }); - assert.ok(fromHeading.includes("provider")); - assert.ok(fromHeading.includes("tools")); - }); - - it("runs heuristics for Multiple areas / Other without inventing per-provider labels", () => { - const labels = detectAreaLabels({ - title: "Dashboard ACL hardening blocks management API on Windows", - body: [ - "### Area", - "Multiple areas", - "### Summary", - "Management API fails closed when icacls hardening cannot be verified.", - ].join("\n"), - labels: ["bug"], - }); - assert.ok(labels.includes("gui"), `got ${labels.join(",")}`); - assert.ok(labels.includes("platform"), `got ${labels.join(",")}`); - assert.ok(labels.includes("proxy"), `got ${labels.join(",")}`); - assert.equal(labels.includes("kiro"), false); - assert.equal(labels.includes("gemini"), false); - assert.equal(labels.includes("windows"), false); - }); - - it("does not map Documentation Area onto the documentation kind label", () => { - const labels = detectAreaLabels({ - title: "Codex Auth UI/docs conflate usage-based switching", - body: ["### Area", "Documentation", "### Summary", "Docs misdefine new session."].join("\n"), - labels: ["enhancement"], - }); - assert.equal(labels.includes("documentation"), false); - assert.equal(labels.includes("docs"), false); - }); - - it("ignores Operating system metadata for platform heuristics", () => { - const labels = detectAreaLabels({ - title: "Dashboard shows empty providers tab", - body: [ - "### Area", - "Dashboard", - "### Summary", - "Providers tab is blank after login.", - "### Operating system", - "Windows 11", - "### Reproduction", - "1. Open the dashboard", - ].join("\n"), - labels: ["bug"], - }); - assert.ok(labels.includes("gui")); - assert.equal(labels.includes("platform"), false); - }); - - it("uses heuristicBody translation text when Area is Other", () => { - const labels = detectAreaLabels({ - title: "问题报告", - body: ["### Area", "Other", "### Summary", "原始描述"].join("\n"), - heuristicBody: [ - "### Area", - "Other", - "### Summary", - "Account pool failover fails when refresh token is already used.", - ].join("\n"), - labels: ["bug"], - }); - assert.ok(labels.includes("account-pool"), `got ${labels.join(",")}`); - }); - - it("matches truncated streaming wording via truncat stem", () => { - const labels = detectAreaLabels({ - title: "Upstream streaming response truncated mid-turn", - body: ["### Area", "Other", "### Summary", "The streaming response was truncated."].join("\n"), - labels: ["bug"], - }); - assert.ok(labels.includes("streaming"), `got ${labels.join(",")}`); - }); -}); diff --git a/.github/scripts/issue-translation.cjs b/.github/scripts/issue-translation.cjs deleted file mode 100644 index c7d546bc23..0000000000 --- a/.github/scripts/issue-translation.cjs +++ /dev/null @@ -1,911 +0,0 @@ -"use strict"; - -const crypto = require("crypto"); - -const MARKER = ""; -const END_MARKER = ""; -const LEGACY_STATE_RE = /\s*/; -const CONTROL_MARKER = ""; -const CONTROL_STATE_V2_RE = - //; -const CONTROL_STATE_LEGACY_RE = - //; -/** Trailing standalone marker (+ optional final whitespace). Never mid-body. */ -const TRAILING_ORPHAN_BODY_STATE_RE = - /[ \t]*(?:\r?\n)?[ \t]*$/; -const ISSUE_BODY_MAX = 65536; -const BOT_LOGIN = "github-actions[bot]"; -const SOURCE_HASH_RE = /^[a-f0-9]{16}$/; -const ISSUE_SOURCE_KEY = "issue"; -const MAX_SOURCE_HASHES = 64; -const MAX_RECENT = 32; -/** Allow small clock skew; far-future timestamps are rejected. */ -const MAX_CLOCK_SKEW_MS = 5 * 60 * 1000; - -const DEFAULT_RATE_LIMIT = { - minIntervalMs: 60_000, - maxPerHour: 10, - minSourceChars: 20, -}; - -/** - * Deterministic fingerprint of the original issue source (title + stripped body). - */ -function hashTranslationSource({ title = "", body = "" } = {}) { - const payload = [ - "title:", - String(title || ""), - "\nbody:\n", - String(body || ""), - ].join(""); - return crypto.createHash("sha256").update(payload, "utf8").digest("hex").slice(0, 16); -} - -/** - * Locate the first generated inline translation block. - * @returns {{ start: number, end: number } | null} - */ -function findTranslationBlockRange(text) { - const markerIdx = String(text || "").indexOf(MARKER); - if (markerIdx === -1) return null; - - let cursor = markerIdx + MARKER.length; - const afterMarker = String(text).slice(cursor); - const legacyState = afterMarker.match(/^\s*\s*/); - if (legacyState) { - cursor += legacyState.index + legacyState[0].length; - } - - const rest = String(text).slice(cursor); - const endRel = rest.indexOf(END_MARKER); - if (endRel !== -1) { - return { start: markerIdx, end: cursor + endRel + END_MARKER.length }; - } - - // Legacy blocks (pre-END_MARKER): fall back to first . - if (/^\s*
/i.test(rest)) { - const closeRel = rest.search(/<\/details>/i); - if (closeRel !== -1) { - return { start: markerIdx, end: cursor + closeRel + "
".length }; - } - return { start: markerIdx, end: cursor }; - } - - if (legacyState) { - return { start: markerIdx, end: cursor }; - } - - return { start: markerIdx, end: markerIdx + MARKER.length }; -} - -/** - * Split an issue body into user prefix/suffix and the generated translation block. - */ -function splitTranslationBlock(body) { - const text = String(body || ""); - const range = findTranslationBlockRange(text); - if (!range) { - const sourceBody = text.replace(/\s+$/, ""); - return { - found: false, - prefix: sourceBody, - block: "", - suffix: "", - sourceBody, - }; - } - - const prefix = text.slice(0, range.start).replace(/\s+$/, ""); - const block = text.slice(range.start, range.end); - const suffix = text.slice(range.end).replace(/^\s+/, ""); - const sourceBody = suffix - ? (prefix ? `${prefix}\n\n${suffix}` : suffix).replace(/\s+$/, "") - : prefix; - - return { found: true, prefix, block, suffix, sourceBody }; -} - -function stripTranslationBlock(body) { - return splitTranslationBlock(body).sourceBody; -} - -/** Legacy body-embedded state (ignored for rate limits). */ -function extractTranslationState(body) { - const match = String(body || "").match(LEGACY_STATE_RE); - if (!match) return null; - try { - const parsed = JSON.parse(match[1]); - if (!parsed || typeof parsed !== "object") return null; - return parsed; - } catch { - return null; - } -} - -function scrubDetectedLanguage(value) { - return ( - String(value || "") - .replace(/[^\p{L}\p{N}\s\-()]/gu, "") - .replace(/\s+/g, " ") - .trim() - .slice(0, 64) || "non-English" - ); -} - -/** - * True when the model (or caller) reported English / no translation needed. - */ -function isEnglishDetectedLanguage(value) { - const lang = scrubDetectedLanguage(value).toLowerCase(); - return lang === "english" || lang === "en" || lang === "eng"; -} - -/** - * Language written into control-state on the no-translation persist path. - * - * Confirmed English only when `sourceComplete` is true (valid parsed - * `requires_translation: false`). Incomplete AI/parse/action failures always - * record `unknown` — never retain a language label that could look confirmed. - */ -function detectedLanguageForControlPersist({ detectedLanguage, sourceComplete } = {}) { - if (sourceComplete !== true) return "unknown"; - return scrubDetectedLanguage(detectedLanguage || "English"); -} - -/** - * Visible bookkeeping language label for the sticky control comment. - * Always non-empty so the bot bubble never renders as a blank ghost comment. - * Missing language is `unknown` — never invent a confirmed English label. - */ -function bookkeepingLanguageLabel(state) { - if (state?.detectedLanguage) return scrubDetectedLanguage(state.detectedLanguage); - return "unknown"; -} - -/** - * Strip obsolete bot-owned body control markers from the legacy trailing - * storage position only. Markers inside fenced code, quotes, or prose are - * left untouched. Surrounding author whitespace is preserved byte-for-byte. - */ -function stripOrphanBodyControlState(body) { - let text = String(body || ""); - // Only remove exact trailing tokens (legacy bot storage). Repeat in case - // multiple obsolete markers were appended at EOF. - while (TRAILING_ORPHAN_BODY_STATE_RE.test(text)) { - text = text.replace(TRAILING_ORPHAN_BODY_STATE_RE, ""); - } - return text; -} - -function isValidControlTimestamp(ts, now = Date.now()) { - return typeof ts === "number" - && Number.isFinite(ts) - && ts <= now + MAX_CLOCK_SKEW_MS; -} - -function findAllControlComments(comments) { - return (Array.isArray(comments) ? comments : []).filter( - (comment) => comment?.user?.login === BOT_LOGIN && comment?.body?.includes(CONTROL_MARKER), - ); -} - -function encodeControlState(state) { - return Buffer.from(JSON.stringify(state), "utf8").toString("base64url"); -} - -function isValidSourceKey(key) { - return key === ISSUE_SOURCE_KEY || /^comment:[1-9][0-9]*$/.test(String(key || "")); -} - -/** - * Per-source completed hashes. Legacy flat `sourceHash` maps only to the issue key. - */ -function migrateSourceHashes(state) { - if (!state || typeof state !== "object") return {}; - const out = {}; - if (state.sourceHashes && typeof state.sourceHashes === "object" && !Array.isArray(state.sourceHashes)) { - for (const [key, value] of Object.entries(state.sourceHashes)) { - if (isValidSourceKey(key) && typeof value === "string" && SOURCE_HASH_RE.test(value)) { - out[key] = value; - } - } - return out; - } - if ( - typeof state.sourceHash === "string" - && SOURCE_HASH_RE.test(state.sourceHash) - && state.sourceHash !== "0000000000000000" - ) { - out[ISSUE_SOURCE_KEY] = state.sourceHash; - } - return out; -} - -function completedHashFor(state, sourceKey) { - const key = isValidSourceKey(sourceKey) ? sourceKey : ISSUE_SOURCE_KEY; - const hashes = migrateSourceHashes(state); - return hashes[key] || null; -} - -function withCompletedSourceHash(hashes, sourceKey, sourceHash) { - const next = { ...hashes }; - if (isValidSourceKey(sourceKey) && typeof sourceHash === "string" && SOURCE_HASH_RE.test(sourceHash)) { - next[sourceKey] = sourceHash; - } - const keys = Object.keys(next); - if (keys.length <= MAX_SOURCE_HASHES) return next; - // Prefer keeping the issue key; drop oldest-inserted comment keys first. - const commentKeys = keys.filter((k) => k !== ISSUE_SOURCE_KEY); - while (Object.keys(next).length > MAX_SOURCE_HASHES && commentKeys.length) { - delete next[commentKeys.shift()]; - } - return next; -} - -function validateControlState(parsed, now = Date.now()) { - if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null; - if (parsed.v !== 2) return null; - if (typeof parsed.sourceHash !== "string" || !SOURCE_HASH_RE.test(parsed.sourceHash)) { - return null; - } - if (!isValidControlTimestamp(parsed.attemptedAt, now)) { - return null; - } - if (!Array.isArray(parsed.recent)) return null; - const recent = parsed.recent - .filter((ts) => isValidControlTimestamp(ts, now)) - .slice(-MAX_RECENT); - if (typeof parsed.requiresTranslation !== "boolean") return null; - - let detectedLanguage = null; - if (parsed.detectedLanguage != null) { - if (typeof parsed.detectedLanguage !== "string") return null; - detectedLanguage = scrubDetectedLanguage(parsed.detectedLanguage); - } - - return { - v: 2, - sourceHash: parsed.sourceHash, - sourceHashes: migrateSourceHashes(parsed), - attemptedAt: parsed.attemptedAt, - recent, - requiresTranslation: parsed.requiresTranslation, - detectedLanguage, - }; -} - -function decodeControlState(encoded, now = Date.now()) { - try { - const json = Buffer.from(String(encoded || ""), "base64url").toString("utf8"); - return validateControlState(JSON.parse(json), now); - } catch { - return null; - } -} - -/** Legacy JSON-in-HTML-comment state (read-only migration). */ -function parseLegacyControlState(raw, now = Date.now()) { - try { - return validateControlState(JSON.parse(raw), now); - } catch { - return null; - } -} - -function parseControlStateFromCommentBody(body, now = Date.now()) { - const text = String(body || ""); - const v2 = text.match(CONTROL_STATE_V2_RE); - if (v2) return decodeControlState(v2[1], now); - const legacy = text.match(CONTROL_STATE_LEGACY_RE); - if (legacy) return parseLegacyControlState(legacy[1], now); - return null; -} - -/** - * Newest github-actions control comment with a valid decoded state. - * Author-forged comments and far-future poisoned payloads are ignored. - * Used for *reading* authoritative rate-limit state. - */ -function findControlComment(comments, now = Date.now()) { - let best = null; - let bestState = null; - for (const comment of findAllControlComments(comments)) { - const state = parseControlStateFromCommentBody(comment.body, now); - if (!state) continue; - if (!bestState || state.attemptedAt >= bestState.attemptedAt) { - best = comment; - bestState = state; - } - } - return best; -} - -/** - * Sticky upsert target: the oldest bot-owned control comment (by id). - * Prefer updating this in place so the bubble stays near the top of the - * thread instead of creating a new comment at the bottom after every - * English classification. Corrupt/unparseable bodies still qualify — we - * overwrite them — so a bad decode never forces a duplicate create. - */ -function findStickyControlComment(comments) { - let sticky = null; - for (const comment of findAllControlComments(comments)) { - if (!Number.isSafeInteger(comment?.id) || comment.id <= 0) continue; - if (!sticky || comment.id < sticky.id) sticky = comment; - } - return sticky; -} - -function extractTranslationControlState(comments, now = Date.now()) { - const newest = findControlComment(comments, now); - if (!newest) return null; - return parseControlStateFromCommentBody(newest.body, now); -} - -/** - * Authoritative control state comes only from verified bot-owned comments. - * Issue body markers and author comments are never consulted. - * The optional second argument is ignored (kept for call-site compatibility). - */ -function resolveControlState(comments, _issueNumber, now = Date.now()) { - return extractTranslationControlState(comments, now); -} - -/** - * Always false: control comments always include a visible bookkeeping line - * so GitHub never renders an HTML-comment-only ghost bubble. - * Kept as an exported predicate for workflow/tests that assert the contract. - */ -function shouldOmitVisibleBookkeeping(_state) { - return false; -} - -function buildTranslationControlComment(state) { - const safe = validateControlState(state) || { - v: 2, - sourceHash: "0000000000000000", - sourceHashes: {}, - attemptedAt: Date.now(), - recent: [], - requiresTranslation: false, - detectedLanguage: null, - }; - const encoded = encodeControlState(safe); - const lang = bookkeepingLanguageLabel(safe); - return [ - CONTROL_MARKER, - ``, - "", - `Automated translation bookkeeping — detected language: ${lang}.`, - ].join("\n"); -} - -function pruneRecent(recent, now, windowMs = 3_600_000) { - const cutoff = now - windowMs; - const maxTs = now + MAX_CLOCK_SKEW_MS; - return (Array.isArray(recent) ? recent : []).filter( - (ts) => typeof ts === "number" && Number.isFinite(ts) && ts > cutoff && ts <= maxTs, - ); -} - -function countRecentAttempts(recent, now, windowMs = 3_600_000) { - return pruneRecent(recent, now, windowMs).length; -} - -/** - * Merge bounded recent-attempt histories from every valid bot control comment - * so canonicalisation does not drop hourly-limit evidence. - */ -function collectMergedRecentFromComments(comments, priorState = null, now = Date.now()) { - const collected = []; - if (Array.isArray(priorState?.recent)) collected.push(...priorState.recent); - for (const comment of findAllControlComments(comments)) { - const state = parseControlStateFromCommentBody(comment.body, now); - if (state?.recent) collected.push(...state.recent); - } - return [...new Set(pruneRecent(collected, now))].sort((a, b) => a - b).slice(-MAX_RECENT); -} - -/** - * Record a new attempt. Far-future poisoned prior state is ignored/healed. - * New attemptedAt always uses wall-clock `now` so skew cannot stick forever. - * - * Completed hashes are stored per `sourceKey` (`issue` vs `comment:`) so - * issue and comment paths do not clobber each other's unchanged_source checks. - * Rate-limit fields (`attemptedAt`, `recent`) stay shared across the issue. - * Pass `sourceComplete: true` only after a valid no-translation decision or a - * successful issue/comment translation apply — never for invalid/empty model - * output or GitHub update failures (those must remain retryable after cooldown). - */ -function mergeTranslationAttemptState({ priorState = null, attempt, now = Date.now() }) { - let prior = null; - if (priorState && isValidControlTimestamp(priorState.attemptedAt, now)) { - prior = { - ...priorState, - recent: (priorState.recent || []).filter((ts) => isValidControlTimestamp(ts, now)), - sourceHashes: migrateSourceHashes(priorState), - }; - } - - const priorRecent = pruneRecent(prior?.recent, now); - const recent = pruneRecent([...priorRecent, now], now); - const sourceComplete = attempt?.sourceComplete === true; - const sourceKey = isValidSourceKey(attempt?.sourceKey) ? attempt.sourceKey : ISSUE_SOURCE_KEY; - let sourceHashes = migrateSourceHashes(prior); - let completedHash = prior?.sourceHash && SOURCE_HASH_RE.test(prior.sourceHash) - ? prior.sourceHash - : "0000000000000000"; - - if ( - sourceComplete - && typeof attempt.sourceHash === "string" - && SOURCE_HASH_RE.test(attempt.sourceHash) - ) { - sourceHashes = withCompletedSourceHash(sourceHashes, sourceKey, attempt.sourceHash); - completedHash = attempt.sourceHash; - } - - return { - v: 2, - sourceHash: completedHash, - sourceHashes, - attemptedAt: now, - recent, - requiresTranslation: Boolean(attempt.requiresTranslation), - detectedLanguage: attempt.detectedLanguage == null - ? null - : scrubDetectedLanguage(attempt.detectedLanguage), - }; -} - -/** - * Delete verified bot control comments by ID. - * Re-checks bot authorship + CONTROL_MARKER before each delete. - * Deletion failures are reported, not thrown. - */ -async function deleteVerifiedControlComments({ - github, - owner, - repo, - issue_number, - commentIds, - comments = null, - keepCommentId = null, -}) { - const keepId = Number.isSafeInteger(keepCommentId) && keepCommentId > 0 - ? keepCommentId - : null; - const ids = [...new Set( - (Array.isArray(commentIds) ? commentIds : []) - .map((id) => Number(id)) - .filter((id) => Number.isSafeInteger(id) && id > 0 && id !== keepId), - )]; - if (!ids.length) { - return { deleted: [], skipped: [], failed: [] }; - } - - let liveComments = comments; - if (!Array.isArray(liveComments)) { - liveComments = await github.paginate(github.rest.issues.listComments, { - owner, - repo, - issue_number, - per_page: 100, - }); - } - const byId = new Map( - (Array.isArray(liveComments) ? liveComments : []) - .filter((c) => Number.isSafeInteger(c?.id)) - .map((c) => [c.id, c]), - ); - - const deleted = []; - const skipped = []; - const failed = []; - for (const id of ids) { - const comment = byId.get(id); - if ( - !comment - || comment.user?.login !== BOT_LOGIN - || !String(comment.body || "").includes(CONTROL_MARKER) - ) { - skipped.push(id); - continue; - } - try { - await github.rest.issues.deleteComment({ - owner, - repo, - comment_id: id, - }); - deleted.push(id); - } catch (err) { - failed.push({ - id, - error: err instanceof Error ? err.message : String(err), - }); - } - } - return { deleted, skipped, failed }; -} - -/** - * Upsert the canonical bot-owned control comment. - * Always includes a visible detected-language bookkeeping line (English too). - * Updates the oldest sticky bot control comment in place when one exists — - * including corrupt bodies — so classification never spams a new bottom bubble. - * Never mutates the issue title or body. - */ -async function upsertTranslationControlComment({ - github, - owner, - repo, - issue_number, - comments, - priorState = null, - attempt, - now = Date.now(), -}) { - const merged = mergeTranslationAttemptState({ priorState, attempt, now }); - const body = buildTranslationControlComment(merged); - // Sticky target ≠ newest valid state: prefer oldest marker comment so the - // thread position stays stable even when state on that comment is corrupt. - const existing = findStickyControlComment(comments); - - if (existing) { - if (existing.body !== body) { - await github.rest.issues.updateComment({ - owner, - repo, - comment_id: existing.id, - body, - }); - } - return { comment: { ...existing, body }, state: merged, created: false }; - } - - const created = await github.rest.issues.createComment({ - owner, - repo, - issue_number, - body, - }); - return { comment: created.data, state: merged, created: true }; -} - -/** - * Persist rate-limit / cooldown state in a bot-owned issue comment. - * Writes/updates the canonical comment first; only then deletes redundant - * older bot control comments. Create/update failure preserves prior comments. - * Never uses the issue body/title or author-created comments as storage. - */ -async function persistTranslationControlState({ - github, - owner, - repo, - issue_number, - comments, - priorState = null, - attempt, - now = Date.now(), -}) { - const mergedRecent = collectMergedRecentFromComments(comments, priorState, now); - const effectivePrior = priorState && isValidControlTimestamp(priorState.attemptedAt, now) - ? { ...priorState, recent: mergedRecent } - : (mergedRecent.length - ? { - v: 2, - // Incomplete synthetic prior: do not treat the current attempt hash as completed. - sourceHash: "0000000000000000", - sourceHashes: {}, - attemptedAt: Math.min(...mergedRecent), - recent: mergedRecent, - requiresTranslation: false, - detectedLanguage: null, - } - : null); - - let upserted; - try { - upserted = await upsertTranslationControlComment({ - github, - owner, - repo, - issue_number, - comments, - priorState: effectivePrior, - attempt, - now, - }); - } catch (err) { - const error = new Error( - `translation control comment persistence failed: ${err instanceof Error ? err.message : String(err)}`, - ); - error.cause = err; - throw error; - } - - const canonicalId = upserted.comment?.id; - const redundantIds = findAllControlComments(comments) - .map((comment) => comment.id) - .filter((id) => Number.isSafeInteger(id) && id > 0 && id !== canonicalId); - - let cleanup = { deleted: [], skipped: [], failed: [] }; - if (redundantIds.length) { - cleanup = await deleteVerifiedControlComments({ - github, - owner, - repo, - issue_number, - commentIds: redundantIds, - comments, - keepCommentId: canonicalId, - }); - } - - return { - storage: "comment", - state: upserted.state, - comment: upserted.comment, - // Always false: bookkeeping line is always visible (no ghost HTML-only bubble). - markerOnly: false, - cleanup, - }; -} - -function isPreparedSourceStillCurrent({ preparedHash, liveTitle, liveBody }) { - const liveHash = hashTranslationSource({ - title: liveTitle || "", - body: liveBody || "", - }); - return liveHash === preparedHash; -} - -/** Stable title key so comment hashes never collide with issue title+body hashes. */ -function commentSourceTitle(commentId) { - return `comment:${commentId}`; -} - -/** - * Hard skips before rate-limit / hash checks. - * @returns {string | null} skip reason, or null when eligible for shouldTranslate - */ -function shouldSkipCommentTranslation(comment, issue = null) { - if (issue?.pull_request) return "pull_request"; - const login = String(comment?.user?.login || ""); - const userType = String(comment?.user?.type || ""); - if (userType === "Bot" || /\[bot\]$/i.test(login) || login === BOT_LOGIN) { - return "bot_author"; - } - const body = String(comment?.body || ""); - if (body.includes(CONTROL_MARKER)) return "control_comment"; - return null; -} - -/** - * Decide whether a user issue comment should be sent to the translator. - * Reuses issue rate limits via the shared per-issue control comment. - * `comment:` is only a hash namespace — minSourceChars applies to the - * stripped comment body alone so short comments cannot burn model quota. - */ -function shouldTranslateComment({ - comment, - issue = null, - priorState = null, - now = Date.now(), - rateLimit = DEFAULT_RATE_LIMIT, -}) { - const skip = shouldSkipCommentTranslation(comment, issue); - if (skip) return { ok: false, reason: skip }; - - const commentId = comment?.id; - if (!Number.isSafeInteger(commentId) || commentId <= 0) { - return { ok: false, reason: "invalid_comment_id" }; - } - - const sourceBody = stripTranslationBlock(comment.body || ""); - const minChars = rateLimit.minSourceChars ?? DEFAULT_RATE_LIMIT.minSourceChars; - if (String(sourceBody).trim().length < minChars) { - return { ok: false, reason: "source_too_short" }; - } - - const decision = shouldTranslate({ - sourceTitle: commentSourceTitle(commentId), - sourceBody, - sourceKey: commentSourceTitle(commentId), - priorState, - now, - // Length already enforced on the body; title is namespace-only. - rateLimit: { ...rateLimit, minSourceChars: 0 }, - }); - if (!decision.ok) return decision; - return { - ...decision, - sourceBody, - sourceTitle: commentSourceTitle(commentId), - commentId, - }; -} - -/** - * Build the in-place comment body: original + folded English translation. - */ -function buildTranslatedCommentBody(sourceBody, translatedBody, detectedLanguage) { - const lang = scrubDetectedLanguage(detectedLanguage); - const translationText = [ - `*Original language: ${lang}*`, - "", - String(translatedBody || ""), - ].join("\n"); - return appendTranslationBlock(sourceBody, translationText); -} - -/** - * Required translated fields for a successful apply. - * Nonempty source title/body each require a nonempty translated counterpart. - * @returns {string[]} missing field names (`title` / `body`) - */ -function missingRequiredTranslationFields({ - sourceTitle = "", - sourceBody = "", - translatedTitle = "", - translatedBody = "", -} = {}) { - const missing = []; - if (String(sourceTitle || "").trim() && !String(translatedTitle || "").trim()) { - missing.push("title"); - } - if (String(sourceBody || "").trim() && !String(translatedBody || "").trim()) { - missing.push("body"); - } - return missing; -} - -function shouldTranslate({ - sourceTitle = "", - sourceBody, - sourceKey = ISSUE_SOURCE_KEY, - priorState = null, - now = Date.now(), - rateLimit = DEFAULT_RATE_LIMIT, -}) { - const title = String(sourceTitle || "").trim(); - const body = String(sourceBody || "").trim(); - const combined = `${title}\n${body}`.trim(); - const minChars = rateLimit.minSourceChars ?? DEFAULT_RATE_LIMIT.minSourceChars; - - if (combined.length < minChars) { - return { ok: false, reason: "source_too_short" }; - } - - const key = isValidSourceKey(sourceKey) ? sourceKey : ISSUE_SOURCE_KEY; - const sourceHash = hashTranslationSource({ title, body }); - if (completedHashFor(priorState, key) === sourceHash) { - return { ok: false, reason: "unchanged_source" }; - } - - const minInterval = rateLimit.minIntervalMs ?? DEFAULT_RATE_LIMIT.minIntervalMs; - const maxPerHour = rateLimit.maxPerHour ?? DEFAULT_RATE_LIMIT.maxPerHour; - const attemptedAt = typeof priorState?.attemptedAt === "number" ? priorState.attemptedAt : 0; - const recent = pruneRecent(priorState?.recent, now); - - if (attemptedAt && now - attemptedAt < minInterval) { - return { ok: false, reason: "rate_limited_interval" }; - } - - if (countRecentAttempts(recent, now) >= maxPerHour) { - return { ok: false, reason: "rate_limited_hourly" }; - } - - return { ok: true, sourceHash, sourceKey: key, recent }; -} - -function sanitizeTranslationBody(raw, maxChars = 60000) { - return String(raw || "") - .split(MARKER).join("") - .split(END_MARKER).join("") - .replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/g, "") - // Defuse pings only: @login / @org/team — not emails, scopes, or decorators. - .replace( - /(^|[\s(])@([A-Za-z0-9](?:[A-Za-z0-9-]{0,38})(?:\/[A-Za-z0-9._-]+)?)/g, - "$1@\u200b$2", - ) - .trim() - .slice(0, maxChars); -} - -function buildTranslationBlock(translatedBody) { - const safeBody = sanitizeTranslationBody(translatedBody); - return [ - "", - MARKER, - "", - "
", - "", - "Translated Message", - "", - safeBody, - "", - "
", - END_MARKER, - "", - ].join("\n"); -} - -function maxTranslationChars(sourceBody) { - const base = stripTranslationBlock(sourceBody); - const emptyBlock = buildTranslationBlock(""); - return Math.max(0, ISSUE_BODY_MAX - base.length - emptyBlock.length - 64); -} - -function fitTranslationBody(sourceBody, translatedBody) { - let safe = sanitizeTranslationBody(translatedBody); - const maxChars = maxTranslationChars(sourceBody); - if (safe.length <= maxChars) return safe; - const note = "\n\n_(Translation truncated to fit GitHub issue body limit.)_"; - const budget = Math.max(0, maxChars - note.length); - return safe.slice(0, budget).trimEnd() + note; -} - -function appendTranslationBlock(sourceBody, translatedBody) { - const base = stripTranslationBlock(sourceBody); - const fitted = fitTranslationBody(base, translatedBody); - const next = base + buildTranslationBlock(fitted); - if (next.length > ISSUE_BODY_MAX) { - throw new Error("Translated issue body exceeds GitHub limit after truncation."); - } - return next; -} - -module.exports = { - MARKER, - END_MARKER, - CONTROL_MARKER, - BOT_LOGIN, - ISSUE_BODY_MAX, - ISSUE_SOURCE_KEY, - DEFAULT_RATE_LIMIT, - MAX_CLOCK_SKEW_MS, - hashTranslationSource, - findTranslationBlockRange, - splitTranslationBlock, - stripTranslationBlock, - extractTranslationState, - findControlComment, - findStickyControlComment, - findAllControlComments, - deleteVerifiedControlComments, - extractTranslationControlState, - resolveControlState, - encodeControlState, - decodeControlState, - validateControlState, - isValidControlTimestamp, - buildTranslationControlComment, - mergeTranslationAttemptState, - collectMergedRecentFromComments, - upsertTranslationControlComment, - persistTranslationControlState, - shouldOmitVisibleBookkeeping, - isPreparedSourceStillCurrent, - commentSourceTitle, - shouldSkipCommentTranslation, - shouldTranslateComment, - buildTranslatedCommentBody, - missingRequiredTranslationFields, - shouldTranslate, - completedHashFor, - migrateSourceHashes, - sanitizeTranslationBody, - scrubDetectedLanguage, - isEnglishDetectedLanguage, - detectedLanguageForControlPersist, - bookkeepingLanguageLabel, - stripOrphanBodyControlState, - buildTranslationBlock, - maxTranslationChars, - fitTranslationBody, - appendTranslationBlock, - pruneRecent, - countRecentAttempts, -}; diff --git a/.github/scripts/issue-translation.test.cjs b/.github/scripts/issue-translation.test.cjs deleted file mode 100644 index f6c754fb9e..0000000000 --- a/.github/scripts/issue-translation.test.cjs +++ /dev/null @@ -1,1688 +0,0 @@ -"use strict"; - -const { describe, it } = require("node:test"); -const assert = require("node:assert/strict"); -const { - MARKER, - END_MARKER, - CONTROL_MARKER, - BOT_LOGIN, - ISSUE_BODY_MAX, - DEFAULT_RATE_LIMIT, - hashTranslationSource, - splitTranslationBlock, - stripTranslationBlock, - appendTranslationBlock, - buildTranslationBlock, - buildTranslationControlComment, - findControlComment, - findStickyControlComment, - extractTranslationControlState, - resolveControlState, - encodeControlState, - decodeControlState, - validateControlState, - mergeTranslationAttemptState, - persistTranslationControlState, - upsertTranslationControlComment, - isPreparedSourceStillCurrent, - shouldTranslate, - commentSourceTitle, - shouldSkipCommentTranslation, - shouldTranslateComment, - buildTranslatedCommentBody, - missingRequiredTranslationFields, - sanitizeTranslationBody, - scrubDetectedLanguage, - isEnglishDetectedLanguage, - detectedLanguageForControlPersist, - bookkeepingLanguageLabel, - stripOrphanBodyControlState, - fitTranslationBody, - shouldOmitVisibleBookkeeping, - deleteVerifiedControlComments, - MAX_CLOCK_SKEW_MS, - collectMergedRecentFromComments, - isValidControlTimestamp, - pruneRecent, - completedHashFor, -} = require("./issue-translation.cjs"); - -const HASH_A = "aaaaaaaaaaaaaaaa"; -const HASH_B = "bbbbbbbbbbbbbbbb"; -const ORPHAN_MARKER = ``; - -const SOURCE = [ - "### Was funktioniert nicht?", - "Der Proxy startet nicht nach dem Update.", - "### Schritte", - "1. ocx start", - "2. Fehler in der Konsole", -].join("\n"); - -function botComment(body, id = 1) { - return { id, user: { login: BOT_LOGIN }, body }; -} - -function mockGithub(handlers = {}) { - const calls = []; - const github = { - paginate: async (_fn, args) => { - calls.push(["paginate", args]); - return handlers.listComments || []; - }, - rest: { - issues: { - listComments: async (args) => { - calls.push(["list", args]); - return { data: handlers.listComments || [] }; - }, - createComment: async (args) => { - calls.push(["create", args]); - if (handlers.create) return handlers.create(args); - return { data: { id: handlers.nextId || 99, body: args.body, user: { login: BOT_LOGIN } } }; - }, - updateComment: async (args) => { - calls.push(["update", args]); - if (handlers.update) return handlers.update(args); - return { data: { id: args.comment_id, body: args.body, user: { login: BOT_LOGIN } } }; - }, - deleteComment: async (args) => { - calls.push(["delete", args]); - if (handlers.delete) return handlers.delete(args); - return {}; - }, - update: async (args) => { - calls.push(["issueUpdate", args]); - if (handlers.issueUpdate) return handlers.issueUpdate(args); - return { data: args }; - }, - }, - }, - }; - return { github, calls }; -} - -describe("hashTranslationSource", () => { - it("changes when only the title changes", () => { - const bodyOnly = hashTranslationSource({ body: SOURCE }); - const withTitle = hashTranslationSource({ title: "Neuer Titel", body: SOURCE }); - assert.notEqual(bodyOnly, withTitle); - }); - - it("changes when only the body changes", () => { - const base = hashTranslationSource({ title: "Titel", body: SOURCE }); - const edited = hashTranslationSource({ title: "Titel", body: SOURCE + "\nmehr" }); - assert.notEqual(base, edited); - }); - - it("is stable for unchanged title and body", () => { - const a = hashTranslationSource({ title: "T", body: SOURCE }); - const b = hashTranslationSource({ title: "T", body: SOURCE }); - assert.equal(a, b); - }); -}); - -describe("splitTranslationBlock", () => { - it("handles generated block at end", () => { - const translated = appendTranslationBlock(SOURCE, "English"); - const split = splitTranslationBlock(translated); - assert.equal(split.sourceBody, SOURCE); - assert.ok(split.block.includes(MARKER)); - }); - - it("preserves suffix after generated block", () => { - const suffix = "Extra logs added by contributor."; - const translated = appendTranslationBlock(SOURCE, "English") + "\n\n" + suffix; - const split = splitTranslationBlock(translated); - assert.equal(split.suffix, suffix); - assert.equal(split.sourceBody, `${SOURCE}\n\n${suffix}`); - }); - - it("preserves prefix before generated block", () => { - const prefix = "Preface"; - const translated = prefix + "\n\n" + appendTranslationBlock(SOURCE, "English").trimStart(); - const split = splitTranslationBlock(translated); - assert.equal(split.prefix, `${prefix}\n\n${SOURCE}`); - assert.equal(split.sourceBody, `${prefix}\n\n${SOURCE}`); - }); - - it("does not remove contributor-authored details elsewhere", () => { - const contributorDetails = [ - "
My notes", - "private repro notes", - "
", - ].join("\n"); - const body = contributorDetails + "\n\n" + appendTranslationBlock(SOURCE, "English").trimStart(); - const split = splitTranslationBlock(body); - assert.ok(split.sourceBody.includes("private repro notes")); - assert.ok(split.sourceBody.includes("My notes")); - }); - - it("fails safely when closing details is missing", () => { - const malformed = `${SOURCE}\n\n${MARKER}\n
\nTranslated Message\n\noops`; - const split = splitTranslationBlock(malformed); - assert.ok(split.sourceBody.includes("oops")); - assert.ok(split.sourceBody.includes(SOURCE)); - }); - - it("preserves nested details inside translated content via end marker", () => { - const nested = [ - "Outer translation", - "
logs", - "inner", - "
", - "still translation", - ].join("\n"); - const body = appendTranslationBlock(SOURCE, nested) + "\n\nuser suffix"; - assert.ok(body.includes(END_MARKER)); - const split = splitTranslationBlock(body); - assert.equal(split.suffix, "user suffix"); - assert.equal(split.sourceBody, `${SOURCE}\n\nuser suffix`); - assert.ok(split.block.includes("inner")); - assert.ok(split.block.includes("still translation")); - }); - - it("removes multi-level nested details only inside the generated block", () => { - const before = "
before\nbefore-log\n
"; - const after = "
after\nafter-log\n
"; - const nested = [ - "top", - "
L1", - "
L2", - "deep", - "
", - "
", - "tail", - ].join("\n"); - const body = [ - before, - "", - appendTranslationBlock(SOURCE, nested).trimStart(), - "", - after, - ].join("\n"); - const stripped = stripTranslationBlock(body); - assert.ok(stripped.includes("before-log")); - assert.ok(stripped.includes("after-log")); - assert.ok(!stripped.includes("deep")); - assert.ok(!stripped.includes("top")); - assert.ok(!stripped.includes(MARKER)); - assert.ok(!stripped.includes(END_MARKER)); - }); - - it("migrates legacy blocks that close on first details end", () => { - const legacy = [ - SOURCE, - "", - MARKER, - "", - "
", - "", - "Translated Message", - "", - "legacy english", - "", - "
", - "", - "user after", - ].join("\n"); - const split = splitTranslationBlock(legacy); - assert.equal(split.suffix, "user after"); - assert.equal(split.sourceBody, `${SOURCE}\n\nuser after`); - const migrated = appendTranslationBlock(split.sourceBody, "fresh"); - assert.ok(migrated.includes(END_MARKER)); - assert.equal((migrated.match(new RegExp(MARKER, "g")) || []).length, 1); - assert.ok(migrated.includes("user after")); - }); - - it("does not greedily erase across duplicate end markers", () => { - const block = buildTranslationBlock("one"); - const forged = `${SOURCE}${block}\n${END_MARKER}\nkeep me`; - const split = splitTranslationBlock(forged); - assert.ok(split.sourceBody.includes("keep me")); - assert.ok(!split.block.includes("keep me")); - assert.equal(split.suffix, `${END_MARKER}\nkeep me`); - }); -}); - -describe("isPreparedSourceStillCurrent", () => { - it("detects body changes between prepare and apply", () => { - const prepared = hashTranslationSource({ title: "T", body: SOURCE }); - assert.equal( - isPreparedSourceStillCurrent({ - preparedHash: prepared, - liveTitle: "T", - liveBody: SOURCE + "\nnew logs", - }), - false, - ); - }); - - it("detects title changes between prepare and apply", () => { - const prepared = hashTranslationSource({ title: "Alt", body: SOURCE }); - assert.equal( - isPreparedSourceStillCurrent({ - preparedHash: prepared, - liveTitle: "Neu", - liveBody: SOURCE, - }), - false, - ); - }); - - it("allows apply when only generated translation changed", () => { - const prepared = hashTranslationSource({ title: "T", body: SOURCE }); - const withBlock = appendTranslationBlock(SOURCE, "English"); - assert.equal( - isPreparedSourceStillCurrent({ - preparedHash: prepared, - liveTitle: "T", - liveBody: stripTranslationBlock(withBlock), - }), - true, - ); - }); -}); - -describe("bot-owned control state", () => { - it("always includes visible bookkeeping, including English", () => { - const german = buildTranslationControlComment({ - v: 2, - sourceHash: HASH_A, - attemptedAt: 1, - recent: [1], - requiresTranslation: true, - detectedLanguage: "German", - }); - assert.match(german, /Automated translation bookkeeping — detected language: German/); - assert.equal(shouldOmitVisibleBookkeeping({ - requiresTranslation: true, - detectedLanguage: "German", - }), false); - - const english = buildTranslationControlComment({ - v: 2, - sourceHash: HASH_A, - attemptedAt: 1, - recent: [1], - requiresTranslation: false, - detectedLanguage: "English", - }); - assert.match(english, /Automated translation bookkeeping — detected language: English/); - assert.equal(shouldOmitVisibleBookkeeping({ - requiresTranslation: false, - detectedLanguage: "English", - }), false); - }); - - it("incomplete AI/parse failures bookkeep as unknown, never false-English", async () => { - assert.equal( - detectedLanguageForControlPersist({ detectedLanguage: "", sourceComplete: false }), - "unknown", - ); - assert.equal( - detectedLanguageForControlPersist({ detectedLanguage: undefined, sourceComplete: false }), - "unknown", - ); - assert.equal( - detectedLanguageForControlPersist({ detectedLanguage: "unknown", sourceComplete: false }), - "unknown", - ); - assert.equal( - detectedLanguageForControlPersist({ detectedLanguage: "English", sourceComplete: false }), - "unknown", - ); - assert.equal( - detectedLanguageForControlPersist({ detectedLanguage: "", sourceComplete: true }), - "English", - ); - assert.equal( - detectedLanguageForControlPersist({ detectedLanguage: "English", sourceComplete: true }), - "English", - ); - assert.equal(bookkeepingLanguageLabel({ requiresTranslation: false, detectedLanguage: null }), "unknown"); - assert.equal(bookkeepingLanguageLabel({ requiresTranslation: false, detectedLanguage: "English" }), "English"); - - const { github, calls } = mockGithub({ nextId: 77 }); - const result = await persistTranslationControlState({ - github, - owner: "o", - repo: "r", - issue_number: 9, - comments: [], - attempt: { - sourceHash: HASH_A, - requiresTranslation: false, - detectedLanguage: detectedLanguageForControlPersist({ - detectedLanguage: "", - sourceComplete: false, - }), - sourceComplete: false, - }, - now: 100, - }); - assert.equal(result.state.sourceHash, "0000000000000000"); - assert.equal(result.state.detectedLanguage, "unknown"); - assert.match(calls[0][1].body, /detected language: unknown/); - assert.doesNotMatch(calls[0][1].body, /detected language: English/); - // Attempt counted (recent) but source stays retryable. - assert.deepEqual(result.state.recent, [100]); - assert.equal(completedHashFor(result.state, "issue"), null); - }); - - it("English creates a bot comment with visible English bookkeeping", async () => { - const { github, calls } = mockGithub({ nextId: 42 }); - const result = await persistTranslationControlState({ - github, - owner: "o", - repo: "r", - issue_number: 7, - comments: [], - attempt: { - sourceHash: HASH_A, - requiresTranslation: false, - detectedLanguage: "English", - sourceComplete: true, - }, - now: 100, - }); - assert.equal(result.storage, "comment"); - assert.equal(result.markerOnly, false); - assert.equal(result.comment.id, 42); - assert.deepEqual(calls.map((c) => c[0]), ["create"]); - assert.match(calls[0][1].body, new RegExp(CONTROL_MARKER)); - assert.match(calls[0][1].body, /Automated translation bookkeeping — detected language: English/); - assert.equal(extractTranslationControlState([botComment(calls[0][1].body, 42)]).sourceHash, HASH_A); - }); - - it("English updates the canonical bot comment instead of creating duplicates", async () => { - const priorBody = buildTranslationControlComment({ - v: 2, - sourceHash: HASH_B, - attemptedAt: 1, - recent: [1], - requiresTranslation: false, - detectedLanguage: "English", - }); - const prior = botComment(priorBody, 11); - const { github, calls } = mockGithub(); - const result = await persistTranslationControlState({ - github, - owner: "o", - repo: "r", - issue_number: 7, - comments: [prior], - priorState: extractTranslationControlState([prior]), - attempt: { - sourceHash: HASH_A, - requiresTranslation: false, - detectedLanguage: "English", - sourceComplete: true, - }, - now: 200, - }); - assert.equal(result.comment.id, 11); - assert.deepEqual(calls.map((c) => c[0]), ["update"]); - assert.equal(calls[0][1].comment_id, 11); - assert.match(calls[0][1].body, /Automated translation bookkeeping — detected language: English/); - }); - - it("updates the oldest sticky control comment even when its state is corrupt", async () => { - const corrupt = botComment( - `${CONTROL_MARKER}\n`, - 3, - ); - const validNewer = botComment(buildTranslationControlComment({ - v: 2, - sourceHash: HASH_B, - attemptedAt: 50, - recent: [50], - requiresTranslation: false, - detectedLanguage: "English", - }), 9); - const { github, calls } = mockGithub(); - const result = await persistTranslationControlState({ - github, - owner: "o", - repo: "r", - issue_number: 7, - comments: [corrupt, validNewer], - priorState: extractTranslationControlState([corrupt, validNewer]), - attempt: { - sourceHash: HASH_A, - requiresTranslation: false, - detectedLanguage: "English", - sourceComplete: true, - }, - now: 100, - }); - assert.equal(findStickyControlComment([corrupt, validNewer]).id, 3); - assert.equal(result.comment.id, 3); - assert.deepEqual(calls.map((c) => c[0]), ["update", "delete"]); - assert.equal(calls[0][1].comment_id, 3); - assert.match(calls[0][1].body, /detected language: English/); - assert.equal(calls[1][1].comment_id, 9); - }); - - it("non-English persist writes or updates a visible bot-owned comment", async () => { - const { github, calls } = mockGithub({ nextId: 50 }); - const created = await persistTranslationControlState({ - github, - owner: "o", - repo: "r", - issue_number: 11, - comments: [], - attempt: { - sourceHash: HASH_A, - requiresTranslation: true, - detectedLanguage: "German", - sourceComplete: true, - }, - now: 100, - }); - assert.equal(created.storage, "comment"); - assert.equal(created.markerOnly, false); - assert.equal(created.comment.id, 50); - assert.match(calls[0][1].body, /detected language: German/); - - const prior = botComment(calls[0][1].body, 50); - calls.length = 0; - const updated = await persistTranslationControlState({ - github, - owner: "o", - repo: "r", - issue_number: 11, - comments: [prior], - priorState: extractTranslationControlState([prior]), - attempt: { - sourceHash: HASH_B, - requiresTranslation: true, - detectedLanguage: "French", - sourceComplete: true, - }, - now: 200, - }); - assert.equal(updated.storage, "comment"); - assert.deepEqual(calls.map((c) => c[0]), ["update"]); - assert.equal(calls[0][1].comment_id, 50); - assert.match(calls[0][1].body, /detected language: French/); - }); - - it("ignores author comments containing the control marker", () => { - const forged = { - id: 9, - user: { login: "attacker" }, - body: buildTranslationControlComment({ - v: 2, - sourceHash: HASH_B, - attemptedAt: 99, - recent: [99], - requiresTranslation: false, - detectedLanguage: "English", - }), - }; - const bot = botComment(buildTranslationControlComment({ - v: 2, - sourceHash: HASH_A, - attemptedAt: 1, - recent: [1], - requiresTranslation: true, - detectedLanguage: "German", - }), 10); - assert.equal(resolveControlState([forged, bot]).sourceHash, HASH_A); - assert.equal(findControlComment([forged, bot]).id, 10); - }); - - it("treats corrupt control state as missing", () => { - const comments = [ - botComment(`${CONTROL_MARKER}\n`), - ]; - assert.equal(extractTranslationControlState(comments), null); - assert.equal(resolveControlState(comments), null); - }); - - it("never treats the issue body as authoritative control state", () => { - const orphan = `${SOURCE}\n\n\n`; - assert.equal(resolveControlState([], 1), null); - assert.equal(extractTranslationControlState([]), null); - assert.equal(stripOrphanBodyControlState(orphan).includes("control-state-v2:"), false); - }); - - it("failed sticky update preserves existing control comments and does not delete", async () => { - // Corrupt sticky comment is still the upsert target; update failure must - // not cascade into deleting it (or any sibling) as "redundant." - const stale = botComment( - `${CONTROL_MARKER}\n`, - 5, - ); - const { github, calls } = mockGithub({ - update: async () => { - throw new Error("API update failed"); - }, - }); - await assert.rejects( - () => persistTranslationControlState({ - github, - owner: "o", - repo: "r", - issue_number: 1, - comments: [stale], - attempt: { - sourceHash: HASH_A, - requiresTranslation: false, - detectedLanguage: "English", - sourceComplete: true, - }, - }), - /persistence failed/, - ); - assert.deepEqual(calls.map((c) => c[0]), ["update"]); - assert.equal(calls[0][1].comment_id, 5); - assert.ok(!calls.some((c) => c[0] === "delete")); - assert.equal(findControlComment([stale]), null); - assert.equal(findStickyControlComment([stale]).id, 5); - }); - - it("re-fetches comments when none are supplied and still verifies authorship", async () => { - const forged = { - id: 9, - user: { login: "attacker" }, - body: `please ignore ${CONTROL_MARKER} forged`, - }; - const bot = botComment(buildTranslationControlComment({ - v: 2, - sourceHash: HASH_A, - attemptedAt: 1, - recent: [1], - requiresTranslation: true, - detectedLanguage: "German", - }), 10); - const { github, calls } = mockGithub({ listComments: [forged, bot] }); - const result = await deleteVerifiedControlComments({ - github, - owner: "o", - repo: "r", - issue_number: 1, - commentIds: [9, 10], - }); - assert.deepEqual(result.deleted, [10]); - assert.deepEqual(result.skipped, [9]); - assert.ok(calls.some((c) => c[0] === "paginate")); - }); - - it("failed comment update preserves the previous comment", async () => { - const priorBody = buildTranslationControlComment({ - v: 2, - sourceHash: HASH_B, - attemptedAt: 1, - recent: [1], - requiresTranslation: false, - detectedLanguage: "English", - }); - const prior = botComment(priorBody, 8); - const { github, calls } = mockGithub({ - update: async () => { - throw new Error("API update failed"); - }, - }); - await assert.rejects( - () => persistTranslationControlState({ - github, - owner: "o", - repo: "r", - issue_number: 1, - comments: [prior], - priorState: extractTranslationControlState([prior]), - attempt: { - sourceHash: HASH_A, - requiresTranslation: false, - detectedLanguage: "English", - sourceComplete: true, - }, - now: 200, - }), - /persistence failed/, - ); - assert.deepEqual(calls.map((c) => c[0]), ["update"]); - assert.ok(!calls.some((c) => c[0] === "delete")); - assert.equal(extractTranslationControlState([prior]).sourceHash, HASH_B); - }); - - it("deletes redundant bot comments only after sticky replacement succeeds", async () => { - const older = botComment(buildTranslationControlComment({ - v: 2, - sourceHash: HASH_B, - attemptedAt: 1, - recent: [1], - requiresTranslation: true, - detectedLanguage: "German", - }), 1); - const newer = botComment(buildTranslationControlComment({ - v: 2, - sourceHash: HASH_A, - attemptedAt: 2, - recent: [1, 2], - requiresTranslation: false, - detectedLanguage: "English", - }), 2); - const { github, calls } = mockGithub(); - const result = await persistTranslationControlState({ - github, - owner: "o", - repo: "r", - issue_number: 1, - comments: [older, newer], - priorState: extractTranslationControlState([older, newer]), - attempt: { - sourceHash: HASH_A, - requiresTranslation: false, - detectedLanguage: "English", - sourceComplete: true, - }, - now: 300, - }); - // Sticky = oldest id; update it in place and delete the newer duplicate. - assert.equal(result.comment.id, 1); - assert.deepEqual(calls.map((c) => c[0]), ["update", "delete"]); - assert.equal(calls[0][1].comment_id, 1); - assert.equal(calls[1][1].comment_id, 2); - assert.deepEqual(result.cleanup.deleted, [2]); - }); - - it("cleanup failure leaves valid fallback comments intact", async () => { - const older = botComment(buildTranslationControlComment({ - v: 2, - sourceHash: HASH_B, - attemptedAt: 1, - recent: [1], - requiresTranslation: true, - detectedLanguage: "German", - }), 1); - const newer = botComment(buildTranslationControlComment({ - v: 2, - sourceHash: HASH_A, - attemptedAt: 2, - recent: [1, 2], - requiresTranslation: false, - detectedLanguage: "English", - }), 2); - const { github, calls } = mockGithub({ - delete: async () => { - throw new Error("delete denied"); - }, - }); - const result = await persistTranslationControlState({ - github, - owner: "o", - repo: "r", - issue_number: 1, - comments: [older, newer], - priorState: extractTranslationControlState([older, newer]), - attempt: { - sourceHash: HASH_A, - requiresTranslation: false, - detectedLanguage: "English", - sourceComplete: true, - }, - now: 300, - }); - assert.equal(result.comment.id, 1); - assert.equal(result.cleanup.failed.length, 1); - assert.equal(result.cleanup.failed[0].id, 2); - assert.ok(calls.some((c) => c[0] === "update")); - // Newer duplicate remains when delete fails — durable fallback remains. - assert.equal(extractTranslationControlState([older, newer]).sourceHash, HASH_A); - assert.equal(extractTranslationControlState([older]).sourceHash, HASH_B); - }); - - it("cooldown and hourly limits survive repeated issue events via bot comments", () => { - const now = 1_700_000_000_000; - const body = buildTranslationControlComment({ - v: 2, - sourceHash: HASH_A, - attemptedAt: now, - recent: [now], - requiresTranslation: false, - detectedLanguage: "English", - }); - const priorState = resolveControlState([botComment(body)]); - const decision = shouldTranslate({ - sourceTitle: "Hello", - sourceBody: "Still English but edited enough to change the hash.", - priorState, - now: now + 5_000, - }); - assert.equal(decision.ok, false); - assert.equal(decision.reason, "rate_limited_interval"); - - const hourly = resolveControlState([botComment(buildTranslationControlComment({ - v: 2, - sourceHash: HASH_A, - attemptedAt: now, - recent: Array.from({ length: 10 }, (_, i) => now - i * 60_000), - requiresTranslation: false, - detectedLanguage: "English", - }))]); - const hourlyDecision = shouldTranslate({ - sourceTitle: "Hello again", - sourceBody: "Another English edit that would otherwise probe the model.", - priorState: hourly, - now: now + 120_000, - }); - assert.equal(hourlyDecision.ok, false); - assert.equal(hourlyDecision.reason, "rate_limited_hourly"); - }); - - it("rapid sequential edits cannot invoke the model repeatedly", async () => { - const { github, calls } = mockGithub({ nextId: 3 }); - const first = await persistTranslationControlState({ - github, - owner: "o", - repo: "r", - issue_number: 9, - comments: [], - attempt: { - sourceHash: HASH_A, - requiresTranslation: false, - detectedLanguage: "English", - sourceComplete: true, - }, - now: 1_000, - }); - const comments = [botComment(first.comment.body, first.comment.id)]; - const priorState = resolveControlState(comments); - const second = shouldTranslate({ - sourceTitle: "Edit two", - sourceBody: "Changed body content that must still be rate limited.", - priorState, - now: 1_000 + 10_000, - }); - assert.equal(second.ok, false); - assert.equal(second.reason, "rate_limited_interval"); - assert.equal(calls.filter((c) => c[0] === "create").length, 1); - }); - - it("persistence never mutates the issue title or body", async () => { - const { github, calls } = mockGithub(); - await persistTranslationControlState({ - github, - owner: "o", - repo: "r", - issue_number: 9, - comments: [], - attempt: { - sourceHash: HASH_A, - requiresTranslation: false, - detectedLanguage: "English", - sourceComplete: true, - }, - }); - assert.ok(!calls.some((c) => c[0] === "issueUpdate")); - }); - - it("selects only github-actions control comments", () => { - const state = { - v: 2, - sourceHash: HASH_A, - sourceHashes: { issue: HASH_A }, - attemptedAt: 1, - recent: [1], - requiresTranslation: true, - detectedLanguage: "German", - }; - const comments = [ - botComment("random bot comment"), - botComment(buildTranslationControlComment(state)), - { user: { login: "contributor" }, body: buildTranslationControlComment(state) }, - ]; - assert.deepEqual(extractTranslationControlState(comments), state); - }); - - it("reader and selector agree on the newest control comment", () => { - const older = { - v: 2, - sourceHash: HASH_A, - sourceHashes: { issue: HASH_A }, - attemptedAt: 1, - recent: [1], - requiresTranslation: true, - detectedLanguage: "German", - }; - const newer = { - v: 2, - sourceHash: HASH_B, - sourceHashes: { issue: HASH_B }, - attemptedAt: 2, - recent: [1, 2], - requiresTranslation: true, - detectedLanguage: "Japanese", - }; - const comments = [ - { id: 1, user: { login: BOT_LOGIN }, body: buildTranslationControlComment(older) }, - { id: 2, user: { login: BOT_LOGIN }, body: buildTranslationControlComment(newer) }, - ]; - const selected = findControlComment(comments); - assert.equal(selected.id, 2); - assert.deepEqual(extractTranslationControlState(comments), newer); - }); - - it("round-trips base64url control state without HTML breakout", () => { - const state = { - v: 2, - sourceHash: HASH_A, - attemptedAt: 42, - recent: [40, 42], - requiresTranslation: true, - detectedLanguage: "German --> @username diff --git a/docs-site/src/components/SiteJsonLd.astro b/docs-site/src/components/SiteJsonLd.astro deleted file mode 100644 index b6043033cb..0000000000 --- a/docs-site/src/components/SiteJsonLd.astro +++ /dev/null @@ -1,81 +0,0 @@ ---- -// Site-name markup for Google, emitted ONLY from a locale home page. -// -// Google's site-names rules (developers.google.com/search/docs/appearance/site-names): -// - put the WebSite entity on the home page only, never site-wide; -// - one WebSite object per page — duplicate/conflicting entities are ignored; -// - for multilingual sites, emit a separate WebSite per localized home page, -// each with a single `inLanguage` value and its own `url`/`@id`. -// Emitting one shared entity across every page and locale is what made Google -// fall back to the bare domain, so this component is home-page scoped by design. -const SITE_URL = 'https://opencodex.me'; - -interface Props { - locale?: 'ko' | 'zh-cn' | 'ru' | 'ja'; -} -const { locale } = Astro.props; - -// Locale path segment (root/English has none) mapped to its BCP-47 tag. -const langs = { ko: 'ko', 'zh-cn': 'zh-CN', ru: 'ru', ja: 'ja' } as const; - -const homeUrl = locale ? `${SITE_URL}/${locale}/` : `${SITE_URL}/`; -const inLanguage = locale ? langs[locale] : 'en'; - -const descriptions = { - en: 'Universal provider proxy for OpenAI Codex & Claude Code — use any LLM with Codex CLI, App, SDK, and Claude Code.', - ko: 'OpenAI Codex & Claude Code를 위한 범용 프로바이더 프록시 — Codex CLI, App, SDK와 Claude Code에서 어떤 LLM이든 사용하세요.', - 'zh-CN': '面向 OpenAI Codex 与 Claude Code 的通用 provider 代理 —— 在 Codex CLI、App、SDK 和 Claude Code 中使用任意 LLM。', - ru: 'Универсальный прокси провайдеров для OpenAI Codex и Claude Code — используйте любую LLM с Codex CLI, App, SDK и Claude Code.', - ja: 'OpenAI Codex & Claude Code 向けの汎用プロバイダープロキシ — Codex CLI、App、SDK と Claude Code で任意の LLM を使えます。', -} as const; - -type GraphNode = Record; - -const graph: GraphNode[] = [ - { - '@type': 'WebSite', - // Per-locale @id: the English root and each translated home page describe - // distinct localized entities instead of redeclaring one shared object. - '@id': `${homeUrl}#website`, - url: homeUrl, - // `name` matches the visible site name (header wordmark + prefix), - // which is what Google requires before it will adopt it over the domain. - name: 'opencodex', - alternateName: 'ocx', - description: descriptions[inLanguage], - inLanguage, - }, -]; - -// The software entity is site-wide truth, so it stays anchored to the English -// root and is emitted exactly once, from the English home page. -if (!locale) { - graph.push({ - '@type': 'SoftwareApplication', - '@id': `${SITE_URL}/#software`, - name: 'opencodex', - alternateName: 'ocx', - description: - 'Local LLM proxy that lets OpenAI Codex (CLI, App, SDK) and Claude Code run on any model — Claude, Gemini, Grok, DeepSeek, Kimi, Qwen, Ollama, OpenRouter, and more — with streaming, tool calls, reasoning tokens, and images working in both directions.', - keywords: - 'codex, claude code, openai codex proxy, claude code proxy, llm proxy, ai gateway, anthropic, gemini, grok, deepseek, ollama, openrouter, responses api, codex cli', - featureList: [ - 'Run Codex CLI/App/SDK on any LLM provider', - 'Run Claude Code on any LLM via the Anthropic Messages API', - 'ChatGPT account pool with quota-aware routing', - 'Streaming, tool calls, reasoning tokens, and vision in both directions', - 'Web dashboard on localhost:10100', - ], - applicationCategory: 'DeveloperApplication', - operatingSystem: 'macOS, Linux, Windows', - offers: { '@type': 'Offer', price: '0', priceCurrency: 'USD' }, - softwareHelp: { '@type': 'CreativeWork', url: `${SITE_URL}/` }, - downloadUrl: 'https://www.npmjs.com/package/@bitkyc08/opencodex', - url: 'https://github.com/lidge-jun/opencodex', - }); -} - -const jsonLd = JSON.stringify({ '@context': 'https://schema.org', '@graph': graph }); ---- - -<script type="application/ld+json" is:inline set:html={jsonLd} /> diff --git a/docs-site/src/content/docs/benchmarks/index.mdx b/docs-site/src/content/docs/benchmarks/index.mdx index 2fb191ea90..06321d7e18 100644 --- a/docs-site/src/content/docs/benchmarks/index.mdx +++ b/docs-site/src/content/docs/benchmarks/index.mdx @@ -4,7 +4,7 @@ description: Public coding-agent benchmark snapshots — capability vs cost per --- These are **static snapshots** of public leaderboards, refreshed manually — not live -OpenCodex metering. Each board lists its source, capture date, and license note. +CodexCommander metering. Each board lists its source, capture date, and license note. Score-per-dollar rankings only appear on boards where every row carries a source-measured cost per task. diff --git a/docs-site/src/content/docs/contributing.md b/docs-site/src/content/docs/contributing.md index 089e3a568c..a34ec3d2bb 100644 --- a/docs-site/src/content/docs/contributing.md +++ b/docs-site/src/content/docs/contributing.md @@ -1,16 +1,15 @@ --- title: Contributing -description: Develop opencodex — setup, layout, conventions, and how to add a provider or adapter. +description: Develop CodexCommander — setup, layout, conventions, and how to add a provider or adapter. --- ## Setup -Source development requires the `bun` CLI on your `PATH`. The published npm package bundles its own -Bun runtime for users, but this checkout's scripts run through your local Bun installation. +Source development requires the `bun` CLI on your `PATH`. No registry package is currently +published; this checkout's scripts run through your local Bun installation. ```bash -git clone https://github.com/pavelhov/opencodex.git -cd opencodex +cd /path/to/CodexCommander bun install bun run dev:proxy # proxy API in dev mode bun run dev:gui # dashboard dev server (another terminal) @@ -46,12 +45,10 @@ The docs site you're reading lives in `docs-site/` (Astro + Starlight): cd docs-site && bun install && bun dev ``` -## Docs publishing +## Docs site -The public docs publish to GitHub Pages at <https://opencodex.me/>. The -`.github/workflows/deploy-docs.yml` workflow runs on `main` pushes that touch `docs-site/**` or the -workflow itself, builds `docs-site`, and deploys the generated site. Before pushing docs changes, -run: +The docs live in `docs-site/` and have no currently published host. Before opening a docs pull +request, build locally: ```bash cd docs-site @@ -59,68 +56,40 @@ bun install --frozen-lockfile bun run build ``` -## CI and releases - -GitHub Actions intentionally stay small: - -- **Cross-platform CI** (`.github/workflows/ci.yml`) runs on pull requests and `main` pushes that - touch runtime, tests, package, script, TypeScript, or workflow files. Its Bun matrix covers Linux, - Windows, and macOS with install, typecheck, tests, privacy scan, a release-helper build smoke, GUI - build, and `ocx help`. A second three-OS lane proves npm global install works without a separately - installed Bun by using the package's bundled runtime. -- **Release** (`.github/workflows/release.yml`) is manual. It does not act as a second full CI - pipeline; before dry-run or publish it requires the exact release commit (`GITHUB_SHA`) to already - have a successful Cross-platform CI run. -- **Stale needs-info** (`.github/workflows/stale-needs-info.yml`) runs daily on the default branch. - Open issues labeled `needs-info` with no activity for 14 days get a warning; after 7 more idle - days they close as not planned. Any update clears the stale warning. To keep long-lived work open, - remove `needs-info` (for example when promoting an issue to `roadmap`). -- **Issue quality** (`.github/workflows/enforce-issue-quality.yml`) validates template structure on - new and edited issues, applies kind labels (`bug`, `enhancement`, `provider-compatibility`, - `documentation`), and adds orthogonal **area** labels from the form Area field plus light - title/Summary heuristics: `provider`, `account-pool`, `catalog`, `gui`, `cli`, `proxy`, - `platform`, `streaming`, `tools`, `install`, and `service`. Kind/process labels stay separate so - you can filter `bug` + `account-pool` without collapsing those axes. Prefer the Area dropdown - over inventing per-provider labels. Area: Documentation does not add a second area tag (the docs - form already seeds `documentation`). Maintainers can re-apply area labels to all open issues with - workflow_dispatch `backfill_open_areas` after the workflow is on the default branch. - -Use the helper for releases: +Publishing automation is not included in this repository. -```bash -bun run release <version> # commits/pushes the bump; publish workflow is dry-run by default -bun run release <version> --publish # publish after the CI-gated dry run is understood -bun run release:watch # watch the newest Release workflow run -``` +## Continuous integration -## Branches +Every pull request and every push to `main` runs one automatic GitHub check: **`ci`** +(`.github/workflows/ci.yml`). That is the only required automation for ordinary +contributions. -- `dev` — the only integration target. Open your pull request here. -- `main` — releases only. It moves by maintainer-controlled promotion from - `dev`; do not open feature pull requests against it. -- `preview` — the prerelease train. +Repository administrators can use the GitHub ruleset **Always-allow** bypass when a +protected-path or branch rule would otherwise block an intentional admin action. Bypass +is for admin recovery and exceptional maintenance, not a substitute for review on +contributor work. -The `dev2-go` line that carried the Go native port has been retired, and the -dual-track carry policy with it. Its history is published read-only at -[lidge-jun/opencodex-go-archive](https://github.com/lidge-jun/opencodex-go-archive). -Bun-native TypeScript on `dev` is the single runtime line. +## Branches and pull requests -Rebase pull requests are welcome. Bringing a stale branch onto the current head -is normal contribution rather than noise — note the source commits in the -description. +- **`main` is the sole default, integration, and pull-request target.** Open feature and + fix pull requests against `main`. +- Branch from the current **`main`** tip. +- Write a real description: what changed, why, and how you verified it (named commands + and results). Empty or placeholder-only descriptions are not enough for review. +- If the change touches the dashboard UI, include a screenshot in the description. +- Behavior changes need a focused regression near the existing tests for that subsystem. + Shared routing, adapter, config, or server changes need the full suite green. -## Pull requests +The retired dual-track Go native port is not part of this repository. Bun-native TypeScript on +`main` is the single runtime line. -- Target **`dev`**. Do not open feature or fix pull requests against **`main`**. -- Branch from the current **`dev`** tip, not from **`main`**. The required **`enforce-target`** check rejects heads whose merge base sits on the **`main`** tip while the branch is far behind the pull request base (the failure mode seen in #644). -- Write a real description: a **Summary** of what changed and why, plus a **Test plan** (or equivalent substance). Empty bodies, placeholder-only text, and descriptions that use escaped `\n` instead of real line breaks fail the check. -- If the title or description mentions `gui`, include a screenshot of the UI change in the description; the `enforce-target` check re-runs on description edits until the screenshot is present. -- Workflow changes in this repository use **`pull_request_target`**. Updated enforcement logic applies only after the workflow is promoted to the repository default branch — the same operational caveat documented in #631. +Rebase pull requests are welcome. Bringing a stale branch onto the current head is +ordinary maintenance — name the source commits in the description. ## Project maintainers The current maintainers, their responsibilities, and the review and merge policy are documented in -[`MAINTAINERS.md`](https://github.com/lidge-jun/opencodex/blob/main/MAINTAINERS.md). GitHub review +[`MAINTAINERS.md`](https://github.com/pavelhov/CodexCommander/blob/main/MAINTAINERS.md). GitHub review ownership for the repository and security-sensitive paths is declared in `.github/CODEOWNERS`. ## Conventions @@ -131,7 +100,7 @@ ownership for the repository and security-sensitive paths is declared in `.githu - **Handle async errors at boundaries** — sidecars never throw into the request path; they degrade to a graceful marker. - **Structure SOT** — current maintainer invariants live in `structure/`. Keep public user workflows - in `docs-site/` and historical investigation notes in `docs/`. + in `docs-site/` and maintained engineering notes in `docs/`. - **Preserve exports** — other modules may depend on them. ## Adding a provider to the catalog @@ -152,14 +121,14 @@ All provider pickers and seeds derive from the canonical registry (`src/provider }, ``` -`src/providers/derive.ts` feeds that entry into `ocx init`, `ocx provider`, dashboard presets, +`src/providers/derive.ts` feeds that entry into `ccx init`, `ccx provider`, dashboard presets, API-key login, and OAuth config seeds. `enrichProviderFromCatalog()` copies model metadata and capability classifications onto the saved provider config. OAuth protocol implementations still live in `src/oauth/`; registry metadata alone is not an OAuth flow. ### Evidence required for a canonical preset -A registry entry is a maintained promise: opencodex ships the destination that a user's API key is +A registry entry is a maintained promise: CodexCommander ships the destination that a user's API key is sent to. A preset therefore needs primary-source evidence, not a working code path. Pull requests that add or promote a provider must supply all of the following in the description: @@ -184,7 +153,7 @@ not a reason for rejection, and it does not lower the evidence bar either. When the evidence is incomplete, the honest home is a reference row in `src/providers/free-directory.ts` rather than the canonical registry. Directory rows carry an explicit `verification` grade (`official`, `primary`, `unverified`) and are inert: users can still -reach the service through the custom OpenAI-compatible flow, while opencodex avoids advertising a +reach the service through the custom OpenAI-compatible flow, while CodexCommander avoids advertising a preset it cannot stand behind. Promote the row to the registry once the evidence above exists. ## Adding an adapter @@ -200,4 +169,4 @@ the factory from `src/index.ts` when it belongs to the public package API. Run the narrowest command that proves your change — `bun run typecheck` for types, a focused `bun test tests/<name>.test.ts` or runtime probe for behavior, then the broader gates appropriate to -the affected surface. opencodex favors small, verifiable commits over large batches. +the affected surface. CodexCommander favors small, verifiable commits over large batches. diff --git a/docs-site/src/content/docs/contributing/pr-quality.md b/docs-site/src/content/docs/contributing/pr-quality.md index a7948d96b3..a513a87456 100644 --- a/docs-site/src/content/docs/contributing/pr-quality.md +++ b/docs-site/src/content/docs/contributing/pr-quality.md @@ -1,6 +1,6 @@ --- title: Pull request quality contract -description: Review readiness, contributor responsibility, trust lanes, and closure policy for OpenCodex pull requests. +description: Review readiness, contributor responsibility, and closure policy for CodexCommander pull requests. --- ## You do not need permission to fix something @@ -17,8 +17,8 @@ not an admission requirement. ## What a ready pull request claims -Marking a PR ready for review is a claim that the change is complete, understood, -and tested. Opening it does not transfer responsibility for the branch to the +Opening a PR for review is a claim that the change is complete, understood, and +tested. Opening it does not transfer responsibility for the branch to the maintainers. Authors are expected to understand every changed line, name the exact commands @@ -30,87 +30,37 @@ on your behalf. "Tested" or "CI passes" without named commands and results is not evidence. -## Automated gates - -Three deterministic checks run before human review, and each failure message -tells you exactly what to change: - -- **PR quality (`enforce-target`).** Pull requests must target `dev` and carry - a real description: a **Summary** of what changed and why, plus a **Test - plan** (or equivalent substance). When the title or description mentions - `gui`, the description must include a screenshot of the UI change; the check - keeps the PR a draft and comments until the screenshot is present. A - maintainer (OWNER / COLLABORATOR / MEMBER — repository owners, - collaborators, and members) can waive the screenshot - requirement with an issue comment saying the change does not touch the GUI - (for example "no gui changes"); a contributor PR author cannot self-waive - (a maintainer who authors the PR can waive, but they already hold push - permission and are not gated by the contributor checklist). - Contributor PRs (authors without repository push permission) open in draft - and stay there until a four-box review-readiness checklist in the - description is complete: local CI green, the branch on the latest `dev` - commit, all correct Codex and CodeRabbit findings fixed, and the - ready-for-review confirmation. Once every box is ticked the check marks the - PR ready for review and notifies the maintainers listed in `MAINTAINERS.md` - (excluding the author). The gate's status and "what to do" live in a single - consolidated bot comment that is rewritten on every run, so there is exactly - one place to look. Completion is bound to the exact commit the PR head - pointed at: if new commits are pushed afterward, the gate moves the PR back - to draft, resets the checklist and the maintainer notification, and asks you - to test and tick the boxes again against the latest code. A retarget to - `dev` clears the wrong-branch message automatically and is remembered by the - gate; the draft stays until the checklist is complete. - Before a completion is accepted, the gate verifies the checklist claims it - can check itself: the head's `ci` check must be green, the branch must be on - the latest `dev` commit or at most 10 commits behind it, and every Codex and - CodeRabbit review thread authored by a review bot on the current head must be - resolved (unresolved threads from other authors do not block). CodeRabbit - findings that fall outside the diff range and are reported only in a review - body on the current head add to the unresolved count while a bot review - thread is open; resolving every bot thread clears the box. A disproved claim - unticks the matching box and keeps the PR a draft. When the checklist is - complete and every gate is green, the gate adds a `review-ready` label as a - visible status marker at the ready moment. - -- **Hygiene.** Behavior changes need a test; new lint or type suppressions, - focused or skipped tests, empty catch blocks, edited generated output, and a - lockfile changed without its manifest each need an explicit approval label. - A comment-only change to a source file is not a behavior change and owes no - test. -- **Cross-platform CI.** The suite runs sharded on Linux and in full on macOS for - every pull request. Windows runs at the shipping boundary — on promotion to - `main` or `preview` — so a slow or flaky Windows runner cannot decide when your - pull request turns green. - This runs for **every** pull request, whatever its base branch — including a - stacked child whose base is another open PR's head. The `paths:` filter, not - the base branch, decides whether the jobs run at all: a PR touching only docs - or `devlog/` queues nothing. - -- **Type label.** The `label` check derives `bug` / `enhancement` / - `documentation` / `chore` from your PR title. A title without a recognisable - prefix (`stack 3/5: …`) falls back to the PR's commits, which usually stay - conventional; `chore`-family commits (`test:`, `ci:`, `refactor:`) do not - outvote a `fix:` or `feat:`. A PR that genuinely mixes types is left - unlabeled rather than guessed, and a label a human sets is never overwritten. - -CodeRabbit reviews every PR and its findings are advisory. Address what it gets -right; say why when it is wrong. It does not block a merge. - -### When a workflow change takes effect - -`enforce-target` and `label` run on `pull_request_target`, which GitHub always -loads from the repository **default branch**. A change to either takes effect -only after it is promoted to `main` — merging it to `dev` does not change live -behavior. The cross-platform CI workflow runs on `pull_request` and takes effect -as soon as it is on the branch being targeted. - -## Sponsored surfaces +## Target and description + +- Target **`main`**. It is the sole default, integration, and pull-request branch. +- Branch from the current **`main`** tip. +- Write a real description: a **Summary** of what changed and why, plus how you + verified it. Empty bodies and placeholder-only text are not review-ready. +- If the title or description mentions the dashboard UI (`gui`), include a + screenshot of the UI change. + +## Automated checks + +Ordinary contributions have **one automatic check**: **`ci`**. It is the +stable aggregate quality gate for every pull request. No repository workflow +adds another automatic contributor merge gate. + +Repository administrators may use the GitHub ruleset **Always-allow** bypass when +a branch or path rule would otherwise block an intentional admin action. That +bypass is for admin recovery and exceptional maintenance; contributor pull +requests still go through review on `main`. + +Publishing automation is not included in this repository. + +Code review bots, when enabled, are advisory. Address what they get right; say +why when they are wrong. They do not replace the author's verification claim. + +## Sensitive surfaces Authentication, credential handling, GitHub Actions workflows, release -automation, and dependency installation need a maintainer to sponsor the change -(`maintainer-sponsored`) before it merges. A bad merge on those surfaces is -expensive and hard to unwind, which is why they are the only surfaces gated this -way. Everything else is open. +automation, and dependency installation need explicit maintainer attention +before merge. A bad merge on those surfaces is expensive and hard to unwind. +Everything else remains open to ordinary contribution on `main`. ## When a pull request is closed diff --git a/docs-site/src/content/docs/getting-started/for-agents.md b/docs-site/src/content/docs/getting-started/for-agents.md index 93019fd483..483f5b3f97 100644 --- a/docs-site/src/content/docs/getting-started/for-agents.md +++ b/docs-site/src/content/docs/getting-started/for-agents.md @@ -1,6 +1,6 @@ --- title: Agent Quickstart -description: Install and operate opencodex from an agent-driven or scripted terminal. +description: Install and operate CodexCommander from an agent-driven or scripted terminal. --- This page is for an AI agent or a scripting user working from a terminal. It focuses on commands, @@ -8,70 +8,58 @@ exit status, and safe headless operation. For a human-led walkthrough, use the [Quickstart](/getting-started/quickstart/). The dashboard remains available for interactive configuration; see [Web Dashboard](/guides/web-dashboard/). -## Set up opencodex +## Set up CodexCommander -Install the published package and confirm that `ocx` is on `PATH`: +Use the existing source checkout. The registry package is not currently published: ```bash -npm install -g @bitkyc08/opencodex -ocx --version +bun install +bun run build:gui +bun run src/cli/index.ts --version ``` Choose one way to run the proxy: ```bash # Foreground: blocks this terminal until stopped. -ocx start +bun run src/cli/index.ts start # Background: installs or updates the service, then starts it. -ocx service +bun run src/cli/index.ts service ``` -Run `ocx init` in an interactive terminal. If `ocx start` is occupying the foreground, use a +Run `ccx init` in an interactive terminal. If `ccx start` is occupying the foreground, use a second terminal: ```bash -ocx init +bun run src/cli/index.ts init ``` -The wizard writes `$OPENCODEX_HOME/config.json` (normally -`~/.opencodex/config.json`). It can also inject the proxy address into Codex's `config.toml` and -install the optional Codex autostart shim. `ocx init` never starts the proxy. For a fully -non-interactive setup, configure providers with `ocx provider add` as shown below instead of driving +The wizard writes `$CODEXCOMMANDER_HOME/config.json` (normally +`~/.codexcommander/config.json`). It can also inject the proxy address into Codex's `config.toml` and +install the optional Codex autostart shim. `ccx init` never starts the proxy. For a fully +non-interactive setup, configure providers with `ccx provider add` as shown below instead of driving the wizard. -## Work from this fork - -For a Codex agent or developer working from source, clone this fork rather than the upstream URL: - -```bash -git clone https://github.com/pavelhov/opencodex.git -cd opencodex -bun install -bun run build:gui -bun run start -``` - -The source command form is `bun run src/cli/index.ts <command>` when `ocx` is not installed on -`PATH`. The fork retains upstream attribution and history. On macOS, the companion built from this -checkout stays at `dist/macos/OpenCodex.app`; see [macOS Menu Bar Companion](/guides/macos-menu-bar/) -instead of installing a development copy elsewhere. +The source command form is `bun run src/cli/index.ts <command>`. On macOS, the companion built from this checkout stays at +`dist/macos/CodexCommander.app`; see [macOS Menu Bar Companion](/guides/macos-menu-bar/) instead of +installing a development copy elsewhere. ## Check a headless installation Use these read-only checks in scripts and agent runs: ```bash -ocx status -ocx doctor -ocx health --json +ccx status +ccx doctor +ccx health --json ``` -`ocx status` reports the proxy and service state. `ocx doctor` diagnoses local environment, -network, Codex runtime, and account-health problems. `ocx health` exits `0` when the proxy is +`ccx status` reports the proxy and service state. `ccx doctor` diagnoses local environment, +network, Codex runtime, and account-health problems. `ccx health` exits `0` when the proxy is healthy and `1` otherwise; `--json` returns structured output. -Commands backed by the management API, such as `ocx combo set`, contact the live proxy. If no live +Commands backed by the management API, such as `ccx combo set`, contact the live proxy. If no live proxy can be found or the API is unreachable, the CLI treats that as a `503` failure and exits nonzero. Start the foreground proxy or background service before retrying. See the [CLI reference](/reference/cli/) and [Management API](/reference/management-api/) for the complete @@ -83,19 +71,19 @@ Registry providers can be added by name. For example, this adds the Anthropic AP makes it the default provider: ```bash -ocx provider add anthropic-apikey \ +ccx provider add anthropic-apikey \ --api-key "$ANTHROPIC_API_KEY" \ --set-default ``` -`ocx provider add` writes local configuration. Add `--sync` if a live proxy is already running and -you want to sync models to Codex immediately; otherwise run `ocx sync` later. Custom providers that +`ccx provider add` writes local configuration. Add `--sync` if a live proxy is already running and +you want to sync models to Codex immediately; otherwise run `ccx sync` later. Custom providers that are not in the registry require both `--adapter` and `--base-url`. Once all target providers are configured and the proxy is running, create a failover combo: ```bash -ocx combo set main \ +ccx combo set main \ --targets anthropic/claude-opus-4-8,openai/gpt-5.6-sol \ --strategy failover ``` @@ -107,13 +95,13 @@ behavior. ## Remote and LAN binds The default loopback bind does not require an API token. A non-loopback bind, such as `0.0.0.0`, -requires `OPENCODEX_API_AUTH_TOKEN`; the proxy refuses to start without it. Set the variable before -`ocx start`, or before `ocx service install` so the service receives it: +requires `CODEXCOMMANDER_API_AUTH_TOKEN`; the proxy refuses to start without it. Set the variable before +`ccx start`, or before `ccx service install` so the service receives it: ```bash -export OPENCODEX_API_AUTH_TOKEN="your-secret-token" -ocx service install +export CODEXCOMMANDER_API_AUTH_TOKEN="your-secret-token" +ccx service install ``` Clients must then authenticate their management and model requests. Read the remote-access rules in -[Configuration](/reference/configuration/) before exposing opencodex beyond the local machine. +[Configuration](/reference/configuration/) before exposing CodexCommander beyond the local machine. diff --git a/docs-site/src/content/docs/getting-started/how-it-works.mdx b/docs-site/src/content/docs/getting-started/how-it-works.mdx index d5b3b0885e..3e26a18cd1 100644 --- a/docs-site/src/content/docs/getting-started/how-it-works.mdx +++ b/docs-site/src/content/docs/getting-started/how-it-works.mdx @@ -1,21 +1,21 @@ --- title: How It Works -description: The full opencodex request lifecycle — parse, route, adapt, bridge, and stream. +description: The full CodexCommander request lifecycle — parse, route, adapt, bridge, and stream. --- import { Steps } from '@astrojs/starlight/components'; -Codex speaks the OpenAI **Responses API**. opencodex accepts `POST /v1/responses` over HTTP with +Codex speaks the OpenAI **Responses API**. CodexCommander accepts `POST /v1/responses` over HTTP with Server-Sent Events, plus an opt-in WebSocket upgrade on the same path. It translates the request to your provider's wire format and the answer back into Responses events — so Codex never knows it isn't talking to OpenAI. ``` - ┌──────────────────────────── opencodex ────────────────────────────┐ + ┌──────────────────────────── CodexCommander ────────────────────────────┐ │ │ Codex ──▶ │ parser ──▶ router ──▶ [vision] ──▶ adapter ──▶ provider │ ──▶ Codex (/v1/ │ │ │ │ │ │ │ (SSE / WS) - responses)│ OcxParsed provider describe buildRequest parseStream │ + responses)│ CodexCommanderParsed provider describe buildRequest parseStream │ │ Request +adapter images + fetch AdapterEvent[] │ │ │ │ │ │ [web-search loop] bridge ─▶ SSE │ @@ -26,13 +26,13 @@ isn't talking to OpenAI. ## Codex auth account selection -When the selected provider is the ChatGPT/Codex passthrough, opencodex can choose a stored pool +When the selected provider is the ChatGPT/Codex passthrough, CodexCommander can choose a stored pool account before the request is forwarded upstream. The rule is intentionally split: - **Existing thread ids keep affinity.** A thread is bound to the account generation that started it, so a long SSH, tmux, or mobile-attached Codex session keeps using one account instead of being rebalanced mid-conversation. -- **New sessions can rebalance.** For a new thread, opencodex picks among eligible accounts using +- **New sessions can rebalance.** For a new thread, CodexCommander picks among eligible accounts using `accountPoolStrategy` (`quota` by default, or `round-robin` / `fill-first`). The `quota` strategy compares known usage across 5h, weekly, and 30d windows and can switch to a lower-usage account when the active account crosses `autoSwitchThreshold`. Accounts in cooldown or needing @@ -54,7 +54,7 @@ effort to use; v2 requests keep Codex's native multi-agent guidance. <Steps> 1. **Parse** — `responses/parser.ts` validates the request with a Zod schema (`responses/schema.ts`) - and lowers it into an internal `OcxParsedRequest`: system prompt, a normalized message list + and lowers it into an internal `CodexCommanderParsedRequest`: system prompt, a normalized message list (text, images, tool calls, tool results), the tool definitions, generation options, and feature flags such as `_webSearch` (hosted web search requested) and `_structuredOutput` (a JSON schema / JSON-object `text.format` was set). Images are preserved as real content parts — never inlined as @@ -65,23 +65,23 @@ effort to use; v2 requests keep Codex's native multi-agent guidance. (`claude-`, `gpt-`, `o1-`/`o3-`/`o4-`, `llama-`/`mixtral-`/`gemma-`) → a provider's `models[]` → the `defaultProvider` fallback. See [Model Routing](/guides/model-routing/). -3. **Authenticate** — for an `oauth` provider, opencodex resolves the current access token as the - bearer key and follows its credential owner: OpenCodex-owned credentials refresh automatically, +3. **Authenticate** — for an `oauth` provider, CodexCommander resolves the current access token as the + bearer key and follows its credential owner: CodexCommander-owned credentials refresh automatically, while linked Grok/Kimi native CLI generations are re-read and used read-only. For ChatGPT/Codex pool accounts, `codex/auth-context.ts` resolves the account first and the passthrough adapter refuses to continue if the required pool credential is unavailable. 4. **Vision sidecar (optional)** — if the routed model is listed in `provider.noVisionModels` and the - request carries an image, opencodex describes each image with the configured ChatGPT vision + request carries an image, CodexCommander describes each image with the configured ChatGPT vision sidecar and replaces it with text, so a text-only model can still reason about it. See [Sidecars](/guides/sidecars/). 5. **Passthrough fast path** — if the adapter is a Responses passthrough (`openai-responses` or - `azure-openai`), opencodex keeps the Responses body, applies targeted routing and compatibility + `azure-openai`), CodexCommander keeps the Responses body, applies targeted routing and compatibility rewrites, then relays the provider's response without converting it through `AdapterEvent`s. 6. **Web-search sidecar (optional)** — if Codex enabled hosted `web_search` but the routed model is - non-OpenAI, opencodex exposes a synthetic `web_search` function tool and runs the model in a small + non-OpenAI, CodexCommander exposes a synthetic `web_search` function tool and runs the model in a small agentic loop, executing real searches through `gpt-5.6-luna` by default over your ChatGPT login and injecting the results back as tool results. @@ -90,7 +90,7 @@ effort to use; v2 requests keep Codex's native multi-agent guidance. routed model runs as a tool-free summarizer and returns the replacement history shape Codex expects. 8. **Adapt** — otherwise the chosen adapter's `buildRequest()` produces the upstream HTTP request - (URL, headers, body) in the provider's native format, and opencodex `fetch`es it. + (URL, headers, body) in the provider's native format, and CodexCommander `fetch`es it. 9. **Bridge** — the adapter's `parseStream()` (or `parseResponse()`) yields internal `AdapterEvent`s (text, reasoning, tool-call start/delta/end, done, error). `bridge.ts` converts that stream back @@ -100,9 +100,9 @@ effort to use; v2 requests keep Codex's native multi-agent guidance. </Steps> -## Why a proxy and not a Codex fork? +## Why the proxy architecture? -Codex hard-codes the Responses API. By translating at the protocol boundary, opencodex works with the +Codex hard-codes the Responses API. By translating at the protocol boundary, CodexCommander works with the Codex **CLI, App, and SDK** unchanged, survives Codex updates, and lets you switch providers per request without touching Codex itself. The translation is bidirectional and streaming-faithful: reasoning summaries, MCP tool namespaces, freeform (`apply_patch`) tools, and `tool_search` discovery diff --git a/docs-site/src/content/docs/getting-started/installation.md b/docs-site/src/content/docs/getting-started/installation.md index a3cc4da3ed..3024610a66 100644 --- a/docs-site/src/content/docs/getting-started/installation.md +++ b/docs-site/src/content/docs/getting-started/installation.md @@ -1,102 +1,73 @@ --- title: Installation -description: Install the opencodex (ocx) proxy, its prerequisites, and verify it runs. +description: Install CodexCommander (`ccx` / `codexcommander`), its prerequisites, and verify it runs. --- -opencodex installs two equivalent command names, `ocx` and `opencodex`. Both launch the same small -local HTTP server (built on Bun). Model requests go to the provider selected by routing; optional +CodexCommander exposes two equivalent command names in packaged or locally linked builds, `ccx` and +`codexcommander`. Both launch the same small local HTTP server (built on Bun). Model requests go to the provider selected by routing; optional vision and web-search sidecars can also use your ChatGPT login when a routed model needs them. ## Prerequisites | Requirement | Why | | --- | --- | -| **[Node](https://nodejs.org) ≥ 18** | `ocx` runs on the Bun runtime, but the runtime is bundled automatically on `npm install` — you do **not** need to install Bun yourself. | -| **[OpenAI Codex](https://openai.com/codex)** (CLI, App, or SDK) | The client opencodex sits in front of. opencodex writes to `$CODEX_HOME/config.toml` (default `~/.codex/config.toml`). | +| **[Bun](https://bun.sh)** | The source runtime and repository scripts run directly on Bun. | +| **[OpenAI Codex](https://openai.com/codex)** (CLI, App, or SDK) | The client CodexCommander sits in front of. CodexCommander writes to `$CODEX_HOME/config.toml` (default `~/.codex/config.toml`). | | A provider account or API key | Anthropic, xAI, Kimi, Ollama Cloud, OpenRouter, an OpenAI-compatible endpoint, or your ChatGPT login. | -## Install +## Run the source checkout ```bash -npm install -g @bitkyc08/opencodex -``` - -:::note[npm blocked the bun postinstall?] -Recent npm versions may block bun's postinstall script (`npm warn -install-scripts ... blocked because they are not covered by allowScripts`), -which leaves the bundled Bun runtime unprepared. Reinstall allowing bun's -script — and always include the package name (npm's abbreviated suggestion -omits it, which would reinstall the current directory instead): - -```bash -npm install -g --allow-scripts=bun @bitkyc08/opencodex - -# if the original install used sudo, keep using sudo: -sudo npm install -g --allow-scripts=bun @bitkyc08/opencodex -``` -::: - -Verify both command aliases are on your `PATH`: - -```bash -ocx --version -opencodex --version +bun install +bun run build:gui +bun run src/cli/index.ts start ``` -### Release channels - -The stable `latest` channel already includes GPT-5.6 Sol/Terra/Luna catalog support for ChatGPT, -OpenAI API-key, OpenRouter, and experimental Cursor routes. Upstream access is still account-gated; -the catalog entries do not grant access by themselves. Use the preview channel only to test -unreleased opencodex builds: +The registry package is not currently published. Run other commands from this checkout by replacing +`ccx <args>` with `bun run src/cli/index.ts <args>`. For example, verify the runtime in another +terminal: ```bash -npm install -g @bitkyc08/opencodex@preview -ocx update --tag preview +bun run src/cli/index.ts --version ``` -## Run from source +## Development mode -To hack on opencodex itself: +Use separate proxy and dashboard processes while editing the UI: ```bash -git clone https://github.com/pavelhov/opencodex.git -cd opencodex -bun install -bun run build:gui # build the dashboard that the proxy serves at / -bun run start # starts the proxy from src/cli/index.ts +bun run dev:proxy +bun run dev:gui # another terminal ``` -The checkout URL above is this fork's source of truth for the approved companion and OpenCode -integration. Upstream attribution and Git history remain intact. `bun run dev` remains an alias for -`bun run dev:proxy`; the proxy API exposes `/healthz`, `/v1/responses`, and `/api/*`. While hacking -on the dashboard, run `bun run dev:proxy` and `bun run dev:gui` in separate terminals instead of the -packaged-dashboard commands above. +`bun run dev` remains an alias for `bun run dev:proxy`; the proxy API exposes `/healthz`, +`/v1/responses`, and `/api/*`. While hacking on the dashboard, run `bun run dev:proxy` and +`bun run dev:gui` in separate terminals instead of the packaged-dashboard commands above. On macOS, build the companion from this same checkout with `bun run test:macos && bun run -build:macos`. Its source-build location is `dist/macos/OpenCodex.app`; do not copy that development +build:macos`. Its source-build location is `dist/macos/CodexCommander.app`; do not copy that development build into Application Support. See [macOS Menu Bar Companion](/guides/macos-menu-bar/) for lifecycle -behavior, Launch at Login, Desktop/Headless/Off modes, and release installation. +behavior, Launch at Login, Desktop/Headless/Off modes, and source-build operation. ## What gets created -opencodex state lives under `$OPENCODEX_HOME` (default `~/.opencodex`). Codex integration files live +CodexCommander state lives under `$CODEXCOMMANDER_HOME` (default `~/.codexcommander`). Codex integration files live under `$CODEX_HOME` (default `~/.codex`). | Path | Purpose | | --- | --- | -| `$OPENCODEX_HOME/config.json` | Your providers, default provider, port, and options. | -| `$OPENCODEX_HOME/ocx.pid` | PID of the running proxy (single-instance guard). | -| `$OPENCODEX_HOME/runtime-port.json` | The live PID, hostname, and port, including an automatically selected fallback port. | -| `$OPENCODEX_HOME/auth.json` | Stored OAuth credentials (when you `ocx login`). | -| `$OPENCODEX_HOME/catalog-backup*.json` | Codex model catalog backups made before opencodex edits it. | -| `$CODEX_HOME/config.toml` | On loopback, opencodex adds a marker-owned root `openai_base_url`; non-loopback binds use `model_provider = "opencodex"` plus `[model_providers.opencodex]` so Codex can send the API-auth header. | -| `$CODEX_HOME/opencodex.config.toml` | Fallback/reference profile written alongside the main Codex config. | -| `$CODEX_HOME/opencodex-catalog.json` | Synced native and routed model catalog used by Codex. | +| `$CODEXCOMMANDER_HOME/config.json` | Your providers, default provider, port, and options. | +| `$CODEXCOMMANDER_HOME/codexcommander.pid` | PID of the running proxy (single-instance guard). | +| `$CODEXCOMMANDER_HOME/runtime-port.json` | The live PID, hostname, and port, including an automatically selected fallback port. | +| `$CODEXCOMMANDER_HOME/auth.json` | Stored OAuth credentials (when you `ccx login`). | +| `$CODEXCOMMANDER_HOME/catalog-backup-<catalog-id>.json` | Codex model catalog backup made before CodexCommander edits it. | +| `$CODEX_HOME/config.toml` | On loopback, CodexCommander adds a marker-owned root `openai_base_url`; non-loopback binds use `model_provider = "codexcommander"` plus `[model_providers.codexcommander]` so Codex can send the API-auth header. | +| `$CODEX_HOME/codexcommander.config.toml` | Fallback/reference profile written alongside the main Codex config. | +| `$CODEX_HOME/codexcommander-catalog.json` | Synced native and routed model catalog used by Codex. | :::note -opencodex never deletes your Codex config. Every injection is reversible — `ocx stop`, `ocx restore`, -or `ocx eject` strip exactly the lines opencodex added and restore native Codex. +CodexCommander never deletes your Codex config. Every injection is reversible — `ccx stop`, `ccx restore`, +or `ccx eject` strip exactly the lines CodexCommander added and restore native Codex. ::: ## Next diff --git a/docs-site/src/content/docs/getting-started/quickstart.md b/docs-site/src/content/docs/getting-started/quickstart.md index 93fb769181..ab88ec0e8a 100644 --- a/docs-site/src/content/docs/getting-started/quickstart.md +++ b/docs-site/src/content/docs/getting-started/quickstart.md @@ -1,6 +1,6 @@ --- title: Quickstart -description: Configure your first provider and route OpenAI Codex through opencodex in three commands. +description: Configure your first provider and route OpenAI Codex through CodexCommander in three commands. --- This guide takes you from a fresh install to running Codex against a non-OpenAI model. @@ -8,25 +8,25 @@ This guide takes you from a fresh install to running Codex against a non-OpenAI ## 1. Run the setup wizard ```bash -ocx init +ccx init ``` -`ocx init` walks you through: +`ccx init` walks you through: 1. **Pick a provider** — choose one of the 76 built-in registry presets or `custom` to type a base URL and adapter. 2. **API key** — paste a key, or reference an environment variable like `${ANTHROPIC_API_KEY}`. 3. **Default model** — for key, local, and custom providers, accept the preset or enter a model id. 4. **Proxy port** — defaults to `10100`. -5. **Inject into Codex?** — on a normal loopback setup, opencodex adds a root `openai_base_url` to +5. **Inject into Codex?** — on a normal loopback setup, CodexCommander adds a root `openai_base_url` to `$CODEX_HOME/config.toml` (default `~/.codex/config.toml`) so Codex's built-in `openai` provider targets the proxy. Remote/LAN binds use a dedicated provider entry with an API-auth header instead. -6. **Install the autostart shim?** — when enabled, launching `codex` runs `ocx ensure` first. +6. **Install the autostart shim?** — when enabled, launching `codex` runs `ccx ensure` first. -The result is saved to `$OPENCODEX_HOME/config.json` (default `~/.opencodex/config.json`). +The result is saved to `$CODEXCOMMANDER_HOME/config.json` (default `~/.codexcommander/config.json`). :::note[GPT-5.6 rollout entries] -The current stable release seeds GPT-5.6 Sol/Terra/Luna for ChatGPT passthrough, OpenAI API-key, +The current source tree seeds GPT-5.6 Sol/Terra/Luna for ChatGPT passthrough, OpenAI API-key, OpenRouter, and the experimental Cursor adapter. They work only when that upstream account has access. The OpenAI API-key and OpenRouter presets advertise a 372,000-token usable context window; Cursor keeps its own @@ -36,30 +36,30 @@ adapter metadata. ## 2. Start the proxy ```bash -ocx start # defaults to port 10100 -ocx start --port 8080 +ccx start # defaults to port 10100 +ccx start --port 8080 ``` -On start, opencodex: +On start, CodexCommander: -- writes its PID to `~/.opencodex/ocx.pid` (and refuses to start twice), +- writes its PID to `~/.codexcommander/codexcommander.pid` (and refuses to start twice), - discovers live models where the provider supports it and **syncs native and routed entries into Codex's model catalog**, - listens on `http://localhost:<port>/v1`. -If the requested port is busy, `ocx start` selects a free port, records it in `runtime-port.json`, +If the requested port is busy, `ccx start` selects a free port, records it in `runtime-port.json`, and updates Codex to use the live listener. Check it: ```bash -ocx status -ocx gui # open the dashboard on the live port +ccx status +ccx gui # open the dashboard on the live port ``` ## 3. Use Codex -Codex now talks to opencodex transparently: +Codex now talks to CodexCommander transparently: ```bash codex "Refactor this function for readability" @@ -75,7 +75,7 @@ codex -m "ollama-cloud/glm-5.2" "Write a SQL migration" ## Choose sub-agent models (optional) A fresh config features five native models in Codex's sub-agent picker: `gpt-5.5`, -`gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna`, and `gpt-5.4-mini`. Open `ocx gui` to replace or +`gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna`, and `gpt-5.4-mini`. Open `ccx gui` to replace or reorder up to five native or routed models. The dashboard can also set one preferred sub-agent model and reasoning effort. See [Sub-agent Surface](/guides/sub-agent-surface/) to choose v1/base/v2 and understand when guidance, native defaults, and fallback apply. @@ -83,23 +83,23 @@ understand when guidance, native defaults, and fallback apply. For a headless roster, use the same live proxy policy: ```bash -ocx agent subagents set anthropic/claude-opus-5,gpt-5.6-sol -ocx v2 mode default +ccx agent subagents set anthropic/claude-opus-5,gpt-5.6-sol +ccx v2 mode default ``` The dashboard's **Use as native Codex sub-agent default** is a separate, default-off opt-in. When -OpenCodex owns the active Codex routing, the next sync or restart writes only its marker-owned +CodexCommander owns the active Codex routing, the next sync or restart writes only its marker-owned `[agents]` defaults for newly created tasks; it does not cause delegation or overwrite user-owned defaults. ## Logging in instead of pasting a key -Some providers support real account login. OpenCodex-owned OAuth credentials auto-refresh; linked +Some providers support real account login. CodexCommander-owned OAuth credentials auto-refresh; linked Grok/Kimi native CLI sessions remain CLI-owned: ```bash -ocx login xai # or: anthropic, kimi, kiro, google-antigravity, cursor -ocx logout xai +ccx login xai # or: anthropic, kimi, kiro, google-antigravity, cursor +ccx logout xai ``` OpenAI itself needs **no key** — the default provider forwards your existing `codex login` @@ -108,9 +108,9 @@ credentials straight through (see [Providers](/guides/providers/)). ## Stopping & restoring ```bash -ocx stop # stop the proxy and restore native Codex -ocx restore # restore native Codex without stopping (alias: ocx eject) -ocx restore back # route Codex through the still-running proxy again +ccx stop # stop the proxy and restore native Codex +ccx restore # restore native Codex without stopping (alias: ccx eject) +ccx restore back # route Codex through the still-running proxy again ``` ## Next diff --git a/docs-site/src/content/docs/guides/claude-code.md b/docs-site/src/content/docs/guides/claude-code.md index e2d1798832..fb302d3695 100644 --- a/docs-site/src/content/docs/guides/claude-code.md +++ b/docs-site/src/content/docs/guides/claude-code.md @@ -1,15 +1,15 @@ --- title: Claude Code -description: Use any routed model from Claude Code — opencodex serves the Anthropic Messages API and gateway model discovery on the same port. +description: Use any routed model from Claude Code — CodexCommander serves the Anthropic Messages API and gateway model discovery on the same port. --- -opencodex serves `POST /v1/messages` (plus `count_tokens`) alongside `/v1/responses`, so Claude +CodexCommander serves `POST /v1/messages` (plus `count_tokens`) alongside `/v1/responses`, so Claude Code can use every routed provider — OAuth logins, account pools, key failover and sidecars included — with zero extra auth work. ## Claude OAuth account pool (experimental) -You can log in multiple Claude accounts via the Providers dashboard (`ocx login anthropic` / +You can log in multiple Claude accounts via the Providers dashboard (`ccx login anthropic` / add-account). By default every request uses the **active** account only. An **experimental, opt-in** Claude account pool (`anthropicAccountPool.enabled`) adds sticky @@ -37,10 +37,10 @@ See [Configuration](/reference/configuration/#anthropicaccountpool-experimental) ## Quickstart ```bash -ocx claude +ccx claude ``` -`ocx claude` ensures the proxy is running, then launches Claude Code with the environment wired: +`ccx claude` ensures the proxy is running, then launches Claude Code with the environment wired: | Variable | Value | | --- | --- | @@ -48,17 +48,14 @@ ocx claude | `ANTHROPIC_AUTH_TOKEN` | Only when the proxy requires an API key — otherwise it is NOT set, so your claude.ai login (subscription + connectors) stays active | | `CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY` | `1` (native `/model` picker discovery) | | `CLAUDE_CODE_AUTO_COMPACT_WINDOW` | Auto-context compaction threshold (default `350000`); only injected when auto-context is enabled | -| `ANTHROPIC_MODEL` | `claudeCode.model` (optional) | -| `ANTHROPIC_DEFAULT_HAIKU_MODEL` | `claudeCode.tierModels.haiku ?? claudeCode.smallFastModel` (optional; legacy `ANTHROPIC_SMALL_FAST_MODEL` too) | -| `ANTHROPIC_DEFAULT_{OPUS,SONNET,FABLE}_MODEL` | `claudeCode.tierModels.*` (optional) | -| `CLAUDE_CODE_ALWAYS_ENABLE_EFFORT` | `1` when `alwaysEnableEffort` is on (conditional) | -| `CLAUDE_CODE_MAX_CONTEXT_TOKENS` / `DISABLE_COMPACT` | Legacy context override when `maxContextTokens` is set (conditional) | -Variables you export yourself always win. Extra arguments pass through: `ocx claude -p "hello"`. +| `ANTHROPIC_DEFAULT_HAIKU_MODEL` / `ANTHROPIC_SMALL_FAST_MODEL` | `claudeCode.smallFastModel` when configured | + +Variables you export yourself always win. Extra arguments pass through: `ccx claude -p "hello"`. One exception is about *where* a variable comes from, not about precedence. The bundled Bun runtime auto-loads a project `.env` / `.env.local`, so a stray `ANTHROPIC_API_KEY` in the directory you happen to launch from used to look identical to a deliberate export — and it -silently disabled a healthy claude.ai subscription in favour of API billing. `ocx claude` now +silently disabled a healthy claude.ai subscription in favour of API billing. `ccx claude` now ignores Anthropic credentials that only a project dotenv introduced. A value you exported in your shell still wins, in every auth mode. To use an API key deliberately, export it (`export ANTHROPIC_API_KEY=...`) rather than leaving it in a project file. @@ -67,9 +64,9 @@ your shell still wins, in every auth mode. To use an API key deliberately, expor Claude Code needs a token in `ANTHROPIC_AUTH_TOKEN` to talk to a gateway, but setting that variable also disables your claude.ai login and its connectors. Which of the two you want -depends on something opencodex can look up, so by default it does. +depends on something CodexCommander can look up, so by default it does. -Leave **Auth mode** on **Auto** (the default) in **Claude → Claude Code** and opencodex +Leave **Auth mode** on **Auto** (the default) in **Claude → Claude Code** and CodexCommander decides at each launch: | What it finds | What it does | @@ -79,15 +76,15 @@ decides at each launch: | It cannot tell (unreadable keychain, corrupt file) | Assumes subscription and prints a warning — it never moves a paying subscriber onto the proxy on a failed read | This is recomputed every launch, not remembered, so logging in or out is picked up on the -next `ocx claude` with nothing to reconfigure. +next `ccx claude` with nothing to reconfigure. Pick **Subscription** or **Proxy** explicitly when you want it fixed. An explicit choice is stored in `claudeCode.authMode` and detection never overrides it — including after you log in or out later. Switch back to Auto to hand the decision back. On macOS, auto-connect (`claudeCode.systemEnv`) follows the same resolution, so a plain -`claude` launched outside `ocx` behaves the same way. That file is a snapshot refreshed when -the proxy starts or you save settings, while `ocx claude` always resolves live. +`claude` launched outside `ccx` behaves the same way. That file is a snapshot refreshed when +the proxy starts or you save settings, while `ccx claude` always resolves live. ## System environment integration (macOS) @@ -106,15 +103,15 @@ is temporarily unavailable, the first available route in that family is used unt You can also manage the same profile from the command line: ```bash -ocx claude desktop [apply] -ocx claude desktop show [--json] -ocx claude desktop move <route> <opus|fable|sonnet|haiku> [--default] -ocx claude desktop default <opus|fable|sonnet|haiku> <route|none> -ocx claude desktop export <path|-> -ocx claude desktop import <path> [--apply] +ccx claude desktop apply +ccx claude desktop show [--json] +ccx claude desktop move <route> <opus|fable|sonnet|haiku> [--default] +ccx claude desktop default <opus|fable|sonnet|haiku> <route|none> +ccx claude desktop export <path|-> +ccx claude desktop import <path> [--apply] ``` -`ocx claude desktop` and `apply` both write the current profile to Claude Desktop. `show` gives a +`ccx claude desktop apply` writes the current profile to Claude Desktop. `show` gives a readable summary; add `--json` for scripts. `export -` writes versioned JSON to standard output. Import validates the complete file before saving, so an invalid file leaves the current profile unchanged. Add `--apply` to write a valid imported profile to Desktop immediately. Use `none` only @@ -123,29 +120,27 @@ for an empty family; every non-empty family must keep one default. Apply writes to Claude Desktop's real Electron user-data `configLibrary`: `~/Library/Application Support/Claude/configLibrary` on macOS, `%APPDATA%\Claude\configLibrary` on Windows, and `${XDG_CONFIG_HOME:-~/.config}/Claude/configLibrary` on Linux. Set -`OPENCODEX_CLAUDE_DESKTOP_CONFIG_DIR` for an explicit library override or -`CLAUDE_USER_DATA_DIR` for an alternate Desktop user-data root. The legacy `Claude-3p` directory is -not read or deleted automatically. +`CODEXCOMMANDER_CLAUDE_DESKTOP_CONFIG_DIR` for an explicit library override or +`CLAUDE_USER_DATA_DIR` for an alternate Desktop user-data root. Non-Anthropic routes receive stable aliases such as `claude-opus-4-8-2026MMDD`. The date-looking part is a synthetic route slot, not the model's release date. Real Anthropic Claude routes keep their real ids. New routes default to the Opus family, but moving a route does not change the -provider or model it calls. The legacy apply flags `--static`, `--hybrid`, and `--discovery-only` -remain available for existing scripts. +provider or model it calls. ## System Environment Integration -When `claudeCode.systemEnv` is set to `true` (default: **off**), `ocx start` uses `launchctl setenv` +When `claudeCode.systemEnv` is set to `true` (default: **off**), `ccx start` uses `launchctl setenv` to inject `ANTHROPIC_BASE_URL` and the related Claude Code environment variables system-wide. New terminal windows and tabs therefore route plain `claude` commands through the proxy without -requiring the `ocx claude` wrapper. Already-open shells are unaffected and must be reopened. +requiring the `ccx claude` wrapper. Already-open shells are unaffected and must be reopened. -`ocx stop` and proxy shutdown **unset the injected keys** (it does not restore previous values — -only the keys opencodex injected are removed). The proxy also writes `~/.opencodex/claude-env.sh`; -`ocx start` installs a `.zshrc` source hook that loads it automatically. +`ccx stop` and proxy shutdown **unset the injected keys** (it does not restore previous values — +only the keys CodexCommander injected are removed). The proxy also writes `~/.codexcommander/claude-env.sh`; +`ccx start` installs a `.zshrc` source hook that loads it automatically. Disable with `claudeCode.systemEnv: false` in the configuration or with the GUI toggle. This -feature is macOS-only; on other platforms, use `ocx claude`. +feature is macOS-only; on other platforms, use `ccx claude`. ## Native Claude passthrough (subscription pierce) @@ -156,13 +151,13 @@ caching and billing identity stay fully native, and routed models keep working i via the picker aliases. **Header handling:** hop-by-hop headers plus `host`, `content-length`, `accept-encoding`, -`x-opencodex-api-key`, and `origin` are stripped before forwarding. All other headers (including +`x-codexcommander-api-key`, and `origin` are stripped before forwarding. All other headers (including `anthropic-beta` and `anthropic-version`) pass through. The passthrough fires when **all four** conditions are met: `nativePassthrough` is not `false`; the model begins with `claude` or `anthropic`; the bearer or `x-api-key` starts with `sk-ant-`; and alias/model-map resolution returns the same model unchanged. This also means the -"claude.ai connectors are disabled" warning no longer appears with `ocx claude`. +"claude.ai connectors are disabled" warning no longer appears with `ccx claude`. Disable with `claudeCode.nativePassthrough: false`; point elsewhere with `claudeCode.anthropicBaseUrl`. @@ -171,24 +166,23 @@ Disable with `claudeCode.nativePassthrough: false`; point elsewhere with Claude Code 2.1.129+ discovers gateway models via `GET /v1/models?limit=1000` and lists them in the native `/model` picker labeled "From gateway". Because the picker only accepts ids beginning -with `claude` or `anthropic`, opencodex exposes routed models as stable, reversible aliases: +with `claude` or `anthropic`, CodexCommander exposes routed models as stable, reversible aliases: | Surface | Format | Example | | --- | --- | --- | -| Claude Code CLI | `claude-ocx-<provider>--<model>` (plain) or `claude-ocx2-…` (escaped) | `claude-ocx-native--gpt-5.6-sol` | +| Claude Code CLI | `claude-ccx2-<provider>--<model>` (plain) or `claude-ccx2-…` (escaped) | `claude-ccx2-native--gpt-5.6-sol` | | Claude Desktop 3P | `claude-opus-4-8-<code>` (3-char base36 hash) | `claude-opus-4-8-ncb` | The proxy picks the family per request: `?ids=cli` or `?ids=desktop` wins; otherwise the `claude-code/*` user-agent gets the readable CLI form and other clients get the Desktop hash. -Both families decode forever — a model saved in `settings.json` under either form keeps working. +Both current families resolve through the running alias registry. Each entry carries an honest display name such as `gemini-3-pro (gemini)`, plus full model capabilities (reasoning-effort ladder, thinking types) in the official ModelInfo shape so Claude Desktop's third-party gateway mode can offer its effort selector. Real Anthropic models keep their -canonical ids. The synthetic 2026 date is an internal slot, not a release date. Legacy hash aliases -and `claude-ocx-<provider>--<model>` ids from older configs still resolve. +canonical ids. The synthetic 2026 date is an internal slot, not a release date. If Claude Desktop's footer picker does not change the model for an already-running 3P -conversation, use `/model <id>` in that conversation. OpenCodex cannot observe picker state; it +conversation, use `/model <id>` in that conversation. CodexCommander cannot observe picker state; it routes the model id carried by each request. Confirm the result under **Logs → requestedModel**. Models with an authoritative 1M context window get an extra `…[1m]` picker row: selecting it makes @@ -200,13 +194,11 @@ slots via `ANTHROPIC_MODEL` or type any routed id with `/model` (Claude Code passes strings through). **Alias grammar rules:** provider must not contain `/` or `--` or equal `native`. -Plain model ids (no `/` or `~`) keep the v1 prefix `claude-ocx-…`. Model ids that contain `/` or -`~` mint the v2 prefix `claude-ocx2-…` with escapes (`/` → `~s`, `~` → `~t`), e.g. -`openrouter/anthropic/claude-opus-4-8` → `claude-ocx2-openrouter--anthropic~sclaude-opus-4-8`. -v1 aliases decode literally (so a historical model id that contained the two-char sequences -`~s` / `~t` is preserved); v2 aliases expand the escapes. Routes that the readable form cannot -express fall back to the hashed alias. Model ids MAY contain `--` (resolution splits on the first -`--` only); native slugs containing `--` fall back to the hashed form. +The current `claude-ccx2-…` encoding escapes `/` as `~s` and `~` as `~t`, e.g. +`openrouter/anthropic/claude-opus-4-8` → `claude-ccx2-openrouter--anthropic~sclaude-opus-4-8`. +Routes that the readable form cannot express fall back to the hashed alias. Model ids MAY contain +`--` (resolution splits on the first `--` only); native slugs containing `--` fall back to the +hashed form. **Model resolution order:** `[1m]` marker stripped → readable alias decoded → Desktop hashed alias decoded → `modelMap` exact match → date-stripped match (`-20250514` removed) → passthrough. @@ -232,11 +224,10 @@ default) fixes that: 2. `CLAUDE_CODE_AUTO_COMPACT_WINDOW` (default `350000`, range `100000`–`1000000`) is injected so the conversation auto-summarizes at that point. -Three config states: +Two config states: - **absent / `true`:** enabled (default) - **`false`:** disabled — no markers, no compaction window injection -- **legacy `maxContextTokens` set:** auto-context is implicitly disabled The compaction value is adjustable on the Claude page. **Warning:** raising it past a model's real window breaks that model — the chat errors out before the summary can fire. @@ -247,37 +238,37 @@ fall back to 350k. ### Effective model environment -`effectiveModelEnv` computes six slots injected by `ocx claude` / system env / shell file: -`ANTHROPIC_MODEL`, four `ANTHROPIC_DEFAULT_{OPUS,SONNET,HAIKU,FABLE}_MODEL`, and legacy -`ANTHROPIC_SMALL_FAST_MODEL`. The effective Haiku is `tierModels.haiku ?? smallFastModel`, fed -to both Haiku variables. +`effectiveModelEnv` computes the two helper slots injected by `ccx claude`, system env, and the +shell file: `ANTHROPIC_DEFAULT_HAIKU_MODEL` and `ANTHROPIC_SMALL_FAST_MODEL`. Both receive +`claudeCode.smallFastModel`. -When both `tierModels.haiku` and `smallFastModel` are absent, OpenCodex leaves both helper variables unset; Claude Code then chooses its native helper model (currently Sonnet), which may incur native-provider charges. +When `smallFastModel` is absent, CodexCommander leaves both helper variables unset; Claude Code then +chooses its native helper model, which may incur native-provider charges. ## Roster agents (injectAgents) -`ocx claude` (and the system-env daemon) syncs your featured subagent roster (Subagents tab, -up to 5 models) plus `ocx-self` into `~/.claude/agents/ocx-*.md`. +`ccx claude` (and the system-env daemon) syncs your featured subagent roster (Subagents tab, +up to 5 models) plus `ccx-self` into `~/.claude/agents/ccx-*.md`. -- **`ocx-self`** pins your `/model` picker default (falling back to `claudeCode.model`); omitted - when neither exists. It does NOT use model inheritance. -- Each agent body contains an `<!-- ocx-route: <model> -->` directive — the proxy uses this to +- **`ccx-self`** pins your `/model` picker default; it is omitted when no picker default exists. + It does NOT use model inheritance. +- Each agent body contains an `<!-- ccx-route: <model> -->` directive — the proxy uses this to pin the real route. The Agent tool's `model` argument is therefore inert; pass `"haiku"` as a placeholder. - Frontmatter carries the alias; routing is directive-driven. -- Only marker-verified `ocx-*.md` files containing `generated-by: opencodex` are ever +- Only marker-verified `ccx-*.md` files containing `generated-by: codexcommander` are ever overwritten or pruned; your own agents are never touched. - Files are atomically synced per file (write + rename). - `enabled: false` or `injectAgents: false` prunes all verified-owned definitions. - GUI PUT and roster changes resync immediately; launcher/system-env sync at launch. -Dispatch: `subagent_type: "ocx-gpt-5-6-sol"`. 1M-capable targets carry `[1m]` automatically. +Dispatch: `subagent_type: "ccx-gpt-5-6-sol"`. 1M-capable targets carry `[1m]` automatically. ## Bundled-skill elision (blockedSkills) Claude Code's bundled `claude-api` skill injects ~840KB (~136k tokens) of Anthropic documentation that auto-triggers on Claude model mentions. Routed models are not trained on that bundle, so by -default opencodex replaces the skill's content with a short stub on **routed** requests. Native +default CodexCommander replaces the skill's content with a short stub on **routed** requests. Native Anthropic passthrough is untouched. **Two carriers are handled:** @@ -310,7 +301,7 @@ Lookup order: discovery alias → exact id → id with date suffix stripped (`-2 ## Sidecar matrix: web search and image understanding -Routed models do not all have the same hosted tools or image support. opencodex fills those gaps +Routed models do not all have the same hosted tools or image support. CodexCommander fills those gaps before the main model answers: - The **web-search sidecar** runs the real hosted search, then gives the routed model the answer and @@ -325,9 +316,9 @@ Both sidecars can use either backend: | `openai` | A small GPT model through the ChatGPT `forward` provider | A ChatGPT login and an enabled `authMode: "forward"` provider | | `anthropic` | Claude through stored Anthropic OAuth; web search uses `web_search_20250305` and vision sends the image to Claude for description | An enabled `adapter: "anthropic"`, `authMode: "oauth"` provider whose active stored account is not marked `needsReauth` | -An explicit `backend` always wins. When it is omitted, opencodex selects `anthropic` if a usable +An explicit `backend` always wins. When it is omitted, CodexCommander selects `anthropic` if a usable stored Anthropic OAuth account exists; otherwise it selects `openai`. Explicitly selecting -`anthropic` without a usable credential **fails closed**: opencodex does not silently borrow +`anthropic` without a usable credential **fails closed**: CodexCommander does not silently borrow ChatGPT credentials or switch backends. The OpenAI backend likewise stays off without both login auth and a forward provider. @@ -439,7 +430,7 @@ Anthropic `/v1/messages/count_tokens` endpoint. ## Debug capture -`ocx debug claude on|off|status|reset`, `OCX_CLAUDE_DEBUG=1`, or `PUT /api/debug {"claude": true}` +`ccx debug claude on|off|status|reset`, `CCX_CLAUDE_DEBUG=1`, or `PUT /api/debug {"claude": true}` controls inbound capture. `GET /api/claude/inbound-debug` returns `{enabled, entries}` (newest first, ring of 20). @@ -455,7 +446,7 @@ The dashboard sidebar has a dedicated **Claude** page (below API) and a **Claude (label intentionally identical in every language). The page shows: - Inbound kill switch (enabled toggle) -- Quickstart (`ocx claude`) and manual env block +- Quickstart (`ccx claude`) and manual env block - Fast Mode selector (Auto / ON / OFF) - Auto-context toggle and compaction threshold dropdown - Subagent auto-registration toggle @@ -470,8 +461,8 @@ fields; `null` resets context/blocklist/compact-window values. **Claude Code says "Did 0 searches"** — Current builds translate completed Responses `web_search_call` items into paired Anthropic `server_tool_use` and `web_search_tool_result` blocks, -including `usage.server_tool_use.web_search_requests`. Update opencodex if an older build completed -the search but Claude Code still counted zero. +including `usage.server_tool_use.web_search_requests`. If a search completes but Claude Code still +counts zero, verify that the running CodexCommander process was rebuilt from the current checkout. **A sidecar does not activate** — For `backend: "openai"`, confirm you are logged into ChatGPT and have an enabled `authMode: "forward"` provider. For `backend: "anthropic"`, confirm the active stored @@ -479,24 +470,24 @@ Anthropic OAuth account is not marked `needsReauth`. An explicit Anthropic selec credential intentionally fails closed. **"claude.ai connectors are disabled"** — An `ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN` is set -in your shell. `ocx claude` deliberately does NOT set `ANTHROPIC_API_KEY`; if you have it exported, -unset it. `ocx claude` injects `ANTHROPIC_BASE_URL`, discovery, auto-context, and configured model slots — but never `ANTHROPIC_API_KEY`. +in your shell. `ccx claude` deliberately does NOT set `ANTHROPIC_API_KEY`; if you have it exported, +unset it. `ccx claude` injects `ANTHROPIC_BASE_URL`, discovery, auto-context, and configured model slots — but never `ANTHROPIC_API_KEY`. **Models not showing in /model picker** — Verify `CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1` is -set (automatic with `ocx claude`). Run `ocx claude` to refresh the gateway model cache at +set (automatic with `ccx claude`). Run `ccx claude` to refresh the gateway model cache at `~/.claude/cache/gateway-models.json`. Check `claudeCode.enabled` is not `false`. **Stale environment after port change** — If the proxy port changed, old shells may have a stale -`ANTHROPIC_BASE_URL`. Open a new terminal, or re-run `ocx claude`. +`ANTHROPIC_BASE_URL`. Open a new terminal, or re-run `ccx claude`. **200k context ceiling despite big model** — Select the `[1m]` variant in the picker, or enable auto-context (on by default). If the picker shows no `[1m]` row, the model's authoritative context window may be below the auto-compact threshold. **High token count from skill loads** — The bundled `claude-api` skill (~136k tokens) auto-loads -on Claude model mentions. This is normal for native passthrough; on routed models, opencodex stubs +on Claude model mentions. This is normal for native passthrough; on routed models, CodexCommander stubs it by default (`blockedSkills: ["claude-api"]`). -**Subagent dispatches to wrong model** — Roster agents (`ocx-*`) use `<!-- ocx-route: ... -->` +**Subagent dispatches to wrong model** — Roster agents (`ccx-*`) use `<!-- ccx-route: ... -->` directives, not the Agent tool's `model` argument. Make sure the directive matches the intended route. Pass `"haiku"` as the model placeholder. diff --git a/docs-site/src/content/docs/guides/codex-app-models.md b/docs-site/src/content/docs/guides/codex-app-models.md index 4abcef24a9..23a7366018 100644 --- a/docs-site/src/content/docs/guides/codex-app-models.md +++ b/docs-site/src/content/docs/guides/codex-app-models.md @@ -1,9 +1,9 @@ --- title: Codex App model picker -description: How opencodex models appear in Codex App, Codex CLI, and Codex TUI through the shared Codex catalog. +description: How CodexCommander models appear in Codex App, Codex CLI, and Codex TUI through the shared Codex catalog. --- -opencodex does not patch Codex App. It writes the same Codex configuration and model catalog that +CodexCommander does not patch Codex App. It writes the same Codex configuration and model catalog that Codex CLI/TUI already use. Because Codex App reads that shared state, routed models can appear in the App's model picker as normal Codex catalog entries. @@ -11,7 +11,7 @@ OpenAI entries use two credential routes: native Codex login and the namespaced `openai-apikey/<model>` API-key transport. Changing `codexAccountMode` between Pool and Direct by itself does not change picker ids. When `codexAccountNamespaces` has eligible selectors whose mapped accounts still exist, however, -opencodex adds separate `<selector>/<native-openai-model>` rows for the mapped accounts and hides +CodexCommander adds separate `<selector>/<native-openai-model>` rows for the mapped accounts and hides the bare native rows from the Codex picker. Selector labels are user-chosen public names with no built-in account-role meaning. Selecting a qualified row uses only its mapped account, does not change the active Pool account, and fails closed instead of switching accounts when the target is @@ -32,24 +32,17 @@ gpt-5.6-sol # bare Codex-login route via Pool or Direct openai-apikey/gpt-5.6-sol # API key ``` -Fresh installs and configs with no saved mode default to Pool. Current configs use marker 2 and -retain the shipped v1 source at `~/.opencodex/config.json.pre-openai-tiers-v2.bak`; restore it with: - -```sh -cp ~/.opencodex/config.json.pre-openai-tiers-v2.bak ~/.opencodex/config.json -``` - -Earlier v1 three-provider configurations migrate automatically into the single option-aware row. +Fresh installs and configs with no saved mode default to Pool. ## Integration path -`ocx init`, `ocx start`, and `ocx sync` wire the shared Codex config and catalog into the proxy; see +`ccx init`, `ccx start`, and `ccx sync` wire the shared Codex config and catalog into the proxy; see [Codex Integration](/guides/codex-integration/) for config injection, catalog sync, shims, WebSocket fallback, and restore mechanics. ## Why routed models show up -Codex's model picker expects Codex-shaped catalog entries. opencodex builds routed entries by cloning +Codex's model picker expects Codex-shaped catalog entries. CodexCommander builds routed entries by cloning a native Codex model template, then replacing the routed model identity: ```text @@ -59,13 +52,13 @@ visibility = "list" ``` The clone keeps strict-parser fields such as reasoning levels, shell type, API support flags, and -base instructions. opencodex then removes native-only capabilities that the route cannot honor, +base instructions. CodexCommander then removes native-only capabilities that the route cannot honor, including OpenAI service-tier metadata. ## Current stable model coverage The native fallback set includes `gpt-5.5`, `gpt-5.4`, `gpt-5.4-mini`, -`gpt-5.3-codex-spark`, and GPT-5.6 Sol/Terra/Luna. For the GPT-5.5/5.4 family, opencodex preserves +`gpt-5.3-codex-spark`, and GPT-5.6 Sol/Terra/Luna. For the GPT-5.5/5.4 family, CodexCommander preserves the installed Codex catalog's richer live entries and only synthesizes a missing entry. The bundled upstream snapshot is used only for GPT-5.6, where it supplies the real per-model identity and metadata instead of an older-template approximation. @@ -134,7 +127,7 @@ service_tier = "fast" fast_mode = true ``` -But the model catalog and runtime request tier id use `priority`. opencodex preserves that split. +But the model catalog and runtime request tier id use `priority`. CodexCommander preserves that split. Native OpenAI passthrough models keep fast support; routed providers are capability-gated — `service_tier` is stripped only when the provider declares `supportsServiceTier: false` (the registry classifies canonical OpenAI as `true`, DeepSeek and Volcengine Ark as `false`), while unclassified @@ -160,8 +153,8 @@ itself. If the picker still shows stale entries, refresh the catalog and restart the target Codex surface: ```bash -ocx sync +ccx sync ``` -opencodex rewrites `models_cache.json` with a deliberately stale cache wrapper whenever catalog +CodexCommander rewrites `models_cache.json` with a deliberately stale cache wrapper whenever catalog visibility, priority, or metadata changes, so the next Codex model refresh reads the new catalog. diff --git a/docs-site/src/content/docs/guides/codex-integration.md b/docs-site/src/content/docs/guides/codex-integration.md index 2362a13c19..a1a06afd52 100644 --- a/docs-site/src/content/docs/guides/codex-integration.md +++ b/docs-site/src/content/docs/guides/codex-integration.md @@ -1,26 +1,25 @@ --- title: Codex Integration -description: How opencodex injects itself into Codex, syncs the model catalog, installs shims, and restores cleanly. +description: How CodexCommander injects itself into Codex, syncs the model catalog, installs shims, and restores cleanly. --- -opencodex makes Codex route through the proxy by editing two things Codex reads: its config +CodexCommander makes Codex route through the proxy by editing two things Codex reads: its config (`$CODEX_HOME/config.toml`, default `~/.codex/config.toml`) and its model catalog. Every edit is idempotent and reversible. The proxy exposes one bare `openai` Codex-login route with Pool(default) and Direct account modes, plus `openai-apikey/<model>` for the configured API key. Pool includes main plus added accounts; -Direct uses only the caller/main bearer. The routes do not fall back to one another. Shipped v1 -configs migrate to marker 2 and preserve `config.json.pre-openai-tiers-v2.bak` for manual restore. +Direct uses only the caller/main bearer. The routes do not fall back to one another. ## Config injection -`ocx init`, `ocx start`, and `ocx sync` call the injector. On the default loopback bind, it keeps -Codex's built-in `openai` provider id and points that provider at opencodex: +`ccx init`, `ccx start`, and `ccx sync` call the injector. On the default loopback bind, it keeps +Codex's built-in `openai` provider id and points that provider at CodexCommander: ```toml # root keys, before the first table -model_catalog_json = "/absolute/path/to/opencodex-catalog.json" -# Auto-injected by opencodex +model_catalog_json = "/absolute/path/to/codexcommander-catalog.json" +# Auto-injected by CodexCommander openai_base_url = "http://127.0.0.1:10100/v1" # only when fastMode is set; unset adds no [features] table @@ -41,7 +40,7 @@ The proxy listens on port `10100` by default and serves `POST /v1/responses`, Codex's built-in `image_gen` tool does not go through `/v1/responses` — the codex-rs extension POSTs `{base_url}/images/generations` (or `/images/edits` when reference images are attached) directly, with the same ChatGPT bearer auth it uses for chat. Because the injected `base_url` -points at opencodex, the proxy relays those calls to the OpenAI upstream. +points at CodexCommander, the proxy relays those calls to the OpenAI upstream. This is separate from the [Image Bridge](/guides/image-bridge/), which only activates when a **Responses** turn lists the hosted `image_generation` tool while a non-OpenAI model is selected. @@ -60,7 +59,7 @@ Standalone `/images/generations` calls never enter that bridge. Antigravity **Cloud Code Assist** endpoint using the `gemini-3.1-flash-image` model. The fallback also fires after OpenAI auth resolution fails (e.g. an expired or missing ChatGPT credential), not only when no OpenAI candidate is configured. This - requires `ocx login google-antigravity`; the OAuth token is sent only to the pinned CCA registry + requires `ccx login google-antigravity`; the OAuth token is sent only to the pinned CCA registry host, never to a config-level `baseUrl` override. The response is returned in the same `{created, data:[{b64_json}]}` shape Codex expects. - **Neither:** the proxy returns a clear error instead of a generic 404. Routed providers @@ -69,9 +68,9 @@ Standalone `/images/generations` calls never enter that bridge. (`[features] image_generation = false` in `config.toml`). The tool declaration still travels with the model's Responses request. For API-key Responses -providers, opencodex lowers Codex's private `image_gen` namespace to an upstream-safe +providers, CodexCommander lowers Codex's private `image_gen` namespace to an upstream-safe `image_gen__<inner-name>` alias (for example `image_gen__imagegen`). When that usable alias replaces -the client declaration, opencodex removes a duplicate hosted `image_generation` declaration. It maps +the client declaration, CodexCommander removes a duplicate hosted `image_generation` declaration. It maps the function call to the explicit `image_gen` namespace before Codex sees it, and encodes the native call again when later history is replayed upstream. This keeps client-side image generation callable on public-compatible upstreams that reserve the namespace or reject dotted function names. ChatGPT @@ -111,21 +110,21 @@ uses a dedicated provider instead: ```toml # root keys -model_provider = "opencodex" -model_catalog_json = "/absolute/path/to/opencodex-catalog.json" +model_provider = "codexcommander" +model_catalog_json = "/absolute/path/to/codexcommander-catalog.json" # appended at the end of the file -# Auto-injected by opencodex -[model_providers.opencodex] -name = "OpenCodex Proxy" +# Auto-injected by CodexCommander +[model_providers.codexcommander] +name = "CodexCommander Proxy" base_url = "http://your-host:10100/v1" wire_api = "responses" requires_openai_auth = true -env_http_headers = { "x-opencodex-api-key" = "OPENCODEX_API_AUTH_TOKEN" } +env_http_headers = { "x-codexcommander-api-key" = "CODEXCOMMANDER_API_AUTH_TOKEN" } # supports_websockets = true # only when config.websockets is true ``` -When OpenCodex owns routing, both modes write `$CODEX_HOME/opencodex.config.toml` as a +When CodexCommander owns routing, both modes write `$CODEX_HOME/codexcommander.config.toml` as a reference/fallback config. On loopback it contains the root keys you can merge manually if automatic injection was removed; on non-loopback it contains the dedicated provider form. External-provider mode leaves this profile untouched. @@ -139,48 +138,40 @@ catalog but reports that routing was not injected. ## Shared model catalog -Codex CLI, TUI, App, and SDK all read the same Codex home. opencodex resolves that directory from +Codex CLI, TUI, App, and SDK all read the same Codex home. CodexCommander resolves that directory from `CODEX_HOME`, falling back to `~/.codex`, and manages: ```text $CODEX_HOME/config.toml -$CODEX_HOME/opencodex.config.toml -$CODEX_HOME/opencodex-catalog.json +$CODEX_HOME/codexcommander.config.toml +$CODEX_HOME/codexcommander-catalog.json $CODEX_HOME/models_cache.json ``` -On WSL, if `CODEX_HOME` is unset and the Linux `~/.codex/config.toml` is absent, opencodex also +On WSL, if `CODEX_HOME` is unset and the Linux `~/.codex/config.toml` is absent, CodexCommander also checks for a single Windows Codex Desktop home at `/mnt/c/Users/*/.codex/config.toml`. When exactly one candidate exists, it uses that directory so WSL app-server mode and Windows Codex Desktop share the same config and auth files. Set `CODEX_HOME` explicitly to override this detection. On Windows, an Orca shell can set both `CODEX_HOME` and `ORCA_CODEX_HOME` to Orca's bundled runtime -home while the ChatGPT/Codex app still reads `%USERPROFILE%\\.codex`. `ocx status` and `ocx doctor` +home while the ChatGPT/Codex app still reads `%USERPROFILE%\\.codex`. `ccx status` and `ccx doctor` warn about this exact mismatch and print redacted target paths. If a background service was installed from that Orca shell, uninstall it from the original shell first, then set `CODEX_HOME` to the app home, unset `ORCA_CODEX_HOME`, rerun sync/restore, and install the service again. In dedicated-provider mode, `requires_openai_auth = true` keeps Codex App/TUI account-gated surfaces -aligned with native Codex. opencodex also serves `/v1/responses` over WebSocket. The dedicated +aligned with native Codex. CodexCommander also serves `/v1/responses` over WebSocket. The dedicated provider advertises `supports_websockets = true` only when `"websockets": true`; on loopback Codex's built-in provider may try WebSocket first, and a disabled proxy returns `426` so Codex falls back to HTTP/SSE. -## Thread identity and history - -The default loopback form keeps new threads tagged with Codex's native `openai` provider, so normal -resume history needs no remapping. On first sync it also migrates threads tagged by older opencodex -builds back to `openai`. Non-loopback dedicated-provider mode still mirrors history under the -`opencodex` provider while active and restores the backed-up metadata on exit. Set -`syncResumeHistory: false` to leave history untouched. - ## Model catalog sync -Codex shows models from an on-disk catalog (`$CODEX_HOME/opencodex-catalog.json` by default). On -start and on `ocx sync`, opencodex: +Codex shows models from an on-disk catalog (`$CODEX_HOME/codexcommander-catalog.json` by default). On +start and on `ccx sync`, CodexCommander: -1. **Backs up** the pristine catalog once to `~/.opencodex/catalog-backup.json` (so featuring is - reversible). +1. **Backs up** the pristine catalog once to + `~/.codexcommander/catalog-backup-<catalog-id>.json` (so featuring is reversible). 2. **Fetches** eligible providers' live model catalogs (cached ~5 min; falls back to the last good list, then configured `models[]`). Forward auth has no model endpoint, and Cursor uses its `GetUsableModels` RPC rather than `/models`. @@ -203,52 +194,52 @@ collision order, provider, and native OpenAI marketing names are all left untouc Add a display name from the CLI (the proxy syncs the catalog right away when live): ```bash -ocx models add deepseek deepseek-v4 --display-name "DeepSeek V4" --context-window 128000 +ccx models add deepseek deepseek-v4 --display-name "DeepSeek V4" --context-window 128000 ``` Remote Codex clients can fetch the same generated catalog over the management API (same admission token as other `/api/*` routes): ```bash -dest="${CODEX_HOME:-$HOME/.codex}/opencodex-catalog.json" +dest="${CODEX_HOME:-$HOME/.codex}/codexcommander-catalog.json" tmp="$(mktemp "${dest}.XXXXXX")" -curl -fsS -H "x-opencodex-api-key: $OPENCODEX_ADMIN_AUTH_TOKEN" \ +curl -fsS -H "x-codexcommander-api-key: $CODEXCOMMANDER_ADMIN_AUTH_TOKEN" \ "https://proxy.example.com/api/catalog" > "$tmp" \ && mv "$tmp" "$dest" -ocx sync-cache +ccx sync-cache ``` -The response is the raw `opencodex-catalog.json` document (no provider credentials). When -available, the `x-opencodex-codex-version` header reports the Codex runtime version on the +The response is the raw `codexcommander-catalog.json` document (no provider credentials). When +available, the `x-codexcommander-codex-version` header reports the Codex runtime version on the server so clients can spot version skew. You can also set or edit it through the management API (`POST /api/custom-models`, `PUT /api/custom-models/<id>` with a `displayName` string) and the web dashboard. A `/` is rejected because it would collide with the routed-slug separator. -The display name is **display-only and stable across regeneration**. Every `ocx sync` and catalog +The display name is **display-only and stable across regeneration**. Every `ccx sync` and catalog refresh re-derives routed entries from `config.json` (including `customModels`), so the configured name is reapplied instead of drifting back to the routed slug. A managed service restart also attempts this sync shortly after the proxy binds. If that best-effort boot sync fails, for example during an -offline login, the previously persisted catalog is retained and the next successful `ocx sync` +offline login, the previously persisted catalog is retained and the next successful `ccx sync` reapplies the configured name. Genuine upstream native names (e.g. `gpt-5.6-sol` → "GPT-5.6-Sol") come from the pinned upstream snapshot and are never overridden by a custom display name. ### External provider managers -If `config.toml` already selects a provider other than `openai` or `opencodex`, OpenCodex leaves the -file unchanged and skips profile writes, catalog/cache refresh, and both immediate and background -Codex history migration. Tools that manage a custom provider often tag existing sessions with that +If `config.toml` already selects a provider other than `openai` or `codexcommander`, CodexCommander leaves the +file unchanged and skips profile writes, catalog/cache refresh, and Codex history synchronization. +Tools that manage a custom provider often tag existing sessions with that provider id; replacing the active id can make those intact sessions disappear from Codex's history -view. The same protection applies to an external provider selected by a legacy root profile. +view. The same protection applies whenever an external provider is active. -Keep one tool as the owner of Codex provider configuration. To use OpenCodex behind an existing +Keep one tool as the owner of Codex provider configuration. To use CodexCommander behind an existing provider manager, point that provider at `http://127.0.0.1:10100/v1` with Responses passthrough (`wire_api = "responses"` in Codex TOML), not Chat Completions translation. When proxy API auth is -enabled, also pass `x-opencodex-api-key` from `OPENCODEX_API_AUTH_TOKEN`, matching the non-loopback -provider form above. To let OpenCodex inject routing directly, first switch Codex back to its -built-in `openai` provider and remove any user-owned root `openai_base_url`, then rerun `ocx start`. +enabled, also pass `x-codexcommander-api-key` from `CODEXCOMMANDER_API_AUTH_TOKEN`, matching the non-loopback +provider form above. To let CodexCommander inject routing directly, first switch Codex back to its +built-in `openai` provider and remove any user-owned root `openai_base_url`, then rerun `ccx start`. ### Catalog troubleshooting @@ -260,43 +251,43 @@ If a model is missing from Codex, or the catalog order/visibility looks wrong, c 2. **`disabledModels`** (top level) — hides models from both the catalog and `/v1/models`, and flips bare native GPT slugs to `visibility: "hide"`. 3. **`liveModels: false` with empty `models`** — when live discovery is off and `models` is empty or - omitted, opencodex exposes no routed models for that provider. + omitted, CodexCommander exposes no routed models for that provider. 4. **Cursor `GetUsableModels`** — the Cursor adapter discovers models through its protobuf `GetUsableModels` RPC, not `/models`, so a Cursor-side change can alter which ids are visible independently of other providers. -5. **Cache and `ocx sync`** — live catalogs are cached for about five minutes (`modelCacheTtlMs`, - default `300000`). Run `ocx sync` to force a fresh fetch and rewrite the catalog immediately. +5. **Cache and `ccx sync`** — live catalogs are cached for about five minutes (`modelCacheTtlMs`, + default `300000`). Run `ccx sync` to force a fresh fetch and rewrite the catalog immediately. 6. **Running Codex `app-server`** — rewriting the on-disk catalog is not enough while a long-lived - Codex `app-server` (Desktop / CLI background host) keeps the previous list in memory. `ocx sync` - and `ocx sync-cache` warn when those processes are detected. Restart them with - `ocx sync --restart-codex` (or stop the matching `app-server` processes yourself), then let Codex + Codex `app-server` (Desktop / CLI background host) keeps the previous list in memory. `ccx sync` + and `ccx sync-cache` warn when those processes are detected. Restart them with + `ccx sync --restart-codex` (or stop the matching `app-server` processes yourself), then let Codex recreate them so the new list appears. :::caution[Other local writers] -Catalog writes (`opencodex-catalog.json`, `config.toml`) are atomic **inside** opencodex, which only -prevents half-written files when two opencodex-owned writers race. That does **not** stop another -local process, file watcher, or sync agent from rewriting catalog visibility or order after opencodex +Catalog writes (`codexcommander-catalog.json`, `config.toml`) are atomic **inside** CodexCommander, which only +prevents half-written files when two CodexCommander-owned writers race. That does **not** stop another +local process, file watcher, or sync agent from rewriting catalog visibility or order after CodexCommander has written. Codex keeps its separate `models_cache.json` and can refresh it independently, changing -the visible list without rewriting `opencodex-catalog.json`. If models flip unexpectedly while the -proxy is running, stop or reconfigure the competing writers, then run `ocx sync` — this is an -external-writer hazard, not a confirmed opencodex defect. +the visible list without rewriting `codexcommander-catalog.json`. If models flip unexpectedly while the +proxy is running, stop or reconfigure the competing writers, then run `ccx sync` — this is an +external-writer hazard, not a confirmed CodexCommander defect. ::: ## Proxy connection errors If Codex retries and then fails with an error like `stream disconnected before completion: error sending request for url (http://127.0.0.1:10100/v1/responses)` -— or Claude Code reports a similar connection failure — the opencodex proxy is not +— or Claude Code reports a similar connection failure — the CodexCommander proxy is not running: nothing is listening on the configured port, so the client renders that raw connection error itself. Restart the proxy: ```bash -ocx start # foreground -ocx service install # persistent: auto-starts on login and respawns on crash +ccx start # foreground +ccx service install # persistent: auto-starts on login and respawns on crash ``` -`ocx status` shows whether the proxy is running and prints the same restart hint when -it is not; `ocx doctor` reports restart safety (service/shim coverage). +`ccx status` shows whether the proxy is running and prints the same restart hint when +it is not; `ccx doctor` reports restart safety (service/shim coverage). ## The subagent picker @@ -304,7 +295,7 @@ Catalog sync makes the selected sub-agent models available to Codex; see [Codex ## Codex account warmup -When a ChatGPT account is added to the Codex account pool, opencodex verifies it before persistence +When a ChatGPT account is added to the Codex account pool, CodexCommander verifies it before persistence with a small streaming request to the Codex Responses backend. The request uses a real Responses item array (`input: [{ type: "message", ... }]`), waits for `response.completed`, and defaults to `gpt-5.4-mini`. If that model returns HTTP 400, it retries with `gpt-5.5`; structured upstream error @@ -314,16 +305,16 @@ off by default; it runs only when Token Guardian is enabled, the `chatgpt` refre ## Restoring native Codex -opencodex never traps you. **`ocx stop` is the single command that fully reverts to native Codex** — it +CodexCommander never traps you. **`ccx stop` is the single command that fully reverts to native Codex** — it stops the proxy, stops the background service if one is installed, and strips every injected line and -routed catalog entry so plain `codex` works exactly as if opencodex was never there: +routed catalog entry so plain `codex` works exactly as if CodexCommander was never there: ```bash -ocx stop # stop the proxy + service, restore native Codex -ocx restore # restore without stopping (alias: ocx eject) -ocx restore back # point plain Codex at the running proxy again +ccx stop # stop the proxy + service, restore native Codex +ccx restore # restore without stopping (alias: ccx eject) +ccx restore back # point plain Codex at the running proxy again ``` -When opencodex runs as a managed [background service](/reference/cli/#ocx-service), it sets -`OCX_SERVICE=1` so a service-driven restart does **not** thrash the Codex config — only an explicit -`ocx stop` / `ocx service stop` restores native Codex. +When CodexCommander runs as a managed [background service](/reference/cli/#ccx-service), it sets +`CCX_SERVICE=1` so a service-driven restart does **not** thrash the Codex config — only an explicit +`ccx stop` / `ccx service stop` restores native Codex. diff --git a/docs-site/src/content/docs/guides/combos.md b/docs-site/src/content/docs/guides/combos.md index b3ee1dc9f1..062345733d 100644 --- a/docs-site/src/content/docs/guides/combos.md +++ b/docs-site/src/content/docs/guides/combos.md @@ -4,7 +4,7 @@ description: Route one virtual model to several providers for failover or weight --- A **combo** is one virtual model that fronts an ordered list of real provider/model targets. Your -client requests `combo/<id>`; opencodex chooses a target, rewrites the request to that concrete +client requests `combo/<id>`; CodexCommander chooses a target, rewrites the request to that concrete `provider/model`, and can try another target when the first one has a retryable failure. This is useful when you want either: @@ -21,11 +21,11 @@ This example creates `combo/main` with Anthropic first and OpenAI second. Both p already exist and be enabled. ```bash -ocx combo set main --targets anthropic/claude-opus-4-8,openai/gpt-5.6-sol +ccx combo set main --targets anthropic/claude-opus-4-8,openai/gpt-5.6-sol ``` The default strategy is failover, so a normal request goes to -`anthropic/claude-opus-4-8`. If that attempt has a retryable failure, opencodex can hop to +`anthropic/claude-opus-4-8`. If that attempt has a retryable failure, CodexCommander can hop to `openai/gpt-5.6-sol`. Use the virtual model anywhere you would normally provide a model id: @@ -40,7 +40,7 @@ Use the virtual model anywhere you would normally provide a model id: Confirm the saved definition: ```bash -ocx combo show main +ccx combo show main ``` :::tip @@ -50,7 +50,7 @@ distribute traffic, and add weights only when equal distribution is not appropri ## How combo names work -The combo id in `ocx combo set <id>` must start with a letter or number. It may then contain +The combo id in `ccx combo set <id>` must start with a letter or number. It may then contain letters, numbers, `.`, `_`, or `-`, up to 64 characters total. Its canonical model id is always `combo/<id>`; for example, id `main` becomes `combo/main`. @@ -101,7 +101,7 @@ successful requests stay on the selected target before the next weighted selecti Create a 2:1 combo with batches of two successful requests: ```bash -ocx combo set balanced \ +ccx combo set balanced \ --targets anthropic/claude-opus-4-8:2,openai/gpt-5.6-sol:1 \ --strategy round-robin \ --sticky 2 @@ -135,7 +135,7 @@ Combo failures are divided into **hop** failures and **terminal** failures. | Any other unclassified error | Stop and return the error. | A hopped target enters cooldown for 60 seconds by default. If the upstream response includes a -valid `Retry-After` value, opencodex uses it instead. Numeric seconds and HTTP-date values are +valid `Retry-After` value, CodexCommander uses it instead. Numeric seconds and HTTP-date values are accepted, and every cooldown is capped at 10 minutes. The current request never retries the same attempted target. Later requests skip it until its @@ -155,23 +155,23 @@ quota, and overload failures; it does not hide caller errors or policy refusals. 2. the caller did not set an effort; and 3. the selected target's catalog advertises that exact effort. -If the request has no `reasoning` object, opencodex creates one. If `reasoning` exists without an +If the request has no `reasoning` object, CodexCommander creates one. If `reasoning` exists without an `effort` property, it preserves the other fields and adds the default. A caller-provided effort is never overwritten. -When target capability is unknown or does not include the configured effort, opencodex omits the +When target capability is unknown or does not include the configured effort, CodexCommander omits the default and leaves the target's own behavior unchanged. Supported values are `low`, `medium`, `high`, `xhigh`, `max`, and `ultra`; omit the field or set it to `null` to leave effort entirely to the caller and target. ## Encrypted v2 sub-agent tasks -There is one important limitation for Codex v2 sub-agents ([issue #92](https://github.com/lidge-jun/opencodex/issues/92)). +There is one important limitation for Codex v2 sub-agents ([issue #92](https://github.com/pavelhov/CodexCommander/issues/92)). A native parent can send a newly spawned worker's task only as ciphertext minted for the native ChatGPT backend. An external provider cannot read that payload. For such a request, a combo filters its eligible targets to canonical native ChatGPT routes, -including after a retryable failure. If the combo has no decrypt-capable target, opencodex stops +including after a retryable failure. If the combo has no decrypt-capable target, CodexCommander stops before dispatch and returns HTTP 400: ```json @@ -208,16 +208,16 @@ combos, and its target picker excludes disabled models and nested combos. The primary commands are: ```bash -ocx combo list -ocx combo show <id> -ocx combo set <id> --targets provider/model[:weight],... -ocx combo remove <id> --yes +ccx combo list +ccx combo show <id> +ccx combo set <id> --targets provider/model[:weight],... +ccx combo remove <id> --yes ``` `set` also accepts `--strategy`, `--sticky`, `--effort`, `--alias`, and `--rename-from`. Use `-` as the value of `--effort` or `--alias` to clear that field. `create` and `update` are aliases for `set`; `delete` is an alias for `remove`; and the same subcommands are available under -`ocx route combo`. +`ccx route combo`. ### Management API @@ -263,8 +263,8 @@ Combos are stored in the top-level `combos` object, keyed by combo id: ### Why does `combo/<id>` return 404? The combo id is unknown. The response is HTTP 404 with type `invalid_request_error`. Run -`ocx combo list`, check spelling and case, and confirm your management command wrote to the same -running opencodex instance that receives model requests. +`ccx combo list`, check spelling and case, and confirm your management command wrote to the same +running CodexCommander instance that receives model requests. ### Why do I get `combo_unavailable`? diff --git a/docs-site/src/content/docs/guides/grok-build.md b/docs-site/src/content/docs/guides/grok-build.md index 9b1fc1bf64..564e090826 100644 --- a/docs-site/src/content/docs/guides/grok-build.md +++ b/docs-site/src/content/docs/guides/grok-build.md @@ -1,49 +1,49 @@ --- title: Grok Build -description: Use any opencodex-routed model from xAI's Grok Build CLI — models are auto-registered into ~/.grok/config.toml while the proxy runs. +description: Use any CodexCommander-routed model from xAI's Grok Build CLI — models are auto-registered into ~/.grok/config.toml while the proxy runs. --- -opencodex serves an OpenAI-compatible `POST /v1/chat/completions` (and `/v1/responses`) on its +CodexCommander serves an OpenAI-compatible `POST /v1/chat/completions` (and `/v1/responses`) on its local port, and Grok Build supports custom models against OpenAI-compatible servers. Starting -with this integration, opencodex registers its whole visible catalog into Grok Build +with this integration, CodexCommander registers its whole visible catalog into Grok Build automatically — no manual config editing required. ## Auto-registration -When `~/.grok` exists, `ocx start` (and `ocx ensure` / `ocx restart`) writes a managed block +When `~/.grok` exists, `ccx start` (and `ccx ensure` / `ccx restart`) writes a managed block into `~/.grok/config.toml`: ```toml -# >>> opencodex managed block — do not edit (removed by `ocx stop`) >>> -[model.ocx-gpt-5-6-sol] +# >>> CodexCommander managed block — do not edit (removed by `ccx stop`) >>> +[model.ccx-gpt-5-6-sol] model = "gpt-5.6-sol" base_url = "http://127.0.0.1:10100/v1" api_backend = "chat_completions" -api_key = "opencodex-loopback" -name = "OCX gpt-5.6-sol" -# ... one [model.ocx-*] table per visible model ... -# <<< opencodex managed block <<< +api_key = "codexcommander-loopback" +name = "CodexCommander gpt-5.6-sol" +# ... one [model.ccx-*] table per visible model ... +# <<< CodexCommander managed block <<< ``` - **Additive:** your own config outside the fence is never touched. Before the first injection into a pre-existing file, a one-time backup is written to - `~/.grok/config.toml.bak-opencodex`. -- **Idempotent:** every `ocx start` (and `ocx ensure` while autostart is enabled) replaces + `~/.grok/config.toml.bak-codexcommander`. +- **Idempotent:** every `ccx start` (and `ccx ensure` while autostart is enabled) replaces the fenced block with the current catalog. -- **Removed on teardown:** `ocx stop`, `ocx eject`, `ocx uninstall`, and graceful +- **Removed on teardown:** `ccx stop`, `ccx eject`, `ccx uninstall`, and graceful non-service daemon shutdown strip the fenced block and restore your file - byte-for-byte. Under a service manager, teardown goes through `ocx stop`/`ocx + byte-for-byte. Under a service manager, teardown goes through `ccx stop`/`ccx uninstall` (service-mode processes intentionally keep the block across respawns). - **Conflict-safe:** aliases already defined by your own `[model.*]` tables are respected - (opencodex suffixes its own entries); a damaged fence (begin marker without end marker) + (CodexCommander suffixes its own entries); a damaged fence (begin marker without end marker) refuses any automatic change and asks for manual repair. Then pick a model inside Grok Build: ```bash -grok models # lists ocx-* entries alongside native grok models -grok -m ocx-anthropic-claude-opus-4-8 -p "hello" -# or in the TUI: /model ocx-anthropic-claude-opus-4-8 +grok models # lists ccx-* entries alongside native grok models +grok -m ccx-anthropic-claude-opus-4-8 -p "hello" +# or in the TUI: /model ccx-anthropic-claude-opus-4-8 ``` ## Reasoning effort @@ -51,7 +51,7 @@ grok -m ocx-anthropic-claude-opus-4-8 -p "hello" Grok Build's `/effort` (and `--effort`) only works for models whose catalog entry advertises the ladder: its model list fetch reads the raw `GET /v1/models` response, and entries there must carry `supports_reasoning_effort` plus `reasoning_efforts` menu -options. For routed model entries, opencodex mirrors the configured provider tiers +options. For routed model entries, CodexCommander mirrors the configured provider tiers (`reasoningEfforts` / `modelReasoningEfforts`, and the default from `modelDefaultReasoningEfforts`) onto that response. This metadata describes the proxy-configured routed ladder — it does not claim native upstream reasoning support, @@ -64,19 +64,19 @@ upstream reasoning ladders rather than provider-configured routed metadata. ## Authentication note Grok Build requires a non-empty API key for custom models even on loopback. The injected -entries carry a placeholder (`opencodex-loopback`) — opencodex ignores admission keys for +entries carry a placeholder (`codexcommander-loopback`) — CodexCommander ignores admission keys for loopback connections, so no real secret is involved. -**Auto-registration is loopback-only.** When opencodex binds a non-loopback host — including +**Auto-registration is loopback-only.** When CodexCommander binds a non-loopback host — including the wildcards `0.0.0.0` and `::`, which expose every interface — requests need your real admission token, and a managed block cannot carry one safely. Writing the literal token would put your secret into `~/.grok/config.toml` and overwrite whatever you set there on the next -`ocx start`/`ensure`/`restart`. So opencodex writes nothing at all in that case (and removes +`ccx start`/`ensure`/`restart`. So CodexCommander writes nothing at all in that case (and removes any block left over from an earlier loopback bind), and you configure the models yourself -outside the managed markers, where nothing opencodex does can clobber them. See +outside the managed markers, where nothing CodexCommander does can clobber them. See [Manual recipe](#manual-recipe-without-auto-registration) for the exact table, and set both `base_url` (a host that is actually reachable from where you run `grok`) and `api_key` -(your `OPENCODEX_API_AUTH_TOKEN`). +(your `CODEXCOMMANDER_API_AUTH_TOKEN`). Do not replace `api_key` with `env_key` here. With no `model_provider` set, an `env_key` that fails to resolve does not stop the request — Grok falls through to your xAI session @@ -84,32 +84,32 @@ token and sends it to whatever `base_url` the entry names, which for a LAN deplo plaintext HTTP endpoint that is not xAI. The injected per-model `api_key` sits first in Grok's credential chain for these models, -so turns against opencodex need no additional Grok login. Keep your normal `grok login` / +so turns against CodexCommander need no additional Grok login. Keep your normal `grok login` / `XAI_API_KEY` setup for native grok models and any harness features that contact xAI directly. ## Manual recipe (without auto-registration) -If you manage `~/.grok/config.toml` yourself — or opencodex is on a non-loopback bind — add -per-model tables with **direct fields**, outside the `# >>> opencodex managed block` markers: +If you manage `~/.grok/config.toml` yourself — or CodexCommander is on a non-loopback bind — add +per-model tables with **direct fields**, outside the `# >>> CodexCommander managed block` markers: ```toml -[model.ocx-opus] +[model.ccx-opus] model = "anthropic/claude-opus-4-8" base_url = "http://127.0.0.1:10100/v1" api_backend = "chat_completions" -api_key = "opencodex-loopback" +api_key = "codexcommander-loopback" ``` For a proxy reachable over the network, point `base_url` at the address `grok` can actually dial and use your admission token: ```toml -[model.ocx-opus] +[model.ccx-opus] model = "anthropic/claude-opus-4-8" base_url = "http://192.168.1.10:10100/v1" # the reachable host, not 127.0.0.1 api_backend = "chat_completions" -api_key = "your-OPENCODEX_API_AUTH_TOKEN" +api_key = "your-CODEXCOMMANDER_API_AUTH_TOKEN" ``` Do not rely on `[model_providers.<id>]` inheritance for the endpoint: as of Grok Build @@ -122,23 +122,23 @@ the id `grok-4.5`. Generated aliases avoid dots entirely for this reason. ## Known limitations -- **Responses backend and keep-alives:** opencodex emits a `response.heartbeat` keep-alive +- **Responses backend and keep-alives:** CodexCommander emits a `response.heartbeat` keep-alive on `/v1/responses` streams during upstream silence. Grok Build's Responses decoder rejects unknown event types, so a manually configured `api_backend = "responses"` model can fail mid-turn on slow upstreams. The auto-registered entries pin `api_backend = "chat_completions"`, which never surfaces raw heartbeat frames. -- **Service-installed `ocx restart`:** when opencodex runs under a service manager, - `ocx restart` currently stops the service and replaces it with an unmanaged process — +- **Service-installed `ccx restart`:** when CodexCommander runs under a service manager, + `ccx restart` currently stops the service and replaces it with an unmanaged process — service persistence (auto-restart, start-at-login) is lost until the next - `ocx service` setup, and if that unmanaged process dies the managed block can point at - a dead proxy until the next `ocx start`/`ocx ensure` refreshes it. -- **Config read timing:** start opencodex first, then launch `grok` for the most + `ccx service` setup, and if that unmanaged process dies the managed block can point at + a dead proxy until the next `ccx start`/`ccx ensure` refreshes it. +- **Config read timing:** start CodexCommander first, then launch `grok` for the most predictable results. Grok Build watches `~/.grok/config.toml` and reloads when the `[model]` table actually changes (roughly a one-second debounce, compared by content), so a refreshed block reaches an open session without a restart. To confirm what Grok parsed, run `grok inspect`: it lists the config sources it loaded and warns about any field it rejected. It does not print the resolved model list. Note that a single TOML error - invalidates the *entire* user config layer, which is why opencodex writes the file + invalidates the *entire* user config layer, which is why CodexCommander writes the file atomically — Grok never sees a half-written config. - **Catalog updates:** the fenced block reflects the catalog at injection time. After - adding providers or models, run `ocx ensure` (or restart the proxy) to refresh it. + adding providers or models, run `ccx ensure` (or restart the proxy) to refresh it. diff --git a/docs-site/src/content/docs/guides/image-bridge.md b/docs-site/src/content/docs/guides/image-bridge.md index 6606fee55b..7c2f3f185b 100644 --- a/docs-site/src/content/docs/guides/image-bridge.md +++ b/docs-site/src/content/docs/guides/image-bridge.md @@ -16,7 +16,7 @@ xAI Grok Imagine, so the model you're actually chatting with can still generate default to avoid unexpected xAI charges — see [Configuration](#configuration) below). - An `xai` provider entry with an **API key**. The bridge pins fulfillment to the registry xAI Images endpoint (`https://api.x.ai/v1`); any configured `baseUrl` override is ignored for image - calls. OAuth / `ocx login xai` alone does **not** arm the bridge (the Grok CLI OAuth transport is + calls. OAuth / `ccx login xai` alone does **not** arm the bridge (the Grok CLI OAuth transport is chat-oriented and is not used for `/images/*`). ```json @@ -32,7 +32,7 @@ xAI Grok Imagine, so the model you're actually chatting with can still generate ## Configuration -Image Bridge options live under `images` in `~/.opencodex/config.json`. Bridging is +Image Bridge options live under `images` in `~/.codexcommander/config.json`. Bridging is **opt-in** — you must set `bridgeEnabled: true` to enable paid xAI Grok Imagine generation: ```json @@ -56,7 +56,7 @@ Image Bridge options live under `images` in `~/.opencodex/config.json`. Bridging ## Artifact Retention -Generated images are written to `~/.opencodex/artifacts/`. To prevent unbounded disk +Generated images are written to `~/.codexcommander/artifacts/`. To prevent unbounded disk growth in long-running sessions, the directory is pruned automatically after each fulfilled image call (once the full batch for that call is on disk) — the oldest files (by modification time) are deleted when the count exceeds the configured maximum (default 200, configurable via @@ -70,13 +70,13 @@ model is selected. It does **not** intercept Codex's built-in `image_gen` tool, which POSTs directly to `/v1/images/generations` (or `/images/edits`) — that path is covered separately in [Codex Integration](/guides/codex-integration/#built-in-image-generation-image_gen). -1. When a Responses request lists `image_generation` in `tools`, OpenCodex detects it +1. When a Responses request lists `image_generation` in `tools`, CodexCommander detects it during request preprocessing. 2. The hosted tool is replaced with a **synthetic function tool** that the routed model can call normally — the model sees a callable tool rather than an opaque hosted tool it can't execute. -3. When the model invokes that tool, OpenCodex intercepts the call and sends the prompt to xAI's +3. When the model invokes that tool, CodexCommander intercepts the call and sends the prompt to xAI's image generation API. -4. Generated images are saved to `~/.opencodex/artifacts/` and the **local file path** is returned +4. Generated images are saved to `~/.codexcommander/artifacts/` and the **local file path** is returned to the model as the tool result. 5. The model continues the conversation with knowledge of the generated image and its location. diff --git a/docs-site/src/content/docs/guides/integrations.md b/docs-site/src/content/docs/guides/integrations.md index aa52dea54c..827ada411a 100644 --- a/docs-site/src/content/docs/guides/integrations.md +++ b/docs-site/src/content/docs/guides/integrations.md @@ -1,17 +1,17 @@ --- title: Client Apps -description: Connect OpenCodex to Codex, Claude Code, Grok Build, OpenCode, Pi, Hermes, OpenClaw, Kimi Code and Gajae Code without mixing client setup with provider credentials. +description: Connect CodexCommander to Codex, Claude Code, Grok Build, OpenCode, Pi, Hermes, OpenClaw, Kimi Code and Gajae Code without mixing client setup with provider credentials. --- The dashboard calls this area **Client Apps**. It answers “where do I work?” while **Providers** answers “where does model access come from?” and **API Access** manages -credentials that a client uses to reach the OpenCodex proxy. +credentials that a client uses to reach the CodexCommander proxy. | Area | Owns | | --- | --- | | **Providers** | Upstream accounts, OAuth logins, API keys, subscription gateways and local model servers | | **Models** | The enabled/visible catalog exported through the proxy | -| **Routing** | How a request is resolved after it reaches OpenCodex | +| **Routing** | How a request is resolved after it reaches CodexCommander | | **Client Apps** | Codex App/CLI/SDK, Claude Code/Desktop, Grok Build, OpenCode and other local clients | | **API Access** | Proxy access keys for clients; never upstream provider credentials | @@ -22,25 +22,25 @@ catalog and a selected-client detail pane. :::note[OpenCode is not OpenCode Go] **OpenCode** is a client app. **OpenCode Go** is a paid model provider and is added under Providers. OpenCode Go currently uses the API key issued by the OpenCode console; the -OpenCodex registry does not expose an OpenCode Go OAuth login. **OpenCode Free** is a +CodexCommander registry does not expose an OpenCode Go OAuth login. **OpenCode Free** is a separate keyless provider preset. ::: -For the five shared file-managed clients, Client Apps writes OpenCodex's provider block +For the five shared file-managed clients, Client Apps writes CodexCommander's provider block into the client's own config file and removes it again through the same reversible writer. Each has a switch: | Client | Config file | Format | When the change takes effect | Credential | |---|---|---|---|---| -| Pi | `~/.pi/agent/models.json` | JSON | new sessions | `OPENCODEX_API_KEY` | -| Hermes | `~/.hermes/config.yaml` | YAML | new sessions | `OPENCODEX_HERMES_API_KEY` | -| OpenClaw | `~/.openclaw/openclaw.json` | JSON5 | immediately, on a running gateway | `OPENCODEX_OPENCLAW_API_KEY` | +| Pi | `~/.pi/agent/models.json` | JSON | new sessions | `CODEXCOMMANDER_API_KEY` | +| Hermes | `~/.hermes/config.yaml` | YAML | new sessions | `CODEXCOMMANDER_HERMES_API_KEY` | +| OpenClaw | `~/.openclaw/openclaw.json` | JSON5 | immediately, on a running gateway | `CODEXCOMMANDER_OPENCLAW_API_KEY` | | Kimi Code | `~/.kimi-code/config.toml` | TOML | on restart, or `/reload` | loopback placeholder | -| Gajae Code | `~/.gjc/agent/models.yml` | YAML | new sessions, or when you open `/model` |`OPENCODEX_GAJAE_API_KEY` | +| Gajae Code | `~/.gjc/agent/models.yml` | YAML | new sessions, or when you open `/model` |`CODEXCOMMANDER_GAJAE_API_KEY` | OpenCode has its own detail flow because it needs stronger persistence semantics than the shared switch. It resolves the active global `opencode.jsonc` or `opencode.json`, -owns only `provider.opencodex`, stores the proxy admission token in protected OpenCodex +owns only `provider.codexcommander`, stores the proxy admission token in protected CodexCommander state, and writes a `{file:…}` reference instead of embedding the token. The page also offers auto-connect, one-click Desktop launch, safe refresh, and restore. Restore is byte-exact while the file is untouched and becomes provider-only after unrelated user @@ -54,22 +54,22 @@ OpenClaw has several, and they do different jobs. `OPENCLAW_CONFIG_PATH` selects file; `OPENCLAW_STATE_DIR`, `OPENCLAW_PROFILE` and `OPENCLAW_HOME` select the state directory, which is also what detection looks at — so a profile or relocated home still reads as installed, while a config-path override moves only the file. If you -are still on the older `.clawdbot` layout, that is found too: the modern directory -wins when it exists, and the legacy one is used when it is the only one there. +use the `.clawdbot` layout, that is found too: the modern directory wins when it exists, and +`.clawdbot` is used when it is the only one there. These must be **absolute paths** or start with `~`. A relative one is refused rather than resolved, because it would mean whatever directory each process happened to start in — and that path is stored with the backup, so it has to name the same file tomorrow as it did today. -opencodex reads these from its own environment. If your gateway runs with a profile -or a relocated home, start opencodex with the same variables set, or it will +CodexCommander reads these from its own environment. If your gateway runs with a profile +or a relocated home, start CodexCommander with the same variables set, or it will correctly follow a different installation. ## The other four surfaces use different controls -**API Access** manages opencodex's own client-facing credentials and is not a client at -all. **Codex CLI** is wired by the proxy service itself — starting opencodex applies it, +**API Access** manages CodexCommander's own client-facing credentials and is not a client at +all. **Codex CLI** is wired by the proxy service itself — starting CodexCommander applies it, stopping it restores native routing — so there is no per-file switch. **Claude** keeps its own enable flag and Desktop's Save/Apply flow, and **Grok Build** keeps its select-then-apply model fence. Those semantics predate this catalog and are unchanged. @@ -77,14 +77,14 @@ select-then-apply model fence. Those semantics predate this catalog and are unch ## Which models each client receives Client Apps does not create a second model catalog. Each integration consumes the -enabled, visible OpenCodex catalog, with the client-specific encoding it requires: +enabled, visible CodexCommander catalog, with the client-specific encoding it requires: - Codex App, CLI and SDK read the shared Codex catalog. - Claude Code 2.1.129+ discovers the gateway catalog through `/v1/models`; older builds can still use routed ids through `/model` or environment overrides. -- Grok Build's managed fence is regenerated from the visible catalog when OpenCodex +- Grok Build's managed fence is regenerated from the visible catalog when CodexCommander starts/ensures, and can be refreshed after catalog changes. -- `ocx opencode` generates OpenCode's runtime provider block from the visible catalog on +- `ccx opencode` generates OpenCode's runtime provider block from the visible catalog on every launch. A block applied to disk is a snapshot and must be refreshed after model visibility changes. @@ -104,7 +104,7 @@ always recoverable: - Ten backups are kept per client. Beyond that, the oldest snapshot files are removed and their history rows read **Backup expired**. -Disable removes only the entries opencodex recorded as its own. If your file changed +Disable removes only the entries CodexCommander recorded as its own. If your file changed after we wrote it, the switch locks and disable refuses rather than guessing which edits were yours. @@ -125,18 +125,18 @@ disk will have moved. Editing that file by hand still works; it is only our automatic rewrite that declines. **Pi, Kimi Code and Gajae Code only work against a loopback bind.** None of their config -schemas has a place for the `x-opencodex-api-key` header that a non-loopback bind +schemas has a place for the `x-codexcommander-api-key` header that a non-loopback bind requires, so a generated config would simply be rejected — and writing one by hand does not help, because there is nowhere in the file to put the header either. Reaching a -remote opencodex from these clients is not supported directly; give them loopback access +remote CodexCommander from these clients is not supported directly; give them loopback access instead, through an SSH tunnel or a local forwarder that adds the header. **Kimi Code cannot hold an environment reference,** so its config carries an -`opencodex-loopback` placeholder rather than a key. No real credential is ever written +`codexcommander-loopback` placeholder rather than a key. No real credential is ever written into any client config. -**For `ocx opencode`, the launcher's provider block wins.** That launcher injects -`provider.opencodex` through `OPENCODE_CONFIG_CONTENT`, which outranks the same entry on +**For `ccx opencode`, the launcher's provider block wins.** That launcher injects +`provider.codexcommander` through `OPENCODE_CONFIG_CONTENT`, which outranks the same entry on disk — the rest of your opencode config still applies as usual. The switch here is what matters when you launch `opencode` directly. @@ -145,17 +145,13 @@ matters when you launch `opencode` directly. The same operations are available headlessly: ```bash -ocx integration client status -ocx integration client enable --client hermes -ocx integration client disable --client hermes -ocx integration client history --client hermes -ocx integration client restore --op <opId> [--confirm-drift] +ccx integration client status +ccx integration client enable --client hermes +ccx integration client disable --client hermes +ccx integration client history --client hermes +ccx integration client restore --op <opId> [--confirm-drift] ``` `--confirm-drift` is never assumed. If the file changed after the operation you are restoring, the command refuses and tells you, because replacing your newer edits is your decision to make. - -Client details were verified against each project's own configuration format; see the -research notes in `devlog/_fin/260802_client_toggle_api/002_client_toggle_matrix.md` -for what was checked and when. diff --git a/docs-site/src/content/docs/guides/macos-menu-bar.md b/docs-site/src/content/docs/guides/macos-menu-bar.md index 4040aef591..61f211ba11 100644 --- a/docs-site/src/content/docs/guides/macos-menu-bar.md +++ b/docs-site/src/content/docs/guides/macos-menu-bar.md @@ -1,79 +1,45 @@ --- title: macOS Menu Bar Companion -description: Install and use the native OpenCodex status, agent-activity, and provider-quota companion. +description: Install and use the native CodexCommander status, agent-activity, and provider-quota companion. --- -The macOS companion puts the most useful OpenCodex state in the menu bar without replacing the +The macOS companion puts the most useful CodexCommander state in the menu bar without replacing the proxy or duplicating the web dashboard. It is a native Swift/AppKit application and talks only to -the OpenCodex instance running on the same Mac. +the CodexCommander instance running on the same Mac. ## Install -1. Download <code>OpenCodex-<version>-macos-universal.zip</code> and its - <code>.sha256</code> file from the matching GitHub release. -2. Verify the archive: - - shasum -a 256 -c OpenCodex-<version>-macos-universal.zip.sha256 - -3. Unzip it and move <code>OpenCodex.app</code> to **Applications**. -4. Open the app. It contains the OpenCodex Bun runtime, proxy source, production dependencies, and - dashboard assets, so a separate npm, Bun, or <code>ocx</code> install is not required. Its icon - appears in the menu bar; it does not add a Dock icon. The first stable launch enables - **Launch at Login** so the icon returns after the next sign-in. - -The bundled runtime still uses the existing user-owned state at <code>~/.opencodex</code> and -<code>~/.codex</code>. It does not copy credentials into the app bundle or Keychain. Provider OAuth -and API-key setup remains in the local dashboard. - -The bundled runtime is read-only in place. **Update** reports that the latest signed app release -must replace the bundle; it never runs npm, Bun, or a source checkout update against signed -<code>Contents/Resources</code>. - -The current release package is a ZIP. Unless its release owner supplies a Developer ID signing -identity, the bundle is ad-hoc signed; it is not a signed and notarized DMG. macOS may block the -first downloaded launch, so Control-click the app, choose **Open**, then confirm **Open**. A signed, -notarized DMG is a later commercial-distribution step that needs the distributor's own certificate, -notarization credentials, package metadata, and update channel. A build made locally does not carry -the downloaded-file quarantine attribute. - -The ZIP is a public-release attachment only when built with a Developer ID identity and validated -by Gatekeeper plus a stapled notarization ticket. Ad-hoc ZIPs are Actions/test artifacts only. - -An installed release may live in **Applications**. Do not use Application Support as an app-install -directory. During active source development, use the repository build in the next section as the one -active companion instead of keeping a copied app alongside it. - -The app registers only a stable bundle path: Applications, `~/Applications`, or the repository's -`dist/macos/OpenCodex.app`. It does not register a quarantined App Translocation path or an app -opened directly from Downloads. Move a release first, then open it. +No packaged macOS app is currently published. Build and run the companion from the existing source +checkout using [Build from source](#build-from-source). Keep the development app at +`dist/macos/CodexCommander.app`; do not copy it into Application Support. ## Startup modes The panel has one **Launch at Login** switch and reports the resulting mode: -- **Desktop** — the OpenCodex menu app launches when you sign in and ensures or attaches to exactly +- **Desktop** — the CodexCommander menu app launches when you sign in and ensures or attaches to exactly one server. This is the default desktop experience. - **Headless** — the menu app is not a login item, but an independently installed - `ocx service` continues starting and supervising the server. + `ccx service` continues starting and supervising the server. - **Off** — neither the menu app nor a background service starts automatically; open the app or run - `ocx start` manually. + `ccx start` manually. -The visible app and background server remain separate internally. With the OpenCodex panel active, +The visible app and background server remain separate internally. With the CodexCommander panel active, **Quit Menu Bar** (`⌘Q`) closes only the companion UI and deliberately leaves routing active. -**Stop OpenCodex and Quit…** (`⌥⌘Q`) is the explicit destructive exit: after confirmation, it stops +**Stop CodexCommander and Quit…** (`⌥⌘Q`) is the explicit destructive exit: after confirmation, it stops the proxy and service, restores native Codex routing, and closes the companion only after the stop is verified. macOS may -therefore list OpenCodex under both **Open at Login** and **Allow in the Background**; those are two +therefore list CodexCommander under both **Open at Login** and **Allow in the Background**; those are two responsibilities of one installation, not duplicate app copies. Turning off Launch at Login never installs, removes, starts, or stops the background service. If macOS requires approval, the startup row links directly to **System Settings → General → Login -Items & Extensions**. OpenCodex reflects a revocation made there instead of repeatedly trying to +Items & Extensions**. CodexCommander reflects a revocation made there instead of repeatedly trying to override it. ## What the panel shows - **Agent activity** — the current active count and live model/provider rows. A spawned child is - nested only when OpenCodex can prove its active parent from request metadata; otherwise it is + nested only when CodexCommander can prove its active parent from request metadata; otherwise it is shown as a standalone subagent. The companion never invents queued, reviewing, rate-limited, or completed history. - **Provider quotas** — provider-reported 5-hour, weekly, monthly, or provider-specific credit @@ -84,7 +50,7 @@ override it. - **Manage** — opens the selected provider's Accounts or API Keys tab. OAuth, API-key entry, reauthentication, account switching, and provider configuration stay in the dashboard. - **Agent catalog update ready** — a persistent, nonfatal card shown when running Codex background - workers still hold an older model roster. The OpenCodex proxy remains healthy and running. + workers still hold an older model roster. The CodexCommander proxy remains healthy and running. - **Apply agent catalog…** — opens a confirmation that reports fresh request activity when available, warns that applying may interrupt an answer, and offers **Apply Now** or **Later**. - **Stop Proxy…** — always asks for confirmation, interrupts active client and sub-agent requests, @@ -94,7 +60,7 @@ override it. presented as completion; the app waits until the new process passes identity checks. - **Quit Menu Bar** — closes the companion UI only. It does not stop the proxy, service, or client routing. With the panel active, this is the safe `⌘Q` action. -- **Stop OpenCodex and Quit…** — confirms the interruption, stops the background proxy and service, +- **Stop CodexCommander and Quit…** — confirms the interruption, stops the background proxy and service, restores native Codex routing, and quits only after the stopped state is confirmed. If stopping fails, the companion stays open and reports the error. With the panel active, its shortcut is `⌥⌘Q`. @@ -110,8 +76,8 @@ not raw provider errors. **View all providers** opens the complete Providers wor ## Agent catalog updates Opening the app automatically synchronizes the Codex model catalog with the providers currently -configured in OpenCodex. If no Codex worker is running, the new roster is ready for the next Codex -task. If a long-lived worker loaded an older roster, OpenCodex stays running and the panel keeps the +configured in CodexCommander. If no Codex worker is running, the new roster is ready for the next Codex +task. If a long-lived worker loaded an older roster, CodexCommander stays running and the panel keeps the nonfatal **Agent catalog update ready** card visible. Choose **Apply agent catalog…** to review the interruption risk. The confirmation requests a fresh @@ -119,32 +85,31 @@ active-request count when possible, but zero active requests is not presented as idle: another request can begin before the action runs. **Apply Now** synchronizes once more, sends `SIGTERM` only to exact current-user `codex … app-server` and `codex-code-mode-host` process matches, and briefly verifies that the old process IDs exited. It never uses a broad `pkill`, restarts the -OpenCodex proxy, or closes the menu app. Codex creates a fresh background host on the next task and +CodexCommander proxy, or closes the menu app. Codex creates a fresh background host on the next task and loads the current roster. -This release does not include **Apply when idle**. If an answer is active, choose **Later** and apply +The current companion does not include **Apply when idle**. If an answer is active, choose **Later** and apply the update when you are ready; the card remains available. The advanced CLI fallback is: ```bash -ocx sync --restart-codex +ccx sync --restart-codex ``` ## Authentication and privacy -The companion does not create another login system, does not migrate anything to macOS Keychain, and -does not read provider credentials from it. +The companion does not create another login system or use macOS Keychain for provider credentials. -Current OpenCodex versions generate an independent management credential at -<code>~/.opencodex/admin-api-token</code> (or -<code>$OPENCODEX_HOME/admin-api-token</code>). The companion reads that existing file through a +Current CodexCommander versions generate an independent management credential at +<code>~/.codexcommander/admin-api-token</code> (or +<code>$CODEXCOMMANDER_HOME/admin-api-token</code>). The companion reads that existing file through a validated, no-follow file descriptor, keeps the value only in process memory, and sends it only to -an identity-verified loopback OpenCodex process. It never displays, logs, copies, stores, or places +an identity-verified loopback CodexCommander process. It never displays, logs, copies, stores, or places the token in a browser URL. -Provider credentials remain owned by OpenCodex. The companion never reads ChatGPT, Kimi, Grok, +Provider credentials remain owned by CodexCommander. The companion never reads ChatGPT, Kimi, Grok, Anthropic, or other provider tokens and never calls provider login endpoints directly. -An installation configured only with <code>OPENCODEX_ADMIN_AUTH_TOKEN</code> works when that +An installation configured only with <code>CODEXCOMMANDER_ADMIN_AUTH_TOKEN</code> works when that variable is inherited by the app process. Apps launched from Finder usually do not inherit shell variables; if there is no protected token file, the companion reports that management authentication is unavailable instead of presenting a token-entry form. @@ -158,7 +123,7 @@ thread/session ids, or historical activity. The app refreshes lightweight activity frequently while the panel is open and slows down when it is closed. Provider quotas refresh at a separate, slower cadence and use the upstream timestamps -reported by OpenCodex. Repeated failures back off automatically, and overlapping refreshes are +reported by CodexCommander. Repeated failures back off automatically, and overlapping refreshes are coalesced. Use **Refresh** for an immediate activity refresh and a forced quota refresh. @@ -166,43 +131,42 @@ Use **Refresh** for an immediate activity refresh and a forced quota refresh. ## Build from source Requires macOS 13 or later and the Xcode Command Line Tools. A universal Intel + Apple silicon -release build requires full Xcode. +build requires full Xcode. ```bash -git clone https://github.com/pavelhov/opencodex.git -cd opencodex +cd /path/to/CodexCommander bun install bun run test:macos bun run build:macos -open dist/macos/OpenCodex.app +open dist/macos/CodexCommander.app ``` -The source app is exactly `dist/macos/OpenCodex.app`. It discovers the checkout's `src/cli/index.ts` +The source app is exactly `dist/macos/CodexCommander.app`. It discovers the checkout's `src/cli/index.ts` and bundled Bun, so it should stay in that location while you work on this repository. Double-clicking it attempts to ensure the proxy, but a missing CLI, offline failure, or failed start does not close the app: its status panel remains available and **Start** can be retried. This source workflow does not install or copy the app into Application Support. A rebuild at the same path is detected on the next launch and refreshes the existing Login Item registration only when Launch at Login remains on. -Each build stamps its exact Git revision into `OpenCodexSourceRevision` in the bundle's `Info.plist` +Each build stamps its exact Git revision into `CodexCommanderSourceRevision` in the bundle's `Info.plist` and prints it at the end of the build. Uncommitted source is marked with `-dirty`, so commit before making a final distributable bundle. ## Troubleshooting - **Proxy unavailable** — use **Start Proxy** in the bundled app. Source builds can also use - <code>ocx start</code> or install the background service with <code>ocx service install</code>. + <code>ccx start</code> or install the background service with <code>ccx service install</code>. - **Menu icon missing after login** — open the app, check its **Launch at Login** row, and follow the **Open Settings** action if macOS reports that approval is required. -- **Authentication unavailable** — run <code>ocx doctor</code>; verify that the OpenCodex state +- **Authentication unavailable** — run <code>ccx doctor</code>; verify that the CodexCommander state directory and <code>admin-api-token</code> are owned by your user and are not group/world accessible. - **Quota unavailable** — open **Provider settings** and connect or reauthenticate the account. If Grok says **Login needs refresh**, run <code>grok</code>, complete its login, then - use **Refresh** in OpenCodex; use <code>kimi</code> for the equivalent Kimi state. Some providers do + use **Refresh** in CodexCommander; use <code>kimi</code> for the equivalent Kimi state. Some providers do not expose a quota API. - **Restart did not recover** — open **Logs** and use the app's status panel. The companion never kills a process or rewrites service state as a fallback. -- **Only native models appear after a stop, update, or cold start** — reopen OpenCodex. Launch +- **Only native models appear after a stop, a Codex update, or a cold start** — reopen CodexCommander. Launch automatically synchronizes the catalog and restores still-configured routed models from its protected last-known-good catalog when live provider discovery is temporarily empty. If **Agent catalog update ready** remains visible, choose **Apply agent catalog…**, or use the CLI fallback in @@ -210,7 +174,7 @@ making a final distributable bundle. ## Uninstall -Turn off **Launch at Login**, quit the companion, and move <code>OpenCodex.app</code> to the Trash. +Turn off **Launch at Login**, quit the companion, and move <code>CodexCommander.app</code> to the Trash. It stores no provider credentials and creates no Keychain entries. Uninstalling the companion does -not stop or uninstall the OpenCodex proxy; run <code>ocx service uninstall</code> separately only if +not stop or uninstall the CodexCommander proxy; run <code>ccx service uninstall</code> separately only if you also want to remove the headless service. diff --git a/docs-site/src/content/docs/guides/model-ordering.md b/docs-site/src/content/docs/guides/model-ordering.md index 41cc44ee87..05b291b3a2 100644 --- a/docs-site/src/content/docs/guides/model-ordering.md +++ b/docs-site/src/content/docs/guides/model-ordering.md @@ -1,10 +1,10 @@ --- title: Model Ordering -description: How opencodex determines model order in the Codex picker and spawn_agent model overrides. +description: How CodexCommander determines model order in the Codex picker and spawn_agent model overrides. --- The Codex model picker does not preserve the order of provider declarations or model arrays in the -opencodex configuration. Its final order comes from catalog priorities, with a deterministic +CodexCommander configuration. Its final order comes from catalog priorities, with a deterministic alphabetical order for routed models that share the same priority. ## The rule Codex applies @@ -14,7 +14,7 @@ discards the catalog array order, so moving an entry earlier in a generated JSON it earlier in the picker. The implementation records this constraint directly in `src/codex/catalog/sync.ts`. -opencodex therefore controls featured placement by assigning lower priorities, not by relying on +CodexCommander therefore controls featured placement by assigning lower priorities, not by relying on array position. Unless noted otherwise, the fixed priorities and worked example below describe a catalog with no eligible Codex account selectors. With `N` eligible selectors, featured priorities use `N` as a stride: a bare native choice at configured rank `i` expands to selector rows at @@ -72,7 +72,7 @@ With no eligible account selectors and a non-empty featured list, the resulting 3. Unselected native models, pushed below the featured block during catalog merge. Without `subagentModels`, routed models remain at priority `5`, native GPT entries use their normal -priority (normally `9` for entries built by opencodex), and the routed group remains provider/id +priority (normally `9` for entries built by CodexCommander), and the routed group remains provider/id alphabetical. ## Example @@ -114,14 +114,14 @@ arrow buttons, or with <kbd>Alt</kbd> + <kbd>↑</kbd>/<kbd>↓</kbd>. The searc contain far more than five catalog models; entries remain addressable by exact id when their route is available, while the five-slot limit applies only to the overrides advertised first to `spawn_agent`. -Use `ocx agent subagents set` or edit the opencodex configuration to add exact +Use `ccx agent subagents set` or edit the CodexCommander configuration to add exact `<selector>/<native-openai-model>` choices that are not in the live library. The command center preserves and can reorder already-configured exact selectors even while their provider is temporarily unavailable. With account selectors, one bare native choice can expand into multiple selector-qualified catalog rows, so configured choices and advertised rows are not necessarily one-to-one. -There is currently no general `modelOrder`, `providerOrder`, or priority-map setting in `OcxConfig`. +There is currently no general `modelOrder`, `providerOrder`, or priority-map setting in `CodexCommanderConfig`. The supported ordering field is `subagentModels`; `disabledModels` and each provider's `selectedModels` are visibility fields. Changing the remaining picker order would require a code-level behavior change rather than a configuration edit. diff --git a/docs-site/src/content/docs/guides/model-routing.md b/docs-site/src/content/docs/guides/model-routing.md index c1616e9e52..cd4bab50db 100644 --- a/docs-site/src/content/docs/guides/model-routing.md +++ b/docs-site/src/content/docs/guides/model-routing.md @@ -1,6 +1,6 @@ --- title: Model Routing -description: How opencodex decides which provider serves a given model id. +description: How CodexCommander decides which provider serves a given model id. --- When Codex asks for a model, `router.ts` resolves it to exactly one configured provider. The rules are @@ -27,7 +27,7 @@ through to one another. 2. **Combo id or alias** — while at least one combo is configured, a canonical `combo/<id>` or configured combo alias selects its concrete target before provider namespaces are checked. With - no configured combos, a legacy physical provider literally named `combo` remains a normal + no configured combos, a configured provider literally named `combo` is treated like any other provider namespace. See [Combos](/guides/combos/) for target selection and failover behavior. 3. **Explicit `provider/model`** — if the id contains `/` and the part before it is the name of a diff --git a/docs-site/src/content/docs/guides/opencode.md b/docs-site/src/content/docs/guides/opencode.md index 7dca6593ce..e5c593f61e 100644 --- a/docs-site/src/content/docs/guides/opencode.md +++ b/docs-site/src/content/docs/guides/opencode.md @@ -1,10 +1,10 @@ --- title: opencode -description: Use any routed model from opencode — opencodex injects a runtime provider block and leaves your own opencode config untouched. +description: Use any routed model from opencode — CodexCommander injects a runtime provider block and leaves your own opencode config untouched. --- opencode reads its providers from merged JSON config layers rather than environment -variables, so there is no `ANTHROPIC_BASE_URL`-style slot to inject. `ocx opencode` +variables, so there is no `ANTHROPIC_BASE_URL`-style slot to inject. `ccx opencode` bridges that gap: it ensures the proxy is running, builds a provider block from the visible catalog, and injects it through OpenCode's inline runtime layer (`OPENCODE_CONFIG_CONTENT`). @@ -12,78 +12,78 @@ visible catalog, and injects it through OpenCode's inline runtime layer ## Quickstart ```bash -ocx opencode +ccx opencode ``` This ensures the proxy is running and launches opencode with only the generated -`provider.opencodex` block injected for that process. Extra arguments pass through: -`ocx opencode run "hello"`. +`provider.codexcommander` block injected for that process. Extra arguments pass through: +`ccx opencode run "hello"`. -Routed models appear in the picker under the `opencodex` provider: +Routed models appear in the picker under the `codexcommander` provider: ```text -opencodex/kiro/glm-5 -opencodex/gpt-5.6-sol # native slugs stay unprefixed +codexcommander/kiro/glm-5 +codexcommander/gpt-5.6-sol # native slugs stay unprefixed ``` ## Your own config is never modified The launcher does not copy or rewrite `~/.config/opencode/opencode.json`, project `opencode.json` / `opencode.jsonc`, or any other on-disk config layer. It may -read global or project config to detect a `provider.opencodex` override, while your +read global or project config to detect a `provider.codexcommander` override, while your existing providers, agents, keybinds, MCP entries, and relative `{file:…}` references keep resolving from their original files. -For this launch only, opencodex adds the generated `provider.opencodex` block through +For this launch only, CodexCommander adds the generated `provider.codexcommander` block through OpenCode's inline runtime layer. That layer merges after global/custom/project config and overrides only conflicting keys for the child process. -| Layer | Behavior with `ocx opencode` | +| Layer | Behavior with `ccx opencode` | | --- | --- | | Global / custom / project config | Left on disk exactly as you wrote it | -| Inline runtime (`OPENCODE_CONFIG_CONTENT`) | Receives only the generated `provider.opencodex` block | +| Inline runtime (`OPENCODE_CONFIG_CONTENT`) | Receives only the generated `provider.codexcommander` block | | Relative `{file:…}` paths | Still resolve against the config file that originally defined them | -If a global or project config also defines `provider.opencodex`, the launcher prints an -informational note: the runtime layer from `ocx opencode` overrides it for that launch. +If a global or project config also defines `provider.codexcommander`, the launcher prints an +informational note: the runtime layer from `ccx opencode` overrides it for that launch. ## Persistent dashboard connection (optional) For plain OpenCode, editor integrations, or one-click Desktop launch, open **Integrations** in the -OpenCodex dashboard and choose **Apply connection**. This is intentionally different from -`ocx opencode`: +CodexCommander dashboard and choose **Apply connection**. This is intentionally different from +`ccx opencode`: - The dashboard selects OpenCode's active global config under `XDG_CONFIG_HOME` (normally `~/.config/opencode/`): `opencode.jsonc` when it exists, otherwise `opencode.json`. -- It makes a JSONC-aware, surgical edit of **only** `provider.opencodex`. Comments, formatting, +- It makes a JSONC-aware, surgical edit of **only** `provider.codexcommander`. Comments, formatting, other providers, agents, keybinds, MCP entries, and unrelated keys remain owned by OpenCode and are preserved. -- The proxy admission token is written to OpenCodex's hardened integration state and the OpenCode +- The proxy admission token is written to CodexCommander's hardened integration state and the OpenCode config receives only a protected `{file:/absolute/path}` reference. The token is not copied into OpenCode's config or auth store. -- **Always keep OpenCode connected** is off by default. After you opt in, OpenCodex refreshes its +- **Always keep OpenCode connected** is off by default. After you opt in, CodexCommander refreshes its managed provider block after proxy startup or a visible-catalog change; it still owns no other OpenCode setting. -**Restore** is reversible by design. When the journal confirms an exact restore is safe, OpenCodex +**Restore** is reversible by design. When the journal confirms an exact restore is safe, CodexCommander restores the original bytes exactly (or removes a config file it created). Otherwise, Dashboard -Restore defaults to a surgical restore of only `provider.opencodex`, preserving later user edits. A +Restore defaults to a surgical restore of only `provider.codexcommander`, preserving later user edits. A full external-config overwrite is available only to an API caller that explicitly confirms the current file hash. The **Open OpenCode** button is a one-click launcher for OpenCode Desktop. If only the CLI is -installed, use `ocx opencode` from a terminal instead; it remains the transient, disk-nonmutating +installed, use `ccx opencode` from a terminal instead; it remains the transient, disk-nonmutating path described above. ## Putting the block into your own config -`ocx opencode` injects the provider block for one launch only. If you have not applied the optional +`ccx opencode` injects the provider block for one launch only. If you have not applied the optional dashboard connection above, plain `opencode` still knows nothing about the proxy. When you want to -merge the block yourself instead, `ocx export` prints the same provider block for you to merge into +merge the block yourself instead, `ccx export` prints the same provider block for you to merge into your own config: ```bash -ocx export --client opencode +ccx export --client opencode ``` The proxy must be running. The command prints the config, the canonical destination @@ -92,31 +92,31 @@ warning, and the env export line. It never touches that file — the section abo moving the block into your config is your explicit act. :::caution[Merge, never replace] -Merge the `provider.opencodex` block into your existing config. Replacing the whole file with the -exported one destroys your other providers, agents, keybinds, and MCP entries. `ocx export --out` +Merge the `provider.codexcommander` block into your existing config. Replacing the whole file with the +exported one destroys your other providers, agents, keybinds, and MCP entries. `ccx export --out` refuses to overwrite an existing file for exactly this reason, so point `--out` at a scratch path and copy the block across: ```bash -ocx export --client opencode --out ~/opencodex-opencode.json +ccx export --client opencode --out ~/codexcommander-opencode.json ``` ::: Unlike the launcher's runtime block, a merged block is a static snapshot: it does not follow your -catalog. Re-run `ocx export` after you add a provider or change model visibility. +catalog. Re-run `ccx export` after you add a provider or change model visibility. Once merged, export the admission key before launching opencode — unless the proxy is on loopback, where none is needed: ```bash -export OPENCODEX_OPENCODE_API_KEY=<your key> +export CODEXCOMMANDER_OPENCODE_API_KEY=<your key> ``` ## The admission key is not written to disk When the proxy requires an API key, the inline runtime config carries opencode's `{env:…}` reference rather than the secret. Loopback binds use that reference as -`apiKey`; non-loopback binds send it only through `x-opencodex-api-key` so proxy +`apiKey`; non-loopback binds send it only through `x-codexcommander-api-key` so proxy admission stays separate from any upstream `Authorization` header. Loopback example: @@ -124,7 +124,7 @@ Loopback example: ```json "options": { "baseURL": "http://127.0.0.1:10100/v1", - "apiKey": "{env:OPENCODEX_OPENCODE_API_KEY}" + "apiKey": "{env:CODEXCOMMANDER_OPENCODE_API_KEY}" } ``` @@ -134,24 +134,24 @@ Non-loopback example: "options": { "baseURL": "http://192.168.1.10:10100/v1", "headers": { - "x-opencodex-api-key": "{env:OPENCODEX_OPENCODE_API_KEY}" + "x-codexcommander-api-key": "{env:CODEXCOMMANDER_OPENCODE_API_KEY}" } } ``` The real value is passed only through the child process environment. -`OPENCODEX_API_AUTH_TOKEN` takes precedence, then the hardened service token file, then +`CODEXCOMMANDER_API_AUTH_TOKEN` takes precedence, then the hardened service token file, then a configured API key — which is what a non-loopback bind requires. A loopback bind (`127.0.0.1`, the default) authenticates nothing, so the `{env:…}` reference is inert and you can leave the variable unset. It matters only when `hostname` is set beyond loopback; -see [Remote access](/reference/configuration/#remote-access). This admission key is opencodex's +see [Remote access](/reference/configuration/#remote-access). This admission key is CodexCommander's own, and is unrelated to the upstream provider keys configured under [Providers](/guides/providers/). ## Reverting -For the transient `ocx opencode` launcher, there is nothing to undo: no OpenCode config file was +For the transient `ccx opencode` launcher, there is nothing to undo: no OpenCode config file was changed. For a dashboard connection, choose **Restore** on **Integrations**; see the exact versus surgical behavior above. Plain `opencode` reads your own config as before once the managed provider is restored. @@ -167,7 +167,7 @@ clamped down to the context window so a small-context model is never given `outp That figure exists to satisfy the schema — it is not a claim about any specific model's true maximum. -The `opencodex` provider block is regenerated on every launch, so per-model tweaks made inside it +The `codexcommander` provider block is regenerated on every launch, so per-model tweaks made inside it will not survive. Keep custom entries under a provider key of your own instead. ## Requirements diff --git a/docs-site/src/content/docs/guides/pi.md b/docs-site/src/content/docs/guides/pi.md index fa44d2754f..577445065d 100644 --- a/docs-site/src/content/docs/guides/pi.md +++ b/docs-site/src/content/docs/guides/pi.md @@ -1,10 +1,10 @@ --- title: Pi -description: Use any routed model from Pi — ocx export writes a custom provider block for Pi's models.json, wired to the running proxy. +description: Use any routed model from Pi — ccx export writes a custom provider block for Pi's models.json, wired to the running proxy. --- Pi reads its providers from a single global JSON file rather than environment variables, so -opencodex does not launch it. Instead, `ocx export` serializes the `opencodex` provider block — +CodexCommander does not launch it. Instead, `ccx export` serializes the `codexcommander` provider block — base URL, model list, and the env reference Pi interpolates — and you merge it into your own config. @@ -13,8 +13,8 @@ config. Start the proxy, then print the config: ```bash -ocx start -ocx export --client pi +ccx start +ccx export --client pi ``` The output leads with the JSON, then prints the destination path, the merge warning, the env @@ -23,10 +23,10 @@ export line, and how many models carry authoritative context limits. ```json { "providers": { - "opencodex": { + "codexcommander": { "baseUrl": "http://127.0.0.1:10100/v1", "api": "openai-completions", - "apiKey": "$OPENCODEX_API_KEY", + "apiKey": "$CODEXCOMMANDER_API_KEY", "models": [ { "id": "anthropic/claude-opus-5", @@ -55,17 +55,17 @@ Pi's global model config is: ``` :::caution[Merge, never replace] -`ocx export` never writes that file. Merge the `providers.opencodex` block into it — replacing the +`ccx export` never writes that file. Merge the `providers.codexcommander` block into it — replacing the file destroys every other provider you have configured there. `--out` exists for a scratch path and refuses to overwrite an existing file without `--force`: ```bash -ocx export --client pi --out ~/opencodex-pi-models.json -ocx export --client pi --json > ~/opencodex-pi-models.json # or redirect the byte-exact JSON +ccx export --client pi --out ~/codexcommander-pi-models.json +ccx export --client pi --json > ~/codexcommander-pi-models.json # or redirect the byte-exact JSON ``` ::: -The exported block is a static snapshot, not a live view. Re-run `ocx export` after adding a +The exported block is a static snapshot, not a live view. Re-run `ccx export` after adding a provider or changing model visibility, and merge the new block over the old one. ## The admission key @@ -74,21 +74,21 @@ Two different keys are easy to confuse here, and only the first one appears in t | Key | What it is | Where it lives | | --- | --- | --- | -| Proxy admission key | opencodex's own credential, generated on the dashboard's **API** tab | referenced by `apiKey` as `$OPENCODEX_API_KEY`; the value stays in your environment | -| Provider key | your Anthropic / OpenAI / OpenRouter key | opencodex's own config, per [Providers](/guides/providers/) | +| Proxy admission key | CodexCommander's own credential, generated on the dashboard's **API** tab | referenced by `apiKey` as `$CODEXCOMMANDER_API_KEY`; the value stays in your environment | +| Provider key | your Anthropic / OpenAI / OpenRouter key | CodexCommander's own config, per [Providers](/guides/providers/) | The exported config carries only the reference, never a secret. Pi interpolates a bare `$NAME`, so the variable is: ```bash -export OPENCODEX_API_KEY=<your key> +export CODEXCOMMANDER_API_KEY=<your key> ``` That name is Pi's alone. opencode uses a different variable -(`OPENCODEX_OPENCODE_API_KEY`, in `{env:…}` form) — see the [opencode guide](/guides/opencode/). +(`CODEXCOMMANDER_OPENCODE_API_KEY`, in `{env:…}` form) — see the [opencode guide](/guides/opencode/). -**A loopback proxy needs no key at all.** opencodex binds `127.0.0.1` by default and authenticates -nothing there, so the `$OPENCODEX_API_KEY` reference is inert and you can leave the variable unset. +**A loopback proxy needs no key at all.** CodexCommander binds `127.0.0.1` by default and authenticates +nothing there, so the `$CODEXCOMMANDER_API_KEY` reference is inert and you can leave the variable unset. It matters only when `hostname` is set beyond loopback, which is also the case where the proxy refuses to start without a token — see [Remote access](/reference/configuration/#remote-access). @@ -96,13 +96,13 @@ refuses to start without a token — see [Remote access](/reference/configuratio `contextWindow` and `maxTokens` are emitted only when the catalog reports an authoritative context window. When it does not, both fields are omitted for that model and Pi applies its own defaults; -`ocx export` prints how many rows fell into that case. +`ccx export` prints how many rows fell into that case. `maxTokens` is a schema-satisfying budget of `32000`, clamped down to the context window so a small-context model is never given more output than context. It is not a claim about any specific model's true maximum. -Two fields are deliberately absent. `cost` requires all four price fields and opencodex has no +Two fields are deliberately absent. `cost` requires all four price fields and CodexCommander has no price data for routed models — emitting zeros would assert that every model is free. `reasoning` is a boolean in Pi while the catalog carries an effort ladder, and mapping one onto the other would be a guess. @@ -113,10 +113,10 @@ a guess. The shape above follows Pi's published custom-provider documentation. It has **not** been verified against a real `~/.pi/agent/models.json` on a machine with Pi installed. If Pi rejects the exported block, the mismatch is on our side — please -[open an issue](https://github.com/lidge-jun/opencodex/issues) with what Pi reported. +[open an issue](https://github.com/pavelhov/CodexCommander/issues) with what Pi reported. ::: ## Requirements -A running opencodex proxy (`ocx start`) and Pi installed. `ocx export` reads the live catalog +A running CodexCommander proxy (`ccx start`) and Pi installed. `ccx export` reads the live catalog through the proxy's management API, so a config can never be emitted with an empty model list. diff --git a/docs-site/src/content/docs/guides/providers.md b/docs-site/src/content/docs/guides/providers.md index 979783b0fb..caef6227a5 100644 --- a/docs-site/src/content/docs/guides/providers.md +++ b/docs-site/src/content/docs/guides/providers.md @@ -1,10 +1,10 @@ --- title: Providers -description: Every way opencodex authenticates and talks to an LLM provider — OAuth, API key, ChatGPT forward, and local. +description: Every way CodexCommander authenticates and talks to an LLM provider — OAuth, API key, ChatGPT forward, and local. --- A **provider** is one upstream LLM endpoint plus how to reach it: an adapter, a base URL, an auth -mode, and an optional model list. Providers live under `providers` in `~/.opencodex/config.json`. +mode, and an optional model list. Providers live under `providers` in `~/.codexcommander/config.json`. ## OpenAI account modes @@ -44,10 +44,6 @@ This estimate is display-only. It does not change account selection, session aff switching, cooldowns, or any other routing decision. Use the [Codex Auth account pool](/guides/web-dashboard/#codex-auth-and-account-pools) for the individual account state and routing controls. -Shipped v1 configs migrate automatically to marker 2 and one option-aware row. The original config -is retained once at `~/.opencodex/config.json.pre-openai-tiers-v2.bak`; restore it with -`cp ~/.opencodex/config.json.pre-openai-tiers-v2.bak ~/.opencodex/config.json`. - ## Auth modes Provider configs accept three `authMode` values (`key` is the default). The built-in registry also @@ -57,7 +53,7 @@ labels local presets separately; those normally omit both `authMode` and `apiKey | --- | --- | --- | | `key` | Sends your API key (`Authorization: Bearer …`, or `x-api-key` / `api-key` per adapter). The key may be a literal or an `${ENV_VAR}` reference. | Most providers. | | `forward` | Relays **your incoming Codex auth headers** verbatim to the provider — no key stored. This is the ChatGPT-login passthrough. | OpenAI (`openai-responses` adapter). | -| `oauth` | Resolves a stored OAuth access token and follows its credential owner. OpenCodex-owned credentials refresh before expiry; linked Grok/Kimi CLI credentials are adopted read-only and remain native-CLI-owned. | xAI, Anthropic, Kimi, Kiro, Google Antigravity, Cursor, GitHub Copilot. | +| `oauth` | Resolves a stored OAuth access token and follows its credential owner. CodexCommander-owned credentials refresh before expiry; linked Grok/Kimi CLI credentials are adopted read-only and remain native-CLI-owned. | xAI, Anthropic, Kimi, Kiro, Google Antigravity, Cursor, GitHub Copilot. | The [`retryOn429`](/reference/configuration/) same-key 429 replay applies only to API-key providers (`authMode: "key"`). OAuth, forward, and local presets are excluded — their @@ -90,40 +86,40 @@ The ChatGPT passthrough catalog also layers in the bare GPT-5.6 Sol/Terra/Luna s ## 2. Account login (OAuth) Seven provider presets use OAuth login — plus GitHub Copilot via an experimental unofficial -device-flow bridge. opencodex stores their credentials in `~/.opencodex/auth.json`. -OpenCodex-owned credentials refresh automatically. When a signed-in Grok or Kimi CLI session is -linked, opencodex adopts its current access generation read-only and the native CLI remains +device-flow bridge. CodexCommander stores their credentials in `~/.codexcommander/auth.json`. +CodexCommander-owned credentials refresh automatically. When a signed-in Grok or Kimi CLI session is +linked, CodexCommander adopts its current access generation read-only and the native CLI remains responsible for renewal. `chatgpt` is also accepted by the login CLI; it acquires a ChatGPT credential while creating a `forward`-mode provider entry. ```bash -ocx login xai # xAI Grok -ocx login anthropic # Anthropic Claude (Pro/Max) -ocx login kimi # Moonshot Kimi -ocx login kiro # import kiro-cli credentials (or token fallback) -ocx login google-antigravity -ocx login cursor # standalone Cursor PKCE login -ocx login command-code # Command Code browser OAuth (or import ~/.commandcode/auth.json) -ocx login github-copilot # GitHub device flow → Copilot token (Copilot Pro/Business) -ocx login chatgpt # standalone ChatGPT OAuth login -ocx logout <provider> +ccx login xai # xAI Grok +ccx login anthropic # Anthropic Claude (Pro/Max) +ccx login kimi # Moonshot Kimi +ccx login kiro # import kiro-cli credentials (or token fallback) +ccx login google-antigravity +ccx login cursor # standalone Cursor PKCE login +ccx login command-code # Command Code browser OAuth (or import ~/.commandcode/auth.json) +ccx login github-copilot # GitHub device flow → Copilot token (Copilot Pro/Business) +ccx login chatgpt # standalone ChatGPT OAuth login +ccx logout <provider> ``` | Provider | Adapter | Base URL | Notes | | --- | --- | --- | --- | | `xai` | `openai-chat` | `https://api.x.ai/v1` | Live-first Grok catalog; `grok-4.5` is the fallback default. | | `anthropic` | `anthropic` | `https://api.anthropic.com` | Claude models; live model list fetched from `/v1/models`. | -| `kimi` | `openai-chat` | `https://api.kimi.com/coding/v1` | Kimi K3 (`k3`, 1M context), fixed-window `k3-256k`, compatibility alias `k3[1m]`, and legacy K2.7/K2.6/K2.5 coding models. | -| `kiro` | `kiro` | `https://runtime.us-east-1.kiro.dev` | Initial login imports the installed, signed-in `kiro-cli` session (on Unix, install with `curl -fsSL https://cli.kiro.dev/install | bash`; on Windows PowerShell, use `irm 'https://cli.kiro.dev/install.ps1' | iex`; then run `kiro-cli login`). **Add account** logs `kiro-cli` out, starts a fresh browser login that switches the account used by `kiro-cli`, and stores account-scoped profile metadata. Existing OpenCodex accounts are preserved, and cancellation or failure restores the previous `kiro-cli` session. | +| `kimi` | `openai-chat` | `https://api.kimi.com/coding/v1` | Kimi K3 (`k3`, 1M context), fixed-window `k3-256k`, compatibility alias `k3[1m]`, and K2.7/K2.6/K2.5 coding models. | +| `kiro` | `kiro` | `https://runtime.us-east-1.kiro.dev` | Initial login imports the installed, signed-in `kiro-cli` session (on Unix, install with `curl -fsSL https://cli.kiro.dev/install | bash`; on Windows PowerShell, use `irm 'https://cli.kiro.dev/install.ps1' | iex`; then run `kiro-cli login`). **Add account** logs `kiro-cli` out, starts a fresh browser login that switches the account used by `kiro-cli`, and stores account-scoped profile metadata. Existing CodexCommander accounts are preserved, and cancellation or failure restores the previous `kiro-cli` session. | | `google-antigravity` | `google` | `https://daily-cloudcode-pa.googleapis.com` | Google OAuth over the Cloud Code Assist wire. Uses the maintained six-model static catalog because CCA does not expose the generic `/models` endpoint. | | `cursor` | `cursor` | `https://api2.cursor.sh` | Experimental PKCE login, live HTTP/2 transport, and account-filtered model discovery. | | `github-copilot` | `openai-chat` | `https://api.githubcopilot.com` | Experimental. GitHub device flow + `copilot_internal` exchange (VS Code OAuth client). Requires an active Copilot subscription; not an official third-party API. | For the canonical Kimi Coding Plan presets (`kimi` account login and `kimi-code` API key), -opencodex forwards only a caller-supplied stable `prompt_cache_key` to the Chat Completions request; +CodexCommander forwards only a caller-supplied stable `prompt_cache_key` to the Chat Completions request; it never generates one. Kimi documents a stable session/task key as required to improve Code Plan cache hit rates, while requests without a key remain keyless. If an opted-in upstream rejects the -field, opencodex does not strip it and retry or mutate saved configuration. Other providers remain +field, CodexCommander does not strip it and retry or mutate saved configuration. Other providers remain deny-by-default. You can also start OAuth from the [web dashboard](/guides/web-dashboard/). @@ -135,11 +131,11 @@ login. The Providers page shows those accounts in a dropdown, lets you add anoth active account without logging the others out. Only identity-less Kimi credentials replace the active slot; Kiro accounts are keyed by profile ARN. `chatgpt` is always single-slot because Codex pool accounts have a separate ledger. -Tokens stay in `~/.opencodex/auth.json`; `/api/oauth/accounts` returns masked metadata only. +Tokens stay in `~/.codexcommander/auth.json`; `/api/oauth/accounts` returns masked metadata only. ### OAuth reliability -opencodex coordinates token refresh and Codex pool routing so concurrent requests do not race the +CodexCommander coordinates token refresh and Codex pool routing so concurrent requests do not race the credential store. This is reliability and diagnostics work — it does **not** guarantee protection from provider enforcement, rate limits, or account actions. @@ -169,44 +165,44 @@ are cleared, and pool selection may rotate — threads are not pinned through a **Codex client metadata.** The ChatGPT forward path passes through the curated `FORWARD_HEADERS` allowlist (authorization, `chatgpt-account-id`, originator, session/thread ids, and related Codex headers — see [Adapters](/reference/adapters/)). Pool mode overwrites only auth and -`chatgpt-account-id` to match the selected credential. opencodex does **not** fabricate official +`chatgpt-account-id` to match the selected credential. CodexCommander does **not** fabricate official client identity (for example `originator`, session, or thread headers) when the caller did not send them. -**Diagnostics and reauth.** Human `ocx status` prints an OAuth health block (redacted account ids, -no tokens). `ocx doctor` adds an OAuth reliability section with writable-store / single-flight checks +**Diagnostics and reauth.** Human `ccx status` prints an OAuth health block (redacted account ids, +no tokens). `ccx doctor` adds an OAuth reliability section with writable-store / single-flight checks and WARN rows that include a recovery Action. When an OAuth provider account needs reauthentication, run -`ocx login <provider>` (or use Reauthenticate in the dashboard). Codex pool accounts are not an -`ocx login` provider — reauthenticate via the dashboard Codex account pool. See -[`ocx status` / `ocx doctor`](/reference/cli/) in the CLI reference. +`ccx login <provider>` (or use Reauthenticate in the dashboard). Codex pool accounts are not an +`ccx login` provider — reauthenticate via the dashboard Codex account pool. See +[`ccx status` / `ccx doctor`](/reference/cli/) in the CLI reference. ### Kiro credential import Kiro login expects the Kiro CLI: on Unix, install it with `curl -fsSL https://cli.kiro.dev/install | bash`; on Windows PowerShell, use `irm 'https://cli.kiro.dev/install.ps1' | iex`; then sign in with `kiro-cli login`. -Without a `kiro-cli` session, `ocx login kiro` falls +Without a `kiro-cli` session, `ccx login kiro` falls back to a pasted access token or the `KIRO_ACCESS_TOKEN` environment variable. -The `ocx login kiro` import path searches the platform Kiro CLI stores and opens SQLite databases +The `ccx login kiro` import path searches the platform Kiro CLI stores and opens SQLite databases read-only. Two environment variables make the source and token row selection explicit: - `KIROCLI_DB_PATH` selects a nonstandard Kiro CLI SQLite database. The path must already exist; - during this import path, opencodex does not create or modify the database, WAL, or SHM files. + during this import path, CodexCommander does not create or modify the database, WAL, or SHM files. - `KIROCLI_TOKEN_KEY` selects the exact `auth_kv` token key when a database contains multiple otherwise ambiguous token rows. A missing selection fails login instead of guessing. On Windows, import looks for `%LOCALAPPDATA%\Kiro-Cli\data.sqlite3`. Forced/add-account login -also needs the local CLI binary: opencodex first uses `PATH`, then falls back to +also needs the local CLI binary: CodexCommander first uses `PATH`, then falls back to `%LOCALAPPDATA%\Kiro-Cli\kiro-cli.exe` and `C:\Program Files\Kiro-Cli\kiro-cli.exe`. -After a successful import, opencodex persists the imported credential to -`~/.opencodex/auth.json`. +After a successful import, CodexCommander persists the imported credential to +`~/.codexcommander/auth.json`. Keep these variables and the selected database private. Do not attach database files or raw login diagnostics to bug reports. **Add account** is a separate write workflow: it snapshots the current session, logs `kiro-cli` out, -and imports the fresh browser login. If the login is cancelled or fails, including while OpenCodex +and imports the fresh browser login. If the login is cancelled or fails, including while CodexCommander persists the credential, rollback replaces the Kiro CLI database and removes its current WAL, SHM, and journal sidecars before publishing the previous session snapshot. @@ -219,16 +215,16 @@ selectors, then retry. Signing in from a machine with no existing `kiro-cli` ses ## 3. API-key catalog -opencodex ships 76 built-in presets: 64 key-based, eight OAuth, three local, and one default +CodexCommander ships 76 built-in presets: 64 key-based, eight OAuth, three local, and one default ChatGPT-forward preset. The dashboard's **Add provider** picker opens a key provider's dashboard, validates the key, and stores it; validation is provider-specific. Notable entries: **ClinePass** uses a Cline API key with the [official subscription catalog](https://docs.cline.bot/getting-started/clinepass) and [Chat Completions endpoint](https://docs.cline.bot/api/chat-completions), operated by Cline Bot Inc. under [Cline's terms](https://cline.bot/tos). A routed id such as `cline-pass/cline-pass/kimi-k3` is -intentional: the first segment selects the opencodex provider, while `cline-pass/kimi-k3` is the +intentional: the first segment selects the CodexCommander provider, while `cline-pass/kimi-k3` is the full model slug sent upstream. ClinePass quota is shared by the account across rolling 5-hour, -weekly, and monthly limits. opencodex currently advertises the live-verified `low` reasoning tier; +weekly, and monthly limits. CodexCommander currently advertises the live-verified `low` reasoning tier; higher requested tiers clamp to `low` until the gateway publishes or verifies a wider ladder. **Cline** is the same API key and endpoint on pay-as-you-go usage billing across 100+ models @@ -289,8 +285,8 @@ Volcengine Agent Plan uses its native Responses endpoint through `openai-respons `https://opencode.ai/zen/go/v1`. It is distinct from the OpenCode Desktop/CLI client described in [OpenCode](/guides/opencode/). Create its key in the [OpenCode console](https://opencode.ai/console), then add **OpenCode Go** from the dashboard's -**Providers** page or configure the `opencode-go` preset with that key. OpenCodex does not scrape an -OpenCode authentication store or migrate this key to Keychain. +**Providers** page or configure the `opencode-go` preset with that key. CodexCommander does not use an +OpenCode authentication store or Keychain for this key. The public model catalog is not evidence that a key works, so a saved key is **unverified** until the first successful inference using that active key. The provider's published caps are reference caps — @@ -307,7 +303,7 @@ remaining models over OpenAI Chat Completions. These trust facts attach only to `https://opencode.ai/zen/go/v1` destination; a same-named custom provider keeps its own behavior. The built-in preset is key-based, so Add Provider groups it under **Paid**, not account-login -providers, and OpenCodex does not offer an OpenCode Go OAuth flow. It is also separate from both the +providers, and CodexCommander does not offer an OpenCode Go OAuth flow. It is also separate from both the **OpenCode** client under Client Apps and the no-key **OpenCode Free** provider. Add Provider search spans Accounts, Free, and Paid, so searching `opencode` from any tab shows all matching presets with their tier labels. @@ -326,7 +322,7 @@ their tier labels. > **Volcengine Plan usage restriction:** Volcengine documents Coding Plan and Agent Plan quota as > valid only inside supported AI coding tools, and warns that using a plan key for general API > calls may suspend the subscription or ban the account. Routing Codex or Claude Code through -> opencodex is the documented use; pointing other automation at a plan key is not. The +> CodexCommander is the documented use; pointing other automation at a plan key is not. The > pay-as-you-go `volcengine` route carries no such restriction. **DeepInfra discovery.** The key-based `deepinfra` OpenAI Chat Completions provider uses the @@ -350,7 +346,7 @@ key from the subscription overview in the [Vultr Console](https://my.vultr.com). **Command Code discovery.** The preset reads Command Code's `/provider/v1/models` list from the fixed Provider API host, preserves provider-native ids, and caps discovery at 256 KiB and 256 raw -rows. `ocx login command-code` supports OAuth via browser sign-in (with optional local CLI credential +rows. `ccx login command-code` supports OAuth via browser sign-in (with optional local CLI credential import from `~/.commandcode/auth.json` for existing Command Code CLI users); the model catalog is account-scoped and comes from the authenticated discovery endpoint after login. Chat requests use the configured Bearer key. Create keys at @@ -392,7 +388,7 @@ deployments require a custom provider. Create an API key in the A custom `openai-chat` provider using `authMode: "key"` and the canonical `https://api.a6api.com` or `https://api.a6api.com/v1` base URL receives an A6API credit meter in -the dashboard and from `ocx account refresh <provider>`. The provider name is arbitrary; detection +the dashboard and from `ccx account refresh <provider>`. The provider name is arbitrary; detection uses the canonical HTTPS endpoint. The meter converts A6API token units into USD using the account's hard credit limit and displays the percentage consumed plus remaining credit. Token expiration is not shown as a quota reset because expiration does not imply that credit replenishes. @@ -430,14 +426,14 @@ management API is `/api/providers/keys` and returns masked keys only. ### Switching accounts from the terminal -Use `ocx account list`, `ocx account current`, and `ocx account use` to inspect or switch the same +Use `ccx account list`, `ccx account current`, and `ccx account use` to inspect or switch the same Codex, OAuth, and API-key pools without opening the dashboard. See the -[CLI reference](/reference/cli/#ocx-account-subcommand) for commands, JSON output, and +[CLI reference](/reference/cli/#ccx-account-subcommand) for commands, JSON output, and new-session behavior. ### GPT-5.6 preview paths -GPT-5.6 Sol/Terra/Luna are seeded in provider fallback lists so `ocx sync` can keep the models +GPT-5.6 Sol/Terra/Luna are seeded in provider fallback lists so `ccx sync` can keep the models visible even while live catalogs lag: | Codex route | Seeded model ids | Codex-visible context | @@ -453,39 +449,39 @@ paths remain upstream-gated; Cursor's live discovery additionally filters its st the logged-in account can use. :::note[Gateways & subscription proxies] -A provider is included when opencodex has a matching wire adapter, **not** based on whether it is an +A provider is included when CodexCommander has a matching wire adapter, **not** based on whether it is an "agent" product. The current adapter ids are `openai-chat`, `openai-responses`, `anthropic`, `google` -(AI Studio, Vertex, and Antigravity/Cloud Code Assist modes), `azure` / `azure-openai`, `kiro`, and +(AI Studio, Vertex, and Antigravity/Cloud Code Assist modes), `azure-openai`, `kiro`, and `cursor`. A proprietary API without one of these implementations, such as native Amazon Bedrock, is not supported directly. -**GitHub Copilot** is an OAuth provider (`ocx login github-copilot`) that exchanges a GitHub +**GitHub Copilot** is an OAuth provider (`ccx login github-copilot`) that exchanges a GitHub device-flow login for a short-lived Copilot API token — not a pasted API key. **GitLab Duo** remains a key/subscription-token gateway on its OpenAI-compatible endpoint. **Cloudflare AI Gateway** needs your account + gateway ids filled into the URL. Copilot fronts a mixed-wire catalog: its GPT-5 family (`gpt-5.3-codex`, `gpt-5.4`, `gpt-5.4-mini`, `gpt-5.5`, `gpt-5.6-luna`, `gpt-5.6-sol`, `gpt-5.6-terra`) rejects -`/chat/completions` for agent traffic, so opencodex routes those models over the +`/chat/completions` for agent traffic, so CodexCommander routes those models over the Responses API by built-in default while every other Copilot model stays on chat completions. The precedence is: hard wire pin → your explicit [`modelAdapters`](/reference/configuration/providers/) entry → registry default → provider-wide adapter. To opt a model without a built-in default (for example `gpt-5.4-nano`) into Responses, set `"modelAdapters": { "gpt-5.4-nano": "openai-responses" }`. -Cursor is tracked separately as an experimental adapter. `adapter: "cursor"` appears in `ocx init` +Cursor is tracked separately as an experimental adapter. `adapter: "cursor"` appears in `ccx init` and the dashboard Add Provider picker as an experimental local config entry with Cursor's static -fallback model catalog metadata. When a Cursor access token is configured, opencodex uses Cursor's +fallback model catalog metadata. When a Cursor access token is configured, CodexCommander uses Cursor's live HTTP/2 transport. Its bundled fallback seed includes `gpt-5.6-sol` / `terra` / `luna` (1M context), `grok-4.5` / `grok-4.5-fast` (500K), and `kimi-k3` (262K); live discovery decides which remain visible for the account. Cursor serves Kimi K3 only as effort-suffixed wire ids, so `cursor/kimi-k3` exposes a `low` / `high` / `max` ladder and defaults to `max`, matching the model's documented API default. Cursor server-driven native read/write/delete/ls/grep/shell/fetch execution is disabled by default because it bypasses Codex's approval and sandbox path; set -`unsafeAllowNativeLocalExec: true` on the `providers.cursor` object in `~/.opencodex/config.json` +`nativeLocalExec: "on"` on the `providers.cursor` object in `~/.codexcommander/config.json` only for trusted local experiments (or via **Providers → Cursor → Edit JSON** in the dashboard). See the [Configuration reference](/reference/configuration/#cursor-provider-adapter-cursor) for a full example. MCP, screen recording, and computer-use are available as executor hooks; without a -configured local executor, opencodex returns typed no-executor results instead of policy-blocking +configured local executor, CodexCommander returns typed no-executor results instead of policy-blocking the request. Cursor OAuth and live model discovery are enabled for this experimental adapter; Cursor is still not shown in key-login lists. ::: @@ -493,7 +489,7 @@ Cursor is still not shown in key-login lists. ### Ollama Cloud Ollama Cloud is a hosted (not local) Ollama, OpenAI-compatible at `https://ollama.com/v1` with a key -from [ollama.com/settings/keys](https://ollama.com/settings/keys). opencodex classifies its cloud +from [ollama.com/settings/keys](https://ollama.com/settings/keys). CodexCommander classifies its cloud lineup by vision capability so the [vision sidecar](/guides/sidecars/) only kicks in for text-only models. Text-only models (e.g. `glm-5.2`, `deepseek-v4-pro`, `gpt-oss`, `qwen3-coder`, `minimax-m2.x`, `nemotron-3-*`) are listed in `noVisionModels`; vision-native models (e.g. @@ -502,7 +498,7 @@ tolerant of Ollama's `:size` tags, so `gpt-oss` covers `gpt-oss:120b` and `gpt-o ## 4. Local providers -Point opencodex at a local OpenAI-compatible server — usually with a blank key: +Point CodexCommander at a local OpenAI-compatible server — usually with a blank key: | Provider | Base URL | | --- | --- | @@ -513,6 +509,6 @@ Point opencodex at a local OpenAI-compatible server — usually with a blank key ## Any OpenAI-compatible endpoint If a provider speaks Chat Completions, the `openai-chat` adapter handles it — choose **Custom** in the -dashboard or `custom` in `ocx init` and enter the base URL. See the +dashboard or `custom` in `ccx init` and enter the base URL. See the [Configuration reference](/reference/configuration/) for every provider field (`headers`, `noReasoningModels`, `noVisionModels`, `models`, …). diff --git a/docs-site/src/content/docs/guides/routing-profile-editor.md b/docs-site/src/content/docs/guides/routing-profile-editor.md index 5dbc737674..cc67c08d48 100644 --- a/docs-site/src/content/docs/guides/routing-profile-editor.md +++ b/docs-site/src/content/docs/guides/routing-profile-editor.md @@ -1,9 +1,9 @@ --- title: Routing Profile Editor -description: Create, edit, validate, dry-run, and remove routing policy profiles from the OpenCodex dashboard. +description: Create, edit, validate, dry-run, and remove routing policy profiles from the CodexCommander dashboard. --- -The **Routing** page in the OpenCodex dashboard can manage `config.routingProfiles` without editing `config.json` by hand. +The **Routing** page in the CodexCommander dashboard can manage `config.routingProfiles` without editing `config.json` by hand. ## Create a profile @@ -50,7 +50,7 @@ Example save payload: "id": "fast", "mode": "create", "profile": { - "alias": "ocx/fast", + "alias": "ccx/fast", "candidates": [ { "provider": "anthropic", "model": "claude-sonnet-5" }, { "provider": "openai", "model": "gpt-5.6" } diff --git a/docs-site/src/content/docs/guides/sidecars.md b/docs-site/src/content/docs/guides/sidecars.md index 006287ab97..56031fd935 100644 --- a/docs-site/src/content/docs/guides/sidecars.md +++ b/docs-site/src/content/docs/guides/sidecars.md @@ -3,13 +3,13 @@ title: "Sidecars: Web Search & Vision" description: Give routed models real web search and text-only models image understanding through native ChatGPT sidecars. --- -Routed models do not all expose hosted **web search** or native **image input**. opencodex backfills +Routed models do not all expose hosted **web search** or native **image input**. CodexCommander backfills those capabilities with two sidecars. Each can run through a ChatGPT-login (`forward`) provider or a stored Anthropic OAuth provider. Sidecar errors become bounded tool results or image markers instead of failing the whole turn. :::note[Automatic backend selection] -Explicit `backend` config wins. When unset, opencodex uses `anthropic` if an enabled Anthropic OAuth +Explicit `backend` config wins. When unset, CodexCommander uses `anthropic` if an enabled Anthropic OAuth provider has an active account not marked `needsReauth`; otherwise it uses `openai`. Explicit `anthropic` without that credential fails closed. `openai` requires both ChatGPT login auth and an enabled `forward` provider. @@ -17,11 +17,11 @@ enabled `forward` provider. ## Web-search sidecar -When Codex requests hosted `web_search` for a non-passthrough routed model, opencodex: +When Codex requests hosted `web_search` for a non-passthrough routed model, CodexCommander: 1. **Drops** the hosted `web_search` tool and exposes a synthetic `web_search(query)` function tool to the routed model instead. The original hosted-tool options are retained for the sidecar call. -2. Runs the routed model in a small **agentic loop**. When it calls `web_search`, opencodex uses the +2. Runs the routed model in a small **agentic loop**. When it calls `web_search`, CodexCommander uses the selected sidecar backend: OpenAI runs hosted `web_search` with `gpt-5.6-luna` by default; Anthropic runs `web_search_20250305` with `claude-sonnet-5` by default. The streamed answer and citations become a tool result. @@ -29,7 +29,7 @@ When Codex requests hosted `web_search` for a non-passthrough routed model, open (default 3), then removes the search tool and forces a final answer. Real client tools such as `apply_patch` or shell finalize the turn so those calls reach Codex. -Every routed-model iteration requests upstream `stream: true`, but opencodex fully buffers semantic +Every routed-model iteration requests upstream `stream: true`, but CodexCommander fully buffers semantic events internally before deciding whether to search or return the final answer. Only the first iteration's final headers/status and 429 key rotations are acquired eagerly. Thus synthetic search calls and preliminary output are never exposed as client-visible model output. @@ -70,10 +70,9 @@ failures after response headers have started are delivered as `response.failed` ## Vision sidecar When the routed model is listed in its provider's `noVisionModels` and a request carries an image, -opencodex describes each image **before** the main call and replaces it with text. The Dashboard and -management API present `gpt-5.6-luna` as the current default, and startup migrates an explicitly -persisted legacy `gpt-5.4-mini` value to Luna. If the `visionSidecar.model` field is entirely absent, -the vision execution path still has a `gpt-5.4-mini` code fallback. +CodexCommander describes each image **before** the main call and replaces it with text. The Dashboard and +management API present `gpt-5.6-luna` as the current default. If the `visionSidecar.model` field is +entirely absent, the vision execution path still has a `gpt-5.4-mini` code fallback. - Images can come from user, developer, and tool-result messages, including Codex's `view_image`. - Each image is sent to the configured native vision model with `reasoning.effort: "low"`; its diff --git a/docs-site/src/content/docs/guides/sub-agent-surface.md b/docs-site/src/content/docs/guides/sub-agent-surface.md index 47558a5f3b..a28d5a7f9d 100644 --- a/docs-site/src/content/docs/guides/sub-agent-surface.md +++ b/docs-site/src/content/docs/guides/sub-agent-surface.md @@ -6,7 +6,7 @@ description: Control how Codex spawns and manages sub-agents across all models. ## What sub-agents are A sub-agent is a separate Codex worker that the main agent can create for a focused task. It has its -own context and tools, so several independent tasks can run in parallel. opencodex controls which +own context and tools, so several independent tasks can run in parallel. CodexCommander controls which Codex collaboration surface exposes those workers, which models Codex offers for them, and how a failed model can fall back. It does not decide when your main agent must delegate. @@ -34,7 +34,7 @@ The selected mode controls the `multi_agent_version` field in every catalog entr - **base** restores upstream pins. Unpinned entries follow the native `multi_agent_v2` feature flag. - **v2** stamps `multi_agent_version = "v2"` on every model. -opencodex applies this as the final pass to both the live `/v1/models` catalog and the catalog synced +CodexCommander applies this as the final pass to both the live `/v1/models` catalog and the catalog synced to disk. That is why a mode change affects newly created App, CLI, and TUI sessions consistently. For a v2 roster, eligibility has three states: an entry stamped `"v2"`, explicitly set to `null`, or @@ -45,11 +45,11 @@ that the model belongs to the other collaboration surface. The dashboard's **Sub-agent delegation** controls three related settings: -- `injectionModel` is the preferred worker model named in opencodex guidance. +- `injectionModel` is the preferred worker model named in CodexCommander guidance. - `injectionEffort` is the optional `reasoning_effort` to request for that model. - `injectionPrompt` replaces the built-in v2 guidance text. -`multiAgentGuidanceEnabled` defaults to on and is the master switch for opencodex-authored guidance +`multiAgentGuidanceEnabled` defaults to on and is the master switch for CodexCommander-authored guidance on both surfaces. Turning it off suppresses both the v2 designation block and v1 proactive text. These are instructions to the main agent, not a proxy-side spawn router. On v2, a full-history fork @@ -66,31 +66,31 @@ Custom `injectionPrompt` text can use all four placeholders: | `{{roster}}` | The resolved picker-visible, surface-compatible roster | | `{{fallback}}` | The configured global fallback guidance | -The built-in v2 guidance has a 700-character budget. If it would exceed the budget, opencodex drops +The built-in v2 guidance has a 700-character budget. If it would exceed the budget, CodexCommander drops the roster first rather than truncating the core spawn instructions. Built-in guidance fires only when a preferred model, eligible roster, or fallback chain resolves. A configured `injectionModel` is sufficient to render a custom prompt; if a bare value cannot resolve uniquely, `{{model}}` expands to an empty string. -On v1, opencodex injects only the upstream-style proactive delegation guidance at `max` or `ultra` +On v1, CodexCommander injects only the upstream-style proactive delegation guidance at `max` or `ultra` effort. It does not add a preferred model, roster, fallback list, or custom prompt on v1. -The default-off `syncCodexSubagentDefaults` option is separate from guidance. When opencodex owns +The default-off `syncCodexSubagentDefaults` option is separate from guidance. When CodexCommander owns active Codex routing, sync or restart can write the selected values as marker-owned `[agents] default_subagent_model` and `default_subagent_reasoning_effort` entries in Codex TOML. -opencodex updates or removes only fields bearing its markers. If either target field is user-owned, +CodexCommander updates or removes only fields bearing its markers. If either target field is user-owned, the pair is left unchanged rather than partially written; ambiguous TOML is rejected without a write. External provider managers and user-owned root routing also remain authoritative. ## Fallback chains -For a spawned worker, opencodex builds this priority order: +For a spawned worker, CodexCommander builds this priority order: 1. The requested primary model. 2. The role's `model_fallback` list from its `$CODEX_HOME/agents/*.toml` definition. -3. The global `subagentModelFallback` list in opencodex config. +3. The global `subagentModelFallback` list in CodexCommander config. -Duplicate model ids are removed while preserving the first occurrence. During selection, opencodex +Duplicate model ids are removed while preserving the first occurrence. During selection, CodexCommander skips candidates that are disabled, unroutable, backed by a disabled provider, marked unhealthy, inside a cooldown, missing a usable pooled Codex account, or beyond the configured quota threshold. Availability probes are cached for `subagentModelFallbackPollMs` (60 seconds by default). @@ -104,9 +104,9 @@ normal heterogeneous fallback chain. Codex may send a v2 native-to-routed child task only as backend-encrypted `encrypted_content`. That payload can be read by the native ChatGPT backend, but not by an external provider. This is the -known [#92 limitation](https://github.com/lidge-jun/opencodex/issues/92). +known [#92 limitation](https://github.com/pavelhov/CodexCommander/issues/92). -opencodex fails safely instead of forwarding an empty or unreadable task: +CodexCommander fails safely instead of forwarding an empty or unreadable task: - A direct non-native route returns HTTP 400 with `error.code = "unreadable_encrypted_agent_task"` and does not echo the ciphertext. @@ -119,18 +119,18 @@ opencodex fails safely instead of forwarding an empty or unreadable task: | Policy | Behavior | | --- | --- | | `"encrypted"` (default) | Preserves ChatGPT's reserved encrypted collaboration schema and the fail-closed behavior above. Use native ChatGPT workers or v1 for external workers. | -| `"plaintext"` | Experimental mixed-provider V2 compatibility. For ChatGPT parents, OpenCodex presents a non-reserved plaintext collaboration namespace and restores the canonical namespace on the client-facing response. For routed parents, it marks only completed V2 message calls as plaintext. Both paths activate Codex's plaintext V2 handler, while its graph, mailbox, wait, follow-up, and completion lifecycle remain native. | +| `"plaintext"` | Experimental mixed-provider V2 compatibility. For ChatGPT parents, CodexCommander presents a non-reserved plaintext collaboration namespace and restores the canonical namespace on the client-facing response. For routed parents, it marks only completed V2 message calls as plaintext. Both paths activate Codex's plaintext V2 handler, while its graph, mailbox, wait, follow-up, and completion lifecycle remain native. | The plaintext decision is made when the parent tool schema is created, before the worker model is known. Consequently **every** V2 `spawn_agent`, `send_message`, and `followup_task` message from that -parent is plaintext, including messages to native ChatGPT workers. OpenCodex suppresses those +parent is plaintext, including messages to native ChatGPT workers. CodexCommander suppresses those arguments from usage-debug body samples, but the trusted local Codex runtime and proxy necessarily handle the plaintext to deliver it. For a canonical ChatGPT parent, plaintext compatibility activates only with the complete recognized -V2 schema. For a routed parent, OpenCodex marks only the exact `collaboration` message calls listed +V2 schema. For a routed parent, CodexCommander marks only the exact `collaboration` message calls listed above; lifecycle and unrelated tools remain untouched. A partial, changed, malformed, or colliding -native schema is not guessed: OpenCodex leaves it untouched and retains the encrypted fail-closed +native schema is not guessed: CodexCommander leaves it untouched and retains the encrypted fail-closed guard. Delivery changes affect subsequent requests, so start a new session after saving instead of switching an active conversation in place. @@ -157,27 +157,27 @@ has a stale catalog. ### CLI -Use `ocx v2` for the collaboration surface and native feature settings: +Use `ccx v2` for the collaboration surface and native feature settings: ```bash -ocx v2 status -ocx v2 mode v1 -ocx v2 mode default -ocx v2 mode v2 -ocx v2 threads 8 +ccx v2 status +ccx v2 mode v1 +ccx v2 mode default +ccx v2 mode v2 +ccx v2 threads 8 ``` -Use `ocx agent` for delegation, roster, effort-cap, and fallback settings: +Use `ccx agent` for delegation, roster, effort-cap, and fallback settings: ```bash -ocx agent status -ocx agent injection set --model anthropic/claude-sonnet-5 --effort xhigh -ocx agent subagents set gpt-5.6-sol,anthropic/claude-sonnet-5 -ocx agent fallback set gpt-5.4-mini,xai/grok-4.5 --poll-ms 60000 -ocx agent effort set --subagent max +ccx agent status +ccx agent injection set --model anthropic/claude-sonnet-5 --effort xhigh +ccx agent subagents set gpt-5.6-sol,anthropic/claude-sonnet-5 +ccx agent fallback set gpt-5.4-mini,xai/grok-4.5 --poll-ms 60000 +ccx agent effort set --subagent max ``` -Pass `-` to clear a nullable `ocx agent injection` value, or use the relevant `clear` action for a +Pass `-` to clear a nullable `ccx agent injection` value, or use the relevant `clear` action for a roster or fallback list. See the [CLI reference](/reference/cli/) for all command families. ### API @@ -227,7 +227,7 @@ to v1. A `"v2"`, `null`, or absent surface value is eligible; a real `"v1"` pin ### Do mode changes affect running sessions? No. Start a new Codex session after changing the mode. If a long-running App host still shows stale -catalog state, run `ocx sync` and restart that Codex surface. +catalog state, run `ccx sync` and restart that Codex surface. ### Can Sol V2 delegate to Kimi, Grok, or DeepSeek? @@ -239,7 +239,7 @@ the native-only confidentiality contract, or use Classic v1 for the older cross- `injectionEffort` affects only delegated-worker guidance and, when explicitly enabled, native Codex sub-agent defaults. It does not change the parent session's effort. `ultra` is a client-facing top -tier that Codex converts to `max`; opencodex then maps or clamps the value for the selected provider. +tier that Codex converts to `max`; CodexCommander then maps or clamps the value for the selected provider. ### Context cap diff --git a/docs-site/src/content/docs/guides/video-bridge.md b/docs-site/src/content/docs/guides/video-bridge.md index 4d0c4930f1..5dec036de3 100644 --- a/docs-site/src/content/docs/guides/video-bridge.md +++ b/docs-site/src/content/docs/guides/video-bridge.md @@ -6,15 +6,15 @@ description: Generate videos with Grok Imagine Video through a non-OpenAI model. ## Overview The Video Bridge lets you use xAI's Grok Imagine Video generation through any non-OpenAI model -routed by opencodex. When enabled, a synthetic `video_gen` tool is injected into the conversation. -The model calls it like any function tool; opencodex intercepts the call, submits a video generation +routed by CodexCommander. When enabled, a synthetic `video_gen` tool is injected into the conversation. +The model calls it like any function tool; CodexCommander intercepts the call, submits a video generation job to xAI, polls until completion, and downloads the result. ## Prerequisites -- An `xai` provider entry with an **API key** (`ocx login xai` alone is not sufficient — the video bridge requires key auth, not OAuth) +- An `xai` provider entry with an **API key** (`ccx login xai` alone is not sufficient — the video bridge requires key auth, not OAuth) - A non-OpenAI model as your routed provider (e.g. Anthropic Claude, Google Gemini) -- opencodex configured to route through the non-OpenAI provider +- CodexCommander configured to route through the non-OpenAI provider > **⚠ Provider key required:** The video bridge only activates when the `xai` provider uses > API key auth. Add this to your config: @@ -27,7 +27,7 @@ job to xAI, polls until completion, and downloads the result. > } > ``` > -> If you onboarded via `ocx login xai` (OAuth), the provider stays in `authMode: "oauth"` +> If you onboarded via `ccx login xai` (OAuth), the provider stays in `authMode: "oauth"` > and the bridge silently won't activate. Set `XAI_API_KEY` in the environment **or** > hard-code the key as shown above. @@ -56,9 +56,9 @@ Add `videoBridgeEnabled: true` to your `images` config: ## How It Works -1. opencodex detects a non-OpenAI routed model with `videoBridgeEnabled: true` +1. CodexCommander detects a non-OpenAI routed model with `videoBridgeEnabled: true` 2. A synthetic `video_gen` function tool is injected into the conversation -3. When the model calls `video_gen`, opencodex submits a job to xAI's `/videos/generations` +3. When the model calls `video_gen`, CodexCommander submits a job to xAI's `/videos/generations` 4. The bridge polls the job status every 5-15 seconds, sending heartbeat messages to keep the stream alive 5. When the video is ready, it's downloaded to the artifacts directory 6. The local file path is returned to the model as a tool result diff --git a/docs-site/src/content/docs/guides/web-dashboard.md b/docs-site/src/content/docs/guides/web-dashboard.md index 8852212965..fd0a42319f 100644 --- a/docs-site/src/content/docs/guides/web-dashboard.md +++ b/docs-site/src/content/docs/guides/web-dashboard.md @@ -1,23 +1,23 @@ --- title: Web Dashboard -description: The opencodex GUI for proxy health, providers, models, delegation guidance, auth pools, usage, and logs. +description: The CodexCommander GUI for proxy health, providers, models, delegation guidance, auth pools, usage, and logs. --- -opencodex ships a local web dashboard (a Vite/React app under `gui/`) served from the proxy. It is the +CodexCommander ships a local web dashboard (a Vite/React app under `gui/`) served from the proxy. It is the shortest path to managing providers, Codex/ChatGPT accounts, catalog models, sidecars, sub-agent settings, and request traffic. ## Opening it ```bash -ocx gui +ccx gui ``` This opens `http://localhost:<port>` in your browser, auto-starting the proxy first if needed. In development you can run the GUI dev server separately against a running proxy: ```bash -ocx start +ccx start bun run dev:gui ``` @@ -26,8 +26,8 @@ bun run dev:gui On the default loopback bind (`localhost` / `127.0.0.1`) the dashboard never asks for a token: the proxy mints short-lived GUI sessions into the served page and renews them silently when they expire or the proxy restarts. Only a dashboard bound to a non-loopback hostname requires -the admin token (`OPENCODEX_ADMIN_AUTH_TOKEN`, or the auto-generated -`~/.opencodex/admin-api-token` file). +the admin token (`CODEXCOMMANDER_ADMIN_AUTH_TOKEN`, or the auto-generated +`~/.codexcommander/admin-api-token` file). When a remote dashboard needs that credential, it presents a standard password form so a browser password manager can offer to save and autofill it. The dashboard itself still keeps the token only @@ -39,19 +39,19 @@ the browser or password manager's decision. | Area | What it does | | --- | --- | | **Dashboard summary** | Multi-agent mode, online state, version, uptime, provider count, 30-day token total, active providers, and available native/routed models. | -| **Sub-agent delegation** | Choose a native or routed model and optional reasoning effort shared by OpenCodex delegation guidance and the separate native-default opt-in. This is not a proxy-side per-spawn router; see below. | +| **Sub-agent delegation** | Choose a native or routed model and optional reasoning effort shared by CodexCommander delegation guidance and the separate native-default opt-in. This is not a proxy-side per-spawn router; see below. | | **Sidecars** | Choose the web-search model and effort plus the vision-description model. Changes apply on the next request. | -| **Maintenance** | Resync the Codex model catalog, inspect project-local config bypass warnings, check the latest or preview release, and run an update with optional proxy restart. | +| **Maintenance** | Resync the Codex model catalog and inspect project-local config bypass warnings. | | **Startup safety** | Show whether injected Codex routing survives a restart, with separate service and launcher-shim health plus exact repair commands. | | **Windows tray** | Install a per-user login tray for one-click proxy start, stop, restart, dashboard access, and status. The tray is a controller, not a proxy restart service. | -| **Codex autostart** | Allow an already-installed Codex launcher shim to run `ocx ensure`. This toggle does not install a shim or background service. | +| **Codex autostart** | Allow an already-installed Codex launcher shim to run `ccx ensure`. This toggle does not install a shim or background service. | | **Providers** | Add, edit, set the default (enabled providers only), enable/disable, and remove providers; manage OAuth account pools and API-key pools where supported. Removing the current default switches to the first remaining enabled provider when one exists; otherwise deletion is refused and the current default is kept. Provider Settings can disable live model discovery for endpoints with missing, slow, or oversized `/models` catalogs. For Claude (Anthropic) OAuth pools, each logged-in account shows its own 5-hour and weekly rate-limit bars (usage is per credential); a failed probe keeps the last-known bars and marks them unavailable until the next successful refresh. | | **Add provider** | Search registry-backed presets for account login, API-key services, local servers, or a custom endpoint. A query searches Accounts, Free and Paid together while the tabs remain useful for browsing. | | **Codex Auth** | Add ChatGPT/Codex pool accounts, select the next-session account, refresh 5h / weekly / 30d quotas, enable or disable quota auto-switch, set its 1–100% threshold, and configure transient-failure failover. | | **Subagents** | Open the **Agent Command Center** to choose and order the five models advertised to `spawn_agent`, search the current catalog, and configure Run Policy for protocol, V2 delivery, guidance, fallback, and thread limits. Saved entries that are not advertised are reported explicitly. | | **Models** | Toggle native GPT and routed models, set provider allowlists and context caps, choose **Classic v1**, **Follow Codex defaults**, or **Concurrent v2**, and configure the v2 thread limit. The Current behavior card reports context as **Uncapped**, **Limited**, or **Mixed limits**. Configured providers stay visible as zero-model groups when discovery is off or returns no rows. Each routed-provider row reports **Auto-discovery on** or **Static catalog only** and links to the owning Provider setting. | | **Client Apps** | Inspect configured and available local clients, apply or remove managed config where supported, review backups, and reach Codex, Claude Code/Desktop, Grok Build, OpenCode and the file-managed clients without treating providers as clients. | -| **API Access** | Issue and manage keys that authenticate other apps to the OpenCodex proxy. Provider credentials remain under Providers. | +| **API Access** | Issue and manage keys that authenticate other apps to the CodexCommander proxy. Provider credentials remain under Providers. | | **Logs** | Auto-refresh recent requests with tokens, requested effort and (when available) effective outbound effort, resolved model, provider, status, request id, duration, and error details. The detail view includes the exact reasoning wire field when the adapter emits one. Filter by opaque conversation/session id (when the client sends one) to total tokens and estimated list-price cost for the currently loaded Logs ring. | | **Usage / Debug** | Inspect token-usage coverage and trends, or enable opt-in provider transport and usage-extraction diagnostics. | | **Storage** | Read-only CODEX_HOME disk breakdown (sessions, archives, DBs, attachments). Optional archived cleanup: preview the oldest N%, then quarantine to `CODEX_HOME/.trash` (default) or permanently delete behind an explicit checkbox. **Auto-cleanup policy** is opt-in and **default OFF** (`storageCleanupPolicy.enabled`); configure threshold/target/schedule/mode on the Storage page, or trigger **Run now**. Quarantined entries can be restored from the Storage page (JSONL + threads). Active sessions stay read-only. Cleanup and restore are refused while Codex holds the newest/active `state_*.sqlite` locked. | @@ -62,8 +62,7 @@ the browser or password manager's decision. There is a single layout, so there is no layout switch to configure. Dashboard sections are addressable instead: `#dashboard` opens Overview, and `#dashboard/providers` and `#dashboard/models` open the other two. Reload, bookmark, and Back all keep the section you were -on. **Logs** works the same way with `#logs` and `#logs/debug`. An older `#providers/workspace` -bookmark now lands on `#providers`. +on. **Logs** works the same way with `#logs` and `#logs/debug`. Cost values in **Logs** and **Usage** are API list-price equivalents calculated from reported tokens. They are not billing receipts or evidence of an actual charge; subscription usage or provider credits @@ -84,19 +83,19 @@ Models page shows that state and links directly to it; it does not keep a second ## Delegation picker vs spawn routing The Dashboard's **Sub-agent delegation** picker stores `injectionModel` and, optionally, -`injectionEffort`. **OpenCodex multi-agent guidance** independently controls the delegation +`injectionEffort`. **CodexCommander multi-agent guidance** independently controls the delegation instructions that use those values. On eligible v2 turns, that guidance tells the parent agent which exact model and reasoning effort to pass to `spawn_agent`; clearing the model also clears the stored effort. The default-off **Use as native Codex subagent defaults** switch applies the same selection to Codex's -native `[agents]` defaults on the next sync/restart when OpenCodex manages the active Codex routing. +native `[agents]` defaults on the next sync/restart when CodexCommander manages the active Codex routing. External user-managed provider configs remain untouched. Those defaults affect newly created Codex tasks and do not themselves cause delegation. Existing user-owned `[agents]` defaults are preserved rather than overwritten, so they may continue to override the requested defaults. :::caution -Neither control is a proxy-side cross-model spawn router. OpenCodex guidance asks Codex to pass +Neither control is a proxy-side cross-model spawn router. CodexCommander guidance asks Codex to pass overrides to `spawn_agent`; native `[agents]` defaults apply only when Codex creates a new task after they have been synchronized. See [Sub-agent Surface](/guides/sub-agent-surface/) for the canonical v1/base/v2 behavior. @@ -128,7 +127,7 @@ and other providers. Higher order is used first, and the pool drops to a lower order only once every account above it is drained or unavailable. A changed order applies from the next unbound request and never moves a thread that is already bound. The Codex Desktop (main) account is ordered like any other, so it can - be set to **Last** and kept as the reserve. An order set from `ocx account priority` outside those + be set to **Last** and kept as the reserve. An order set from `ccx account priority` outside those five presets stays visible and selectable on the card. - Thread affinity prevents per-request flapping. With quota auto-switch enabled, a long-running thread is periodically re-evaluated and may rebind after its relevant usage reaches the threshold @@ -136,8 +135,8 @@ and other providers. - New sessions can choose the lowest-usage eligible account. Paid plans score the hottest known 5h, weekly, or 30d window; Go/Free plans use the 30d window only. - When WHAM supplies `limit_window_seconds`, Codex Auth classifies a primary window of at least 28 - days as 30d instead of assuming every primary window is weekly. Responses without a duration keep - the legacy weekly interpretation. + days as 30d instead of assuming every primary window is weekly. Responses without a duration are + interpreted as weekly. - **Refresh quotas** re-reads account usage immediately so routing and the account cards use the same values. - Pool request logs use opaque labels such as `p3fa91c`, never account emails. @@ -150,7 +149,7 @@ visible fields, incomplete-coverage meaning, and routing boundary. ## Integrations The **Integrations** page connects OpenCode without treating it as another provider login. Its -**Apply connection** action changes only `provider.opencodex` in OpenCode's active global JSONC/JSON +**Apply connection** action changes only `provider.codexcommander` in OpenCode's active global JSONC/JSON file, preserves comments and unrelated keys, and delivers the proxy credential through a protected file reference rather than copying a key into OpenCode config. **Always keep OpenCode connected** is an opt-in refresh after proxy startup or model-catalog changes. @@ -159,7 +158,7 @@ If OpenCode config changed after Apply, the page reports that user edits are pre removes or restores only the managed provider. When the journal permits an exact restore, the original file is restored byte-for-byte. The **Open OpenCode** action launches OpenCode Desktop in one click; when only the CLI is installed, use -`ocx opencode` for its non-mutating, transient connection instead. See +`ccx opencode` for its non-mutating, transient connection instead. See [OpenCode](/guides/opencode/) for the file-selection and restore details. ## How the dashboard talks to the proxy @@ -174,7 +173,6 @@ The GUI is a thin client over the proxy's JSON management API. Useful endpoints | `POST /api/startup-action` | Install the background service or Codex launcher shim through fixed, allowlisted actions. | | `GET` / `POST /api/windows-tray` | Read or change the Windows tray installation and visible-process state. POST accepts `install`, `start`, `stop`, or `uninstall`. | | `POST /api/sync` | Rebuild the shared model catalog and stale the Codex model cache. | -| `GET /api/update/check` · `POST /api/update/run` · `GET /api/update/status` | Check, run, and monitor self-update jobs. Worker PIDs are persisted so a crashed job recovers automatically; legacy no-PID jobs recover after ten minutes. | | `GET` / `PUT /api/sidecar-settings` | Read or set search/vision sidecar model settings. | | `GET` / `PUT /api/injection-model` | Read or set the shared sub-agent model/effort selection and the independent guidance/native-default switches. | | `GET` / `PUT /api/v2` | Read or set the surface mode, Codex feature flag, and v2 thread limit. | diff --git a/docs-site/src/content/docs/index.mdx b/docs-site/src/content/docs/index.mdx index 985cbde406..64dca20b46 100644 --- a/docs-site/src/content/docs/index.mdx +++ b/docs-site/src/content/docs/index.mdx @@ -1,12 +1,12 @@ --- -title: "opencodex — Run Codex on any LLM" +title: "CodexCommander — Run Codex on any LLM" description: Universal provider proxy for OpenAI Codex & Claude Code — use any LLM with Codex CLI, App, SDK, and Claude Code. template: splash head: - # Brand-first, no " | opencodex" suffix: Google matches the site name against + # Brand-first, no " | CodexCommander" suffix: Google matches the site name against # the home page title, so the wordmark leads and is not duplicated. - tag: title - content: "opencodex — Run Codex on any LLM" + content: "CodexCommander — Run Codex on any LLM" - tag: meta attrs: property: og:locale diff --git a/docs-site/src/content/docs/ja/benchmarks/index.mdx b/docs-site/src/content/docs/ja/benchmarks/index.mdx index 78e35c15e9..6f597bd7ca 100644 --- a/docs-site/src/content/docs/ja/benchmarks/index.mdx +++ b/docs-site/src/content/docs/ja/benchmarks/index.mdx @@ -3,7 +3,7 @@ title: ベンチマーク description: 公開コーディングエージェントベンチマークのスナップショット — タスクあたりコスト vs 能力、ボードごとの出典表記。 --- -公開リーダーボードを**手動で更新する静的スナップショット**です — OpenCodex のライブ +公開リーダーボードを**手動で更新する静的スナップショット**です — CodexCommander のライブ 計測ではありません。ボードごとに出典、取得日、ライセンスメモを付け、スコア/$ ランキングはすべての行に出典が測定したタスクあたりコストがあるボードでのみ表示します。 diff --git a/docs-site/src/content/docs/ja/contributing.md b/docs-site/src/content/docs/ja/contributing.md index 79820965ef..d4a5f28c56 100644 --- a/docs-site/src/content/docs/ja/contributing.md +++ b/docs-site/src/content/docs/ja/contributing.md @@ -1,13 +1,12 @@ --- title: コントリビュート -description: opencodex の開発環境、構成、規約、プロバイダーとアダプターの追加方法。 +description: CodexCommander の開発環境、構成、規約、プロバイダーとアダプターの追加方法。 --- ## セットアップ ```bash -git clone https://github.com/pavelhov/opencodex.git -cd opencodex +cd /path/to/CodexCommander bun install bun run dev:proxy # 開発モードのプロキシ API bun run dev:gui # ダッシュボード dev サーバー(別ターミナル) @@ -44,12 +43,9 @@ bun run prepare:package # パッケージランチャー/asset 更新 cd docs-site && bun install && bun dev ``` -## ドキュメントのデプロイ +## ドキュメントサイト -公開ドキュメントは GitHub Pages の <https://opencodex.me/ja/> に公開されます。 -`.github/workflows/deploy-docs.yml` は `main` push で `docs-site/**` またはワークフロー自体が変わると -実行されます。`docs-site` をビルドした後、生成されたサイトをデプロイします。ドキュメント変更を push する前に以下を -実行してください。 +ドキュメントは `docs-site/` にあり、現在公開中のホストはありません。ドキュメントの pull request を出す前に、ローカルでビルドしてください。 ```bash cd docs-site @@ -57,42 +53,31 @@ bun install --frozen-lockfile bun run build ``` -## CI とリリース +公開自動化はこのリポジトリに含まれていません。 -GitHub Actions は必要な作業のみを行います。 +## 継続的インテグレーション -- **Cross-platform CI**(`.github/workflows/ci.yml`)はランタイム、テスト、パッケージ、スクリプト、 - TypeScript、ワークフローファイルが変更された pull request と `main` push で実行されます。Bun matrix は Linux、 - Windows、macOS で install、typecheck、tests、privacy scan、release helper build smoke、GUI build、 - `ocx help` を検査します。別途 3 OS レーンはバンドルランタイムを使い、Bun を別途インストールしなくても - npm global install が動作するか確認します。 -- **Release**(`.github/workflows/release.yml`)は手動で実行します。2 つ目の完全 CI パイプラインではなく、 - dry-run や publish 前に正確なリリースコミット(`GITHUB_SHA`)で Cross-platform CI が - 成功したか確認します。 +すべての pull request と `main` へのすべての push では、自動チェックを **1 つ**だけ実行します: +**`ci`** (`.github/workflows/ci.yml`)。通常の貢献で必須の自動化はこれだけです。 -リリースには helper を使ってください。 +リポジトリ管理者は、保護ルールが意図した管理者操作を阻む場合に GitHub ruleset の +**Always-allow** bypass を使えます。これは管理者の復旧と例外的な保守用であり、 +コントリビューター作業のレビュー代替ではありません。 -```bash -bun run release <version> # バージョン bump を commit/push、publish ワークフローはデフォルト dry-run -bun run release <version> --publish # CI-gated dry-run を確認した後、実際の publish -bun run release:watch # 直近の Release ワークフロー run を監視 -``` - -## ブランチ +## ブランチと pull request -- `dev` — 唯一の統合先。すべての PR をここに出します。 -- `main` — リリース専用。`dev` からメンテナーが昇格させるときだけ動きます。機能 PR を直接 - 出さないでください。 -- `preview` — プレリリーストレイン。 +- **`main` が唯一の default / 統合 / PR ターゲットです。** 機能修正の PR は `main` に向けてください。 +- 現在の **`main` tip** からブランチを切ってください。 +- 説明文には、何をなぜ変えたかと、検証方法(実行したコマンドと結果)を書いてください。空や + プレースホルダーだけの説明ではレビューできません。 +- ダッシュボード UI を触る場合は、説明にスクリーンショットを含めてください。 +- 振る舞い変更には、そのサブシステムの既存テスト近くに集中した回帰テストが必要です。共有 + ルーティング、アダプター、設定、サーバー変更ではフルスイートを通してください。 -Go ネイティブポートを担っていた `dev2-go` は廃止し、2 本の統合ラインを維持する方針も -終了しました。履歴は -[lidge-jun/opencodex-go-archive](https://github.com/lidge-jun/opencodex-go-archive) -に読み取り専用で残しています。現在は `dev` の Bun ネイティブ TypeScript が単一のランタイム -ラインです。 +`main` 上の Bun ネイティブ TypeScript が唯一のランタイム線です。 -リベース PR を歓迎します。古いブランチを現在の head にリベースすることは、ノイズではなく -通常の貢献です。説明欄に元のコミットを記載してください。 +リベース PR は歓迎します。古いブランチを現在の head に載せ直すのは通常の保守です。説明に +元コミットを書いてください。 ## 規約 @@ -103,7 +88,7 @@ Go ネイティブポートを担っていた `dev2-go` は廃止し、2 本の - **非同期エラーは境界で処理** — サイドカーはリクエストパスにエラーを投げず、適切な marker で 低下します。 - **Structure SOT** — 現在のメンテナンス不変条件は `structure/` に置きます。公開ユーザーワークフローは - `docs-site/`、過去の調査/診断記録は `docs/` に置きます。 + `docs-site/`、保守対象の技術・実装ノートは `docs/` に置きます。 - **export の保存** — 他のモジュールが依存している可能性があります。 ## カタログにプロバイダーを追加 @@ -124,7 +109,7 @@ Go ネイティブポートを担っていた `dev2-go` は廃止し、2 本の }, ``` -`src/providers/derive.ts` はこのエントリを `ocx init`、`ocx provider`、ダッシュボード preset、API キーログイン、 +`src/providers/derive.ts` はこのエントリを `ccx init`、`ccx provider`、ダッシュボード preset、API キーログイン、 OAuth 設定 seed に供給します。`enrichProviderFromCatalog()` はモデルメタデータと capability 分類を 保存するプロバイダー設定にコピーします。OAuth プロトコル実装は引き続き `src/oauth/` にあります。 レジストリメタデータを追加するだけでは OAuth flow は生まれません。 @@ -142,4 +127,4 @@ factory の場合は `src/index.ts` からも export してください。 変更を証明する最も狭いコマンドから実行してください。型は `bun run typecheck`、動作は集中した `bun test tests/<name>.test.ts` またはランタイム probe で確認した後、影響範囲に応じた広い gate を -実行します。opencodex は大きな batch より小さく検証可能な commit を好みます。 +実行します。CodexCommander は大きな batch より小さく検証可能な commit を好みます。 diff --git a/docs-site/src/content/docs/ja/getting-started/for-agents.md b/docs-site/src/content/docs/ja/getting-started/for-agents.md index 87d07ecd4f..31b3da5e04 100644 --- a/docs-site/src/content/docs/ja/getting-started/for-agents.md +++ b/docs-site/src/content/docs/ja/getting-started/for-agents.md @@ -1,67 +1,70 @@ --- title: エージェントのクイックスタート -description: ユーザー同意の境界を越えずに、エージェント主導またはスクリプト化された端末から opencodex をインストールして操作します。 +description: ユーザー同意の境界を越えずに、エージェント主導またはスクリプト化された端末から CodexCommander をインストールして操作します。 --- このページは、端末から作業する AI エージェントやスクリプト利用者向けです。コマンド、終了ステータス、安全なヘッドレス運用に焦点を当てています。人間が操作しながら進める場合は、[クイックスタート](/getting-started/quickstart/) を参照してください。対話形式で設定する場合は、[Web ダッシュボード](/guides/web-dashboard/)も利用できます。 -## opencodex のセットアップ +## CodexCommander のセットアップ -公開されたパッケージをインストールし、`ocx` が `PATH` 上にあることを確認します。 +既存のソースチェックアウトを使用します。レジストリパッケージは現在公開されていません。 ```bash -npm install -g @bitkyc08/opencodex -ocx --version +bun install +bun run build:gui +bun run src/cli/index.ts --version ``` プロキシを実行する方法を 1 つ選択します。 ```bash # Foreground: blocks this terminal until stopped. -ocx start +bun run src/cli/index.ts start # Background: installs or updates the service, then starts it. -ocx service +bun run src/cli/index.ts service ``` -対話型端末で `ocx init` を実行します。 `ocx start` がフォアグラウンドを占有している場合は、2 番目の端末を使用します。 +対話型端末で `ccx init` を実行します。 `ccx start` がフォアグラウンドを占有している場合は、2 番目の端末を使用します。 ```bash -ocx init +bun run src/cli/index.ts init ``` -ウィザードは `$OPENCODEX_HOME/config.json` (通常は `~/.opencodex/config.json`) を書き込みます。プロキシアドレスを Codex の `config.toml` に挿入し、任意で Codex の自動起動 shim をインストールすることもできます。`ocx init` 自体はプロキシを起動しません。完全に非対話型でセットアップする場合は、ウィザードを操作せず、以下のように `ocx provider add` でプロバイダーを設定します。 +以降の `ccx <args>` は、このチェックアウトでは `bun run src/cli/index.ts <args>` として実行できます。 + +ウィザードは `$CODEXCOMMANDER_HOME/config.json` (通常は `~/.codexcommander/config.json`) を書き込みます。プロキシアドレスを Codex の `config.toml` に挿入し、任意で Codex の自動起動 shim をインストールすることもできます。`ccx init` 自体はプロキシを起動しません。完全に非対話型でセットアップする場合は、ウィザードを操作せず、以下のように `ccx provider add` でプロバイダーを設定します。 ## ヘッドレスインストールを確認する スクリプトおよびエージェントの実行では、次の読み取り専用チェックを使用します。 ```bash -ocx status -ocx doctor -ocx health --json +ccx status +ccx doctor +ccx health --json ``` -`ocx status` はプロキシとサービスの状態を報告します。`ocx doctor` は、ローカル環境、ネットワーク、Codex ランタイム、アカウントの健全性に関する問題を診断します。`ocx health` はプロキシが正常なら終了コード `0`、それ以外なら `1` を返します。`--json` を付けると構造化された出力を返します。 +`ccx status` はプロキシとサービスの状態を報告します。`ccx doctor` は、ローカル環境、ネットワーク、Codex ランタイム、アカウントの健全性に関する問題を診断します。`ccx health` はプロキシが正常なら終了コード `0`、それ以外なら `1` を返します。`--json` を付けると構造化された出力を返します。 -`ocx combo set` など、管理 API を利用するコマンドは稼働中のプロキシに接続します。プロキシが見つからない場合や API に到達できない場合、CLI は `503` エラーとして扱い、非ゼロで終了します。再試行する前に、フォアグラウンドのプロキシまたはバックグラウンドサービスを起動してください。コマンドとエンドポイントの全体像は、[CLI リファレンス](/reference/cli/) と [管理 API](/reference/management-api/) を参照してください。 +`ccx combo set` など、管理 API を利用するコマンドは稼働中のプロキシに接続します。プロキシが見つからない場合や API に到達できない場合、CLI は `503` エラーとして扱い、非ゼロで終了します。再試行する前に、フォアグラウンドのプロキシまたはバックグラウンドサービスを起動してください。コマンドとエンドポイントの全体像は、[CLI リファレンス](/reference/cli/) と [管理 API](/reference/management-api/) を参照してください。 ## ダッシュボードを使用せずにプロバイダーとコンボを追加する レジストリ プロバイダーは名前で追加できます。たとえば、これは Anthropic API キー プリセットを追加し、それをデフォルトのプロバイダーにします。 ```bash -ocx provider add anthropic-apikey \ +ccx provider add anthropic-apikey \ --api-key "$ANTHROPIC_API_KEY" \ --set-default ``` -`ocx provider add` はローカル設定を書き込みます。稼働中のプロキシがすでに実行中で、モデルを Codex にすぐに同期したい場合は、`--sync` を追加します。それ以外の場合は、後で `ocx sync` を実行します。レジストリにないカスタム プロバイダーには、`--adapter` と `--base-url` の両方が必要です。 +`ccx provider add` はローカル設定を書き込みます。稼働中のプロキシがすでに実行中で、モデルを Codex にすぐに同期したい場合は、`--sync` を追加します。それ以外の場合は、後で `ccx sync` を実行します。レジストリにないカスタム プロバイダーには、`--adapter` と `--base-url` の両方が必要です。 すべてのターゲット プロバイダーが構成され、プロキシが実行されたら、フェイルオーバー コンボを作成します。 ```bash -ocx combo set main \ +ccx combo set main \ --targets anthropic/claude-opus-4-8,openai/gpt-5.6-sol \ --strategy failover ``` @@ -70,11 +73,11 @@ ocx combo set main \ ## リモートとLANのバインド -デフォルトのループバック バインドには API トークンは必要ありません。 `0.0.0.0` などの非ループバック バインドには `OPENCODEX_API_AUTH_TOKEN` が必要です。プロキシはそれなしでは起動を拒否します。変数を `ocx start` の前、または `ocx service install` の前に設定して、サービスがそれを受け取るようにします。 +デフォルトのループバック バインドには API トークンは必要ありません。 `0.0.0.0` などの非ループバック バインドには `CODEXCOMMANDER_API_AUTH_TOKEN` が必要です。プロキシはそれなしでは起動を拒否します。変数を `ccx start` の前、または `ccx service install` の前に設定して、サービスがそれを受け取るようにします。 ```bash -export OPENCODEX_API_AUTH_TOKEN="your-secret-token" -ocx service install +export CODEXCOMMANDER_API_AUTH_TOKEN="your-secret-token" +ccx service install ``` -その後、クライアントは管理リクエストとモデルリクエストを認証する必要があります。 opencodex をローカル マシンの外に公開する前に、[構成](/reference/configuration/) のリモート アクセス ルールを読んでください。 +その後、クライアントは管理リクエストとモデルリクエストを認証する必要があります。 CodexCommander をローカル マシンの外に公開する前に、[構成](/reference/configuration/) のリモート アクセス ルールを読んでください。 diff --git a/docs-site/src/content/docs/ja/getting-started/how-it-works.mdx b/docs-site/src/content/docs/ja/getting-started/how-it-works.mdx index ecb08d07e0..2c57fdcee5 100644 --- a/docs-site/src/content/docs/ja/getting-started/how-it-works.mdx +++ b/docs-site/src/content/docs/ja/getting-started/how-it-works.mdx @@ -1,21 +1,21 @@ --- title: 仕組み -description: opencodex のリクエストライフサイクル全体 — parse, route, adapt, bridge, stream。 +description: CodexCommander のリクエストライフサイクル全体 — parse, route, adapt, bridge, stream。 --- import { Steps } from '@astrojs/starlight/components'; -Codex は OpenAI **Responses API** を使います。opencodex は HTTP と Server-Sent Events で届く +Codex は OpenAI **Responses API** を使います。CodexCommander は HTTP と Server-Sent Events で届く `POST /v1/responses` リクエストを受け付け、同じパスの WebSocket upgrade もオプションでサポートします。 リクエストはプロバイダーの wire フォーマットに、レスポンスは再び Responses イベントに変換されるため、Codex 側は 非 OpenAI モデルと通信していることを知る必要はありません。 ``` - ┌──────────────────────────── opencodex ────────────────────────────┐ + ┌──────────────────────────── CodexCommander ────────────────────────────┐ │ │ Codex ──▶ │ parser ──▶ router ──▶ [vision] ──▶ adapter ──▶ provider │ ──▶ Codex (/v1/ │ │ │ │ │ │ │ (SSE / WS) - responses)│ OcxParsed provider describe buildRequest parseStream │ + responses)│ CodexCommanderParsed provider describe buildRequest parseStream │ │ Request +adapter images + fetch AdapterEvent[] │ │ │ │ │ │ [web-search loop] bridge ─▶ SSE │ @@ -26,7 +26,7 @@ Codex は OpenAI **Responses API** を使います。opencodex は HTTP と Serv ## Codex 認証アカウントの選択 -選択されたプロバイダーが ChatGPT/Codex パススルーのとき、opencodex は上流に転送する前に保存された +選択されたプロバイダーが ChatGPT/Codex パススルーのとき、CodexCommander は上流に転送する前に保存された プールアカウントを選べます。ルールは意図的に 2 つに分かれています。 - **既存 thread ID は同じアカウントを維持します。** thread は開始時に選択されたアカウント世代に @@ -52,7 +52,7 @@ Codex は OpenAI **Responses API** を使います。opencodex は HTTP と Serv <Steps> 1. **Parse** — `responses/parser.ts` が Zod スキーマ(`responses/schema.ts`)でリクエストを検証し、 - これを内部 `OcxParsedRequest` に変換します: システムプロンプト、正規化されたメッセージ一覧 + これを内部 `CodexCommanderParsedRequest` に変換します: システムプロンプト、正規化されたメッセージ一覧 (テキスト、画像、ツール呼び出し、ツール結果)、ツール定義、生成オプション、そして `_webSearch`(ホスト型ウェブ検索が要求された)や `_structuredOutput`(JSON スキーマ / JSON-object `text.format` が設定された)のような機能フラグ。画像は実際のコンテンツパートとして保存され、 @@ -63,14 +63,14 @@ Codex は OpenAI **Responses API** を使います。opencodex は HTTP と Serv (`claude-`、`gpt-`、`o1-`/`o3-`/`o4-`、`llama-`/`mixtral-`/`gemma-`) → プロバイダーの `models[]` → `defaultProvider` フォールバック。[モデルルーティング](/ja/guides/model-routing/)を参照してください。 -3. **Authenticate** — `oauth` プロバイダーの場合、opencodex は現在の access トークンを - bearer キーとして解決し、認証情報の所有者に従います。OpenCodex 所有の認証情報は自動更新され、 +3. **Authenticate** — `oauth` プロバイダーの場合、CodexCommander は現在の access トークンを + bearer キーとして解決し、認証情報の所有者に従います。CodexCommander 所有の認証情報は自動更新され、 リンクされた Grok/Kimi ネイティブ CLI の世代は再読み込みして読み取り専用で使います。 ChatGPT/Codex プールアカウントでは `codex/auth-context.ts` がまずアカウントを解決し、必要な プール認証情報がない場合はパススルーアダプターは進みません。 4. **Vision サイドカー(任意)** — ルーティングされたモデルが `provider.noVisionModels` に列挙されており - リクエストに画像が含まれる場合、opencodex は設定された ChatGPT vision サイドカーで各画像を説明した + リクエストに画像が含まれる場合、CodexCommander は設定された ChatGPT vision サイドカーで各画像を説明した 後テキストに置き換えます。これによりテキスト専用モデルでも該当画像を推論できます。 [サイドカー](/ja/guides/sidecars/)を参照してください。 @@ -79,7 +79,7 @@ Codex は OpenAI **Responses API** を使います。opencodex は HTTP と Serv プロバイダー応答は `AdapterEvent` に変換せずそのまま渡します。 6. **ウェブ検索サイドカー(任意)** — Codex がホスト型 `web_search` を有効化したがルーティングされたモデルが - OpenAI ではない場合、opencodex は合成 `web_search` function tool を公開し、モデルを小さな + OpenAI ではない場合、CodexCommander は合成 `web_search` function tool を公開し、モデルを小さな エージェントループで実行しながら、デフォルトの `gpt-5.6-luna` を ChatGPT ログインで呼び出して実際の検索を行い、 その結果をツール結果として再注入します。 @@ -88,7 +88,7 @@ Codex は OpenAI **Responses API** を使います。opencodex は HTTP と Serv ルーティングモデルではツールなしで要約を実行し Codex が要求する代替会話履歴形式を返します。 8. **Adapt** — それ以外の場合、選ばれたアダプターの `buildRequest()` がプロバイダーのネイティブ - フォーマットで上流 HTTP リクエスト(URL、ヘッダー、本体)を生成し、opencodex がこれを `fetch` します。 + フォーマットで上流 HTTP リクエスト(URL、ヘッダー、本体)を生成し、CodexCommander がこれを `fetch` します。 9. **Bridge** — アダプターの `parseStream()`(または `parseResponse()`)が内部 `AdapterEvent` を 生成します(テキスト、推論、ツール呼び出し start/delta/end、done、error)。`bridge.ts` はそのストリームを @@ -98,9 +98,9 @@ Codex は OpenAI **Responses API** を使います。opencodex は HTTP と Serv </Steps> -## なぜ Codex フォークではなくプロキシなのか? +## プロトコルプロキシを使う理由 -Codex は Responses API をハードコーディングしています。opencodex はプロトコル境界で変換を行うことで +Codex は Responses API をハードコーディングしています。CodexCommander はプロトコル境界で変換を行うことで Codex **CLI、App、SDK** を変更なくそのままサポートし、Codex の更新の影響を受けず、 Codex 自体を触らずにリクエストごとにプロバイダーを切り替えられます。この変換は双方向で ストリーミングに忠実です: 推論要約、MCP ツール名前空間、自由形式(`apply_patch`)ツール、 diff --git a/docs-site/src/content/docs/ja/getting-started/installation.md b/docs-site/src/content/docs/ja/getting-started/installation.md index c82ba8bd6e..87fe8a5138 100644 --- a/docs-site/src/content/docs/ja/getting-started/installation.md +++ b/docs-site/src/content/docs/ja/getting-started/installation.md @@ -1,9 +1,9 @@ --- title: インストール -description: opencodex(ocx)プロキシと前提条件をインストールし、正常に実行できるか確認します。 +description: CodexCommander(ccx)プロキシと前提条件をインストールし、正常に実行できるか確認します。 --- -opencodex をインストールすると同じ実行ファイルを指す `ocx` と `opencodex` コマンドが一緒に提供されます。 +パッケージ済みまたはローカルリンクされたビルドでは、`ccx` と `codexcommander` の 2 つの同等なコマンドが提供されます。 どちらも Bun ベースの小さなローカル HTTP サーバーを実行します。モデルリクエストはルーティングで選ばれたプロバイダーに 転送され、必要に応じて vision とウェブ検索のサイドカーが ChatGPT ログインを使うこともあります。 @@ -11,85 +11,58 @@ opencodex をインストールすると同じ実行ファイルを指す `ocx` | 要件 | 理由 | --- | --- | -| **[Node](https://nodejs.org) ≥ 18** | `ocx` は Bun ランタイムで実行されますが、ランタイムは `npm install` 時に自動でバンドルされるため、Bun を自分でインストールする必要は**ありません**。 | -| **[OpenAI Codex](https://openai.com/codex)**(CLI、App、または SDK) | opencodex が前に立つクライアントです。opencodex は `$CODEX_HOME/config.toml`(デフォルト `~/.codex/config.toml`)に書き込みます。 | +| **[Bun](https://bun.sh)** | ソースランタイムとリポジトリのスクリプトは Bun で直接実行されます。 | +| **[OpenAI Codex](https://openai.com/codex)**(CLI、App、または SDK) | CodexCommander が前に立つクライアントです。CodexCommander は `$CODEX_HOME/config.toml`(デフォルト `~/.codex/config.toml`)に書き込みます。 | | プロバイダーアカウントまたは API キー | Anthropic、xAI、Kimi、Ollama Cloud、OpenRouter、OpenAI API キー、OpenAI 互換エンドポイント、または ChatGPT ログイン。 | -## インストール +## ソースチェックアウトを実行 ```bash -npm install -g @bitkyc08/opencodex -``` - -:::note[npm が bun の postinstall をブロックした?] -最新の npm は bun の postinstall スクリプトをブロックすることがあります(`npm warn -install-scripts ... blocked because they are not covered by allowScripts`)。 -この場合バンドル Bun ランタイムが準備されないため、bun スクリプトを許可して -再インストールしてください。npm 警告の省略コマンドにはパッケージ名が含まれておらず、現在の -ディレクトリを再インストールしてしまうので、必ずパッケージ名を明示してください: - -```bash -npm install -g --allow-scripts=bun @bitkyc08/opencodex - -# 最初に sudo でインストールした場合は sudo を維持してください: -sudo npm install -g --allow-scripts=bun @bitkyc08/opencodex -``` -::: - -両方のコマンドが `PATH` にあることを確認します: - -```bash -ocx --version -opencodex --version +bun install +bun run build:gui +bun run src/cli/index.ts start ``` -### 配布チャネル - -安定チャネルの `latest` にも ChatGPT、OpenAI API キー、OpenRouter、実験段階の Cursor 経路のための -GPT-5.6 Sol/Terra/Luna カタログ情報がすでに含まれています。ただしモデルの利用権まで付与されるわけでは -ありません。まだ正式配布されていない opencodex ビルドを試す場合のみ preview チャネルを使ってください: +レジストリパッケージは現在公開されていません。このチェックアウトでは、`ccx <args>` を +`bun run src/cli/index.ts <args>` に置き換えて実行します。別のターミナルでランタイムを確認します: ```bash -npm install -g @bitkyc08/opencodex@preview -ocx update --tag preview +bun run src/cli/index.ts --version ``` -## ソースから実行 +## 開発モード -opencodex 自体を直接修正しながら作業するには: +UI を編集するときはプロキシとダッシュボードを別々に実行します: ```bash -git clone https://github.com/pavelhov/opencodex.git -cd opencodex -bun install bun run dev:proxy # 開発モードでプロキシ API を起動 (src/cli/index.ts start) bun run dev:gui # ダッシュボード dev サーバーを起動 (別ターミナル) ``` -`bun run dev` は `bun run dev:proxy` のエイリアスとして残っています。プロキシ API は `/healthz`、 +`bun run dev` は `bun run dev:proxy` のエイリアスです。プロキシ API は `/healthz`、 `/v1/responses`、`/api/*` を公開し、`GET /` は `bun run build:gui` が `gui/dist` を生成した 後にのみパッケージされたダッシュボードを提供します。ダッシュボードを編集する際は `bun run dev:gui` でフロントエンドを -別途実行してください。 +別途実行してください。macOS コンパニオンは同じチェックアウトから `bun run test:macos && bun run build:macos` でビルドでき、ソースビルドは `dist/macos/CodexCommander.app` に生成されます。 ## 生成されるもの -opencodex の状態ファイルは `$OPENCODEX_HOME`(デフォルト `~/.opencodex`)の下に、Codex 連携ファイルは +CodexCommander の状態ファイルは `$CODEXCOMMANDER_HOME`(デフォルト `~/.codexcommander`)の下に、Codex 連携ファイルは `$CODEX_HOME`(デフォルト `~/.codex`)の下に保存されます。 | パス | 用途 | --- | --- | -| `$OPENCODEX_HOME/config.json` | プロバイダー、デフォルトプロバイダー、ポート、オプション。 | -| `$OPENCODEX_HOME/ocx.pid` | 実行中のプロキシの PID(単一インスタンスガード)。 | -| `$OPENCODEX_HOME/runtime-port.json` | 自動で選んだ代替ポートを含む現在の PID、ホスト名、ポート。 | -| `$OPENCODEX_HOME/auth.json` | 保存された OAuth 認証情報(`ocx login` 時)。 | -| `$OPENCODEX_HOME/catalog-backup*.json` | opencodex が変更する前に作成した Codex モデルカタログのバックアップ。 | -| `$CODEX_HOME/config.toml` | ローカル専用構成では opencodex が管理するルート `openai_base_url` を追加します。ローカル以外のアドレスにバインドする場合は Codex が API 認証ヘッダーを送れるよう `model_provider = "opencodex"` と `[model_providers.opencodex]` を使います。 | -| `$CODEX_HOME/opencodex.config.toml` | デフォルト Codex 設定と一緒に生成される参考用 fallback プロファイル。 | -| `$CODEX_HOME/opencodex-catalog.json` | Codex が使うネイティブおよびルーティングモデルカタログ。 | +| `$CODEXCOMMANDER_HOME/config.json` | プロバイダー、デフォルトプロバイダー、ポート、オプション。 | +| `$CODEXCOMMANDER_HOME/codexcommander.pid` | 実行中のプロキシの PID(単一インスタンスガード)。 | +| `$CODEXCOMMANDER_HOME/runtime-port.json` | 自動で選んだ代替ポートを含む現在の PID、ホスト名、ポート。 | +| `$CODEXCOMMANDER_HOME/auth.json` | 保存された OAuth 認証情報(`ccx login` 時)。 | +| `$CODEXCOMMANDER_HOME/catalog-backup-<catalog-id>.json` | CodexCommander が変更する前に作成した Codex モデルカタログのバックアップ。 | +| `$CODEX_HOME/config.toml` | ローカル専用構成では CodexCommander が管理するルート `openai_base_url` を追加します。ローカル以外のアドレスにバインドする場合は Codex が API 認証ヘッダーを送れるよう `model_provider = "codexcommander"` と `[model_providers.codexcommander]` を使います。 | +| `$CODEX_HOME/codexcommander.config.toml` | デフォルト Codex 設定と一緒に生成される参考用 fallback プロファイル。 | +| `$CODEX_HOME/codexcommander-catalog.json` | Codex が使うネイティブおよびルーティングモデルカタログ。 | :::note -opencodex は決して Codex 設定を削除しません。すべての注入は元に戻せます — `ocx stop`、`ocx restore`、 -または `ocx eject` は opencodex が追加した行だけを正確に削除し、ネイティブ Codex を復元します。 +CodexCommander は決して Codex 設定を削除しません。すべての注入は元に戻せます — `ccx stop`、`ccx restore`、 +または `ccx eject` は CodexCommander が追加した行だけを正確に削除し、ネイティブ Codex を復元します。 ::: ## 次へ diff --git a/docs-site/src/content/docs/ja/getting-started/quickstart.md b/docs-site/src/content/docs/ja/getting-started/quickstart.md index 4e39921f90..01a322ea9d 100644 --- a/docs-site/src/content/docs/ja/getting-started/quickstart.md +++ b/docs-site/src/content/docs/ja/getting-started/quickstart.md @@ -1,6 +1,6 @@ --- title: クイックスタート -description: 最初のプロバイダーを構成し、3 つのコマンドで OpenAI Codex を opencodex 経由でルーティングします。 +description: 最初のプロバイダーを構成し、3 つのコマンドで OpenAI Codex を CodexCommander 経由でルーティングします。 --- このガイドでは、新規インストールから非 OpenAI モデルに対して Codex を実行するまでを説明します。 @@ -8,51 +8,51 @@ description: 最初のプロバイダーを構成し、3 つのコマンドで O ## 1. セットアップウィザードを実行します ```bash -ocx init +ccx init ``` -`ocx init` では次の手順を説明します。 +`ccx init` では次の手順を説明します。 1. **プロバイダーを選択してください** — 76 個の組み込みレジストリプリセットのいずれか、または `custom` を選択してベース URL とアダプターを入力します。 2. **API キー** — キーを貼り付けるか、`${ANTHROPIC_API_KEY}` のような環境変数を参照します。 3. **デフォルト モデル** — キー、ローカル、カスタム プロバイダーの場合は、プリセットを受け入れるか、モデル ID を入力します。 4. **プロキシ ポート** — デフォルトは `10100` です。 -5. **Codex に挿入しますか?** - 通常のループバック設定では、opencodex はルート `openai_base_url` を +5. **Codex に挿入しますか?** - 通常のループバック設定では、CodexCommander はルート `openai_base_url` を `$CODEX_HOME/config.toml` (デフォルトは `~/.codex/config.toml`) なので、Codex の組み込み `openai` プロバイダーはプロキシをターゲットにします。リモート/LAN バインドでは、代わりに API 認証ヘッダーを持つ専用プロバイダー エントリを使用します。 -6. **自動起動シムをインストールしますか?** — 有効にすると、`codex` を起動すると、最初に `ocx ensure` が実行されます。 +6. **自動起動シムをインストールしますか?** — 有効にすると、`codex` を起動すると、最初に `ccx ensure` が実行されます。 -結果は `$OPENCODEX_HOME/config.json` (デフォルトは `~/.opencodex/config.json`) に保存されます。 +結果は `$CODEXCOMMANDER_HOME/config.json` (デフォルトは `~/.codexcommander/config.json`) に保存されます。 :::note[GPT-5.6 ロールアウト エントリ] -現在の安定版リリースでは、ChatGPT パススルー、OpenAI API キー、OpenRouter、実験用 Cursor アダプター用に GPT-5.6 Sol/Terra/Luna をシードしています。これらは、上流アカウントがアクセス権を持っている場合にのみ機能します。 OpenAI API キーと OpenRouter プリセットは、372,000 トークンの使用可能なコンテキスト ウィンドウをアドバタイズします。カーソルは独自のアダプターのメタデータを保持します。 +現在のソースツリーでは、ChatGPT パススルー、OpenAI API キー、OpenRouter、実験用 Cursor アダプター用に GPT-5.6 Sol/Terra/Luna をシードしています。これらは、上流アカウントがアクセス権を持っている場合にのみ機能します。 OpenAI API キーと OpenRouter プリセットは、372,000 トークンの使用可能なコンテキスト ウィンドウをアドバタイズします。Cursor は独自のアダプターのメタデータを保持します。 ::: ## 2.プロキシを開始します ```bash -ocx start # defaults to port 10100 -ocx start --port 8080 +ccx start # defaults to port 10100 +ccx start --port 8080 ``` -開始時、opencodex: +開始時、CodexCommander: -- PID を `~/.opencodex/ocx.pid` に書き込みます (そして 2 回起動を拒否します)。 +- PID を `~/.codexcommander/codexcommander.pid` に書き込みます (そして 2 回起動を拒否します)。 - プロバイダーがサポートするライブ モデルを検出し、**ネイティブ エントリとルーティングされたエントリを同期します Codex のモデル カタログ**、 - `http://localhost:<port>/v1`で聴いています。 -要求されたポートがビジーの場合、`ocx start` は空きポートを選択し、それを `runtime-port.json` に記録し、ライブ リスナーを使用するように Codex を更新します。 +要求されたポートがビジーの場合、`ccx start` は空きポートを選択し、それを `runtime-port.json` に記録し、ライブ リスナーを使用するように Codex を更新します。 確認してください: ```bash -ocx status -ocx gui # open the dashboard on the live port +ccx status +ccx gui # open the dashboard on the live port ``` ## 3.Codexを使用する -Codex は透過的に opencodex と通信するようになりました。 +Codex は透過的に CodexCommander と通信するようになりました。 ```bash codex "Refactor this function for readability" @@ -67,16 +67,16 @@ codex -m "ollama-cloud/glm-5.2" "Write a SQL migration" ## サブエージェント モデルの選択 (オプション) -新しい設定には、Codex のサブエージェント ピッカーの 5 つのネイティブ モデル、`gpt-5.5`、`gpt-5.6-sol`、`gpt-5.6-terra`、`gpt-5.6-luna`、および `gpt-5.4-mini` が含まれています。 `ocx gui` を開いて、最大 5 つのネイティブ モデルまたはルーティング モデルを置換または並べ替えます。ダッシュボードでは、優先サブエージェント モデルと推論負荷を 1 つ設定することもできます。 v1/base/v2 を選択し、ガイダンス、ネイティブのデフォルト、およびフォールバックがいつ適用されるかを理解するには、[サブエージェントサーフェス](/guides/sub-agent-surface/) を参照してください。 +新しい設定には、Codex のサブエージェント ピッカーの 5 つのネイティブ モデル、`gpt-5.5`、`gpt-5.6-sol`、`gpt-5.6-terra`、`gpt-5.6-luna`、および `gpt-5.4-mini` が含まれています。 `ccx gui` を開いて、最大 5 つのネイティブ モデルまたはルーティング モデルを置換または並べ替えます。ダッシュボードでは、優先サブエージェント モデルと推論負荷を 1 つ設定することもできます。 v1/base/v2 を選択し、ガイダンス、ネイティブのデフォルト、およびフォールバックがいつ適用されるかを理解するには、[サブエージェントサーフェス](/guides/sub-agent-surface/) を参照してください。 ## キーを貼り付ける代わりにログインする -一部のプロバイダーは実際のアカウントログインをサポートします。OpenCodex 所有の OAuth +一部のプロバイダーは実際のアカウントログインをサポートします。CodexCommander 所有の OAuth 認証情報は自動更新され、リンクされた Grok/Kimi ネイティブ CLI セッションは CLI 所有のままです。 ```bash -ocx login xai # or: anthropic, kimi, kiro, google-antigravity, cursor -ocx logout xai +ccx login xai # or: anthropic, kimi, kiro, google-antigravity, cursor +ccx logout xai ``` OpenAI 自体には **キーは必要ありません**。デフォルトのプロバイダーは既存の `codex login` 認証情報をそのまま転送します ([プロバイダー](/guides/providers/) を参照)。 @@ -84,9 +84,9 @@ OpenAI 自体には **キーは必要ありません**。デフォルトのプ ## 停止と復元 ```bash -ocx stop # stop the proxy and restore native Codex -ocx restore # restore native Codex without stopping (alias: ocx eject) -ocx restore back # route Codex through the still-running proxy again +ccx stop # stop the proxy and restore native Codex +ccx restore # restore native Codex without stopping (alias: ccx eject) +ccx restore back # route Codex through the still-running proxy again ``` ## 次 diff --git a/docs-site/src/content/docs/ja/guides/claude-code.md b/docs-site/src/content/docs/ja/guides/claude-code.md index 546204648f..0d88ea0bd8 100644 --- a/docs-site/src/content/docs/ja/guides/claude-code.md +++ b/docs-site/src/content/docs/ja/guides/claude-code.md @@ -1,19 +1,19 @@ --- title: Claude Code の使い方 -description: Claude Code でルーティングされたすべてのモデルを使います。opencodex は同じポートで Anthropic Messages API とゲートウェイモデル検索を提供します。 +description: Claude Code でルーティングされたすべてのモデルを使います。CodexCommander は同じポートで Anthropic Messages API とゲートウェイモデル検索を提供します。 --- -opencodex は `/v1/responses` と共に `POST /v1/messages`(`count_tokens` も)を提供します。そのため Claude +CodexCommander は `/v1/responses` と共に `POST /v1/messages`(`count_tokens` も)を提供します。そのため Claude Code から OAuth ログイン、アカウントプール、キーフェイルオーバー、サイドカーを含むすべてのルーティングプロバイダーを別途の 認証作業なしで使えます。 ## クイックスタート ```bash -ocx claude +ccx claude ``` -`ocx claude` はプロキシが実行中か確認した後、環境を接続して Claude Code を実行します。 +`ccx claude` はプロキシが実行中か確認した後、環境を接続して Claude Code を実行します。 | 変数 | 値 | --- | --- | @@ -21,26 +21,23 @@ ocx claude | `ANTHROPIC_AUTH_TOKEN` | プロキシに API キーが必要なときのみ設定します。それ以外は設定せず、claude.ai ログイン(サブスクリプション + コネクター)を維持します | | `CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY` | `1` (デフォルトの `/model` ピッカーのモデル検索) | | `CLAUDE_CODE_AUTO_COMPACT_WINDOW` | 自動コンテキスト圧縮のしきい値(デフォルト `350000`)。自動コンテキストがオンのときのみ注入します | -| `ANTHROPIC_MODEL` | `claudeCode.model` (任意) | -| `ANTHROPIC_DEFAULT_HAIKU_MODEL` | `claudeCode.tierModels.haiku ?? claudeCode.smallFastModel` (任意、従来の `ANTHROPIC_SMALL_FAST_MODEL` もサポート) | -| `ANTHROPIC_DEFAULT_{OPUS,SONNET,FABLE}_MODEL` | `claudeCode.tierModels.*` (任意) | -| `CLAUDE_CODE_ALWAYS_ENABLE_EFFORT` | `alwaysEnableEffort` がオンなら `1` (条件付き) | -| `CLAUDE_CODE_MAX_CONTEXT_TOKENS` / `DISABLE_COMPACT` | `maxContextTokens` が設定された場合の従来コンテキスト上書き値 (条件付き) | -直接 export した変数が常に優先します。追加引数はそのまま渡されます: `ocx claude -p "hello"`。 +| `ANTHROPIC_DEFAULT_HAIKU_MODEL` / `ANTHROPIC_SMALL_FAST_MODEL` | 設定時の `claudeCode.smallFastModel` | + +直接 export した変数が常に優先します。追加引数はそのまま渡されます: `ccx claude -p "hello"`。 ## システム環境統合(macOS) -`claudeCode.systemEnv` を `true` に設定すると(デフォルト: **オフ`)`ocx start` が `launchctl setenv` を +`claudeCode.systemEnv` を `true` に設定すると(デフォルト: **オフ`)`ccx start` が `launchctl setenv` を 使い `ANTHROPIC_BASE_URL` と関連 Claude Code 環境変数をシステム全体に注入します。そのため新規 -ターミナルのウィンドウとタブでは `ocx claude` ラッパーなしでも通常の `claude` コマンドがプロキシを経由します。すでに開いている +ターミナルのウィンドウとタブでは `ccx claude` ラッパーなしでも通常の `claude` コマンドがプロキシを経由します。すでに開いている シェルには適用されないので開き直す必要があります。 -`ocx stop` とプロキシ終了は**注入されたキーを解除します**。以前の値を復元せず、opencodex が -注入したキーのみ削除します。プロキシは `~/.opencodex/claude-env.sh` も書き出し、`ocx start` はこのファイルを +`ccx stop` とプロキシ終了は**注入されたキーを解除します**。以前の値を復元せず、CodexCommander が +注入したキーのみ削除します。プロキシは `~/.codexcommander/claude-env.sh` も書き出し、`ccx start` はこのファイルを 自動で読み込む `.zshrc` source hook をインストールします。 設定で `claudeCode.systemEnv: false` に指定するか GUI トグルでオフにできます。この機能は macOS -専用で、他のプラットフォームでは `ocx claude` を使ってください。 +専用で、他のプラットフォームでは `ccx claude` を使ってください。 ## ネイティブ Claude パススルー(サブスクリプション直接接続) @@ -50,12 +47,12 @@ ocx claude ネイティブ状態で維持され、同じセッションでピッカーエイリアスを使ってルーティングモデルも引き続き使えます。 **ヘッダー処理:** hop-by-hop ヘッダーと `host`、`content-length`、`accept-encoding`、 -`x-opencodex-api-key`、`origin` は転送前に削除します。それ以外のヘッダー(`anthropic-beta`、 +`x-codexcommander-api-key`、`origin` は転送前に削除します。それ以外のヘッダー(`anthropic-beta`、 `anthropic-version` を含む)はそのまま転送します。 次の 4 つの条件を**すべて**満たすとパススルーが動作します。`nativePassthrough` が `false` でなく、 モデル名が `claude` または `anthropic` で始まり、bearer または `x-api-key` が `sk-ant-` で -始まり、エイリアス/モデルマップ解決結果が変更されていない同じモデルであること。そのため `ocx claude` を +始まり、エイリアス/モデルマップ解決結果が変更されていない同じモデルであること。そのため `ccx claude` を 使うとき "claude.ai connectors are disabled" 警告ももう表示されません。 `claudeCode.nativePassthrough: false` でオフにでき、`claudeCode.anthropicBaseUrl` で別のアドレスを @@ -65,28 +62,25 @@ ocx claude Claude Code 2.1.129 以降は `GET /v1/models?limit=1000` でゲートウェイモデルを探し、デフォルトの `/model` ピッカーの "From gateway" 項目に表示します。ピッカーは `claude` または `anthropic` で始まる ID のみ -受け付けるため、opencodex はルーティングモデルを安定で元に戻せるエイリアスとして公開します。 +受け付けるため、CodexCommander はルーティングモデルを安定で元に戻せるエイリアスとして公開します。 | 画面 | 形式 | 例 | | --- | --- | --- | -| Claude Code CLI | `claude-ocx-<provider>--<model>` (plain) または `claude-ocx2-…` (escaped) | `claude-ocx-native--gpt-5.6-sol` | +| Claude Code CLI | `claude-ccx2-<provider>--<model>` (plain) または `claude-ccx2-…` (escaped) | `claude-ccx2-native--gpt-5.6-sol` | | Claude Desktop 3P | `claude-opus-4-8-<code>` (3 桁の base36 ハッシュ) | `claude-opus-4-8-ncb` | プロキシはリクエストごとに系列を選びます。`?ids=cli` または `?ids=desktop` が優先し、指定しないと `claude-code/*` user-agent には読みやすい CLI 形式を、他のクライアントには Desktop ハッシュを -提供します。両系列は継続してデコードできるため、どちらの形式でも `settings.json` に保存したモデルは -引き続き動作します。 +提供します。現在の両系列は実行中のエイリアスレジストリで解決されます。 Claude Desktop のフッターピッカーで実行中の 3P 会話のモデルが切り替わらない場合は、その会話で -`/model <id>` を使用してください。OpenCodex はピッカーの状態を直接参照できず、各リクエストに +`/model <id>` を使用してください。CodexCommander はピッカーの状態を直接参照できず、各リクエストに 含まれるモデル ID をルーティングします。結果は **Logs → requestedModel** で確認できます。 **エイリアス構文ルール:** provider には `/` や `--` を含められず `native` と同じでもいけません。 -`/` も `~` も含まない plain な model ID は v1 接頭辞 `claude-ocx-…` のままです。`/` または `~` を含む -model ID は v2 接頭辞 `claude-ocx2-…` で発行し、エスケープします(`/` → `~s`、`~` → `~t`)。例: -`openrouter/anthropic/claude-opus-4-8` → `claude-ocx2-openrouter--anthropic~sclaude-opus-4-8`。 -v1 エイリアスはリテラルにデコードします(歴史的に model ID に含まれていた 2 文字列 `~s` / `~t` も保持)。 -v2 エイリアスはエスケープを展開します。読みやすい形式で表現できないルートはハッシュエイリアスに +現在の `claude-ccx2-…` エンコードでは `/` を `~s`、`~` を `~t` にエスケープします。例: +`openrouter/anthropic/claude-opus-4-8` → `claude-ccx2-openrouter--anthropic~sclaude-opus-4-8`。 +読みやすい形式で表現できないルートはハッシュエイリアスに 置き換えます。モデル ID には `--` を含め**られます**(解析時は最初の `--` だけを基準に分割します)。 `--` を含むネイティブスラッグはハッシュ形式に置き換えます。 @@ -113,11 +107,10 @@ Claude Code は未知モデルのコンテキストを 200k トークンとし 2. `CLAUDE_CODE_AUTO_COMPACT_WINDOW`(デフォルト `350000`、範囲 `100000`–`1000000`)を注入し、該当 地点で会話を自動要約します。 -設定状態は 3 つです。 +設定状態は 2 つです。 - **なし / `true`:** 使用(デフォルト) - **`false`:** 使用不可。標識も付かず圧縮ウィンドウも注入しません -- **従来の `maxContextTokens` 設定:** 自動コンテキストを自動でオフにします Claude ページで圧縮値を調整できます。**警告:** モデルの実際のコンテキストウィンドウより大きく上げると 要約を開始する前にチャットエラーが発生します。 @@ -127,38 +120,36 @@ Claude ページで圧縮値を調整できます。**警告:** モデルの実 ### 実モデル環境 -`effectiveModelEnv` は `ocx claude` / システム環境 / シェルファイルが注入するスロット 6 つを計算します。 -`ANTHROPIC_MODEL`、4 つの `ANTHROPIC_DEFAULT_{OPUS,SONNET,HAIKU,FABLE}_MODEL`、従来 -`ANTHROPIC_SMALL_FAST_MODEL` です。実際の Haiku 値は `tierModels.haiku ?? smallFastModel` で、 -両 Haiku 変数に入ります。 +`effectiveModelEnv` は `ccx claude`、システム環境、シェルファイルが注入する 2 つのヘルパースロット +`ANTHROPIC_DEFAULT_HAIKU_MODEL` と `ANTHROPIC_SMALL_FAST_MODEL` を計算します。どちらにも +`claudeCode.smallFastModel` が入ります。 -`tierModels.haiku` と `smallFastModel` の両方がない場合、OpenCodex は 2 つのヘルパーモデル変数を未設定のままにします。その後 Claude Code がネイティブのヘルパーモデル(現在は Sonnet)を選択し、ネイティブプロバイダーで料金が発生する可能性があります。 +`smallFastModel` がない場合、CodexCommander は 2 つのヘルパーモデル変数を未設定のままにします。その後 Claude Code がネイティブのヘルパーモデルを選択し、ネイティブプロバイダーで料金が発生する可能性があります。 ## ロスターエージェント(injectAgents) -`ocx claude` とシステム環境デーモンは推奨サブエージェントロスター(Subagents タブ、最大 5 モデル)と -`ocx-self` を `~/.claude/agents/ocx-*.md` に同期します。 +`ccx claude` とシステム環境デーモンは推奨サブエージェントロスター(Subagents タブ、最大 5 モデル)と +`ccx-self` を `~/.claude/agents/ccx-*.md` に同期します。 -- **`ocx-self`** は `/model` ピッカーのデフォルトを固定し、値がない場合は `claudeCode.model` を使います。 - 両方ない場合は作成しません。モデル継承は使いません。 -- 各エージェント本文には `<!-- ocx-route: <model> -->` ディレクティブが含まれます。プロキシはこのディレクティブで +- **`ccx-self`** は `/model` ピッカーのデフォルトを固定します。ピッカーのデフォルトがない場合は作成せず、モデル継承も使いません。 +- 各エージェント本文には `<!-- ccx-route: <model> -->` ディレクティブが含まれます。プロキシはこのディレクティブで 実際のルートを固定します。そのため Agent ツールの `model` 引数は機能せず、プレースホルダとして `"haiku"` を渡してください。 - frontmatter にはエイリアスが入り、ルーティングはディレクティブに従います。 -- `generated-by: opencodex` が含まれる標識検証済み `ocx-*.md` ファイルのみ上書きまたは整理します。 +- `generated-by: codexcommander` が含まれる標識検証済み `ccx-*.md` ファイルのみ上書きまたは整理します。 ユーザー作成のエージェントは触りません。 - ファイルごとに原子的に同期します(write + rename)。 - `enabled: false` または `injectAgents: false` を設定すると所有権確認済みの定義をすべて整理します。 - GUI PUT とロスター変更は即座に再同期し、launcher/system-env は実行時に同期します。 -ディスパッチ例: `subagent_type: "ocx-gpt-5-6-sol"`。1M をサポートする対象には `[1m]` が自動で +ディスパッチ例: `subagent_type: "ccx-gpt-5-6-sol"`。1M をサポートする対象には `[1m]` が自動で 付きます。 ## バンドルスキルの省略(blockedSkills) Claude Code のバンドル `claude-api` スキルは Anthropic ドキュメント約 840KB(約 136k トークン)を注入し、 Claude モデルに言及すると自動実行されます。ルーティングモデルはこのバンドルで学習されていないため、 -opencodex はデフォルトで**ルーティングされた**リクエストのスキル内容を短いスタブに差し替えます。ネイティブ +CodexCommander はデフォルトで**ルーティングされた**リクエストのスキル内容を短いスタブに差し替えます。ネイティブ Anthropic パススルーはそのまま維持します。 **2 つの配信形式を処理します。** @@ -190,7 +181,7 @@ Anthropic パススルーはそのまま維持します。 ## サイドカーマトリクス: ウェブ検索と画像理解 -ルーティングモデルごとに使えるホスト型ツールと画像サポート範囲が異なります。opencodex はメインモデルが +ルーティングモデルごとに使えるホスト型ツールと画像サポート範囲が異なります。CodexCommander はメインモデルが 応答する前に不足機能を次の 2 つのサイドカーで補います。 - **ウェブ検索サイドカー**は実際のホスト型検索を実行した後、回答と出典をツール結果としてルーティングモデルに @@ -316,7 +307,7 @@ role、`tool_use_id` のない `tool_result`、id/name のない `tool_use`、na ## デバッグキャプチャ -`ocx debug claude on|off|status|reset`、`OCX_CLAUDE_DEBUG=1` または +`ccx debug claude on|off|status|reset`、`CCX_CLAUDE_DEBUG=1` または `PUT /api/debug {"claude": true}` で入力キャプチャを制御します。`GET /api/claude/inbound-debug` は `{enabled, entries}` を返します(最新項目から、20 件の循環バッファ)。 @@ -332,7 +323,7 @@ role、`tool_use_id` のない `tool_result`、id/name のない `tool_use`、na ラベルはすべての言語で意図的に同じです。ページには次の項目が表示されます。 - 入力遮断スイッチ(使用トグル) -- クイックスタート(`ocx claude`)と手動環境ブロック +- クイックスタート(`ccx claude`)と手動環境ブロック - Fast Mode セレクター(Auto / ON / OFF) - 自動コンテキストトグルと圧縮しきい値ドロップダウン - サブエージェント自動登録トグル @@ -347,8 +338,8 @@ ID、エイリアス、ポートを返します。`PUT /api/claude-code` は部 **Claude Code に "Did 0 searches" と表示される** — 現在バージョンは完了した Responses `web_search_call` を Anthropic の `server_tool_use` と `web_search_tool_result` ブロック対に変換し、 -`usage.server_tool_use.web_search_requests` も同時に記録します。検索は行われたのに 0 回と表示される古い -バージョンを使っている場合は opencodex を更新してください。 +`usage.server_tool_use.web_search_requests` も同時に記録します。検索は行われたのに 0 回と表示される場合は、 +実行中の CodexCommander プロセスが現在のチェックアウトから再ビルドされたものか確認してください。 **サイドカーが起動しない** — `backend: "openai"` の場合 ChatGPT ログインと有効化された `authMode: "forward"` プロバイダーが両方あるか確認してください。`backend: "anthropic"` の場合保存された @@ -356,27 +347,27 @@ Anthropic OAuth アクティブアカウントが `needsReauth` 状態でない Anthropic バックエンドを明示すると意図的に失敗後停止します。 **"claude.ai connectors are disabled"** — シェルに `ANTHROPIC_API_KEY` または -`ANTHROPIC_AUTH_TOKEN` が設定されています。`ocx claude` は意図的に `ANTHROPIC_API_KEY` を -設定しないため、直接 export していれば解除してください。`ocx claude` 使用時は +`ANTHROPIC_AUTH_TOKEN` が設定されています。`ccx claude` は意図的に `ANTHROPIC_API_KEY` を +設定しないため、直接 export していれば解除してください。`ccx claude` 使用時は `ANTHROPIC_BASE_URL`、検索、自動コンテキスト、設定されたモデルスロットを注入しますが `ANTHROPIC_API_KEY` は絶対に注入しません。 **/model ピッカーにモデルが表示されない** — `CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1` が -設定されているか確認してください(`ocx claude` では自動)。`ocx claude` を実行して +設定されているか確認してください(`ccx claude` では自動)。`ccx claude` を実行して `~/.claude/cache/gateway-models.json` のゲートウェイモデルキャッシュを更新してください。 `claudeCode.enabled` が `false` でないかも確認してください。 **ポート変更後に古い環境が残る** — プロキシポートが変わった場合、既存シェルの -`ANTHROPIC_BASE_URL` が古い値の可能性があります。新規ターミナルを開くか `ocx claude` を再実行してください。 +`ANTHROPIC_BASE_URL` が古い値の可能性があります。新規ターミナルを開くか `ccx claude` を再実行してください。 **大型モデルなのにコンテキストが 200k に制限される** — ピッカーで `[1m]` 変種を選ぶか、デフォルトでオンの 自動コンテキストを使ってください。ピッカーに `[1m]` 行がない場合はモデルの公式コンテキストウィンドウが 自動圧縮しきい値より小さい可能性があります。 **スキル呼び出し時のトークン数が多い** — バンドル `claude-api` スキル(約 136k トークン)は Claude モデルに -言及すると自動で読み込まれます。ネイティブパススルーでは正常で、ルーティングモデルでは opencodex が +言及すると自動で読み込まれます。ネイティブパススルーでは正常で、ルーティングモデルでは CodexCommander が デフォルトでスタブに差し替えます(`blockedSkills: ["claude-api"]`)。 -**サブエージェントが誤ったモデルにディスパッチされる** — ロスターエージェント(`ocx-*`)は Agent ツールの `model` -引数ではなく `<!-- ocx-route: ... -->` ディレクティブを使います。ディレクティブが希望ルートと一致するか確認し、 +**サブエージェントが誤ったモデルにディスパッチされる** — ロスターエージェント(`ccx-*`)は Agent ツールの `model` +引数ではなく `<!-- ccx-route: ... -->` ディレクティブを使います。ディレクティブが希望ルートと一致するか確認し、 モデルプレースホルダとして `"haiku"` を渡してください。 diff --git a/docs-site/src/content/docs/ja/guides/codex-app-models.md b/docs-site/src/content/docs/ja/guides/codex-app-models.md index 17e1ecac4c..c1faa45ac0 100644 --- a/docs-site/src/content/docs/ja/guides/codex-app-models.md +++ b/docs-site/src/content/docs/ja/guides/codex-app-models.md @@ -1,11 +1,11 @@ --- title: Codex App モデル ピッカー -description: opencodex モデルが、共有 Codex カタログを通じて Codex App、Codex CLI、Codex TUI にどのように表示されるか。 +description: CodexCommander モデルが、共有 Codex カタログを通じて Codex App、Codex CLI、Codex TUI にどのように表示されるか。 --- -opencodex は Codex アプリにパッチを適用しません。 Codex CLI/TUI が既に使用しているのと同じ Codex 設定とモデル カタログを書き込みます。 Codex アプリはその共有状態を読み取るため、ルーティングされたモデルは通常の Codex カタログ エントリとしてアプリのモデル ピッカーに表示されます。 +CodexCommander は Codex アプリにパッチを適用しません。 Codex CLI/TUI が既に使用しているのと同じ Codex 設定とモデル カタログを書き込みます。 Codex アプリはその共有状態を読み取るため、ルーティングされたモデルは通常の Codex カタログ エントリとしてアプリのモデル ピッカーに表示されます。 -OpenAI エントリには、ネイティブ Codex ログインと、名前空間付きの `openai-apikey/<model>` API キーという 2 つの資格情報ルートがあります。`codexAccountMode` だけを Pool と Direct の間で変更しても、ピッカー ID は変わりません。ただし、`codexAccountNamespaces` に対象アカウントが存在する selector がある場合、opencodex は対応するアカウントごとに `<selector>/<native-openai-model>` 行を追加し、ピッカーでは bare native 行を非表示にします。Selector 名はユーザーが決める公開ラベルであり、組み込みのアカウント role の意味はありません。`selector` 付きの行を選択すると、対応付けられたアカウントだけが使用され、アクティブな Pool アカウントは変更されません。対象を利用できない場合、別のアカウントへ切り替えずにリクエストが失敗します。詳しくは [Codex アカウントの明示的な selector](/reference/configuration/routing/#exact-codex-account-selectors) を参照してください。API GPT-5.6 エントリは 1,050,000 コンテキスト / 922,000 最大入力を使用し、`*-pro` ピッカー ID は `reasoning.mode: "pro"` のベース ワイヤ モデルに解決されますが、ログ、使用状況、およびピッカー状態は仮想 ID を保持します。 API カタログは、`gpt-5.5`、`gpt-5.6`、Sol/Terra/Luna、およびそれらの 3 つの Pro 仮想 ID の 8 つの ID に固定されています。汎用の `gpt-5.6-pro` エイリアスはありません。コンパクト リクエストは、選択された層を保持しますが、推論オブジェクトなしで基本モデルを送信します。 +OpenAI エントリには、ネイティブ Codex ログインと、名前空間付きの `openai-apikey/<model>` API キーという 2 つの資格情報ルートがあります。`codexAccountMode` だけを Pool と Direct の間で変更しても、ピッカー ID は変わりません。ただし、`codexAccountNamespaces` に対象アカウントが存在する selector がある場合、CodexCommander は対応するアカウントごとに `<selector>/<native-openai-model>` 行を追加し、ピッカーでは bare native 行を非表示にします。Selector 名はユーザーが決める公開ラベルであり、組み込みのアカウント role の意味はありません。`selector` 付きの行を選択すると、対応付けられたアカウントだけが使用され、アクティブな Pool アカウントは変更されません。対象を利用できない場合、別のアカウントへ切り替えずにリクエストが失敗します。詳しくは [Codex アカウントの明示的な selector](/reference/configuration/routing/#exact-codex-account-selectors) を参照してください。API GPT-5.6 エントリは 1,050,000 コンテキスト / 922,000 最大入力を使用し、`*-pro` ピッカー ID は `reasoning.mode: "pro"` のベース ワイヤ モデルに解決されますが、ログ、使用状況、およびピッカー状態は仮想 ID を保持します。 API カタログは、`gpt-5.5`、`gpt-5.6`、Sol/Terra/Luna、およびそれらの 3 つの Pro 仮想 ID の 8 つの ID に固定されています。汎用の `gpt-5.6-pro` エイリアスはありません。コンパクト リクエストは、選択された層を保持しますが、推論オブジェクトなしで基本モデルを送信します。 ピッカー ID で資格情報ルートを明示的に選択します。Pool/Direct は Providers ページで変更します。以下の `<selector>` は、`codexAccountNamespaces` で対応付けたユーザー定義の公開ラベルです。 @@ -15,21 +15,15 @@ gpt-5.6-sol # Pool または Direct による bare Codex openai-apikey/gpt-5.6-sol # API key ``` -新規インストールと保存モードのない設定は、デフォルトでプールになります。現在の設定はマーカー 2 を使用し、出荷された v1 ソースを `~/.opencodex/config.json.pre-openai-tiers-v2.bak` に保持します。次のようにして復元します。 - -```sh -cp ~/.opencodex/config.json.pre-openai-tiers-v2.bak ~/.opencodex/config.json -``` - -以前の v1 の 3 プロバイダー設定は、単一のオプション対応行に自動的に移行されます。 +新規インストールと保存モードのない設定は、デフォルトで Pool になります。 ## 統合パス -`ocx init`、`ocx start`、および `ocx sync` は、共有 Codex 設定とカタログをプロキシに接続します。設定の挿入、カタログの同期、シム、WebSocket フォールバック、および復元の仕組みについては、[Codexの統合](/guides/codex-integration/) を参照してください。 +`ccx init`、`ccx start`、および `ccx sync` は、共有 Codex 設定とカタログをプロキシに接続します。設定の挿入、カタログの同期、シム、WebSocket フォールバック、および復元の仕組みについては、[Codexの統合](/guides/codex-integration/) を参照してください。 ## 配線されたモデルが表示される理由 -Codex のモデル ピッカーは、Codex の形をしたカタログ エントリを想定しています。 opencodex は、ネイティブ Codex モデル テンプレートを複製し、ルーティングされたモデル ID を置き換えることによって、ルーティングされたエントリを構築します。 +Codex のモデル ピッカーは、Codex の形をしたカタログ エントリを想定しています。 CodexCommander は、ネイティブ Codex モデル テンプレートを複製し、ルーティングされたモデル ID を置き換えることによって、ルーティングされたエントリを構築します。 ```text slug = "anthropic/claude-sonnet-..." @@ -37,11 +31,11 @@ display_name = "anthropic/claude-sonnet-..." visibility = "list" ``` -クローンは、推論レベル、シェル タイプ、API サポート フラグ、基本命令などの厳密なパーサー フィールドを保持します。次に、opencodex は、OpenAI サービス層メタデータなど、ルートが尊重できないネイティブのみの機能を削除します。 +クローンは、推論レベル、シェル タイプ、API サポート フラグ、基本命令などの厳密なパーサー フィールドを保持します。次に、CodexCommander は、OpenAI サービス層メタデータなど、ルートが尊重できないネイティブのみの機能を削除します。 ## 現在の安定したモデルの範囲 -ネイティブ フォールバック セットには、`gpt-5.5`、`gpt-5.4`、`gpt-5.4-mini`、`gpt-5.3-codex-spark`、および GPT-5.6 Sol/Terra/Luna が含まれます。 GPT-5.5/5.4 ファミリの場合、opencodex は、インストールされている Codex カタログの豊富なライブ エントリを保存し、欠落しているエントリのみを合成します。バンドルされたアップストリーム スナップショットは GPT-5.6 でのみ使用され、古いテンプレートの近似値の代わりに実際のモデルごとの ID とメタデータが提供されます。 +ネイティブ フォールバック セットには、`gpt-5.5`、`gpt-5.4`、`gpt-5.4-mini`、`gpt-5.3-codex-spark`、および GPT-5.6 Sol/Terra/Luna が含まれます。 GPT-5.5/5.4 ファミリの場合、CodexCommander は、インストールされている Codex カタログの豊富なライブ エントリを保存し、欠落しているエントリのみを合成します。バンドルされたアップストリーム スナップショットは GPT-5.6 でのみ使用され、古いテンプレートの近似値の代わりに実際のモデルごとの ID とメタデータが提供されます。 |ルート |ピッカー ID とカタログのメタデータ | | --- | --- | @@ -93,11 +87,11 @@ service_tier = "fast" fast_mode = true ``` -ただし、モデル カタログとランタイム リクエスト層 ID は `priority` を使用します。opencodex はその分割を保持します。ネイティブ OpenAI パススルー モデルは高速サポートを維持します。ルーティングされたプロバイダーはケイパビリティでゲートされ、`supportsServiceTier: false` と宣言された場合のみ `service_tier` が削除されます (レジストリは正規 OpenAI を `true`、DeepSeek と Volcengine Ark を `false` に分類します)。未分類のカスタム ゲートウェイは呼び出し元の値をそのまま保持し、注入もされません。そのため、受け入れられない場所で高速オプションがアドバタイズされることはなく、カスタム ゲートウェイは `true` で明示的にオプトインできます。 +ただし、モデル カタログとランタイム リクエスト層 ID は `priority` を使用します。CodexCommander はその分割を保持します。ネイティブ OpenAI パススルー モデルは高速サポートを維持します。ルーティングされたプロバイダーはケイパビリティでゲートされ、`supportsServiceTier: false` と宣言された場合のみ `service_tier` が削除されます (レジストリは正規 OpenAI を `true`、DeepSeek と Volcengine Ark を `false` に分類します)。未分類のカスタム ゲートウェイは呼び出し元の値をそのまま保持し、注入もされません。そのため、受け入れられない場所で高速オプションがアドバタイズされることはなく、カスタム ゲートウェイは `true` で明示的にオプトインできます。 ## サブエージェントの選択 -Codex は、ピッカーに表示されるカタログ エントリを `priority` の昇順で並べ替え、最初の 5 つを `spawn_agent` モデル オーバーライドとしてアドバタイズします。ダッシュボードの **Agent Command Center** では、bare native id または routed `provider/model` id を最大 5 つ選択して保存できます。設定済みの account-qualified `<selector>/<native-openai-model>` id も保持され、各保存項目が実際に公開されたか除外されたかが表示されます。opencodex は選択順に低いカタログ priority を割り当てます。account selector が有効な場合、bare native の選択は selector-qualified グループに展開されます。他のモデルは引き続き正確な ID で呼び出すことができます。 +Codex は、ピッカーに表示されるカタログ エントリを `priority` の昇順で並べ替え、最初の 5 つを `spawn_agent` モデル オーバーライドとしてアドバタイズします。ダッシュボードの **Agent Command Center** では、bare native id または routed `provider/model` id を最大 5 つ選択して保存できます。設定済みの account-qualified `<selector>/<native-openai-model>` id も保持され、各保存項目が実際に公開されたか除外されたかが表示されます。CodexCommander は選択順に低いカタログ priority を割り当てます。account selector が有効な場合、bare native の選択は selector-qualified グループに展開されます。他のモデルは引き続き正確な ID で呼び出すことができます。 Active Roster は、ダッシュボードの **サブエージェント委任** の選択とは別のものです。Codex が最初に提供する override を制御しますが、モデルを選択したり、委任をトリガーしたりすることはありません。 @@ -106,7 +100,7 @@ Active Roster は、ダッシュボードの **サブエージェント委任** ピッカーに古いエントリがまだ表示されている場合は、カタログを更新し、ターゲットの Codex サーフェスを再起動します。 ```bash -ocx sync +ccx sync ``` -opencodex は、カタログの可視性、優先度、またはメタデータが変更されるたびに、意図的に古いキャッシュ ラッパーで `models_cache.json` を書き換えるため、次回の Codex モデルの更新で新しいカタログが読み取られます。 +CodexCommander は、カタログの可視性、優先度、またはメタデータが変更されるたびに、意図的に古いキャッシュ ラッパーで `models_cache.json` を書き換えるため、次回の Codex モデルの更新で新しいカタログが読み取られます。 diff --git a/docs-site/src/content/docs/ja/guides/codex-integration.md b/docs-site/src/content/docs/ja/guides/codex-integration.md index 9a2c8c6943..e8275c31cd 100644 --- a/docs-site/src/content/docs/ja/guides/codex-integration.md +++ b/docs-site/src/content/docs/ja/guides/codex-integration.md @@ -1,20 +1,20 @@ --- title: Codexの統合 -description: opencodex が自身を Codex に挿入し、モデル カタログを同期し、shim をインストールし、クリーンに復元する方法。 +description: CodexCommander が自身を Codex に挿入し、モデル カタログを同期し、shim をインストールし、クリーンに復元する方法。 --- -opencodex は、Codex が読み取る 2 つの内容 (構成 (`$CODEX_HOME/config.toml`、デフォルト `~/.codex/config.toml`) とそのモデル カタログ) を編集することで、プロキシを経由する Codex ルートを作成します。すべての編集は冪等であり、元に戻すことができます。 +CodexCommander は、Codex が読み取る 2 つの内容 (構成 (`$CODEX_HOME/config.toml`、デフォルト `~/.codex/config.toml`) とそのモデル カタログ) を編集することで、プロキシを経由する Codex ルートを作成します。すべての編集は冪等であり、元に戻すことができます。 -プロキシは、プール (デフォルト) およびダイレクト アカウント モードで 1 つのベア `openai` Codex ログイン ルートと、構成された API キーの `openai-apikey/<model>` を公開します。プールにはメインアカウントと追加アカウントが含まれます。直接は、発信者/メインベアラーのみを使用します。ルートは相互にフォールバックしません。出荷された v1 設定はマーカー 2 に移行され、手動復元用に `config.json.pre-openai-tiers-v2.bak` が保存されます。 +プロキシは、Pool (デフォルト) および Direct アカウントモードで 1 つの bare `openai` Codex ログインルートと、設定された API キー用の `openai-apikey/<model>` を公開します。Pool にはメインアカウントと追加アカウントが含まれ、Direct は呼び出し元/メインの bearer だけを使用します。ルート間でフォールバックはしません。 ## 設定の注入 -`ocx init`、`ocx start`、および `ocx sync` はインジェクターを呼び出します。デフォルトのループバック バインドでは、Codex の組み込み `openai` プロバイダー ID を保持し、そのプロバイダーを opencodex にポイントします。 +`ccx init`、`ccx start`、および `ccx sync` はインジェクターを呼び出します。デフォルトのループバック バインドでは、Codex の組み込み `openai` プロバイダー ID を保持し、そのプロバイダーを CodexCommander にポイントします。 ```toml # root keys, before the first table -model_catalog_json = "/absolute/path/to/opencodex-catalog.json" -# Auto-injected by opencodex +model_catalog_json = "/absolute/path/to/codexcommander-catalog.json" +# Auto-injected by CodexCommander openai_base_url = "http://127.0.0.1:10100/v1" # fastMode を設定した場合のみ。未設定なら [features] は作られません @@ -30,7 +30,7 @@ fast_mode = true ### 組み込みの画像生成 (`image_gen`) -Codex の組み込み `image_gen` ツールは、`/v1/responses` を経由しません。codex-rs 拡張機能は、チャットに使用するものと同じ ChatGPT ベアラー認証を使用して、`{base_url}/images/generations` (または参照画像が添付されている場合は `/images/edits`) を直接 POST します。挿入された `base_url` は opencodex を指しているため、プロキシはそれらの呼び出しを OpenAI アップストリームに中継します。 +Codex の組み込み `image_gen` ツールは、`/v1/responses` を経由しません。codex-rs 拡張機能は、チャットに使用するものと同じ ChatGPT ベアラー認証を使用して、`{base_url}/images/generations` (または参照画像が添付されている場合は `/images/edits`) を直接 POST します。挿入された `base_url` は CodexCommander を指しているため、プロキシはそれらの呼び出しを OpenAI アップストリームに中継します。 これは [イメージブリッジ](/guides/image-bridge/) とは別のもので、非 OpenAI モデルが選択されているときに **Responses** ターンでホストされた `image_generation` ツールがリストされた場合にのみアクティブになります。スタンドアロン `/images/generations` コールがそのブリッジに入ることはありません。 @@ -41,11 +41,11 @@ Codex の組み込み `image_gen` ツールは、`/v1/responses` を経由しま - **明示的なカスタム プロバイダー:** `images.provider` をカスタム API キーの ID に設定します。 `openai-responses` プロバイダー。そのエンドポイントは OpenAI Images API を実装します。明示的な選択はクローズに失敗し、別の有料アップストリームにフォールバックすることはありません。レジストリで管理されているプロバイダー ID はここでは受け入れられません。組み込みの OpenAI 層を使用するには、`images.provider` を省略します。 - **Google Antigravity (CCA) フォールバック:** OpenAI 前方候補でもキー付きでもない場合 -プロバイダーが構成されている場合、`/v1/images/generations` (`/images/edits` ではありません) は、`gemini-3.1-flash-image` モデルを使用して Antigravity **Cloud Code Assist** エンドポイントにフォールバックします。フォールバックは、OpenAI 候補が構成されていない場合だけでなく、OpenAI 認証の解決が失敗した後 (ChatGPT 資格情報の期限切れまたは欠落など) にも起動されます。これには `ocx login google-antigravity` が必要です。 OAuth トークンは、固定された CCA レジストリ ホストにのみ送信され、構成レベルの `baseUrl` オーバーライドには送信されません。応答は、Codex が期待するのと同じ `{created, data:[{b64_json}]}` 形状で返されます。 +プロバイダーが構成されている場合、`/v1/images/generations` (`/images/edits` ではありません) は、`gemini-3.1-flash-image` モデルを使用して Antigravity **Cloud Code Assist** エンドポイントにフォールバックします。フォールバックは、OpenAI 候補が構成されていない場合だけでなく、OpenAI 認証の解決が失敗した後 (ChatGPT 資格情報の期限切れまたは欠落など) にも起動されます。これには `ccx login google-antigravity` が必要です。 OAuth トークンは、固定された CCA レジストリ ホストにのみ送信され、構成レベルの `baseUrl` オーバーライドには送信されません。応答は、Codex が期待するのと同じ `{created, data:[{b64_json}]}` 形状で返されます。 - **どちらでもない:** プロキシは一般的な 404 ではなく明確なエラーを返します。 ルーティングされたプロバイダー (Cursor、Gemini、Kiro など) は `image_generation` ツール リレーとして機能できません。このツールをまったく提供したくない場合は、Codex で `codex features disable image_generation` (`config.toml` では `[features] image_generation = false`) を使用してツールを無効にします。 -ツール宣言は引き続きモデルの応答リクエストとともに送信されます。 API キー応答プロバイダーの場合、opencodex は Codex のプライベート `image_gen` 名前空間をアップストリームで安全な `image_gen__<inner-name>` エイリアス (`image_gen__imagegen` など) に下げます。使用可能なエイリアスがクライアント宣言を置き換えると、opencodex は重複したホストされた `image_generation` 宣言を削除します。 Codex が関数呼び出しを認識する前に、関数呼び出しを明示的な `image_gen` 名前空間にマップし、後の履歴がアップストリームで再生されるときにネイティブ呼び出しを再度エンコードします。これにより、名前空間を予約したり、ドット付き関数名を拒否したりするパブリック互換のアップストリームで、クライアント側のイメージ生成を呼び出すことができるようになります。 ChatGPT 転送モードは変更されず、ネイティブの Responses Lite の形状が維持されます。 +ツール宣言は引き続きモデルの応答リクエストとともに送信されます。 API キー応答プロバイダーの場合、CodexCommander は Codex のプライベート `image_gen` 名前空間をアップストリームで安全な `image_gen__<inner-name>` エイリアス (`image_gen__imagegen` など) に下げます。使用可能なエイリアスがクライアント宣言を置き換えると、CodexCommander は重複したホストされた `image_generation` 宣言を削除します。 Codex が関数呼び出しを認識する前に、関数呼び出しを明示的な `image_gen` 名前空間にマップし、後の履歴がアップストリームで再生されるときにネイティブ呼び出しを再度エンコードします。これにより、名前空間を予約したり、ドット付き関数名を拒否したりするパブリック互換のアップストリームで、クライアント側のイメージ生成を呼び出すことができるようになります。 ChatGPT 転送モードは変更されず、ネイティブの Responses Lite の形状が維持されます。 OpenAI 互換のカスタム ゲートウェイの場合は、専用プロバイダーを構成し、スタンドアロン イメージ リクエストに対してのみ選択します。 @@ -77,21 +77,21 @@ OpenAI 互換のカスタム ゲートウェイの場合は、専用プロバイ ```toml # root keys -model_provider = "opencodex" -model_catalog_json = "/absolute/path/to/opencodex-catalog.json" +model_provider = "codexcommander" +model_catalog_json = "/absolute/path/to/codexcommander-catalog.json" # appended at the end of the file -# Auto-injected by opencodex -[model_providers.opencodex] -name = "OpenCodex Proxy" +# Auto-injected by CodexCommander +[model_providers.codexcommander] +name = "CodexCommander Proxy" base_url = "http://your-host:10100/v1" wire_api = "responses" requires_openai_auth = true -env_http_headers = { "x-opencodex-api-key" = "OPENCODEX_API_AUTH_TOKEN" } +env_http_headers = { "x-codexcommander-api-key" = "CODEXCOMMANDER_API_AUTH_TOKEN" } # supports_websockets = true # only when config.websockets is true ``` -OpenCodex がルーティングを所有している場合、どちらのモードも参照/フォールバック設定として `$CODEX_HOME/opencodex.config.toml` を書き込みます。ループバックでは、自動挿入が削除された場合に手動でマージできるルート キーが含まれています。非ループバックでは、専用のプロバイダー フォームが含まれます。外部プロバイダー モードでは、このプロファイルは変更されません。 +CodexCommander がルーティングを所有している場合、どちらのモードも参照/フォールバック設定として `$CODEX_HOME/codexcommander.config.toml` を書き込みます。ループバックでは、自動挿入が削除された場合に手動でマージできるルート キーが含まれています。非ループバックでは、専用のプロバイダー フォームが含まれます。外部プロバイダー モードでは、このプロファイルは変更されません。 :::caution `openai_base_url`、`model_provider`、`model_catalog_json` などのルート キーは、最初の `[table]` ヘッダーの前に**なければなりません**。インジェクターはその配置を保証し、それ自身の古い/重複したコピーを削除し、ユーザー所有のルート `openai_base_url` を決して上書きしません。存在する場合、sync はカタログを更新しますが、ルーティングが挿入されなかったことを報告します。 @@ -99,31 +99,27 @@ OpenCodex がルーティングを所有している場合、どちらのモー ## 共有モデルカタログ -Codex CLI、TUI、App、SDK はすべて同じ Codex ホームを読み取ります。 opencodex は、そのディレクトリを `CODEX_HOME` から解決して `~/.codex` にフォールバックし、以下を管理します。 +Codex CLI、TUI、App、SDK はすべて同じ Codex ホームを読み取ります。 CodexCommander は、そのディレクトリを `CODEX_HOME` から解決して `~/.codex` にフォールバックし、以下を管理します。 ```text $CODEX_HOME/config.toml -$CODEX_HOME/opencodex.config.toml -$CODEX_HOME/opencodex-catalog.json +$CODEX_HOME/codexcommander.config.toml +$CODEX_HOME/codexcommander-catalog.json $CODEX_HOME/models_cache.json ``` -WSL では、`CODEX_HOME` が設定されておらず、Linux `~/.codex/config.toml` が存在しない場合、opencodex は `/mnt/c/Users/*/.codex/config.toml` にある単一の Windows Codex デスクトップ ホームもチェックします。候補が 1 つだけ存在する場合は、そのディレクトリが使用されるため、WSL アプリサーバー モードと Windows Codex デスクトップは同じ設定ファイルと認証ファイルを共有します。この検出をオーバーライドするには、`CODEX_HOME` を明示的に設定します。 +WSL では、`CODEX_HOME` が設定されておらず、Linux `~/.codex/config.toml` が存在しない場合、CodexCommander は `/mnt/c/Users/*/.codex/config.toml` にある単一の Windows Codex デスクトップ ホームもチェックします。候補が 1 つだけ存在する場合は、そのディレクトリが使用されるため、WSL アプリサーバー モードと Windows Codex デスクトップは同じ設定ファイルと認証ファイルを共有します。この検出をオーバーライドするには、`CODEX_HOME` を明示的に設定します。 -Windows では、ChatGPT/Codex アプリが `%USERPROFILE%\\.codex` を読み取りながら、Orca シェルは `CODEX_HOME` と `ORCA_CODEX_HOME` の両方を Orca のバンドルされたランタイム ホームに設定できます。 `ocx status` および `ocx doctor` は、この正確な不一致について警告し、編集されたターゲット パスを出力します。バックグラウンド サービスが Orca シェルからインストールされている場合は、最初に元のシェルからアンインストールし、次に `CODEX_HOME` をアプリ ホームに設定し、`ORCA_CODEX_HOME` の設定を解除し、同期/復元を再実行して、サービスを再度インストールします。 +Windows では、ChatGPT/Codex アプリが `%USERPROFILE%\\.codex` を読み取りながら、Orca シェルは `CODEX_HOME` と `ORCA_CODEX_HOME` の両方を Orca のバンドルされたランタイム ホームに設定できます。 `ccx status` および `ccx doctor` は、この正確な不一致について警告し、編集されたターゲット パスを出力します。バックグラウンド サービスが Orca シェルからインストールされている場合は、最初に元のシェルからアンインストールし、次に `CODEX_HOME` をアプリ ホームに設定し、`ORCA_CODEX_HOME` の設定を解除し、同期/復元を再実行して、サービスを再度インストールします。 -専用プロバイダー モードでは、`requires_openai_auth = true` は Codex App/TUI アカウント ゲート サーフェスをネイティブ Codex と一致させます。 opencodex は WebSocket 経由で `/v1/responses` も提供します。専用プロバイダーは、`"websockets": true` の場合にのみ `supports_websockets = true` をアドバタイズします。ループバック時 Codex の組み込みプロバイダーは最初に WebSocket を試行し、無効になったプロキシが `426` を返すため、Codex は HTTP/SSE にフォールバックします。 - -## スレッドのアイデンティティと履歴 - -デフォルトのループバック形式では、Codex のネイティブ `openai` プロバイダーでタグ付けされた新しいスレッドが維持されるため、通常の再開履歴には再マッピングが必要ありません。最初の同期時に、古い opencodex ビルドでタグ付けされたスレッドも `openai` に移行されます。非ループバック専用プロバイダー モードでは、アクティブな間は `opencodex` プロバイダーの下で履歴がミラーリングされ、終了時にバックアップされたメタデータが復元されます。履歴を残さないように `syncResumeHistory: false` を設定します。 +専用プロバイダー モードでは、`requires_openai_auth = true` は Codex App/TUI アカウント ゲート サーフェスをネイティブ Codex と一致させます。 CodexCommander は WebSocket 経由で `/v1/responses` も提供します。専用プロバイダーは、`"websockets": true` の場合にのみ `supports_websockets = true` をアドバタイズします。ループバック時 Codex の組み込みプロバイダーは最初に WebSocket を試行し、無効になったプロキシが `426` を返すため、Codex は HTTP/SSE にフォールバックします。 ## モデルカタログの同期 -Codex には、ディスク上のカタログ (デフォルトでは `$CODEX_HOME/opencodex-catalog.json`) からのモデルが表示されます。起動時および `ocx sync`、opencodex: +Codex には、ディスク上のカタログ (デフォルトでは `$CODEX_HOME/codexcommander-catalog.json`) からのモデルが表示されます。起動時および `ccx sync`、CodexCommander: -1. **元のカタログを `~/.opencodex/catalog-backup.json` に一度バックアップ**します (したがって、フィーチャリングは -可逆)。 +1. **元のカタログを `~/.codexcommander/catalog-backup-<catalog-id>.json` に一度バックアップ**します + (したがって、フィーチャリングは可逆)。 2. **対象プロバイダーのライブ モデル カタログを取得** (最大 5 分間キャッシュされ、最後の正常なカタログにフォールバックします) リストを作成し、`models[]` を設定します)。前方認証にはモデル エンドポイントがなく、Cursor は `/models` ではなく `GetUsableModels` RPC を使用します。 3. **マージ** ルーティングされたモデルを、ネイティブ Codex から複製された名前空間エントリ (`provider/model`) として結合します。 @@ -141,31 +137,31 @@ Codex には、ディスク上のカタログ (デフォルトでは `$CODEX_HOM CLI から表示名を追加します (プロキシは、ライブ時にカタログをすぐに同期します)。 ```bash -ocx models add deepseek deepseek-v4 --display-name "DeepSeek V4" --context-window 128000 +ccx models add deepseek deepseek-v4 --display-name "DeepSeek V4" --context-window 128000 ``` リモート Codex クライアントは、管理 API 経由で同じ生成されたカタログをフェッチできます (他の `/api/*` ルートと同じアドミッション トークン)。 ```bash -dest="${CODEX_HOME:-$HOME/.codex}/opencodex-catalog.json" +dest="${CODEX_HOME:-$HOME/.codex}/codexcommander-catalog.json" tmp="$(mktemp "${dest}.XXXXXX")" -curl -fsS -H "x-opencodex-api-key: $OPENCODEX_ADMIN_AUTH_TOKEN" \ +curl -fsS -H "x-codexcommander-api-key: $CODEXCOMMANDER_ADMIN_AUTH_TOKEN" \ "https://proxy.example.com/api/catalog" > "$tmp" \ && mv "$tmp" "$dest" -ocx sync-cache +ccx sync-cache ``` -応答は生の `opencodex-catalog.json` ドキュメント (プロバイダーの資格情報なし) です。利用可能な場合、`x-opencodex-codex-version` ヘッダーはサーバー上の Codex ランタイム バージョンを報告するため、クライアントはバージョンの偏りを特定できます。 +応答は生の `codexcommander-catalog.json` ドキュメント (プロバイダーの資格情報なし) です。利用可能な場合、`x-codexcommander-codex-version` ヘッダーはサーバー上の Codex ランタイム バージョンを報告するため、クライアントはバージョンの偏りを特定できます。 管理 API (`POST /api/custom-models`、`PUT /api/custom-models/<id>` と `displayName` 文字列) および Web ダッシュボードを通じて設定または編集することもできます。 `/` は、配線済みスラグ セパレータと衝突する可能性があるため拒否されます。 -表示名は **表示専用であり、再生成しても安定しています**。 `ocx sync` およびカタログが更新されるたびに、`config.json` (`customModels` を含む) からルーティングされたエントリが再取得されるため、設定された名前はルーティングされたスラッグに戻るのではなく、再適用されます。管理対象サービスの再起動でも、プロキシのバインド直後にこの同期が試行されます。オフライン ログイン中など、ベストエフォート型ブート同期が失敗した場合、以前に永続化されたカタログが保持され、次に成功した `ocx sync` が構成された名前を再適用します。本物のアップストリーム ネイティブ名 (例: `gpt-5.6-sol` → "GPT-5.6-Sol") は、固定されたアップストリーム スナップショットから取得され、カスタム表示名によって上書きされることはありません。 +表示名は **表示専用であり、再生成しても安定しています**。 `ccx sync` およびカタログが更新されるたびに、`config.json` (`customModels` を含む) からルーティングされたエントリが再取得されるため、設定された名前はルーティングされたスラッグに戻るのではなく、再適用されます。管理対象サービスの再起動でも、プロキシのバインド直後にこの同期が試行されます。オフライン ログイン中など、ベストエフォート型ブート同期が失敗した場合、以前に永続化されたカタログが保持され、次に成功した `ccx sync` が構成された名前を再適用します。本物のアップストリーム ネイティブ名 (例: `gpt-5.6-sol` → "GPT-5.6-Sol") は、固定されたアップストリーム スナップショットから取得され、カスタム表示名によって上書きされることはありません。 ### 外部プロバイダーマネージャー -`config.toml` がすでに `openai` または `opencodex` 以外のプロバイダーを選択している場合、OpenCodex はファイルを変更しないままにし、プロファイルの書き込み、カタログ/キャッシュの更新、および即時およびバックグラウンドの両方の Codex 履歴の移行をスキップします。カスタム プロバイダーを管理するツールは、多くの場合、既存のセッションにそのプロバイダー ID をタグ付けします。アクティブな ID を置き換えると、それらの無傷のセッションが Codex の履歴ビューから消える可能性があります。同じ保護が、レガシー ルート プロファイルによって選択された外部プロバイダーにも適用されます。 +`config.toml` がすでに `openai` または `codexcommander` 以外のプロバイダーを選択している場合、CodexCommander はファイルを変更せず、プロファイルの書き込み、カタログ/キャッシュの更新、および Codex 履歴の同期をスキップします。カスタム プロバイダーを管理するツールは、多くの場合、既存のセッションにそのプロバイダー ID をタグ付けします。アクティブな ID を置き換えると、それらの無傷のセッションが Codex の履歴ビューから消える可能性があります。同じ保護は、外部プロバイダーが有効な場合には常に適用されます。 -1 つのツールを Codex プロバイダー設定の所有者として保持します。既存のプロバイダー マネージャーの背後で OpenCodex を使用するには、チャット完了変換ではなく、応答パススルー (Codex TOML では `wire_api = "responses"`) を使用して、そのプロバイダーを `http://127.0.0.1:10100/v1` に指定します。プロキシ API 認証が有効な場合は、上記の非ループバック プロバイダー フォームと一致して、`OPENCODEX_API_AUTH_TOKEN` から `x-opencodex-api-key` も渡します。 OpenCodex にルーティングを直接挿入させるには、まず Codex を組み込みの `openai` プロバイダーに戻し、ユーザー所有のルート `openai_base_url` を削除してから、`ocx start` を再実行します。 +1 つのツールを Codex プロバイダー設定の所有者として保持します。既存のプロバイダー マネージャーの背後で CodexCommander を使用するには、チャット完了変換ではなく、応答パススルー (Codex TOML では `wire_api = "responses"`) を使用して、そのプロバイダーを `http://127.0.0.1:10100/v1` に指定します。プロキシ API 認証が有効な場合は、上記の非ループバック プロバイダー フォームと一致して、`CODEXCOMMANDER_API_AUTH_TOKEN` から `x-codexcommander-api-key` も渡します。 CodexCommander にルーティングを直接挿入させるには、まず Codex を組み込みの `openai` プロバイダーに戻し、ユーザー所有のルート `openai_base_url` を削除してから、`ccx start` を再実行します。 ### カタログのトラブルシューティング @@ -176,28 +172,28 @@ ocx sync-cache 2. **`disabledModels`** (トップレベル) — カタログと `/v1/models` の両方からモデルを非表示にし、反転します 裸のネイティブ GPT スラッグを `visibility: "hide"` にします。 3. **`liveModels: false` と空の `models`** — ライブ検出がオフで、`models` が空の場合、または -省略すると、opencodex はそのプロバイダーのルーティング モデルを公開しません。 +省略すると、CodexCommander はそのプロバイダーのルーティング モデルを公開しません。 4. **Cursor `GetUsableModels`** — Cursor アダプターはその protobuf を通じてモデルを検出します。 `/models` ではなく `GetUsableModels` RPC であるため、カーソル側の変更により、他のプロバイダーとは独立して表示される ID が変更される可能性があります。 -5. **キャッシュと `ocx sync`** - ライブ カタログは約 5 分間キャッシュされます (`modelCacheTtlMs`、 -デフォルト `300000`)。 `ocx sync` を実行して新しいフェッチを強制し、カタログをすぐに再書き込みします。 +5. **キャッシュと `ccx sync`** - ライブ カタログは約 5 分間キャッシュされます (`modelCacheTtlMs`、 +デフォルト `300000`)。 `ccx sync` を実行して新しいフェッチを強制し、カタログをすぐに再書き込みします。 6. **Codex `app-server` の実行** - 有効期間が長い間、ディスク上のカタログを書き換えるだけでは十分ではありません -Codex `app-server` (デスクトップ/CLI バックグラウンド ホスト) は、以前のリストをメモリに保持します。 `ocx sync` および `ocx sync-cache` は、これらのプロセスが検出されると警告します。 `ocx sync --restart-codex` でそれらを再起動し (または、一致する `app-server` プロセスを自分で停止し)、Codex でそれらを再作成すると、新しいリストが表示されます。 +Codex `app-server` (デスクトップ/CLI バックグラウンド ホスト) は、以前のリストをメモリに保持します。 `ccx sync` および `ccx sync-cache` は、これらのプロセスが検出されると警告します。 `ccx sync --restart-codex` でそれらを再起動し (または、一致する `app-server` プロセスを自分で停止し)、Codex でそれらを再作成すると、新しいリストが表示されます。 :::caution[その他の地元作家] -カタログ書き込み (`opencodex-catalog.json`、`config.toml`) はアトミック **内部** opencodex であり、opencodex が所有する 2 つのライターが競合する場合にのみ、ファイルの書きかけが防止されます。これは、opencodex が書き込まれた後に、別のローカル プロセス、ファイル ウォッチャー、または同期エージェントがカタログの可視性や順序を書き換えることを**阻止するものではありません。 Codex は個別の `models_cache.json` を保持しており、それを個別に更新して、`opencodex-catalog.json` を書き換えることなく表示リストを変更できます。プロキシの実行中にモデルが予期せず反転した場合は、競合するライターを停止または再構成してから、`ocx sync` を実行します。これは外部ライターの危険であり、確認された opencodex の欠陥ではありません。 +カタログ書き込み (`codexcommander-catalog.json`、`config.toml`) はアトミック **内部** CodexCommander であり、CodexCommander が所有する 2 つのライターが競合する場合にのみ、ファイルの書きかけが防止されます。これは、CodexCommander が書き込まれた後に、別のローカル プロセス、ファイル ウォッチャー、または同期エージェントがカタログの可視性や順序を書き換えることを**阻止するものではありません。 Codex は個別の `models_cache.json` を保持しており、それを個別に更新して、`codexcommander-catalog.json` を書き換えることなく表示リストを変更できます。プロキシの実行中にモデルが予期せず反転した場合は、競合するライターを停止または再構成してから、`ccx sync` を実行します。これは外部ライターの危険であり、確認された CodexCommander の欠陥ではありません。 ::: ## プロキシ接続エラー -Codex が再試行して `stream disconnected before completion: error sending request for url (http://127.0.0.1:10100/v1/responses)` のようなエラーで失敗した場合、または Claude Code が同様の接続エラーを報告した場合、opencodex プロキシは実行されていません。設定されたポートで何もリッスンしていないため、クライアントはその生の接続エラー自体を表示します。プロキシを再起動します。 +Codex が再試行して `stream disconnected before completion: error sending request for url (http://127.0.0.1:10100/v1/responses)` のようなエラーで失敗した場合、または Claude Code が同様の接続エラーを報告した場合、CodexCommander プロキシは実行されていません。設定されたポートで何もリッスンしていないため、クライアントはその生の接続エラー自体を表示します。プロキシを再起動します。 ```bash -ocx start # foreground -ocx service install # persistent: auto-starts on login and respawns on crash +ccx start # foreground +ccx service install # persistent: auto-starts on login and respawns on crash ``` -`ocx status` は、プロキシが実行されているかどうかを示し、実行されていない場合は同じ再起動ヒントを出力します。 `ocx doctor` は再起動の安全性 (サービス/シム カバレッジ) を報告します。 +`ccx status` は、プロキシが実行されているかどうかを示し、実行されていない場合は同じ再起動ヒントを出力します。 `ccx doctor` は再起動の安全性 (サービス/シム カバレッジ) を報告します。 ## サブエージェントピッカー @@ -205,16 +201,16 @@ ocx service install # persistent: auto-starts on login and respawns on crash ## Codex アカウントのウォームアップ -ChatGPT アカウントが Codex アカウント プールに追加されると、opencodex は、Codex Response バックエンドへの小さなストリーミング リクエストで永続化する前にそれを検証します。リクエストは実際の応答項目配列 (`input: [{ type: "message", ... }]`) を使用し、`response.completed` を待機し、デフォルトは `gpt-5.4-mini` になります。そのモデルが HTTP 400 を返した場合、`gpt-5.5` で再試行します。構造化されたアップストリーム エラーの詳細は、生の応答本体を公開することなく表示されます。バックグラウンドの再検証は個別に行われ、デフォルトではオフになっています。これは、トークン ガーディアンが有効で、`chatgpt` 更新ポリシーが `proactive` で、`tokenGuardian.codexWarmupEnabled` が true の場合にのみ実行されます。 +ChatGPT アカウントが Codex アカウント プールに追加されると、CodexCommander は、Codex Response バックエンドへの小さなストリーミング リクエストで永続化する前にそれを検証します。リクエストは実際の応答項目配列 (`input: [{ type: "message", ... }]`) を使用し、`response.completed` を待機し、デフォルトは `gpt-5.4-mini` になります。そのモデルが HTTP 400 を返した場合、`gpt-5.5` で再試行します。構造化されたアップストリーム エラーの詳細は、生の応答本体を公開することなく表示されます。バックグラウンドの再検証は個別に行われ、デフォルトではオフになっています。これは、トークン ガーディアンが有効で、`chatgpt` 更新ポリシーが `proactive` で、`tokenGuardian.codexWarmupEnabled` が true の場合にのみ実行されます。 ## ネイティブ Codexの復元 -opencodex は決してあなたを罠にはめることはありません。 **`ocx stop` は、ネイティブ Codex に完全に戻す単一のコマンドです**。プロキシを停止し、バックグラウンド サービスがインストールされている場合はそれを停止し、挿入されたすべての行とルーティングされたカタログ エントリを削除するため、プレーンな `codex` は、opencodex が存在しなかったかのように正確に動作します。 +CodexCommander は決してあなたを罠にはめることはありません。 **`ccx stop` は、ネイティブ Codex に完全に戻す単一のコマンドです**。プロキシを停止し、バックグラウンド サービスがインストールされている場合はそれを停止し、挿入されたすべての行とルーティングされたカタログ エントリを削除するため、プレーンな `codex` は、CodexCommander が存在しなかったかのように正確に動作します。 ```bash -ocx stop # stop the proxy + service, restore native Codex -ocx restore # restore without stopping (alias: ocx eject) -ocx restore back # point plain Codex at the running proxy again +ccx stop # stop the proxy + service, restore native Codex +ccx restore # restore without stopping (alias: ccx eject) +ccx restore back # point plain Codex at the running proxy again ``` -opencodex が管理対象 [バックグラウンドサービス](/reference/cli/#ocx-service) として実行される場合、`OCX_SERVICE=1` が設定されるため、サービス主導の再起動によって Codex 設定がスラッシングされなくなります。明示的な `ocx stop` / `ocx service stop` のみがネイティブ Codex を復元します。 +CodexCommander が管理対象 [バックグラウンドサービス](/reference/cli/#ccx-service) として実行される場合、`CCX_SERVICE=1` が設定されるため、サービス主導の再起動によって Codex 設定がスラッシングされなくなります。明示的な `ccx stop` / `ccx service stop` のみがネイティブ Codex を復元します。 diff --git a/docs-site/src/content/docs/ja/guides/combos.md b/docs-site/src/content/docs/ja/guides/combos.md index d1f9dce94a..f3aad06454 100644 --- a/docs-site/src/content/docs/ja/guides/combos.md +++ b/docs-site/src/content/docs/ja/guides/combos.md @@ -3,7 +3,7 @@ title: "コンボ: フェイルオーバーとロードバランシング" description: フェイルオーバーまたは加重負荷分散のために、1 つの仮想モデルを複数のプロバイダーにルーティングします。 --- -**コンボ** は、実際のプロバイダー/モデル ターゲットの順序付きリストの先頭にある 1 つの仮想モデルです。クライアントは `combo/<id>` をリクエストします。 opencodex はターゲットを選択し、リクエストをその具体的な `provider/model` に書き換えます。最初のターゲットで再試行可能な障害が発生した場合は、別のターゲットを試行できます。 +**コンボ** は、実際のプロバイダー/モデル ターゲットの順序付きリストの先頭にある 1 つの仮想モデルです。クライアントは `combo/<id>` をリクエストします。 CodexCommander はターゲットを選択し、リクエストをその具体的な `provider/model` に書き換えます。最初のターゲットで再試行可能な障害が発生した場合は、別のターゲットを試行できます。 これは、次のいずれかが必要な場合に便利です。 @@ -17,10 +17,10 @@ description: フェイルオーバーまたは加重負荷分散のために、1 この例では、最初に Anthropic、2 番目に OpenAI を使用して `combo/main` を作成します。両方のプロバイダーがすでに存在し、有効になっている必要があります。 ```bash -ocx combo set main --targets anthropic/claude-opus-4-8,openai/gpt-5.6-sol +ccx combo set main --targets anthropic/claude-opus-4-8,openai/gpt-5.6-sol ``` -デフォルトの戦略はフェイルオーバーであるため、通常のリクエストは `anthropic/claude-opus-4-8` に送信されます。その試行に再試行可能な失敗があった場合、opencodex は `openai/gpt-5.6-sol` にホップできます。 +デフォルトの戦略はフェイルオーバーであるため、通常のリクエストは `anthropic/claude-opus-4-8` に送信されます。その試行に再試行可能な失敗があった場合、CodexCommander は `openai/gpt-5.6-sol` にホップできます。 通常モデル ID を指定する場所であればどこでも仮想モデルを使用します。 @@ -34,7 +34,7 @@ ocx combo set main --targets anthropic/claude-opus-4-8,openai/gpt-5.6-sol 保存された定義を確認します。 ```bash -ocx combo show main +ccx combo show main ``` :::tip @@ -43,7 +43,7 @@ ocx combo show main ## コンボ名の仕組み -`ocx combo set <id>` のコンボ ID は文字または数字で始まる必要があります。文字、数字、`.`、`_`、または `-` を合計 64 文字まで含めることができます。その正規モデル ID は常に `combo/<id>` です。たとえば、ID `main` は `combo/main` になります。 +`ccx combo set <id>` のコンボ ID は文字または数字で始まる必要があります。文字、数字、`.`、`_`、または `-` を合計 64 文字まで含めることができます。その正規モデル ID は常に `combo/<id>` です。たとえば、ID `main` は `combo/main` になります。 `combo/` 名前空間は、コンボの構成中に予約されます。 `combo` という名前のプロバイダーはそれを占有することはできず、コンボ ID は構成されたプロバイダー名を複製することはできません。 @@ -83,7 +83,7 @@ ocx combo show main 成功した 2 つのリクエストのバッチを含む 2:1 コンボを作成します。 ```bash -ocx combo set balanced \ +ccx combo set balanced \ --targets anthropic/claude-opus-4-8:2,openai/gpt-5.6-sol:1 \ --strategy round-robin \ --sticky 2 @@ -112,7 +112,7 @@ ocx combo set balanced \ |クライアントのキャンセル (499)、`origin_rejected`、サイバー ポリシーの拒否、コンテキスト オーバーフロー、または無効なリクエスト |停止してエラーを返します。別のターゲットではリクエストは有効になりません。 | |その他の未分類のエラー |停止してエラーを返します。 | -ホップされたターゲットはデフォルトで 60 秒間のクールダウンに入ります。アップストリーム応答に有効な `Retry-After` 値が含まれている場合、opencodex は代わりにそれを使用します。秒数値と HTTP 日付値が受け入れられ、各クールダウンの上限は 10 分です。 +ホップされたターゲットはデフォルトで 60 秒間のクールダウンに入ります。アップストリーム応答に有効な `Retry-After` 値が含まれている場合、CodexCommander は代わりにそれを使用します。秒数値と HTTP 日付値が受け入れられ、各クールダウンの上限は 10 分です。 現在のリクエストは、同じ試行ターゲットを再試行することはありません。以降のリクエストでは、クールダウンが期限切れになるまでスキップされます。適格なターゲットが残っていない場合、プロキシは `error.code = "combo_unavailable"` を含む HTTP 503 を返します。 @@ -128,15 +128,15 @@ ocx combo set balanced \ 2. 呼び出し側は努力を設定しませんでした。そして 3. 選択したターゲットのカタログは、その正確な取り組みを宣伝します。 -リクエストに `reasoning` オブジェクトがない場合、opencodex はオブジェクトを作成します。 `reasoning` が `effort` プロパティなしで存在する場合、他のフィールドは保持され、デフォルトが追加されます。呼び出し元が提供した努力は決し​​て上書きされません。 +リクエストに `reasoning` オブジェクトがない場合、CodexCommander はオブジェクトを作成します。 `reasoning` が `effort` プロパティなしで存在する場合、他のフィールドは保持され、デフォルトが追加されます。呼び出し元が提供した努力は決し​​て上書きされません。 -ターゲットの機能が不明な場合、または設定されたエフォートが含まれていない場合、opencodex はデフォルトを省略し、ターゲット自体の動作を変更しないままにします。サポートされている値は、`low`、`medium`、`high`、`xhigh`、`max`、および `ultra` です。このフィールドを省略するか、`null` に設定して、呼び出し元とターゲットに作業を完全に任せます。 +ターゲットの機能が不明な場合、または設定されたエフォートが含まれていない場合、CodexCommander はデフォルトを省略し、ターゲット自体の動作を変更しないままにします。サポートされている値は、`low`、`medium`、`high`、`xhigh`、`max`、および `ultra` です。このフィールドを省略するか、`null` に設定して、呼び出し元とターゲットに作業を完全に任せます。 ## 暗号化された v2 サブエージェント タスク -Codex v2 サブエージェントには重要な制限が 1 つあります ([第92号](https://github.com/lidge-jun/opencodex/issues/92))。ネイティブの親は、新しく生成されたワーカーのタスクを、ネイティブ ChatGPT バックエンド用に作成された暗号文としてのみ送信できます。外部プロバイダーはそのペイロードを読み取ることができません。 +Codex v2 サブエージェントには重要な制限が 1 つあります ([第92号](https://github.com/pavelhov/CodexCommander/issues/92))。ネイティブの親は、新しく生成されたワーカーのタスクを、ネイティブ ChatGPT バックエンド用に作成された暗号文としてのみ送信できます。外部プロバイダーはそのペイロードを読み取ることができません。 -このようなリクエストの場合、コンボは、再試行可能な失敗後も含め、対象となるターゲットを正規のネイティブ ChatGPT ルートにフィルタリングします。コンボに復号化可能なターゲットがない場合、opencodex はディスパッチ前に停止し、HTTP 400 を返します。 +このようなリクエストの場合、コンボは、再試行可能な失敗後も含め、対象となるターゲットを正規のネイティブ ChatGPT ルートにフィルタリングします。コンボに復号化可能なターゲットがない場合、CodexCommander はディスパッチ前に停止し、HTTP 400 を返します。 ```json { @@ -169,13 +169,13 @@ v1/base/v2 モードと完全な暗号化タスクのワークフローについ 主なコマンドは次のとおりです。 ```bash -ocx combo list -ocx combo show <id> -ocx combo set <id> --targets provider/model[:weight],... -ocx combo remove <id> --yes +ccx combo list +ccx combo show <id> +ccx combo set <id> --targets provider/model[:weight],... +ccx combo remove <id> --yes ``` -`set` は、`--strategy`、`--sticky`、`--effort`、`--alias`、および `--rename-from` も受け入れます。そのフィールドをクリアするには、`--effort` または `--alias` の値として `-` を使用します。 `create` および `update` は、`set` のエイリアスです。 `delete` は `remove` のエイリアスです。同じサブコマンドが `ocx route combo` で使用できます。 +`set` は、`--strategy`、`--sticky`、`--effort`、`--alias`、および `--rename-from` も受け入れます。そのフィールドをクリアするには、`--effort` または `--alias` の値として `-` を使用します。 `create` および `update` は、`set` のエイリアスです。 `delete` は `remove` のエイリアスです。同じサブコマンドが `ccx route combo` で使用できます。 ### 管理 API @@ -217,7 +217,7 @@ ocx combo remove <id> --yes ### `combo/<id>` が 404 を返すのはなぜですか? -コンボIDは不明です。応答はタイプ `invalid_request_error` の HTTP 404 です。 `ocx combo list` を実行し、スペルと大文字小文字を確認して、モデル要求を受信する同じ実行中の opencodex インスタンスに管理コマンドが書き込まれたことを確認します。 +コンボIDは不明です。応答はタイプ `invalid_request_error` の HTTP 404 です。 `ccx combo list` を実行し、スペルと大文字小文字を確認して、モデル要求を受信する同じ実行中の CodexCommander インスタンスに管理コマンドが書き込まれたことを確認します。 ### `combo_unavailable` が発生するのはなぜですか? diff --git a/docs-site/src/content/docs/ja/guides/grok-build.md b/docs-site/src/content/docs/ja/guides/grok-build.md index b7c18f3cf4..f4337818e4 100644 --- a/docs-site/src/content/docs/ja/guides/grok-build.md +++ b/docs-site/src/content/docs/ja/guides/grok-build.md @@ -1,73 +1,73 @@ --- title: グロクビルド -description: xAI の Grok Build CLI から opencodex でルーティングされたモデルを使用します。モデルはプロキシの実行中に ~/.grok/config.toml に自動登録されます。 +description: xAI の Grok Build CLI から CodexCommander でルーティングされたモデルを使用します。モデルはプロキシの実行中に ~/.grok/config.toml に自動登録されます。 --- -opencodex はローカル ポート上で OpenAI 互換の `POST /v1/chat/completions` (および `/v1/responses`) を提供し、Grok Build は OpenAI 互換サーバーに対するカスタム モデルをサポートします。この統合により、opencodex は表示されているカタログ全体を Grok Build に自動的に登録します。手動による構成編集は必要ありません。 +CodexCommander はローカル ポート上で OpenAI 互換の `POST /v1/chat/completions` (および `/v1/responses`) を提供し、Grok Build は OpenAI 互換サーバーに対するカスタム モデルをサポートします。この統合により、CodexCommander は表示されているカタログ全体を Grok Build に自動的に登録します。手動による構成編集は必要ありません。 ## 自動登録 -`~/.grok` が存在する場合、`ocx start` (および `ocx ensure` / `ocx restart`) はマネージド ブロックを `~/.grok/config.toml` に書き込みます。 +`~/.grok` が存在する場合、`ccx start` (および `ccx ensure` / `ccx restart`) はマネージド ブロックを `~/.grok/config.toml` に書き込みます。 ```toml -# >>> opencodex managed block — do not edit (removed by `ocx stop`) >>> -[model.ocx-gpt-5-6-sol] +# >>> CodexCommander managed block — do not edit (removed by `ccx stop`) >>> +[model.ccx-gpt-5-6-sol] model = "gpt-5.6-sol" base_url = "http://127.0.0.1:10100/v1" api_backend = "chat_completions" -api_key = "opencodex-loopback" -name = "OCX gpt-5.6-sol" -# ... one [model.ocx-*] table per visible model ... -# <<< opencodex managed block <<< +api_key = "codexcommander-loopback" +name = "CodexCommander gpt-5.6-sol" +# ... one [model.ccx-*] table per visible model ... +# <<< CodexCommander managed block <<< ``` - **追加:** フェンスの外側にある独自の設定には決して触れません。最初の前に -既存のファイルに注入すると、1 回限りのバックアップが `~/.grok/config.toml.bak-opencodex` に書き込まれます。 -- **べき等:** すべての `ocx start` (および自動起動が有効な場合は `ocx ensure`) が置き換えられます。 +既存のファイルに注入すると、1 回限りのバックアップが `~/.grok/config.toml.bak-codexcommander` に書き込まれます。 +- **べき等:** すべての `ccx start` (および自動起動が有効な場合は `ccx ensure`) が置き換えられます。 現在のカタログを含むフェンスで囲まれたブロック。 -- **分解時に削除:** `ocx stop`、`ocx eject`、`ocx uninstall`、およびグレースフル -非サービスデーモンをシャットダウンすると、フェンスで囲まれたブロックが削除され、ファイルがバイト単位で復元されます。サービス マネージャーの下では、ティアダウンは `ocx stop`/`ocx uninstall` を経由します (サービス モード プロセスは、再生成後も意図的にブロックを保持します)。 +- **分解時に削除:** `ccx stop`、`ccx eject`、`ccx uninstall`、およびグレースフル +非サービスデーモンをシャットダウンすると、フェンスで囲まれたブロックが削除され、ファイルがバイト単位で復元されます。サービス マネージャーの下では、ティアダウンは `ccx stop`/`ccx uninstall` を経由します (サービス モード プロセスは、再生成後も意図的にブロックを保持します)。 - **競合安全:** 独自の `[model.*]` テーブルですでに定義されているエイリアスが尊重されます -(opencodex は独自のエントリに接尾辞を付けます);損傷したフェンス (終了マーカーのない開始マーカー) は自動変更を拒否し、手動での修復を要求します。 +(CodexCommander は独自のエントリに接尾辞を付けます);損傷したフェンス (終了マーカーのない開始マーカー) は自動変更を拒否し、手動での修復を要求します。 次に、Grok Build 内のモデルを選択します。 ```bash -grok models # lists ocx-* entries alongside native grok models -grok -m ocx-anthropic-claude-opus-4-8 -p "hello" -# or in the TUI: /model ocx-anthropic-claude-opus-4-8 +grok models # lists ccx-* entries alongside native grok models +grok -m ccx-anthropic-claude-opus-4-8 -p "hello" +# or in the TUI: /model ccx-anthropic-claude-opus-4-8 ``` ## 認証メモ -Grok Build では、ループバックでもカスタム モデルに対して空ではない API キーが必要です。挿入されたエントリにはプレースホルダー (`opencodex-loopback`) が含まれます。opencodex はループバック接続のアドミッション キーを無視するため、実際の秘密は関係しません。 +Grok Build では、ループバックでもカスタム モデルに対して空ではない API キーが必要です。挿入されたエントリにはプレースホルダー (`codexcommander-loopback`) が含まれます。CodexCommander はループバック接続のアドミッション キーを無視するため、実際の秘密は関係しません。 -**自動登録はループバックのみです。** opencodex が非ループバック ホスト (すべてのインターフェイスを公開するワイルドカード `0.0.0.0` および `::` を含む) をバインドする場合、リクエストには実際のアドミッション トークンが必要であり、マネージド ブロックはそれを安全に運ぶことができません。リテラルトークンを書き込むと、シークレットが `~/.grok/config.toml` に設定され、そこで設定した内容が次の `ocx start`/`ensure`/`restart` に上書きされます。したがって、その場合、opencodex は何も書き込みません (そして、以前のループバック バインドで残ったブロックはすべて削除します)。また、管理対象マーカーの外側でモデルを自分で設定します。opencodex が何をしてもモデルを破壊することはありません。正確なテーブルについては [マニュアルレシピ](#manual-recipe-without-auto-registration) を参照し、`base_url` (`grok` を実行する場所から実際に到達可能なホスト) と `api_key` (`OPENCODEX_API_AUTH_TOKEN`) の両方を設定します。 +**自動登録はループバックのみです。** CodexCommander が非ループバック ホスト (すべてのインターフェイスを公開するワイルドカード `0.0.0.0` および `::` を含む) をバインドする場合、リクエストには実際のアドミッション トークンが必要であり、マネージド ブロックはそれを安全に運ぶことができません。リテラルトークンを書き込むと、シークレットが `~/.grok/config.toml` に設定され、そこで設定した内容が次の `ccx start`/`ensure`/`restart` に上書きされます。したがって、その場合、CodexCommander は何も書き込みません (そして、以前のループバック バインドで残ったブロックはすべて削除します)。また、管理対象マーカーの外側でモデルを自分で設定します。CodexCommander が何をしてもモデルを破壊することはありません。正確なテーブルについては [マニュアルレシピ](#manual-recipe-without-auto-registration) を参照し、`base_url` (`grok` を実行する場所から実際に到達可能なホスト) と `api_key` (`CODEXCOMMANDER_API_AUTH_TOKEN`) の両方を設定します。 ここで `api_key` を `env_key` に置き換えないでください。 `model_provider` が設定されていない場合、解決に失敗した `env_key` はリクエストを停止しません。Grok は xAI セッション トークンに到達し、それをエントリ名が `base_url` に送信します。LAN デプロイメントの場合、これは xAI ではないプレーンテキスト HTTP エンドポイントです。 -注入されたモデルごとの `api_key` は、これらのモデルの Grok 資格情報チェーンの最初に位置するため、opencodex に対抗する場合は追加の Grok ログインは必要ありません。ネイティブ grok モデルおよび xAI に直接接続するハーネス機能については、通常の `grok login` / `XAI_API_KEY` セットアップを維持します。 +注入されたモデルごとの `api_key` は、これらのモデルの Grok 資格情報チェーンの最初に位置するため、CodexCommander に対抗する場合は追加の Grok ログインは必要ありません。ネイティブ grok モデルおよび xAI に直接接続するハーネス機能については、通常の `grok login` / `XAI_API_KEY` セットアップを維持します。 ## 手動レシピ(自動登録なし) -`~/.grok/config.toml` を自分で管理する場合、または opencodex が非ループバック バインド上にある場合は、**直接フィールド**を持つモデルごとのテーブルを `# >>> opencodex managed block` マーカーの外側に追加します。 +`~/.grok/config.toml` を自分で管理する場合、または CodexCommander が非ループバック バインド上にある場合は、**直接フィールド**を持つモデルごとのテーブルを `# >>> CodexCommander managed block` マーカーの外側に追加します。 ```toml -[model.ocx-opus] +[model.ccx-opus] model = "anthropic/claude-opus-4-8" base_url = "http://127.0.0.1:10100/v1" api_backend = "chat_completions" -api_key = "opencodex-loopback" +api_key = "codexcommander-loopback" ``` ネットワーク経由で到達可能なプロキシの場合は、`grok` が実際にダイヤルしてアドミッション トークンを使用できるアドレスに `base_url` を指定します。 ```toml -[model.ocx-opus] +[model.ccx-opus] model = "anthropic/claude-opus-4-8" base_url = "http://192.168.1.10:10100/v1" # the reachable host, not 127.0.0.1 api_backend = "chat_completions" -api_key = "your-OPENCODEX_API_AUTH_TOKEN" +api_key = "your-CODEXCOMMANDER_API_AUTH_TOKEN" ``` エンドポイントの `[model_providers.<id>]` 継承に依存しないでください。Grok Build 0.2.101 では、継承された `base_url` は推論ルーティングに適用されません (リクエストはデフォルトの xAI プロキシにフォールスルーされ、401 で失敗します)。モデルごとのフィールドを正しくルーティングします。 @@ -76,11 +76,11 @@ api_key = "your-OPENCODEX_API_AUTH_TOKEN" ## 既知の制限事項 -- **バックエンドとキープアライブの応答:** opencodex は `response.heartbeat` キープアライブを発行します +- **バックエンドとキープアライブの応答:** CodexCommander は `response.heartbeat` キープアライブを発行します アップストリーム沈黙中の `/v1/responses` ストリーム。 Grok Build の Responses デコーダは未知のイベント タイプを拒否するため、手動で構成された `api_backend = "responses"` モデルは低速なアップストリームではターン中に失敗する可能性があります。自動登録されたエントリは `api_backend = "chat_completions"` をピン留めしますが、生のハートビート フレームが表示されることはありません。 -- **サービスでインストールされた `ocx restart`:** opencodex がサービス マネージャーの下で実行される場合、 -現在、`ocx restart` はサービスを停止し、アンマネージド プロセスに置き換えます。サービスの永続性 (自動再起動、ログイン時開始) は、次の `ocx service` セットアップまで失われます。また、そのアンマネージド プロセスが終了した場合、次の `ocx start`/`ocx ensure` が更新するまで、マネージド ブロックは無効なプロキシを指す可能性があります。 -- **構成読み取りタイミング:** 最初に opencodex を起動し、その後 `grok` を起動します。 -予測可能な結果。 Grok Build は `~/.grok/config.toml` を監視し、`[model]` テーブルが実際に変更されると (内容で比較すると約 1 秒のデバウンス) 再ロードするため、更新されたブロックは再起動せずに開いているセッションに到達します。 Grok が解析した内容を確認するには、`grok inspect` を実行します。ロードされた設定ソースがリストされ、拒否されたフィールドについて警告が表示されます。解決されたモデルのリストは出力されません。単一の TOML エラーがユーザー設定レイヤー「全体」を無効にすることに注意してください。これが、opencodex がファイルをアトミックに書き込む理由です。Grok は書きかけの設定を決して認識しません。 +- **サービスでインストールされた `ccx restart`:** CodexCommander がサービス マネージャーの下で実行される場合、 +現在、`ccx restart` はサービスを停止し、アンマネージド プロセスに置き換えます。サービスの永続性 (自動再起動、ログイン時開始) は、次の `ccx service` セットアップまで失われます。また、そのアンマネージド プロセスが終了した場合、次の `ccx start`/`ccx ensure` が更新するまで、マネージド ブロックは無効なプロキシを指す可能性があります。 +- **構成読み取りタイミング:** 最初に CodexCommander を起動し、その後 `grok` を起動します。 +予測可能な結果。 Grok Build は `~/.grok/config.toml` を監視し、`[model]` テーブルが実際に変更されると (内容で比較すると約 1 秒のデバウンス) 再ロードするため、更新されたブロックは再起動せずに開いているセッションに到達します。 Grok が解析した内容を確認するには、`grok inspect` を実行します。ロードされた設定ソースがリストされ、拒否されたフィールドについて警告が表示されます。解決されたモデルのリストは出力されません。単一の TOML エラーがユーザー設定レイヤー「全体」を無効にすることに注意してください。これが、CodexCommander がファイルをアトミックに書き込む理由です。Grok は書きかけの設定を決して認識しません。 - **カタログの更新:** フェンスで囲まれたブロックには、射出時のカタログが反映されます。後 -プロバイダーまたはモデルを追加するには、`ocx ensure` を実行して (またはプロキシを再起動して) 更新します。 +プロバイダーまたはモデルを追加するには、`ccx ensure` を実行して (またはプロキシを再起動して) 更新します。 diff --git a/docs-site/src/content/docs/ja/guides/image-bridge.md b/docs-site/src/content/docs/ja/guides/image-bridge.md index f07d16a1e9..4df2a560a3 100644 --- a/docs-site/src/content/docs/ja/guides/image-bridge.md +++ b/docs-site/src/content/docs/ja/guides/image-bridge.md @@ -12,7 +12,7 @@ OpenAI 以外のモデル (Claude、Gemini、Grok など) を介して Codex を - **設定で `images.bridgeEnabled: true` を設定してブリッジを有効にします** (これはオフになっています) 予期しない xAI 請求を避けるためのデフォルト — 以下の [構成](#configuration) を参照してください)。 - **API キー**を持つ `xai` プロバイダー エントリ。ブリッジはフルフィルメントをレジストリ xAI に固定します -画像エンドポイント (`https://api.x.ai/v1`);設定された `baseUrl` オーバーライドは、イメージ呼び出しでは無視されます。 OAuth / `ocx login xai` だけではブリッジを準備しません** (Grok CLI OAuth トランスポートはチャット指向であり、`/images/*` には使用されません)。 +画像エンドポイント (`https://api.x.ai/v1`);設定された `baseUrl` オーバーライドは、イメージ呼び出しでは無視されます。 OAuth / `ccx login xai` だけではブリッジを準備しません** (Grok CLI OAuth トランスポートはチャット指向であり、`/images/*` には使用されません)。 「`json { "providers": { "xai": { "adapter": "openai-chat", "apiKey": "xai-…", "authMode": "key" } } } `」 @@ -21,7 +21,7 @@ OpenAI 以外のモデル (Claude、Gemini、Grok など) を介して Codex を ## 構成 -Image Bridge オプションは、`~/.opencodex/config.json` の `images` の下にあります。ブリッジングは**オプトイン**です。有料の xAI Grok Imagine 生成を有効にするには、`bridgeEnabled: true` を設定する必要があります。 +Image Bridge オプションは、`~/.codexcommander/config.json` の `images` の下にあります。ブリッジングは**オプトイン**です。有料の xAI Grok Imagine 生成を有効にするには、`bridgeEnabled: true` を設定する必要があります。 ```json { @@ -44,19 +44,19 @@ Image Bridge オプションは、`~/.opencodex/config.json` の `images` の下 ## アーティファクトの保持 -生成されたイメージは`~/.opencodex/artifacts/`に書き込まれます。長時間実行セッションで際限なくディスクが増大するのを防ぐため、イメージ呼び出しが実行されるたびに (その呼び出しの完全なバッチがディスク上にあると) ディレクトリは自動的にプルーニングされます。カウントが構成された最大値 (デフォルトは 200、`images.artifactsKeepCount` で構成可能) を超えると、(変更時間による) 最も古いファイルが削除されます。枝刈りを生き残ったパスのみがモデルに返されます。 +生成されたイメージは`~/.codexcommander/artifacts/`に書き込まれます。長時間実行セッションで際限なくディスクが増大するのを防ぐため、イメージ呼び出しが実行されるたびに (その呼び出しの完全なバッチがディスク上にあると) ディレクトリは自動的にプルーニングされます。カウントが構成された最大値 (デフォルトは 200、`images.artifactsKeepCount` で構成可能) を超えると、(変更時間による) 最も古いファイルが削除されます。枝刈りを生き残ったパスのみがモデルに返されます。 ## 仕組み Image Bridge は、**非 OpenAI** モデルが選択されているときに、`/v1/responses` ツール配列にホストされた `image_generation` ツールを含む **レスポンス** ターンでのみアクティブになります。これは、`/v1/images/generations` (または `/images/edits`) に直接 POST する Codex の組み込み `image_gen` ツールをインターセプトしません**。そのパスについては [Codexの統合](/guides/codex-integration/#built-in-image-generation-image_gen) で別途説明します。 -1. 応答リクエストで `tools` に `image_generation` がリストされると、OpenCodex がそれを検出します +1. 応答リクエストで `tools` に `image_generation` がリストされると、CodexCommander がそれを検出します リクエストの前処理中。 2. ホストされたツールは、ルーティングされたモデルが呼び出すことができる **合成関数ツール** に置き換えられます。 通常 — モデルは、実行できない不透明なホストされたツールではなく、呼び出し可能なツールを認識します。 -3. モデルがそのツールを呼び出すと、OpenCodex が呼び出しを傍受し、プロンプトを xAI のサーバーに送信します。 +3. モデルがそのツールを呼び出すと、CodexCommander が呼び出しを傍受し、プロンプトを xAI のサーバーに送信します。 画像生成API。 -4. 生成されたイメージは `~/.opencodex/artifacts/` に保存され、**ローカル ファイル パス**が返されます。 +4. 生成されたイメージは `~/.codexcommander/artifacts/` に保存され、**ローカル ファイル パス**が返されます。 ツールの結果としてモデルに適用されます。 5. モデルは、生成された画像とその位置を認識して会話を続けます。 diff --git a/docs-site/src/content/docs/ja/guides/macos-menu-bar.md b/docs-site/src/content/docs/ja/guides/macos-menu-bar.md index d2919dc895..481170acff 100644 --- a/docs-site/src/content/docs/ja/guides/macos-menu-bar.md +++ b/docs-site/src/content/docs/ja/guides/macos-menu-bar.md @@ -1,54 +1,34 @@ --- title: macOS メニューバーコンパニオン -description: OpenCodex のネイティブなステータス、エージェントアクティビティ、プロバイダークォータのコンパニオンをインストールして使用します。 +description: CodexCommander のネイティブなステータス、エージェントアクティビティ、プロバイダークォータのコンパニオンをインストールして使用します。 --- macOS コンパニオンは、プロキシを置き換えたり Web ダッシュボードを重複させたりせずに、最も -有用な OpenCodex の状態をメニューバーに表示します。ネイティブの Swift/AppKit -アプリケーションであり、同じ Mac 上で実行されている OpenCodex インスタンスとのみ通信します。 +有用な CodexCommander の状態をメニューバーに表示します。ネイティブの Swift/AppKit +アプリケーションであり、同じ Mac 上で実行されている CodexCommander インスタンスとのみ通信します。 ## インストール -1. 対応する GitHub リリースから <code>OpenCodex-<version>-macos-universal.zip</code> と - その <code>.sha256</code> ファイルをダウンロードします。 -2. アーカイブを検証します。 - - shasum -a 256 -c OpenCodex-<version>-macos-universal.zip.sha256 - -3. 展開して <code>OpenCodex.app</code> を**アプリケーション**に移動します。 -4. アプリを開きます。アプリには Bun ランタイム、プロキシ、依存関係、ダッシュボードが含まれるため、 - 別途 npm、Bun、<code>ocx</code> をインストールする必要はありません。アイコンはメニューバーに表示され、 - Dock アイコンは追加されません。安定した場所からの初回起動では **Launch at Login** が有効になります。 - -バンドルされたランタイムは既存のユーザー状態(<code>~/.opencodex</code> と <code>~/.codex</code>)を使用します。 -認証情報をアプリバンドルや Keychain にコピーすることはありません。プロバイダーの OAuth と API キー設定は -ローカルダッシュボードで行います。 - -バンドル内のランタイムは読み取り専用です。更新は署名済みの最新 <code>OpenCodex.app</code> を置き換えて行い、 -署名済みの <code>Contents/Resources</code> に対して npm、Bun、ソース更新を実行しません。 - -リリースが Developer ID で署名され、公証されるまでは、macOS がダウンロード後の初回起動を -ブロックする場合があります。アプリを Control-クリックして**開く**を選び、もう一度**開く**を -確認してください。ローカルで作成したビルドには、ダウンロードファイルの隔離属性は付きません。 +パッケージ済み macOS アプリは現在公開されていません。[ソースからビルド](#ソースからビルド)の手順で既存のチェックアウトから実行してください。開発アプリは `dist/macos/CodexCommander.app` に置き、Application Support へコピーしないでください。 ## 起動モード - **Desktop** — サインイン時にメニューアプリを開き、1 つのサーバーを確認または起動します。 -- **Headless** — メニューアプリは開かず、別途インストールした `ocx service` だけを起動します。 -- **Off** — 自動起動せず、アプリまたは `ocx start` で手動起動します。 +- **Headless** — メニューアプリは開かず、別途インストールした `ccx service` だけを起動します。 +- **Off** — 自動起動せず、アプリまたは `ccx start` で手動起動します。 設定行から **Launch at Login** を切り替えられます。承認が必要な場合は macOS の Login Items 設定を直接開けます。この切り替えはバックグラウンドサービスをインストール、停止、削除しません。 -表示中のアプリとバックグラウンドプロキシは別々に動作します。OpenCodex パネルがアクティブなとき、 -**Quit Menu Bar**(`⌘Q`)はコンパニオン UI だけを閉じ、ルーティングを継続します。**Stop OpenCodex and Quit…** +表示中のアプリとバックグラウンドプロキシは別々に動作します。CodexCommander パネルがアクティブなとき、 +**Quit Menu Bar**(`⌘Q`)はコンパニオン UI だけを閉じ、ルーティングを継続します。**Stop CodexCommander and Quit…** (`⌥⌘Q`)は明示的な破壊的終了で、確認後にプロキシとサービスを停止してネイティブ Codex ルーティングを復元し、停止を確認できた場合にのみコンパニオンを終了します。 ## パネルに表示される内容 - **エージェントアクティビティ** — 現在のアクティブ数とライブのモデル/プロバイダー行です。 - OpenCodex がリクエストメタデータからアクティブな親を証明できる場合にのみ、生成された子が + CodexCommander がリクエストメタデータからアクティブな親を証明できる場合にのみ、生成された子が ネストされます。それ以外の場合は独立したサブエージェントとして表示されます。コンパニオンは、 キュー済み、レビュー中、レート制限中、または完了済みの履歴を作り上げることはありません。 - **プロバイダークォータ** — 利用可能な場合、プロバイダーが報告した 5 時間、週間、月間、または @@ -59,7 +39,7 @@ macOS コンパニオンは、プロキシを置き換えたり Web ダッシュ - **管理** — 選択したプロバイダーの Accounts または API Keys タブを開きます。OAuth、API キー 入力、再認証、アカウント切り替え、プロバイダー設定は引き続きダッシュボードで行います。 - **Agent catalog update ready** — 実行中の Codex バックグラウンドワーカーが古いモデル一覧を - 保持しているときに表示される、永続的で非致命的なカードです。OpenCodex プロキシは正常に実行を続けます。 + 保持しているときに表示される、永続的で非致命的なカードです。CodexCommander プロキシは正常に実行を続けます。 - **Apply agent catalog…** — 可能な場合は最新のリクエストアクティビティを表示し、回答が中断される 可能性を警告する確認画面を開きます。選択肢は **Apply Now** と **Later** です。 - **Stop Proxy…** — 常に確認を求め、アクティブなクライアントとサブエージェントのリクエストを中断し、 @@ -69,7 +49,7 @@ macOS コンパニオンは、プロキシを置き換えたり Web ダッシュ 新しいプロセスがアイデンティティチェックに合格するまでアプリが待機します。 - **Quit Menu Bar** — コンパニオン UI だけを閉じます。プロキシ、サービス、クライアントの ルーティングは停止しません。パネルがアクティブなときの安全な `⌘Q` 操作です。 -- **Stop OpenCodex and Quit…** — 中断を確認し、バックグラウンドプロキシとサービスを停止して +- **Stop CodexCommander and Quit…** — 中断を確認し、バックグラウンドプロキシとサービスを停止して ネイティブ Codex ルーティングを復元します。停止を確認できた場合にのみ終了し、失敗時は コンパニオンを開いたままエラーを表示します。パネルがアクティブなときのショートカットは `⌥⌘Q` です。 @@ -85,42 +65,42 @@ Provider 設定を開けます。リンクされた Grok または Kimi CLI の ## エージェントカタログの更新 -アプリを開くと、現在 OpenCodex に設定されているプロバイダーから Codex モデルカタログを自動的に +アプリを開くと、現在 CodexCommander に設定されているプロバイダーから Codex モデルカタログを自動的に 同期します。Codex ワーカーが実行されていなければ、新しい一覧は次の Codex タスクで使用されます。 -長時間実行中のワーカーが古い一覧を読み込んでいる場合も OpenCodex は動作を続け、パネルには非致命的な +長時間実行中のワーカーが古い一覧を読み込んでいる場合も CodexCommander は動作を続け、パネルには非致命的な **Agent catalog update ready** カードが表示され続けます。 中断の可能性を確認するには **Apply agent catalog…** を選びます。可能な場合は直前にアクティブな リクエスト数を取得しますが、ゼロ件でも Codex がアイドルである証明とは表示しません。処理開始前に 新しいリクエストが始まる可能性があるためです。**Apply Now** はもう一度同期し、現在のユーザーが所有する 正確な `codex … app-server` と `codex-code-mode-host` の一致だけに `SIGTERM` を送り、古いプロセス ID が -終了したことを短時間確認します。広範な `pkill` は使わず、OpenCodex プロキシを再起動せず、メニュー +終了したことを短時間確認します。広範な `pkill` は使わず、CodexCommander プロキシを再起動せず、メニュー アプリも閉じません。次のタスクで Codex が新しいバックグラウンドホストを作成し、最新の一覧を読み込みます。 -このリリースには **Apply when idle** はありません。回答が進行中なら **Later** を選び、準備ができてから +現在のコンパニオンには **Apply when idle** はありません。回答が進行中なら **Later** を選び、準備ができてから 更新してください。カードは表示されたままです。上級者向けの CLI フォールバックは次のとおりです。 ```bash -ocx sync --restart-codex +ccx sync --restart-codex ``` ## 認証とプライバシー -コンパニオンは別のログインシステムを作らず、macOS Keychain への移行やそこからのプロバイダー -認証情報の読み取りも行いません。 +コンパニオンは別のログインシステムを作らず、macOS Keychain を使用せず、そこからプロバイダー +認証情報を読み取ることもありません。 -現在の OpenCodex バージョンは、<code>~/.opencodex/admin-api-token</code>(または -<code>$OPENCODEX_HOME/admin-api-token</code>)に独立した管理用認証情報を生成します。 +現在の CodexCommander バージョンは、<code>~/.codexcommander/admin-api-token</code>(または +<code>$CODEXCOMMANDER_HOME/admin-api-token</code>)に独立した管理用認証情報を生成します。 コンパニオンは、シンボリックリンクをたどらないよう検証されたファイルディスクリプターを通じて 既存のファイルを読み取り、値をプロセスメモリ内だけに保持し、アイデンティティが検証された -ループバックの OpenCodex プロセスにのみ送信します。トークンを表示、ログ記録、コピー、保存したり、 +ループバックの CodexCommander プロセスにのみ送信します。トークンを表示、ログ記録、コピー、保存したり、 ブラウザー URL に入れたりすることはありません。 -プロバイダー認証情報の管理は引き続き OpenCodex が担います。コンパニオンは ChatGPT、Kimi、 +プロバイダー認証情報の管理は引き続き CodexCommander が担います。コンパニオンは ChatGPT、Kimi、 Grok、Anthropic、その他のプロバイダートークンを読み取らず、プロバイダーのログイン エンドポイントを直接呼び出すこともありません。 -<code>OPENCODEX_ADMIN_AUTH_TOKEN</code> だけで構成されたインストールは、その変数をアプリ +<code>CODEXCOMMANDER_ADMIN_AUTH_TOKEN</code> だけで構成されたインストールは、その変数をアプリ プロセスが継承している場合に動作します。Finder から起動したアプリは通常、シェル変数を 継承しません。保護されたトークンファイルがない場合、コンパニオンはトークン入力フォームを 表示せず、管理認証が利用できないことを報告します。 @@ -133,7 +113,7 @@ Grok、Anthropic、その他のプロバイダートークンを読み取らず ## ポーリング パネルが開いている間、アプリは軽量なアクティビティ情報を頻繁に更新し、閉じると頻度を -下げます。プロバイダークォータは別のより遅い間隔で更新され、OpenCodex が報告するアップ +下げます。プロバイダークォータは別のより遅い間隔で更新され、CodexCommander が報告するアップ ストリームのタイムスタンプを使用します。失敗が繰り返されると自動的にバックオフし、重複する 更新はまとめられます。 @@ -141,40 +121,38 @@ Grok、Anthropic、その他のプロバイダートークンを読み取らず ## ソースからビルド -macOS 13 以降と Xcode Command Line Tools が必要です。Intel + Apple silicon のユニバーサル -リリースビルドには完全版の Xcode が必要です。 +macOS 13 以降と Xcode Command Line Tools が必要です。Intel + Apple silicon のユニバーサルビルドには完全版の Xcode が必要です。 ```bash -git clone https://github.com/pavelhov/opencodex.git -cd opencodex +cd /path/to/CodexCommander bun install bun run test:macos bun run build:macos -open dist/macos/OpenCodex.app +open dist/macos/CodexCommander.app ``` -ソースアプリの場所は `dist/macos/OpenCodex.app` です。同じ checkout の Bun と CLI を使うため、 +ソースアプリの場所は `dist/macos/CodexCommander.app` です。同じ checkout の Bun と CLI を使うため、 先に `bun install` が必要です。開発中はこの場所に置き、Application Support へコピーしないでください。 ダブルクリックするとプロキシの起動を試みますが、オフラインまたは起動失敗でもアプリは閉じず、 パネルと **Start** コントロールは利用できます。 -各ビルドは正確な Git リビジョンをバンドルの `Info.plist` の `OpenCodexSourceRevision` に記録し、 +各ビルドは正確な Git リビジョンをバンドルの `Info.plist` の `CodexCommanderSourceRevision` に記録し、 ビルド完了時にも表示します。未コミットのソースには `-dirty` が付くため、最終配布ビルドの前に コミットしてください。 ## トラブルシューティング -- **プロキシが利用できない** — <code>ocx start</code> で起動するか、 - <code>ocx service install</code> でバックグラウンドサービスをインストールします。 -- **認証が利用できない** — <code>ocx doctor</code> を実行します。OpenCodex の状態ディレクトリと +- **プロキシが利用できない** — <code>ccx start</code> で起動するか、 + <code>ccx service install</code> でバックグラウンドサービスをインストールします。 +- **認証が利用できない** — <code>ccx doctor</code> を実行します。CodexCommander の状態ディレクトリと <code>admin-api-token</code> が自分のユーザーの所有物であり、グループおよびその他のユーザーから アクセスできないことを確認してください。 - **クォータが利用できない** — プロバイダーの**管理**先を開き、アカウントを接続するか再認証 します。Grok に**ログインの更新が必要**と表示された場合は <code>grok</code> でログインを完了し、 - OpenCodex で**更新**してください。Kimi の場合は <code>kimi</code> を使用します。一部のプロバイダーは + CodexCommander で**更新**してください。Kimi の場合は <code>kimi</code> を使用します。一部のプロバイダーは クォータ API を公開していません。 -- **再起動後に復旧しない** — **Logs** を開き、<code>ocx status</code> を実行します。コンパニオンは +- **再起動後に復旧しない** — **Logs** を開き、<code>ccx status</code> を実行します。コンパニオンは フォールバックとしてプロセスを強制終了したり、サービス状態を書き換えたりしません。 -- **停止・更新・コールドスタート後にネイティブモデルしか表示されない** — OpenCodex を再度開いて +- **停止・Codex 更新・コールドスタート後にネイティブモデルしか表示されない** — CodexCommander を再度開いて ください。起動時にカタログを自動同期し、プロバイダー検出が一時的に空でも、保護された最終正常 カタログから現在も設定されているルートモデルを復元します。**Agent catalog update ready** が残る場合は **Apply agent catalog…** を選ぶか、[エージェントカタログの更新](#エージェントカタログの更新)にある @@ -182,7 +160,7 @@ open dist/macos/OpenCodex.app ## アンインストール -**Launch at Login** をオフにしてからコンパニオンを終了し、<code>OpenCodex.app</code> をゴミ箱に +**Launch at Login** をオフにしてからコンパニオンを終了し、<code>CodexCommander.app</code> をゴミ箱に 移動します。プロバイダー認証情報を保存せず、Keychain 項目も作成しません。コンパニオンを -アンインストールしても OpenCodex プロキシは停止または削除されません。ヘッドレスサービスも -削除する場合のみ、別途 <code>ocx service uninstall</code> を実行してください。 +アンインストールしても CodexCommander プロキシは停止または削除されません。ヘッドレスサービスも +削除する場合のみ、別途 <code>ccx service uninstall</code> を実行してください。 diff --git a/docs-site/src/content/docs/ja/guides/model-ordering.md b/docs-site/src/content/docs/ja/guides/model-ordering.md index d4f32bfe6a..f23e68525e 100644 --- a/docs-site/src/content/docs/ja/guides/model-ordering.md +++ b/docs-site/src/content/docs/ja/guides/model-ordering.md @@ -1,9 +1,9 @@ --- title: モデルの並び順について -description: opencodex が Codex モデルピッカーと spawn_agent モデルオーバーライドの順序を決める方式。 +description: CodexCommander が Codex モデルピッカーと spawn_agent モデルオーバーライドの順序を決める方式。 --- -Codex モデルピッカーは opencodex 設定に書かれたプロバイダー宣言順やモデル配列順を保存しません。 +Codex モデルピッカーは CodexCommander 設定に書かれたプロバイダー宣言順やモデル配列順を保存しません。 最終順序はカタログ priority で決まり、同じ priority を持つルーティングモデルには決定論的 アルファベット順ソートが適用されます。 @@ -12,7 +12,7 @@ Codex モデルピッカーは opencodex 設定に書かれたプロバイダー Codex の models-manager はピッカーに表示されるカタログ項目を `priority` 昇順でソートします。 カタログ配列順は捨てるため、生成された JSON 配列で項目を前に動かしてもピッカーでは前に移動しません。この制約は `src/codex/catalog/sync.ts` に直接記録されています。 -そのため opencodex は配列位置ではなくより低い priority を付与してフィーチャー位置を制御します。 +そのため CodexCommander は配列位置ではなくより低い priority を付与してフィーチャー位置を制御します。 この表の固定値と以下の例は、有効な account selector がない構成を説明します。`N` 個の selector が ある場合、設定 rank `i` の featured bare native は priority `i * N + j` の selector 行へ展開され、 `j` は 0 から始まる selector の位置です。featured routed 行には `i * N`、exact @@ -67,7 +67,7 @@ Codex の priority ソートでもこの先頭順序は保存されます。 3. カタログマージ過程で featured ブロックの下に押し下げられた選択されていないネイティブモデル `subagentModels` がない場合、ルーティングモデルは priority `5` を維持し、ネイティブ GPT 項目は通常 priority -(opencodex が作った項目は通常 `9`)を使います。ルーティンググループ内部は引き続きプロバイダー/ID +(CodexCommander が作った項目は通常 `9`)を使います。ルーティンググループ内部は引き続きプロバイダー/ID アルファベット順です。 ## 例 @@ -110,12 +110,12 @@ account selector がある場合、5 項目の制限は bare native の選択が **Agent Library** には 5 つをはるかに超えるカタログモデルが含まれる場合があります。ルートが利用可能な 場合にエントリを正確な id で指定でき、5 枠の制限は `spawn_agent` に最初に公開されるオーバーライドにのみ適用されます。 -`ocx agent subagents set` を使うか、opencodex 設定を編集して、ライブ ライブラリにない正確な +`ccx agent subagents set` を使うか、CodexCommander 設定を編集して、ライブ ライブラリにない正確な `<selector>/<native-openai-model>` の選択肢を追加します。コマンド センターは、設定済みの正確な selector を、そのプロバイダーが一時的に利用できない間も保持し、並べ替えできます。account selector がある 場合は 1 つの bare native が複数の selector-qualified 行に展開されるため、設定した選択肢と公開される 行は必ずしも一対一ではありません。 -現在 `OcxConfig` には一般 `modelOrder`、`providerOrder`、priority map 設定はありません。サポートされるソート +現在 `CodexCommanderConfig` には一般 `modelOrder`、`providerOrder`、priority map 設定はありません。サポートされるソート フィールドは `subagentModels` です。`disabledModels` と各プロバイダーの `selectedModels` は公開 フィールドです。そのため残りのピッカー順序を変えるには設定変更ではなくコード動作の変更が必要です。 diff --git a/docs-site/src/content/docs/ja/guides/model-routing.md b/docs-site/src/content/docs/ja/guides/model-routing.md index 1268afc175..dac033ccf4 100644 --- a/docs-site/src/content/docs/ja/guides/model-routing.md +++ b/docs-site/src/content/docs/ja/guides/model-routing.md @@ -1,6 +1,6 @@ --- title: モデルルーティング -description: opencodex が与えられたモデル ID をどのプロバイダーが処理するか決定する方式。 +description: CodexCommander が与えられたモデル ID をどのプロバイダーが処理するか決定する方式。 --- Codex がモデルを要求すると `router.ts` がこれを正確に一つの設定されたプロバイダーに解釈します。ルールは @@ -26,7 +26,7 @@ model ID は変更しません。`openai-apikey/<model>` は API key transport 2. **Combo ID または alias** — 1 つ以上の combo が設定されている間は、canonical `combo/<id>` または設定済み combo alias が provider namespace より先に concrete target を選択します。 - combo が 1 つも設定されていない場合、文字どおり `combo` という名前の legacy physical provider + combo が 1 つも設定されていない場合、文字どおり `combo` という名前の physical provider は通常の provider namespace として残ります。target selection と failover の動作は [Combos](/ja/guides/combos/)を参照してください。 diff --git a/docs-site/src/content/docs/ja/guides/opencode.md b/docs-site/src/content/docs/ja/guides/opencode.md index 46650ba90a..73e9cafe95 100644 --- a/docs-site/src/content/docs/ja/guides/opencode.md +++ b/docs-site/src/content/docs/ja/guides/opencode.md @@ -1,97 +1,97 @@ --- title: オープンコード -description: オープンコードからルーティングされたモデルを使用します。opencodex はランタイム プロバイダー ブロックを挿入し、独自のオープンコード設定をそのまま残します。 +description: オープンコードからルーティングされたモデルを使用します。CodexCommander はランタイム プロバイダー ブロックを挿入し、独自のオープンコード設定をそのまま残します。 --- -opencode は、環境変数ではなくマージされた JSON 構成レイヤーからプロバイダーを読み取るため、挿入する `ANTHROPIC_BASE_URL` スタイルのスロットはありません。 `ocx opencode` はそのギャップを橋渡しします。プロキシが実行されていることを確認し、表示されているカタログからプロバイダー ブロックを構築し、OpenCode のインライン ランタイム層 (`OPENCODE_CONFIG_CONTENT`) を通じてそれを挿入します。 +opencode は、環境変数ではなくマージされた JSON 構成レイヤーからプロバイダーを読み取るため、挿入する `ANTHROPIC_BASE_URL` スタイルのスロットはありません。 `ccx opencode` はそのギャップを橋渡しします。プロキシが実行されていることを確認し、表示されているカタログからプロバイダー ブロックを構築し、OpenCode のインライン ランタイム層 (`OPENCODE_CONFIG_CONTENT`) を通じてそれを挿入します。 ## クイックスタート ```bash -ocx opencode +ccx opencode ``` -これにより、プロキシが確実に実行され、そのプロセスに挿入された生成された `provider.opencodex` ブロックのみを使用してオープンコードが起動されます。追加の引数は `ocx opencode run "hello"` を通過します。 +これにより、プロキシが確実に実行され、そのプロセスに挿入された生成された `provider.codexcommander` ブロックのみを使用してオープンコードが起動されます。追加の引数は `ccx opencode run "hello"` を通過します。 -ルーティングされたモデルは、ピッカーの `opencodex` プロバイダーの下に表示されます。 +ルーティングされたモデルは、ピッカーの `codexcommander` プロバイダーの下に表示されます。 ```text -opencodex/kiro/glm-5 -opencodex/gpt-5.6-sol # native slugs stay unprefixed +codexcommander/kiro/glm-5 +codexcommander/gpt-5.6-sol # native slugs stay unprefixed ``` ## あなた自身の設定は決して変更されません -ランチャーは、`~/.config/opencode/opencode.json`、プロジェクト `opencode.json` / `opencode.jsonc`、またはその他のディスク上の構成レイヤーをコピーしたり書き換えたりしません。既存のプロバイダー、エージェント、キーバインド、MCP エントリ、および相対的な `{file:…}` 参照は元のファイルから解決され続けますが、`provider.opencodex` オーバーライドを検出するためにグローバルまたはプロジェクト設定を読み取ることがあります。 +ランチャーは、`~/.config/opencode/opencode.json`、プロジェクト `opencode.json` / `opencode.jsonc`、またはその他のディスク上の構成レイヤーをコピーしたり書き換えたりしません。既存のプロバイダー、エージェント、キーバインド、MCP エントリ、および相対的な `{file:…}` 参照は元のファイルから解決され続けますが、`provider.codexcommander` オーバーライドを検出するためにグローバルまたはプロジェクト設定を読み取ることがあります。 -この起動の場合のみ、opencodex は、OpenCode のインライン ランタイム層を介して、生成された `provider.opencodex` ブロックを追加します。そのレイヤーは、グローバル/カスタム/プロジェクト設定の後にマージされ、子プロセスの競合するキーのみをオーバーライドします。 +この起動の場合のみ、CodexCommander は、OpenCode のインライン ランタイム層を介して、生成された `provider.codexcommander` ブロックを追加します。そのレイヤーは、グローバル/カスタム/プロジェクト設定の後にマージされ、子プロセスの競合するキーのみをオーバーライドします。 -|レイヤー | `ocx opencode` での動作 | +|レイヤー | `ccx opencode` での動作 | | --- | --- | |グローバル / カスタム / プロジェクト構成 |書き込んだとおりにディスク上に残ります | -|インライン ランタイム (`OPENCODE_CONFIG_CONTENT`) |生成された `provider.opencodex` ブロックのみを受信します。 +|インライン ランタイム (`OPENCODE_CONFIG_CONTENT`) |生成された `provider.codexcommander` ブロックのみを受信します。 |相対 `{file:…}` パス |最初に定義した設定ファイルに対して引き続き解決します。 -グローバルまたはプロジェクト設定でも `provider.opencodex` が定義されている場合、ランチャーは情報メモを出力します。`ocx opencode` のランタイム層がその起動に対してそれをオーバーライドします。 +グローバルまたはプロジェクト設定でも `provider.codexcommander` が定義されている場合、ランチャーは情報メモを出力します。`ccx opencode` のランタイム層がその起動に対してそれをオーバーライドします。 ## ダッシュボードの永続接続(任意) -通常の OpenCode、エディター統合、または Desktop のワンクリック起動で使うには、OpenCodex -ダッシュボードの **Integrations** で **Apply connection** を選びます。これは `ocx opencode` とは +通常の OpenCode、エディター統合、または Desktop のワンクリック起動で使うには、CodexCommander +ダッシュボードの **Integrations** で **Apply connection** を選びます。これは `ccx opencode` とは 別の経路です。 - `XDG_CONFIG_HOME` 配下(通常は `~/.config/opencode/`)のアクティブなグローバル設定を選び、 `opencode.jsonc` が存在すればそれを、なければ `opencode.json` を使います。 -- JSONC 編集は `provider.opencodex` だけを変更するため、コメント、書式、他のプロバイダー、 +- JSONC 編集は `provider.codexcommander` だけを変更するため、コメント、書式、他のプロバイダー、 エージェント、MCP、無関係なキーは保持されます。 -- プロキシのアドミッション トークンは OpenCodex の保護された状態に残り、OpenCode 設定には +- プロキシのアドミッション トークンは CodexCommander の保護された状態に残り、OpenCode 設定には `{file:/absolute/path}` 参照だけが入ります。OpenCode の認証ストアは読みません。 - **Always keep OpenCode connected** はデフォルトでオフで、明示的に有効にした後だけプロキシ起動や 表示カタログ変更時にこの管理ブロックを更新します。 journal が正確な復元を安全と確認した場合、**Restore** は元のバイト列を正確に復元します。それ以外では、 -ダッシュボードは他のユーザー編集を保持したまま管理対象の `provider.opencodex` だけを外科的に +ダッシュボードは他のユーザー編集を保持したまま管理対象の `provider.codexcommander` だけを外科的に 復元または削除します。**Open OpenCode** は OpenCode Desktop をワンクリックで起動します。CLI だけの -場合は、ディスクを変更しない `ocx opencode` を使用してください。 +場合は、ディスクを変更しない `ccx opencode` を使用してください。 ## ブロックを独自の設定に入れる -`ocx opencode` は 1 回の起動に対してのみプロバイダー ブロックを挿入します。上のダッシュボード永続接続を +`ccx opencode` は 1 回の起動に対してのみプロバイダー ブロックを挿入します。上のダッシュボード永続接続を 適用していない場合、プレーン `opencode` はまだプロキシについて何も知りません。プレーンな `opencode` -から、またはランチャーを経由しないエディター拡張機能からルーティングされたモデルを利用できるようにしたい場合、`ocx export` は同じプロバイダー ブロックを出力して、独自の設定にマージします。 +から、またはランチャーを経由しないエディター拡張機能からルーティングされたモデルを利用できるようにしたい場合、`ccx export` は同じプロバイダー ブロックを出力して、独自の設定にマージします。 ```bash -ocx export --client opencode +ccx export --client opencode ``` プロキシが実行されている必要があります。このコマンドは、構成、正規の宛先 (`~/.config/opencode/opencode.json`、またはそれが設定されている場合は `XDG_CONFIG_HOME` の下)、マージ警告、および env エクスポート行を出力します。そのファイルには決して触れません。上記のセクションはそのままであり、ブロックを設定に移動するのは明示的な行為です。 :::caution[マージし、決して置き換えないでください] -`provider.opencodex` ブロックを既存の設定にマージします。ファイル全体をエクスポートされたファイルで置き換えると、他のプロバイダー、エージェント、キーバインド、および MCP エントリが破壊されます。 `ocx export --out` はまさにこの理由で既存のファイルの上書きを拒否するため、`--out` をスクラッチ パスに指定し、ブロックを次のようにコピーします。 +`provider.codexcommander` ブロックを既存の設定にマージします。ファイル全体をエクスポートされたファイルで置き換えると、他のプロバイダー、エージェント、キーバインド、および MCP エントリが破壊されます。 `ccx export --out` はまさにこの理由で既存のファイルの上書きを拒否するため、`--out` をスクラッチ パスに指定し、ブロックを次のようにコピーします。 ```bash -ocx export --client opencode --out ~/opencodex-opencode.json +ccx export --client opencode --out ~/codexcommander-opencode.json ``` ::: -ランチャーのランタイム ブロックとは異なり、マージされたブロックは静的なスナップショットであり、カタログに従いません。プロバイダーを追加するか、モデルの可視性を変更した後、`ocx export` を再実行します。 +ランチャーのランタイム ブロックとは異なり、マージされたブロックは静的なスナップショットであり、カタログに従いません。プロバイダーを追加するか、モデルの可視性を変更した後、`ccx export` を再実行します。 マージしたら、オープンコードを起動する前にアドミッション キーをエクスポートします。プロキシがループバック上にある場合を除き、何も必要ありません。 ```bash -export OPENCODEX_OPENCODE_API_KEY=<your key> +export CODEXCOMMANDER_OPENCODE_API_KEY=<your key> ``` ## アドミッションキーがディスクに書き込まれません -プロキシが API キーを必要とする場合、インライン ランタイム設定にはシークレットではなくオープンコードの `{env:…}` 参照が含まれます。ループバック バインドでは、その参照を `apiKey` として使用します。非ループバック バインドは `x-opencodex-api-key` を介してのみ送信するため、プロキシ アドミッションはアップストリームの `Authorization` ヘッダーから分離されたままになります。 +プロキシが API キーを必要とする場合、インライン ランタイム設定にはシークレットではなくオープンコードの `{env:…}` 参照が含まれます。ループバック バインドでは、その参照を `apiKey` として使用します。非ループバック バインドは `x-codexcommander-api-key` を介してのみ送信するため、プロキシ アドミッションはアップストリームの `Authorization` ヘッダーから分離されたままになります。 ループバックの例: ```json "options": { "baseURL": "http://127.0.0.1:10100/v1", - "apiKey": "{env:OPENCODEX_OPENCODE_API_KEY}" + "apiKey": "{env:CODEXCOMMANDER_OPENCODE_API_KEY}" } ``` @@ -101,18 +101,18 @@ export OPENCODEX_OPENCODE_API_KEY=<your key> "options": { "baseURL": "http://192.168.1.10:10100/v1", "headers": { - "x-opencodex-api-key": "{env:OPENCODEX_OPENCODE_API_KEY}" + "x-codexcommander-api-key": "{env:CODEXCOMMANDER_OPENCODE_API_KEY}" } } ``` -実際の値は、子プロセス環境を介してのみ渡されます。 `OPENCODEX_API_AUTH_TOKEN` が優先され、次に強化されたサービス トークン ファイル、次に設定された API キーが優先されます。これは、非ループバック バインドに必要なものです。 +実際の値は、子プロセス環境を介してのみ渡されます。 `CODEXCOMMANDER_API_AUTH_TOKEN` が優先され、次に強化されたサービス トークン ファイル、次に設定された API キーが優先されます。これは、非ループバック バインドに必要なものです。 -ループバック バインド (`127.0.0.1`、デフォルト) は何も認証しないため、`{env:…}` 参照は不活性であり、変数を設定しないままにすることができます。 `hostname` がループバックを超えて設定されている場合にのみ問題になります。 [リモートアクセス](/reference/configuration/#remote-access)を参照してください。このアドミッション キーは opencodex 独自のものであり、[プロバイダー](/guides/providers/) で構成されたアップストリーム プロバイダー キーとは無関係です。 +ループバック バインド (`127.0.0.1`、デフォルト) は何も認証しないため、`{env:…}` 参照は不活性であり、変数を設定しないままにすることができます。 `hostname` がループバックを超えて設定されている場合にのみ問題になります。 [リモートアクセス](/reference/configuration/#remote-access)を参照してください。このアドミッション キーは CodexCommander 独自のものであり、[プロバイダー](/guides/providers/) で構成されたアップストリーム プロバイダー キーとは無関係です。 ## 元に戻す -一時的な `ocx opencode` では元に戻す必要はありません。OpenCode 設定ファイルを変更しないためです。 +一時的な `ccx opencode` では元に戻す必要はありません。OpenCode 設定ファイルを変更しないためです。 ダッシュボード接続は **Integrations** の **Restore** で戻します。journal が許可すれば元のバイト列を 正確に復元し、それ以外では管理対象プロバイダーだけが外科的に復元されます。 @@ -122,7 +122,7 @@ export OPENCODEX_OPENCODE_API_KEY=<your key> opencode のスキーマは、`output` のない `context` を含む `limit` ブロックを拒否し、カタログにはモデルごとに権限のある出力フィールドがないため、`32000` の `output` バジェットが一緒に出力され、コンテキスト ウィンドウに固定されるため、コンテキストの小さいモデルには `output > context` が与えられません。この数値はスキーマを満たすために存在します。これは、特定のモデルの真の最大値について主張するものではありません。 -`opencodex` プロバイダー ブロックは起動のたびに再生成されるため、内部で行われたモデルごとの調整は存続しません。代わりに、独自のプロバイダー キーの下にカスタム エントリを保持します。 +`codexcommander` プロバイダー ブロックは起動のたびに再生成されるため、内部で行われたモデルごとの調整は存続しません。代わりに、独自のプロバイダー キーの下にカスタム エントリを保持します。 ## 要件 diff --git a/docs-site/src/content/docs/ja/guides/pi.md b/docs-site/src/content/docs/ja/guides/pi.md index 788fe48c60..b134760326 100644 --- a/docs-site/src/content/docs/ja/guides/pi.md +++ b/docs-site/src/content/docs/ja/guides/pi.md @@ -1,17 +1,17 @@ --- title: 円周率 -description: Pi からルーティングされたモデルを使用します。ocx エクスポートは、実行中のプロキシに接続された Pi の models.json のカスタム プロバイダー ブロックを書き込みます。 +description: Pi からルーティングされたモデルを使用します。ccx エクスポートは、実行中のプロキシに接続された Pi の models.json のカスタム プロバイダー ブロックを書き込みます。 --- -Pi は環境変数ではなく単一のグローバル JSON ファイルからプロバイダーを読み取るため、opencodex はそれを起動しません。代わりに、`ocx export` は `opencodex` プロバイダー ブロック (ベース URL、モデル リスト、Pi が補間する環境参照) をシリアル化し、それを独自の設定にマージします。 +Pi は環境変数ではなく単一のグローバル JSON ファイルからプロバイダーを読み取るため、CodexCommander はそれを起動しません。代わりに、`ccx export` は `codexcommander` プロバイダー ブロック (ベース URL、モデル リスト、Pi が補間する環境参照) をシリアル化し、それを独自の設定にマージします。 ## クイックスタート プロキシを開始し、設定を出力します。 ```bash -ocx start -ocx export --client pi +ccx start +ccx export --client pi ``` 出力は JSON で始まり、宛先パス、マージ警告、env エクスポート行、および権威コンテキスト制限を持つモデルの数を出力します。 @@ -19,10 +19,10 @@ ocx export --client pi ```json { "providers": { - "opencodex": { + "codexcommander": { "baseUrl": "http://127.0.0.1:10100/v1", "api": "openai-completions", - "apiKey": "$OPENCODEX_API_KEY", + "apiKey": "$CODEXCOMMANDER_API_KEY", "models": [ { "id": "anthropic/claude-opus-5", @@ -48,15 +48,15 @@ Pi のグローバル モデル設定は次のとおりです。 ``` :::caution[マージし、決して置き換えないでください] -`ocx export` はそのファイルを書き込むことはありません。 `providers.opencodex` ブロックをそれにマージします。ファイルを置き換えると、そこで構成した他のプロバイダーはすべて破棄されます。 `--out` はスクラッチ パスに存在し、`--force` なしで既存のファイルを上書きすることを拒否します。 +`ccx export` はそのファイルを書き込むことはありません。 `providers.codexcommander` ブロックをそれにマージします。ファイルを置き換えると、そこで構成した他のプロバイダーはすべて破棄されます。 `--out` はスクラッチ パスに存在し、`--force` なしで既存のファイルを上書きすることを拒否します。 ```bash -ocx export --client pi --out ~/opencodex-pi-models.json -ocx export --client pi --json > ~/opencodex-pi-models.json # or redirect the byte-exact JSON +ccx export --client pi --out ~/codexcommander-pi-models.json +ccx export --client pi --json > ~/codexcommander-pi-models.json # or redirect the byte-exact JSON ``` ::: -エクスポートされたブロックは静的なスナップショットであり、ライブ ビューではありません。プロバイダーを追加するかモデルの可視性を変更した後、`ocx export` を再実行し、新しいブロックを古いブロックにマージします。 +エクスポートされたブロックは静的なスナップショットであり、ライブ ビューではありません。プロバイダーを追加するかモデルの可視性を変更した後、`ccx export` を再実行し、新しいブロックを古いブロックにマージします。 ## アドミッションキー @@ -64,33 +64,33 @@ ocx export --client pi --json > ~/opencodex-pi-models.json # or redirect the b |キー |それは何ですか |それが住んでいる場所 | | --- | --- | --- | -|プロキシ アドミッション キー | opencodex 自身の認証情報。ダッシュボードの **API** タブで生成されます。 `apiKey` では `$OPENCODEX_API_KEY` として参照されます。値は環境内に残ります。 -|プロバイダーキー | Anthropic / OpenAI / OpenRouter キー | opencodex 独自の設定、[プロバイダー](/guides/providers/) ごと | +|プロキシ アドミッション キー | CodexCommander 自身の認証情報。ダッシュボードの **API** タブで生成されます。 `apiKey` では `$CODEXCOMMANDER_API_KEY` として参照されます。値は環境内に残ります。 +|プロバイダーキー | Anthropic / OpenAI / OpenRouter キー | CodexCommander 独自の設定、[プロバイダー](/guides/providers/) ごと | エクスポートされた設定には参照のみが含まれ、シークレットは含まれません。 Pi は裸の `$NAME` を補間するため、変数は次のようになります。 ```bash -export OPENCODEX_API_KEY=<your key> +export CODEXCOMMANDER_API_KEY=<your key> ``` -その名前はパイだけです。 opencode は別の変数 (`OPENCODEX_OPENCODE_API_KEY`、`{env:…}` 形式) を使用します。[オープンコードガイド](/guides/opencode/) を参照してください。 +その名前はパイだけです。 opencode は別の変数 (`CODEXCOMMANDER_OPENCODE_API_KEY`、`{env:…}` 形式) を使用します。[オープンコードガイド](/guides/opencode/) を参照してください。 -**ループバック プロキシにはキーはまったく必要ありません。** opencodex はデフォルトで `127.0.0.1` をバインドし、そこでは何も認証しないため、`$OPENCODEX_API_KEY` 参照は不活性であり、変数を設定しないままにすることができます。これは、`hostname` がループバックを超えて設定されている場合にのみ問題になります。これは、プロキシがトークンなしでの開始を拒否する場合でもあります。[リモートアクセス](/reference/configuration/#remote-access) を参照してください。 +**ループバック プロキシにはキーはまったく必要ありません。** CodexCommander はデフォルトで `127.0.0.1` をバインドし、そこでは何も認証しないため、`$CODEXCOMMANDER_API_KEY` 参照は不活性であり、変数を設定しないままにすることができます。これは、`hostname` がループバックを超えて設定されている場合にのみ問題になります。これは、プロキシがトークンなしでの開始を拒否する場合でもあります。[リモートアクセス](/reference/configuration/#remote-access) を参照してください。 ## モデルのメタデータ -`contextWindow` および `maxTokens` は、カタログが権限のあるコンテキスト ウィンドウを報告する場合にのみ発行されます。そうでない場合、そのモデルでは両方のフィールドが省略され、Pi は独自のデフォルトを適用します。 `ocx export` は、そのケースに該当する行数を出力します。 +`contextWindow` および `maxTokens` は、カタログが権限のあるコンテキスト ウィンドウを報告する場合にのみ発行されます。そうでない場合、そのモデルでは両方のフィールドが省略され、Pi は独自のデフォルトを適用します。 `ccx export` は、そのケースに該当する行数を出力します。 `maxTokens` は、`32000` のスキーマを満たすバジェットであり、コンテキスト ウィンドウに固定されているため、小さなコンテキスト モデルにはコンテキストを超える出力が与えられません。これは、特定のモデルの真の最大値について主張するものではありません。 -2 つのフィールドは意図的に省略されています。 `cost` には 4 つの価格フィールドがすべて必要ですが、opencodex にはルーティング モデルの価格データがありません。ゼロを出力すると、すべてのモデルが無料であると主張されます。 `reasoning` は Pi のブール値ですが、カタログにはエフォート ラダーが記載されており、一方をもう一方にマッピングするのは推測になります。 +2 つのフィールドは意図的に省略されています。 `cost` には 4 つの価格フィールドがすべて必要ですが、CodexCommander にはルーティング モデルの価格データがありません。ゼロを出力すると、すべてのモデルが無料であると主張されます。 `reasoning` は Pi のブール値ですが、カタログにはエフォート ラダーが記載されており、一方をもう一方にマッピングするのは推測になります。 ## スキーマのステータス :::note[実際のインストールに対して未検証] -上の形状は、Pi が公開しているカスタム プロバイダーのドキュメントに従っています。 Pi がインストールされたマシン上の実際の `~/.pi/agent/models.json` に対して検証されていません**。 Pi がエクスポートされたブロックを拒否した場合、不一致は私たちの側にあります。Pi が報告した内容を [問題を開く](https://github.com/lidge-jun/opencodex/issues) してください。 +上の形状は、Pi が公開しているカスタム プロバイダーのドキュメントに従っています。 Pi がインストールされたマシン上の実際の `~/.pi/agent/models.json` に対して検証されていません**。 Pi がエクスポートされたブロックを拒否した場合、不一致は私たちの側にあります。Pi が報告した内容を [問題を開く](https://github.com/pavelhov/CodexCommander/issues) してください。 ::: ## 要件 -実行中の opencodex プロキシ (`ocx start`) と Pi がインストールされている。 `ocx export` はプロキシの管理 API を通じてライブ カタログを読み取るため、空のモデル リストで設定を出力することはできません。 +実行中の CodexCommander プロキシ (`ccx start`) と Pi がインストールされている。 `ccx export` はプロキシの管理 API を通じてライブ カタログを読み取るため、空のモデル リストで設定を出力することはできません。 diff --git a/docs-site/src/content/docs/ja/guides/providers.md b/docs-site/src/content/docs/ja/guides/providers.md index 5029b0f2ba..e7f823c4fb 100644 --- a/docs-site/src/content/docs/ja/guides/providers.md +++ b/docs-site/src/content/docs/ja/guides/providers.md @@ -1,10 +1,10 @@ --- title: プロバイダー -description: opencodex が LLM プロバイダーを認証し通信するすべての方式 — OAuth、API キー、ChatGPT 転送、そしてローカル。 +description: CodexCommander が LLM プロバイダーを認証し通信するすべての方式 — OAuth、API キー、ChatGPT 転送、そしてローカル。 --- **プロバイダー**は一つの上流 LLM エンドポイントとそこへの到達方法を合わせたものです: アダプター、ベース URL、認証 -モード、そしてオプションのモデル一覧で構成されます。プロバイダーは `~/.opencodex/config.json` の `providers` の下にあります。 +モード、そしてオプションのモデル一覧で構成されます。プロバイダーは `~/.codexcommander/config.json` の `providers` の下にあります。 ## OpenAI アカウントモード @@ -39,10 +39,6 @@ Codex login を Pool モードで使うと、Providers の概要には任意の その他のルーティング判断には影響しません。個別アカウントの状態とルーティング設定は [Codex Auth のアカウントプール](/ja/guides/web-dashboard/#codex-auth-and-account-pools)を参照してください。 -出荷版 v1 config は marker 2 の単一オプション行に自動移行されます。オリジナルは -`~/.opencodex/config.json.pre-openai-tiers-v2.bak` に一度保存され、次のコマンドで復元します: -`cp ~/.opencodex/config.json.pre-openai-tiers-v2.bak ~/.opencodex/config.json`。 - ## 認証モード プロバイダー設定で使える `authMode` は 3 種類で、デフォルトは `key` です。組み込みレジストリは @@ -52,7 +48,7 @@ Codex login を Pool モードで使うと、Providers の概要には任意の | --- | --- | --- | | `key` | API キーを送信します(`Authorization: Bearer …`、またはアダプターにより `x-api-key` / `api-key`)。キーはリテラルまたは `${ENV_VAR}` 参照です。 | 大半のプロバイダー。 | | `forward` | **受け取った Codex 認証ヘッダーを**プロバイダーにそのまま中継します — キーを保存しません。ChatGPT ログインのパススルーです。 | OpenAI(`openai-responses` アダプター)。 | -| `oauth` | 保存された OAuth アクセストークンを bearer キーとして使い、認証情報の所有者に従います。OpenCodex 所有の認証情報は期限切れ前に更新され、リンクされた Grok/Kimi CLI 認証情報は読み取り専用で採用されてネイティブ CLI 所有のままです。 | xAI、Anthropic、Kimi、Kiro、Google Antigravity、Cursor。 | +| `oauth` | 保存された OAuth アクセストークンを bearer キーとして使い、認証情報の所有者に従います。CodexCommander 所有の認証情報は期限切れ前に更新され、リンクされた Grok/Kimi CLI 認証情報は読み取り専用で採用されてネイティブ CLI 所有のままです。 | xAI、Anthropic、Kimi、Kiro、Google Antigravity、Cursor。 | [`retryOn429`](/ja/reference/configuration/)(同一キーでの 429 リトライ)は API キー プロバイダー (`authMode: "key"`)のみに適用されます。OAuth・forward・ローカル プリセットは除外されます — @@ -85,40 +81,40 @@ ChatGPT パススルーカタログには GPT-5.6 Sol/Terra/Luna の名前空間 ## 2. アカウントログイン(OAuth) OAuth ログインを使うプロバイダープリセットは 7 つで、これに実験的な非公式デバイスフロー -ブリッジ経由の GitHub Copilot が加わります。認証情報は `~/.opencodex/auth.json` に保存されます。 -OpenCodex 所有の認証情報は自動更新されます。サインイン済みの Grok または Kimi CLI セッションを -リンクした場合、opencodex は現在のアクセス世代を読み取り専用で採用し、更新の責任はネイティブ +ブリッジ経由の GitHub Copilot が加わります。認証情報は `~/.codexcommander/auth.json` に保存されます。 +CodexCommander 所有の認証情報は自動更新されます。サインイン済みの Grok または Kimi CLI セッションを +リンクした場合、CodexCommander は現在のアクセス世代を読み取り専用で採用し、更新の責任はネイティブ CLI に残します。ログイン CLI は `chatgpt` も受け付けます。このコマンドは ChatGPT 認証情報を 発行し `forward` モードのプロバイダーエントリを作成します。 ```bash -ocx login xai # xAI Grok -ocx login anthropic # Anthropic Claude (Pro/Max) -ocx login kimi # Moonshot Kimi -ocx login kiro # kiro-cli 認証情報の取り込み(トークンフォールバック対応) -ocx login google-antigravity -ocx login cursor # Cursor 専用 PKCE ログイン -ocx login command-code # Command Code のブラウザ OAuth (または ~/.commandcode/auth.json を取り込み) -ocx login github-copilot # GitHub デバイスフロー → Copilot トークン (Copilot Pro/Business) -ocx login chatgpt # 別途 ChatGPT OAuth ログイン -ocx logout <provider> +ccx login xai # xAI Grok +ccx login anthropic # Anthropic Claude (Pro/Max) +ccx login kimi # Moonshot Kimi +ccx login kiro # kiro-cli 認証情報の取り込み(トークンフォールバック対応) +ccx login google-antigravity +ccx login cursor # Cursor 専用 PKCE ログイン +ccx login command-code # Command Code のブラウザ OAuth (または ~/.commandcode/auth.json を取り込み) +ccx login github-copilot # GitHub デバイスフロー → Copilot トークン (Copilot Pro/Business) +ccx login chatgpt # 別途 ChatGPT OAuth ログイン +ccx logout <provider> ``` | プロバイダー | アダプター | ベース URL | 備考 | | --- | --- | --- | --- | | `xai` | `openai-chat` | `https://api.x.ai/v1` | ライブ一覧を優先し、フォールバックのデフォルトモデルは `grok-4.5`。 | | `anthropic` | `anthropic` | `https://api.anthropic.com` | Claude モデル; ライブモデル一覧は `/v1/models` から取得。 | -| `kimi` | `openai-chat` | `https://api.kimi.com/coding/v1` | Kimi K3(`k3`、1M コンテキスト)、固定ウィンドウ `k3-256k`、互換エイリアス `k3[1m]`、レガシー K2.7/K2.6/K2.5 コーディングモデル。 | -| `kiro` | `kiro` | `https://runtime.us-east-1.kiro.dev` | 初回ログインは、インストール済みでサインインした `kiro-cli` セッションを取り込みます(Unix では `curl -fsSL https://cli.kiro.dev/install | bash`、Windows PowerShell では `irm 'https://cli.kiro.dev/install.ps1' | iex` でインストールしてから `kiro-cli login` を実行)。**アカウントを追加**は `kiro-cli` をログアウトして新しいブラウザログインを開始し、`kiro-cli` 自体のアカウントを切り替えてアカウント別プロファイルメタデータを保存します。既存の OpenCodex アカウントは保持され、キャンセルまたは失敗時には以前の `kiro-cli` セッションが復元されます。 | +| `kimi` | `openai-chat` | `https://api.kimi.com/coding/v1` | Kimi K3(`k3`、1M コンテキスト)、固定ウィンドウ `k3-256k`、互換エイリアス `k3[1m]`、K2.7/K2.6/K2.5 コーディングモデル。 | +| `kiro` | `kiro` | `https://runtime.us-east-1.kiro.dev` | 初回ログインは、インストール済みでサインインした `kiro-cli` セッションを取り込みます(Unix では `curl -fsSL https://cli.kiro.dev/install | bash`、Windows PowerShell では `irm 'https://cli.kiro.dev/install.ps1' | iex` でインストールしてから `kiro-cli login` を実行)。**アカウントを追加**は `kiro-cli` をログアウトして新しいブラウザログインを開始し、`kiro-cli` 自体のアカウントを切り替えてアカウント別プロファイルメタデータを保存します。既存の CodexCommander アカウントは保持され、キャンセルまたは失敗時には以前の `kiro-cli` セッションが復元されます。 | | `google-antigravity` | `google` | `https://daily-cloudcode-pa.googleapis.com` | Google OAuth を Cloud Code Assist wire で使用。CCA は汎用 `/models` エンドポイントを公開しないため、管理された 6 モデルの静的カタログを使用します。 | | `cursor` | `cursor` | `https://api2.cursor.sh` | 実験的 PKCE ログイン、HTTP/2 トランスポート、アカウント別モデル探索をサポート。 | | `github-copilot` | `openai-chat` | `https://api.githubcopilot.com` | 実験的。GitHub デバイスフロー + `copilot_internal` 交換(VS Code OAuth クライアント)。有効な Copilot サブスクリプションが必要で、公式のサードパーティ API ではありません。 | 正規の Kimi Coding Plan プリセット(`kimi` アカウントログインと `kimi-code` API key)では、 -opencodex は呼び出し元が指定した安定した `prompt_cache_key` だけを Chat Completions リクエストへ +CodexCommander は呼び出し元が指定した安定した `prompt_cache_key` だけを Chat Completions リクエストへ 転送し、自ら生成しません。Kimi のドキュメントでは、Code Plan のキャッシュヒット率を高めるために 安定したセッション/タスク key が必須とされています。key のないリクエストは keyless のままです。 -opt-in した上流がこのフィールドを拒否しても、opencodex はフィールドを削除して再試行したり、保存済み +opt-in した上流がこのフィールドを拒否しても、CodexCommander はフィールドを削除して再試行したり、保存済み 設定を変更したりしません。他のプロバイダーは deny-by-default のままです。 [ウェブダッシュボード](/ja/guides/web-dashboard/)からも OAuth を開始できます。 @@ -128,34 +124,34 @@ opt-in した上流がこのフィールドを拒否しても、opencodex はフ 認証情報に固定アカウント ID やメールがある OAuth プロバイダーはログインを複数保持できます。 Providers ページでアカウントを追加し、別アカウントをログアウトせずにアクティブアカウントだけを切り替えられます。 アカウント識別情報がない Kimi 認証情報だけがアクティブスロットを差し替え、Kiro アカウントはプロファイル ARN をキーに保存されます。 -`chatgpt` は Codex アカウントプールに別の保存場所があり、常に単一スロットのみ書き込みます。トークンは `~/.opencodex/auth.json` に保存され、 +`chatgpt` は Codex アカウントプールに別の保存場所があり、常に単一スロットのみ書き込みます。トークンは `~/.codexcommander/auth.json` に保存され、 `/api/oauth/accounts` はマスク済みメタデータのみを返します。 ### Kiro 認証情報の取り込み -Kiro のログインには Kiro CLI が必要です。Unix では `curl -fsSL https://cli.kiro.dev/install | bash`、Windows PowerShell では `irm 'https://cli.kiro.dev/install.ps1' | iex` でインストールしてから、先に `kiro-cli login` でサインインしてください。`kiro-cli` セッションがない場合、`ocx login kiro` は貼り付けたアクセストークンまたは `KIRO_ACCESS_TOKEN` 環境変数にフォールバックします。 +Kiro のログインには Kiro CLI が必要です。Unix では `curl -fsSL https://cli.kiro.dev/install | bash`、Windows PowerShell では `irm 'https://cli.kiro.dev/install.ps1' | iex` でインストールしてから、先に `kiro-cli login` でサインインしてください。`kiro-cli` セッションがない場合、`ccx login kiro` は貼り付けたアクセストークンまたは `KIRO_ACCESS_TOKEN` 環境変数にフォールバックします。 -通常の `ocx login kiro` 取り込みは CLI の SQLite データベースを読み取り専用で開き、データベース、WAL、SHM を変更しません。 +通常の `ccx login kiro` 取り込みは CLI の SQLite データベースを読み取り専用で開き、データベース、WAL、SHM を変更しません。 - `KIROCLI_DB_PATH` は標準外の Kiro CLI SQLite データベースを選択します。指定するデータベースは既に存在している必要があります。 - `KIROCLI_TOKEN_KEY` は複数の曖昧なトークン行がある場合に、取り込む正確な `auth_kv` 行のキーを指定します。選択がない場合、推測せずログインに失敗します。 -取り込んだ認証情報は `~/.opencodex/auth.json` に保存されます。**アカウントを追加**のロールバックは別処理で、以前のスナップショットを復元する際にデータベースを置き換え、現在の WAL、SHM、journal サイドカーを削除します。 +取り込んだ認証情報は `~/.codexcommander/auth.json` に保存されます。**アカウントを追加**のロールバックは別処理で、以前のスナップショットを復元する際にデータベースを置き換え、現在の WAL、SHM、journal サイドカーを削除します。 ロールバックはスナップショットがある場合にのみ可能なため、セッションストアが存在するのに取得できない場合(ファイルが読めない、スキーマの不一致、トークン選択があいまい)、`KIROCLI_DB_PATH` / `KIRO_CLI_DB_FILE` が実際の CLI ストアと異なるインポート先を指す場合、またはプライマリ CLI データベースに認識できるトークン行がない場合、**アカウントを追加**は `kiro-cli` のログアウトを拒否します。通常の `kiro-cli` データパス上の壊れたデータベースを修復または削除し、インポート専用セレクタが設定されていれば解除してから再試行してください。既存の `kiro-cli` セッションがまったくない環境には影響しません。 ## 3. API キーカタログ -opencodex には組み込みプリセットが 76 個含まれています。キー方式 64、OAuth 8、ローカル 3、 +CodexCommander には組み込みプリセットが 76 個含まれています。キー方式 64、OAuth 8、ローカル 3、 デフォルト ChatGPT 転送プリセット 1 です。ダッシュボードの **Add provider** ピッカーはキー発行ページを開き、 入力したキーを検証した後保存します(検証はプロバイダー固有です)。主な項目は以下のとおりです: **ClinePass** は Cline API キーで[公式サブスクリプションカタログ](https://docs.cline.bot/getting-started/clinepass)と [Chat Completions エンドポイント](https://docs.cline.bot/api/chat-completions)に接続します。運営主体は [Cline の利用規約](https://cline.bot/tos)に記載された Cline Bot Inc. です。`cline-pass/cline-pass/kimi-k3` のようなルーティング ID は -意図した形式です。先頭は opencodex のプロバイダー、残りの `cline-pass/kimi-k3` は upstream に送信する +意図した形式です。先頭は CodexCommander のプロバイダー、残りの `cline-pass/kimi-k3` は upstream に送信する 完全なモデル slug です。使用量はアカウントのローリング 5 時間、週次、月次の各上限で共有されます。 -現在 opencodex が公開する reasoning tier は実機検証済みの `low` のみで、より高い要求は公式範囲が +現在 CodexCommander が公開する reasoning tier は実機検証済みの `low` のみで、より高い要求は公式範囲が 公開または検証されるまで `low` にクランプされます。 **Cline** は同じ API キー・エンドポイントを従量課金で使い、100 以上のモデルにアクセスできます @@ -215,7 +211,7 @@ Volcengine Agent Plan は `openai-responses` アダプターでネイティブ R `opencode-go` は `https://opencode.ai/zen/go/v1` の OpenCode Go サブスクリプションプロバイダーで、 OpenCode Desktop/CLI とは別物です。[OpenCode コンソール](https://opencode.ai/console)でキーを作成し、 ダッシュボードの **Providers** から **OpenCode Go** を追加するか、そのキーで `opencode-go` プリセットを -構成します。OpenCodex は OpenCode の認証ストアを読み取らず、このキーを Keychain に移行しません。 +構成します。CodexCommander は OpenCode の認証ストアを読み取らず、このキーを Keychain に保存しません。 公開モデルカタログはキーの有効性の証拠ではありません。保存されたキーは、アクティブなキーで最初の 推論に成功して初めて**検証済み**になります。公開上限は参照値で、**$12 / 5 時間**、**$30 / 7 日**、 @@ -223,7 +219,7 @@ OpenCode Desktop/CLI とは別物です。[OpenCode コンソール](https://ope 請求ではありません。権威ある制限イベントは、upstream が具体的に報告した場合にのみ表示されます。 組み込みプリセットは API キー方式なので、Add Provider ではアカウントログインではなく **Paid** に分類され、 -OpenCodex は OpenCode Go の OAuth フローを提供しません。Client Apps の **OpenCode** クライアントや、キー不要の +CodexCommander は OpenCode Go の OAuth フローを提供しません。Client Apps の **OpenCode** クライアントや、キー不要の **OpenCode Free** プロバイダーとも別物です。Add Provider の検索は Accounts、Free、Paid を横断するため、 どのタブから `opencode` を検索しても一致するプリセットと区分が表示されます。 @@ -258,7 +254,7 @@ Nscale の service token は [Nscale Console](https://console.nscale.com) で作 **Command Code の discovery:** preset は Command Code の `/provider/v1/models` リストを固定の Provider API ホストから読み、スラッシュを含むネイティブモデル ID を保持し、live discovery を -256 KiB と raw 256 行に制限します。`ocx login command-code` はブラウザーでの OAuth サインインを +256 KiB と raw 256 行に制限します。`ccx login command-code` はブラウザーでの OAuth サインインを サポートします(既存の Command Code CLI ユーザー向けに `~/.commandcode/auth.json` からのローカル CLI 資格情報の取り込みも可能)。モデルカタログはアカウント単位で、ログイン後に認証済みの discovery エンドポイントから取得します。チャットリクエストは設定済みの bearer キーを使います。 @@ -298,7 +294,7 @@ API キーは [Scaleway console](https://console.scaleway.com/generative-api) `openai-chat`、`authMode: "key"`、正規の `https://api.a6api.com` または `https://api.a6api.com/v1` を使うカスタムプロバイダーでは、ダッシュボードと -`ocx account refresh <provider>` に A6API クレジット使用量が表示されます。プロバイダー名は任意です。 +`ccx account refresh <provider>` に A6API クレジット使用量が表示されます。プロバイダー名は任意です。 アカウントの hard credit limit を基準にトークン単位を USD に換算し、使用率と残高を表示します。トークン期限は補充を意味しないため、クォータの リセットとしては表示しません。アクティブキーだけを正規ホストへ送信し、リダイレクトを拒否します。負数や 整合しない請求合計からはレポートを生成しません。 @@ -320,13 +316,13 @@ API キーは [Scaleway console](https://console.scaleway.com/generative-api) ### ターミナルでアカウントを切り替え -ダッシュボードを開かずに `ocx account list`、`ocx account current`、`ocx account use` で同じ Codex、 +ダッシュボードを開かずに `ccx account list`、`ccx account current`、`ccx account use` で同じ Codex、 OAuth、API キープールを確認・切り替えできます。完全なコマンド、JSON 出力、新規セッション適用方式は -[CLI リファレンス](/ja/reference/cli/#ocx-account-subcommand)を参照してください。 +[CLI リファレンス](/ja/reference/cli/#ccx-account-subcommand)を参照してください。 ### GPT-5.6 プレビュー経路 -ライブモデルカタログの更新が遅れても `ocx sync` でモデルが消えないよう、GPT-5.6 +ライブモデルカタログの更新が遅れても `ccx sync` でモデルが消えないよう、GPT-5.6 Sol/Terra/Luna をフォールバックリストに入れています。 | Codex 経路 | 事前登録されたモデル ID | Codex に表示されるコンテキスト | @@ -341,12 +337,12 @@ Sol/Terra/Luna をフォールバックリストに入れています。 使います。4 経路すべてで実際の利用権は上流アカウントが決定し、Cursor はライブ探索結果に基づき現在のアカウントで使えるモデルのみ残します。 :::note[ゲートウェイとサブスクリプションプロキシ] -プロバイダー対応可否は「エージェント」製品かどうかではなく、opencodex に合う wire アダプターがあるかで +プロバイダー対応可否は「エージェント」製品かどうかではなく、CodexCommander に合う wire アダプターがあるかで 決まります。現在のアダプター ID は `openai-chat`、`openai-responses`、`anthropic`、`google`(AI Studio、 -Vertex、Antigravity/Cloud Code Assist モード)、`azure` / `azure-openai`、`kiro`、`cursor` です。 +Vertex、Antigravity/Cloud Code Assist モード)、`azure-openai`、`kiro`、`cursor` です。 Amazon Bedrock ネイティブ API のような、これらの実装のいずれにも合わない独自プロトコルは直接サポートしません。 **GitHub Copilot** と **GitLab Duo** は独自の汎用 OpenAI 互換エンドポイントにマッピングされたマルチモデル -ゲートウェイです。Copilot は `ocx login github-copilot` で GitHub デバイスフロー OAuth ログインを +ゲートウェイです。Copilot は `ccx login github-copilot` で GitHub デバイスフロー OAuth ログインを サポートします(非公式ブリッジ — VS Code 公開クライアント ID でログイン後、短期 Copilot API トークンに 交換し、有効な Copilot サブスクリプションが必要で GitHub ポリシー変更でブロックされる可能性あり)。GitLab Duo は Bearer **サブスクリプショントークン**(通常の API キーではない)で認証します。**Cloudflare AI @@ -354,23 +350,23 @@ Gateway** は URL にアカウント + ゲートウェイ ID を埋める必要 Copilot は混在 wire カタログを提供します。GPT-5 系モデル(`gpt-5.3-codex`、`gpt-5.4`、 `gpt-5.4-mini`、`gpt-5.5`、`gpt-5.6-luna`、`gpt-5.6-sol`、`gpt-5.6-terra`)はエージェント -通信の `/chat/completions` を拒否するため、opencodex はこれらのモデルを組み込みデフォルトで +通信の `/chat/completions` を拒否するため、CodexCommander はこれらのモデルを組み込みデフォルトで Responses API 経由にルーティングし、他の Copilot モデルはすべて chat completions のままです。 優先順位は次のとおりです: ハード wire ピン → 明示的な [`modelAdapters`](/ja/reference/configuration/providers/) エントリ → レジストリのデフォルト → プロバイダー全体の adapter。組み込みデフォルトのないモデル(例: `gpt-5.4-nano`)を Responses に移すには、`"modelAdapters": { "gpt-5.4-nano": "openai-responses" }` を設定してください。 -Cursor は別の実験的アダプターとして追跡します。`adapter: "cursor"` は `ocx init` とダッシュボード Add +Cursor は別の実験的アダプターとして追跡します。`adapter: "cursor"` は `ccx init` とダッシュボード Add Provider ピッカーに実験的 local config 項目として表示され、Cursor の静的フォールバックモデルカタログ -メタデータを保存します。Cursor アクセストークンを設定すると opencodex は Cursor ライブ HTTP/2 トランスポートを +メタデータを保存します。Cursor アクセストークンを設定すると CodexCommander は Cursor ライブ HTTP/2 トランスポートを 使います。バンドル済みフォールバックリストには 1M コンテキストの `gpt-5.6-sol` / `terra` / `luna`、500K コンテキストの `grok-4.5` / `grok-4.5-fast`、262K コンテキストの `kimi-k3` が含まれ、ライブ探索結果に基づき現在の アカウントに表示するモデルを決定します。Cursor は Kimi K3 を effort サフィックス付きの wire id としてのみ提供するため、`cursor/kimi-k3` は `low` / `high` / `max` のラダーを公開し、既定値はモデル ドキュメントの API 既定値と同じ `max` です。Cursor サーバーが直接送るネイティブ read/write/delete/ls/grep/shell/fetch 実行は Codex 承認とサンドボックス経路をバイパスするためデフォルトで無効です。信頼できるローカル実験でのみ -`~/.opencodex/config.json` の `providers.cursor` に `unsafeAllowNativeLocalExec: true` を設定してください。 +`~/.codexcommander/config.json` の `providers.cursor` に `nativeLocalExec: "on"` を設定してください。 ダッシュボードからは **Providers → Cursor → Edit JSON** で設定できます。完全な例は [設定リファレンス](/ja/reference/configuration/#cursor-provider-adapter-cursor)を参照してください。 MCP、画面録画、computer-use はエグゼキューターフックで開かれており、ローカル @@ -382,7 +378,7 @@ MCP、画面録画、computer-use はエグゼキューターフックで開か ### Ollama Cloud Ollama Cloud はホステッド型(ローカルではない)Ollama で、`https://ollama.com/v1` で OpenAI 互換、キーは -[ollama.com/settings/keys](https://ollama.com/settings/keys) で発行されます。opencodex はクラウド +[ollama.com/settings/keys](https://ollama.com/settings/keys) で発行されます。CodexCommander はクラウド ラインナップをビジョン機能で分類し、[ビジョンサイドカー](/ja/guides/sidecars/)がテキスト専用モデルにのみ 動作するようにします。テキスト専用モデル(例: `glm-5.2`、`deepseek-v4-pro`、`gpt-oss`、`qwen3-coder`、 `minimax-m2.x`、`nemotron-3-*`)は `noVisionModels` に列挙され、ビジョンネイティブモデル(例: @@ -391,7 +387,7 @@ Ollama の `:size` タグに寛容なので `gpt-oss` は `gpt-oss:120b` と `gp ## 4. ローカルプロバイダー -opencodex をローカルの OpenAI 互換サーバーに向けてください — 通常は空キーで使います: +CodexCommander をローカルの OpenAI 互換サーバーに向けてください — 通常は空キーで使います: | プロバイダー | ベース URL | | --- | --- | @@ -402,6 +398,6 @@ opencodex をローカルの OpenAI 互換サーバーに向けてください ## すべての OpenAI 互換エンドポイント プロバイダーが Chat Completions を使うなら `openai-chat` アダプターが処理します — ダッシュボードで -**Custom** を選ぶか `ocx init` で `custom` を選んだ後ベース URL を入力してください。すべてのプロバイダーフィールド +**Custom** を選ぶか `ccx init` で `custom` を選んだ後ベース URL を入力してください。すべてのプロバイダーフィールド (`headers`、`noReasoningModels`、`noVisionModels`、`models`、…)は [設定リファレンス](/ja/reference/configuration/)を参照してください。 diff --git a/docs-site/src/content/docs/ja/guides/sidecars.md b/docs-site/src/content/docs/ja/guides/sidecars.md index cc64fc7895..d7e5611463 100644 --- a/docs-site/src/content/docs/ja/guides/sidecars.md +++ b/docs-site/src/content/docs/ja/guides/sidecars.md @@ -3,7 +3,7 @@ title: "サイドカー: ウェブ検索とビジョン" description: ネイティブ ChatGPT サイドカー経由でルーティングモデルに実際のウェブ検索を、テキスト専用モデルに画像理解を提供します。 --- -ルーティングモデルごとにホスト型**ウェブ検索**やネイティブ**画像入力**のサポート範囲が異なります。opencodex は +ルーティングモデルごとにホスト型**ウェブ検索**やネイティブ**画像入力**のサポート範囲が異なります。CodexCommander は ChatGPT ログイン(`forward`)プロバイダーまたは保存された Anthropic OAuth プロバイダーを使う 2 つの サイドカーで不足機能を補います。サイドカーエラーはターン全体を失敗させず、長さ制限付きのツール 結果や画像案内文に差し替わります。 @@ -17,7 +17,7 @@ OAuth プロバイダーがあるとき `anthropic`、ないとき `openai` を ## ウェブ検索サイドカー -Codex がパススルーでないルーティングモデルにホスト型 `web_search` を要求すると opencodex は次の順序で +Codex がパススルーでないルーティングモデルにホスト型 `web_search` を要求すると CodexCommander は次の順序で 処理します。 1. ホスト型 `web_search` ツールを**削除し**、ルーティングモデルには合成 `web_search(query)` 関数ツールを @@ -30,7 +30,7 @@ Codex がパススルーでないルーティングモデルにホスト型 `web **反復**します。限度に達すると検索ツールを削除し最終回答を強制します。`apply_patch` や shell のような実際のクライアントツールが出たらターンを終了し該当呼び出しが Codex に渡るようにします。 -ルーティングモデルのすべての反復は上流に `stream: true` を要求しますが、opencodex は検索可否や最終 +ルーティングモデルのすべての反復は上流に `stream: true` を要求しますが、CodexCommander は検索可否や最終 回答を決める前に意味のある event を内部ですべてバッファリングします。最初の反復の最終 header/status と 429 キーローテーションのみ先行取得します。したがって合成検索呼び出しと中間出力はクライアントに モデル出力として公開されません。 @@ -68,10 +68,10 @@ stall は全体生成 timeout ではありません。SSE 開始前の失敗は ## ビジョンサイドカー -ルーティングモデルが該当プロバイダーの `noVisionModels` にありリクエストに画像が来る場合、opencodex は +ルーティングモデルが該当プロバイダーの `noVisionModels` にありリクエストに画像が来る場合、CodexCommander は メイン呼び出し**前に**各画像を説明したテキストに差し替えます。ダッシュボードと管理 API の現在のデフォルト選択は -`gpt-5.6-luna` で、起動時に明示的に保存された既存 `gpt-5.4-mini` 値も Luna にマイグレーションします。 -ただし `visionSidecar.model` フィールド自体がない場合はビジョン実行経路はコードフォールバックの `gpt-5.4-mini` を使います。 +`gpt-5.6-luna` です。`visionSidecar.model` フィールド自体がない場合は、ビジョン実行経路はコードフォールバックの +`gpt-5.4-mini` を使います。 - 画像はユーザー、developer、ツール結果メッセージから来ます。Codex の `view_image` 結果も 含まれます。 diff --git a/docs-site/src/content/docs/ja/guides/sub-agent-surface.md b/docs-site/src/content/docs/ja/guides/sub-agent-surface.md index 2f948aa2fe..56d51a5708 100644 --- a/docs-site/src/content/docs/ja/guides/sub-agent-surface.md +++ b/docs-site/src/content/docs/ja/guides/sub-agent-surface.md @@ -5,7 +5,7 @@ description: Codex がすべてのモデルにわたってサブエージェン ## サブエージェントとは -サブエージェントは、メイン エージェントが焦点を絞ったタスク用に作成できる別個の Codex ワーカーです。独自のコンテキストとツールがあるため、複数の独立したタスクを並行して実行できます。 opencodex は、どの Codex コラボレーション サーフェスがこれらのワーカーを公開するか、Codex がワーカーに提供するモデル、および失敗したモデルがどのようにフォールバックできるかを制御します。メインエージェントがいつ委任する必要があるかは決定されません。 +サブエージェントは、メイン エージェントが焦点を絞ったタスク用に作成できる別個の Codex ワーカーです。独自のコンテキストとツールがあるため、複数の独立したタスクを並行して実行できます。 CodexCommander は、どの Codex コラボレーション サーフェスがこれらのワーカーを公開するか、Codex がワーカーに提供するモデル、および失敗したモデルがどのようにフォールバックできるかを制御します。メインエージェントがいつ委任する必要があるかは決定されません。 ## モード @@ -29,7 +29,7 @@ description: Codex がすべてのモデルにわたってサブエージェン - **base** は上流のピンを復元します。固定されていないエントリは、ネイティブ `multi_agent_v2` 機能フラグに従います。 - **v2** はすべてのモデルに `multi_agent_version = "v2"` のスタンプを押します。 -opencodex は、これを最終パスとしてライブ `/v1/models` カタログとディスクに同期されたカタログの両方に適用します。そのため、モードの変更は、新しく作成されたアプリ、CLI、および TUI セッションに一貫して影響します。 +CodexCommander は、これを最終パスとしてライブ `/v1/models` カタログとディスクに同期されたカタログの両方に適用します。そのため、モードの変更は、新しく作成されたアプリ、CLI、および TUI セッションに一貫して影響します。 v2 ロスターの場合、適格性には 3 つの状態があります。`"v2"` スタンプが付いているエントリー、明示的に `null` に設定されているエントリー、または `multi_agent_version` フィールドのないエントリーが適格です。純正の `"v1"` ピンは、モデルが他のコラボレーション サーフェスに属していると記載されているため、除外されます。 @@ -37,11 +37,11 @@ v2 ロスターの場合、適格性には 3 つの状態があります。`"v2" ダッシュボードの **サブエージェント委任** は、次の 3 つの関連設定を制御します。 -- `injectionModel` は、opencodex ガイダンスで指定されている優先ワーカー モデルです。 +- `injectionModel` は、CodexCommander ガイダンスで指定されている優先ワーカー モデルです。 - `injectionEffort` は、そのモデルをリクエストするためのオプションの `reasoning_effort` です。 - `injectionPrompt` は、組み込みの v2 ガイダンス テキストを置き換えます。 -`multiAgentGuidanceEnabled` はデフォルトでオンになっており、両方のサーフェスで opencodex が作成したガイダンスのマスター スイッチです。これをオフにすると、v2 指定ブロックと v1 プロアクティブ テキストの両方が抑制されます。 +`multiAgentGuidanceEnabled` はデフォルトでオンになっており、両方のサーフェスで CodexCommander が作成したガイダンスのマスター スイッチです。これをオフにすると、v2 指定ブロックと v1 プロアクティブ テキストの両方が抑制されます。 これらはメイン エージェントに対する指示であり、プロキシ側のスポーン ルーターに対する指示ではありません。 v2 では、全履歴フォークは親モデルを継承し、モデルまたはエフォートのオーバーライドを拒否します。したがって、ガイダンスでは、`model` または `reasoning_effort` を渡すときに `fork_turns: "none"` (または `"3"` などの正の部分ターン カウント) を使用し、タスク メッセージを自己完結型にするように Codex に指示します。 @@ -54,31 +54,31 @@ v2 ロスターの場合、適格性には 3 つの状態があります。`"v2" | `{{roster}}` |解決されたピッカー表示、サーフェス互換のロスター | | `{{fallback}}` |設定されたグローバル フォールバック ガイダンス | -組み込みの v2 ガイダンスの予算は 700 文字です。予算を超える場合、opencodex はコア スポーン命令を切り捨てるのではなく、まずロスターを削除します。組み込みガイダンスは、優先モデル、適格なロスター、またはフォールバック チェーンが解決された場合にのみ起動されます。カスタムプロンプトは `injectionModel` が設定されていれば生成され、セレクターなしの値を一意に解決できない場合は `{{model}}` が空文字列になります。 +組み込みの v2 ガイダンスの予算は 700 文字です。予算を超える場合、CodexCommander はコア スポーン命令を切り捨てるのではなく、まずロスターを削除します。組み込みガイダンスは、優先モデル、適格なロスター、またはフォールバック チェーンが解決された場合にのみ起動されます。カスタムプロンプトは `injectionModel` が設定されていれば生成され、セレクターなしの値を一意に解決できない場合は `{{model}}` が空文字列になります。 -v1 では、opencodex は、`max` または `ultra` の取り組みでアップストリーム スタイルのプロアクティブな委任ガイダンスのみを挿入します。 v1 では、優先モデル、ロスター、フォールバック リスト、カスタム プロンプトは追加されません。 +v1 では、CodexCommander は、`max` または `ultra` の取り組みでアップストリーム スタイルのプロアクティブな委任ガイダンスのみを挿入します。 v1 では、優先モデル、ロスター、フォールバック リスト、カスタム プロンプトは追加されません。 -デフォルトでオフになっている `syncCodexSubagentDefaults` オプションは、ガイダンスとは別のものです。 opencodex がアクティブな Codex ルーティングを所有している場合、同期または再起動により、選択された値をマーカー所有の `[agents] default_subagent_model` および `default_subagent_reasoning_effort` エントリとして Codex TOML に書き込むことができます。 opencodex は、そのマーカーを持つフィールドのみを更新または削除します。いずれかのターゲット フィールドがユーザー所有の場合、ペアは部分的に書き込まれるのではなく、変更されないままになります。曖昧な TOML は書き込みなしで拒否されます。外部プロバイダー マネージャーとユーザー所有のルート ルーティングも引き続き権限を持ちます。 +デフォルトでオフになっている `syncCodexSubagentDefaults` オプションは、ガイダンスとは別のものです。 CodexCommander がアクティブな Codex ルーティングを所有している場合、同期または再起動により、選択された値をマーカー所有の `[agents] default_subagent_model` および `default_subagent_reasoning_effort` エントリとして Codex TOML に書き込むことができます。 CodexCommander は、そのマーカーを持つフィールドのみを更新または削除します。いずれかのターゲット フィールドがユーザー所有の場合、ペアは部分的に書き込まれるのではなく、変更されないままになります。曖昧な TOML は書き込みなしで拒否されます。外部プロバイダー マネージャーとユーザー所有のルート ルーティングも引き続き権限を持ちます。 ## フォールバックチェーン -生成されたワーカーの場合、opencodex は次の優先順位を構築します。 +生成されたワーカーの場合、CodexCommander は次の優先順位を構築します。 1. 要求されたプライマリ モデル。 2. `$CODEX_HOME/agents/*.toml` 定義からのロールの `model_fallback` リスト。 -3. opencodex 構成内のグローバル `subagentModelFallback` リスト。 +3. CodexCommander 構成内のグローバル `subagentModelFallback` リスト。 -重複するモデル ID は、最初に出現したモデル ID を保持しながら削除されます。選択中、opencodex は、無効になっている、ルーティングできない、無効なプロバイダーによってサポートされている、異常とマークされている、クールダウン中、使用可能なプールされた Codex アカウントがない、または設定されたクォータしきい値を超えている候補をスキップします。可用性プローブは `subagentModelFallbackPollMs` に対してキャッシュされます (デフォルトでは 60 秒)。 +重複するモデル ID は、最初に出現したモデル ID を保持しながら削除されます。選択中、CodexCommander は、無効になっている、ルーティングできない、無効なプロバイダーによってサポートされている、異常とマークされている、クールダウン中、使用可能なプールされた Codex アカウントがない、または設定されたクォータしきい値を超えている候補をスキップします。可用性プローブは `subagentModelFallbackPollMs` に対してキャッシュされます (デフォルトでは 60 秒)。 フォールバックでは、互換性のない暗号化タスクは読み取り可能になりません。子タスクが ChatGPT 用に暗号化されている場合、外部モデルがチェーンの前の方に表示されている場合でも、選択は正規のネイティブ ChatGPT ターゲットに制限されます。 ## 暗号化された v2 タスク配信 -Codex は、v2 ネイティブからルーティングされた子タスクを、バックエンドで暗号化された `encrypted_content` としてのみ送信できます。そのペイロードは、ネイティブ ChatGPT バックエンドによって読み取ることができますが、外部プロバイダーによっては読み取ることができません。これは既知の [#92限定](https://github.com/lidge-jun/opencodex/issues/92) です。 +Codex は、v2 ネイティブからルーティングされた子タスクを、バックエンドで暗号化された `encrypted_content` としてのみ送信できます。そのペイロードは、ネイティブ ChatGPT バックエンドによって読み取ることができますが、外部プロバイダーによっては読み取ることができません。これは既知の [#92限定](https://github.com/pavelhov/CodexCommander/issues/92) です。 -これは既定の `multiAgentV2MessageDelivery: "encrypted"` の動作です。実験的な `"plaintext"` を選ぶと、OpenCodex は完全な既知の V2 スキーマだけを非予約名前空間へ変換し、Codex 側で元の `collaboration` に戻します。これにより Sol などのネイティブ親から Kimi、Grok、DeepSeek へ V2 のまま委任できます。ただし、その親からのネイティブ子宛てを含むすべての V2 メッセージが平文になります。保存後は新しいセッションを開始してください。未知または部分的なスキーマは変換せず、安全に失敗します。 +これは既定の `multiAgentV2MessageDelivery: "encrypted"` の動作です。実験的な `"plaintext"` を選ぶと、CodexCommander は完全な既知の V2 スキーマだけを非予約名前空間へ変換し、Codex 側で元の `collaboration` に戻します。これにより Sol などのネイティブ親から Kimi、Grok、DeepSeek へ V2 のまま委任できます。ただし、その親からのネイティブ子宛てを含むすべての V2 メッセージが平文になります。保存後は新しいセッションを開始してください。未知または部分的なスキーマは変換せず、安全に失敗します。 -opencodex は、空のタスクまたは読み取り不可能なタスクを転送するのではなく、安全に失敗します。 +CodexCommander は、空のタスクまたは読み取り不可能なタスクを転送するのではなく、安全に失敗します。 - 直接の非ネイティブ ルートは HTTP 400 を返します。 `error.code = "unreadable_encrypted_agent_task"` であり、暗号文はエコーされません。 @@ -103,27 +103,27 @@ opencodex は、空のタスクまたは読み取り不可能なタスクを転 ### CLI -コラボレーション サーフェスとネイティブ機能の設定には `ocx v2` を使用します。 +コラボレーション サーフェスとネイティブ機能の設定には `ccx v2` を使用します。 ```bash -ocx v2 status -ocx v2 mode v1 -ocx v2 mode default -ocx v2 mode v2 -ocx v2 threads 8 +ccx v2 status +ccx v2 mode v1 +ccx v2 mode default +ccx v2 mode v2 +ccx v2 threads 8 ``` -委任、ロスター、エフォートキャップ、およびフォールバック設定には `ocx agent` を使用します。 +委任、ロスター、エフォートキャップ、およびフォールバック設定には `ccx agent` を使用します。 ```bash -ocx agent status -ocx agent injection set --model anthropic/claude-sonnet-5 --effort xhigh -ocx agent subagents set gpt-5.6-sol,anthropic/claude-sonnet-5 -ocx agent fallback set gpt-5.4-mini,xai/grok-4.5 --poll-ms 60000 -ocx agent effort set --subagent max +ccx agent status +ccx agent injection set --model anthropic/claude-sonnet-5 --effort xhigh +ccx agent subagents set gpt-5.6-sol,anthropic/claude-sonnet-5 +ccx agent fallback set gpt-5.4-mini,xai/grok-4.5 --poll-ms 60000 +ccx agent effort set --subagent max ``` -`-` を渡して null 許容の `ocx agent injection` 値をクリアするか、ロスターまたはフォールバック リストに関連する `clear` アクションを使用します。すべてのコマンド ファミリについては、[CLI リファレンス](/reference/cli/) を参照してください。 +`-` を渡して null 許容の `ccx agent injection` 値をクリアするか、ロスターまたはフォールバック リストに関連する `clear` アクションを使用します。すべてのコマンド ファミリについては、[CLI リファレンス](/reference/cli/) を参照してください。 ### API @@ -165,11 +165,11 @@ curl -X PUT http://localhost:10100/api/injection-model \ ### モードの変更は実行中のセッションに影響しますか? -いいえ。モードを変更した後、新しい Codex セッションを開始します。長時間実行されているアプリ ホストで依然として古いカタログ状態が表示される場合は、`ocx sync` を実行して、その Codex サーフェスを再起動します。 +いいえ。モードを変更した後、新しい Codex セッションを開始します。長時間実行されているアプリ ホストで依然として古いカタログ状態が表示される場合は、`ccx sync` を実行して、その Codex サーフェスを再起動します。 ### 推論負荷 -`injectionEffort` は、委任されたワーカーのガイダンスのみに影響し、明示的に有効にすると、ネイティブ Codex サブエージェントのデフォルトに影響します。親セッションの労力は変わりません。 `ultra` は、Codex が `max` に変換するクライアント向けの最上位層です。次に、opencodex は、選択したプロバイダーの値をマップまたはクランプします。 +`injectionEffort` は、委任されたワーカーのガイダンスのみに影響し、明示的に有効にすると、ネイティブ Codex サブエージェントのデフォルトに影響します。親セッションの労力は変わりません。 `ultra` は、Codex が `max` に変換するクライアント向けの最上位層です。次に、CodexCommander は、選択したプロバイダーの値をマップまたはクランプします。 ### コンテキストキャップ diff --git a/docs-site/src/content/docs/ja/guides/video-bridge.md b/docs-site/src/content/docs/ja/guides/video-bridge.md index 0c59ae681e..f96d85b286 100644 --- a/docs-site/src/content/docs/ja/guides/video-bridge.md +++ b/docs-site/src/content/docs/ja/guides/video-bridge.md @@ -5,13 +5,13 @@ description: Grok Imagine Video を使用して非 OpenAI モデルを通じて ## 概要 -Video Bridge を使用すると、opencodex によってルーティングされる非 OpenAI モデルを通じて xAI の Grok Imagine Video 生成を使用できます。有効にすると、合成 `video_gen` ツールが会話に挿入されます。モデルはこれを他の関数ツールと同様に呼び出します。 opencodex は通話をインターセプトし、ビデオ生成ジョブを xAI に送信し、完了するまでポーリングして、結果をダウンロードします。 +Video Bridge を使用すると、CodexCommander によってルーティングされる非 OpenAI モデルを通じて xAI の Grok Imagine Video 生成を使用できます。有効にすると、合成 `video_gen` ツールが会話に挿入されます。モデルはこれを他の関数ツールと同様に呼び出します。 CodexCommander は通話をインターセプトし、ビデオ生成ジョブを xAI に送信し、完了するまでポーリングして、結果をダウンロードします。 ## 前提条件 -- **API キー**を持つ `xai` プロバイダー エントリ (`ocx login xai` だけでは十分ではありません。ビデオ ブリッジには OAuth ではなくキー認証が必要です) +- **API キー**を持つ `xai` プロバイダー エントリ (`ccx login xai` だけでは十分ではありません。ビデオ ブリッジには OAuth ではなくキー認証が必要です) - ルーティングプロバイダーとしての非 OpenAI モデル (例: Anthropic Claude、Google Gemini) -- opencodex は非 OpenAI プロバイダーを介してルーティングするように構成されています +- CodexCommander は非 OpenAI プロバイダーを介してルーティングするように構成されています > **⚠ プロバイダー キーが必要です:** ビデオ ブリッジは、`xai` プロバイダーが使用する場合にのみアクティブになります。 > APIキー認証。これを設定に追加します。 @@ -24,7 +24,7 @@ Video Bridge を使用すると、opencodex によってルーティングされ > } > ``` > -> `ocx login xai` (OAuth) 経由でオンボードした場合、プロバイダーは `authMode: "oauth"` のままになります。 +> `ccx login xai` (OAuth) 経由でオンボードした場合、プロバイダーは `authMode: "oauth"` のままになります。 > ブリッジは静かに起動しません。 **または**環境で`XAI_API_KEY`を設定します > 上に示したようにキーをハードコーディングします。 @@ -53,9 +53,9 @@ Video Bridge を使用すると、opencodex によってルーティングされ ## 仕組み -1. opencodex は、`videoBridgeEnabled: true` を使用して非 OpenAI ルーティング モデルを検出します +1. CodexCommander は、`videoBridgeEnabled: true` を使用して非 OpenAI ルーティング モデルを検出します 2. 合成 `video_gen` 関数ツールが会話に挿入されます -3. モデルが `video_gen` を呼び出すと、opencodex が xAI の `/videos/generations` にジョブを送信します。 +3. モデルが `video_gen` を呼び出すと、CodexCommander が xAI の `/videos/generations` にジョブを送信します。 4. ブリッジは 5 ~ 15 秒ごとにジョブ ステータスをポーリングし、ストリームを維持するためにハートビート メッセージを送信します。 5. ビデオの準備ができたら、アーティファクト ディレクトリにダウンロードされます 6. ローカル ファイル パスがツールの結果としてモデルに返されます。 diff --git a/docs-site/src/content/docs/ja/guides/web-dashboard.md b/docs-site/src/content/docs/ja/guides/web-dashboard.md index fda2ad6914..13998b3c35 100644 --- a/docs-site/src/content/docs/ja/guides/web-dashboard.md +++ b/docs-site/src/content/docs/ja/guides/web-dashboard.md @@ -1,29 +1,29 @@ --- title: ウェブダッシュボード -description: プロキシ状態、プロバイダー、モデル、委任ガイド、認証プール、使用量、ログを管理する opencodex GUI。 +description: プロキシ状態、プロバイダー、モデル、委任ガイド、認証プール、使用量、ログを管理する CodexCommander GUI。 --- -opencodex はプロキシが提供するローカルウェブダッシュボード(`gui/` 配下の Vite/React アプリ)を含みます。 +CodexCommander はプロキシが提供するローカルウェブダッシュボード(`gui/` 配下の Vite/React アプリ)を含みます。 プロバイダー、Codex/ChatGPT アカウント、カタログモデル、サイドカー、サブエージェント設定、リクエストトラフィックを最も 早く管理できる画面です。 ## 開く ```bash -ocx gui +ccx gui ``` ブラウザで `http://localhost:<port>` を開きます。プロキシがオフなら先に自動で起動します。 開発中は実行中のプロキシと GUI 開発サーバーを別々に起動できます。 ```bash -ocx start +ccx start bun run dev:gui ``` ## サインイン -`localhost` や `127.0.0.1` などのループバックアドレスで開いたダッシュボードは、短時間有効な GUI セッションを自動的に受け取るため、通常はトークン入力が不要です。ループバック以外のホストで公開する場合は、`OPENCODEX_ADMIN_AUTH_TOKEN`、または自動生成される `~/.opencodex/admin-api-token` ファイルの管理トークンが必要です。 +`localhost` や `127.0.0.1` などのループバックアドレスで開いたダッシュボードは、短時間有効な GUI セッションを自動的に受け取るため、通常はトークン入力が不要です。ループバック以外のホストで公開する場合は、`CODEXCOMMANDER_ADMIN_AUTH_TOKEN`、または自動生成される `~/.codexcommander/admin-api-token` ファイルの管理トークンが必要です。 リモートダッシュボードでは標準のパスワードフォームが表示され、ブラウザのパスワードマネージャーで保存・自動入力できます。ダッシュボード自体はトークンをメモリ内だけに保持し、`localStorage` や `sessionStorage` には書き込みません。保存するかどうかはブラウザまたはパスワードマネージャーだけが決定します。 @@ -32,19 +32,19 @@ bun run dev:gui | 領域 | 機能 | --- | --- | | **ダッシュボード要約** | マルチエージェントモード、オンライン状態、バージョン、稼働時間、プロバイダー数、直近30日トークン合計、アクティブプロバイダーと利用可能なネイティブ/ルーティングモデルを表示します。 | -| **サブエージェント委任** | OpenCodex の委任ガイダンスとオプションの Codex ネイティブサブエージェント既定値で共有するネイティブ/ルーティングモデルと任意の推論強度を選びます。スポーンごとのルーターではありません。下記を参照してください。 | +| **サブエージェント委任** | CodexCommander の委任ガイダンスとオプションの Codex ネイティブサブエージェント既定値で共有するネイティブ/ルーティングモデルと任意の推論強度を選びます。スポーンごとのルーターではありません。下記を参照してください。 | | **サイドカー** | ウェブ検索モデルと強度、画像説明モデルを選択します。次回リクエストから適用されます。 | -| **メンテナンス** | Codex モデルカタログを再同期し、プロジェクトローカル設定のバイパス警告を確認し、latest/preview 更新を照会またはオプションのプロキシ再起動と共にインストールします。 | +| **メンテナンス** | Codex モデルカタログを再同期し、プロジェクトローカル設定のバイパス警告を確認します。 | | **起動安全性** | 注入された Codex ルーティングが再起動後も機能するか、サービスと launcher shim の状態、正確な修復コマンドと共に表示します。 | | **Windows トレイ** | ユーザーのログイントレイを導入し、プロキシ開始・停止・再起動・ダッシュボード・状態をクリックで操作します。トレイは再起動サービスではありません。 | -| **Codex 自動起動** | インストール済み Codex launcher shim に `ocx ensure` の実行を許可します。このトグルは shim やバックグラウンドサービスをインストールしません。 | +| **Codex 自動起動** | インストール済み Codex launcher shim に `ccx ensure` の実行を許可します。このトグルは shim やバックグラウンドサービスをインストールしません。 | | **プロバイダー** | プロバイダーを追加、編集、既定に設定(有効なプロバイダーのみ)、有効化/無効化、削除し、対応する OAuth アカウントプールと API キープールを管理します。現在の既定を削除すると、残っている最初の有効なプロバイダーに切り替わります(存在する場合)。なければ削除は拒否され、現在の既定は保持されます。Claude(Anthropic)OAuth プールでは、ログイン済みの各アカウントに独自の 5 時間・週間レート制限バーが表示され(利用量は資格情報単位)、取得失敗時は直近の値を保持して一時利用不可と表示します。 | | **プロバイダー追加** | レジストリベースのプリセットからアカウントログイン、API キーサービス、ローカルサーバー、custom エンドポイントを検索します。検索中は Accounts、Free、Paid をまとめて対象にし、タブはブラウズに使えます。 | | **Codex 認証** | ChatGPT/Codex プールアカウントを追加し、次回セッションアカウントを選び、5 時間 / 週間 / 30 日クォータを更新し、クォータ自動切り替えのオン/オフと 1~100% のしきい値、一時的失敗フェイルオーバーを設定します。 | | **サブエージェント** | **Agent Command Center** で `spawn_agent` に公開する 5 モデルの選択と並べ替え、現在のカタログ検索、プロトコル・V2 配信・ガイダンス・フォールバック・スレッド上限の Run Policy 設定を行います。保存済みでも公開されない項目は明示的に表示されます。 | | **モデル** | ネイティブ GPT とルーティングモデルをオン/オフし、プロバイダー許可リストとコンテキスト上限を設定し、**Classic v1**、**Follow Codex defaults**、**Concurrent v2** を選択して v2 スレッド数を設定します。「現在の動作」カードではコンテキストを **上限なし**、**制限あり**、**混在** として表示します。各ルーティングプロバイダーには **自動検出オン** または **静的カタログのみ** が表示され、管理元のプロバイダー設定へ移動できます。 | | **Client Apps** | 設定済み・利用可能なローカルクライアントを確認し、対応する管理設定の適用/削除とバックアップ確認を行い、プロバイダーと混同せずに Codex、Claude Code/Desktop、Grok Build、OpenCode、ファイル管理クライアントへ移動します。 | -| **API Access** | 他のアプリが OpenCodex プロキシへ接続するための認証キーを発行・管理します。上流プロバイダーの認証情報は Providers に残ります。 | +| **API Access** | 他のアプリが CodexCommander プロキシへ接続するための認証キーを発行・管理します。上流プロバイダーの認証情報は Providers に残ります。 | | **ログ** | トークン、要求された強度と(利用可能な場合は)実際に送信された強度、実際のモデル、プロバイダー、状態、リクエスト ID、所要時間、エラー詳細を含む最近のリクエストを自動更新します。アダプターが reasoning パラメーターを送信した場合、詳細表示に正確な wire field も表示されます。 | | **使用量 / デバッグ** | トークン使用量の測定範囲と推移を見るか、オプションのプロバイダートランスポート/使用量抽出診断をオンにします。 | | **ストレージ** | CODEX_HOME のディスク内訳(セッション、アーカイブ、DB、添付)を読み取り専用で表示。任意のアーカイブクリーンアップ: 最古 N% をプレビューし、既定では `CODEX_HOME/.trash` へ隔離、または明示チェックで完全削除。**自動クリーンアップ方針**はオプトインで**既定 OFF**(`storageCleanupPolicy.enabled`)。Storage ページでしきい値/目標/スケジュール/モードを設定するか **今すぐ実行**。隔離エントリは Storage ページから復元可能(JSONL + スレッド)。アクティブセッションは読み取り専用。最新/アクティブな `state_*.sqlite` がロック中はクリーンアップと復元を拒否。 | @@ -52,7 +52,7 @@ bun run dev:gui ### セクションへのリンク -レイアウトは 1 つだけなので、切り替える設定はありません。代わりに Dashboard の各セクションに URL があります。`#dashboard` は Overview、`#dashboard/providers` と `#dashboard/models` は残りの 2 つです。再読み込み・ブックマーク・戻る操作のいずれでも、表示していたセクションが保たれます。**Logs** も `#logs` と `#logs/debug` で同じように動作します。以前の `#providers/workspace` のブックマークは `#providers` に移動します。 +レイアウトは 1 つだけなので、切り替える設定はありません。代わりに Dashboard の各セクションに URL があります。`#dashboard` は Overview、`#dashboard/providers` と `#dashboard/models` は残りの 2 つです。再読み込み・ブックマーク・戻る操作のいずれでも、表示していたセクションが保たれます。**Logs** も `#logs` と `#logs/debug` で同じように動作します。 **ログ**と**使用量**のコスト値は報告されたトークンで計算した API 定価換算値です。請求明細や 実際の請求証拠ではなく、サブスクリプション使用量またはプロバイダークレジットが代わりに適用される場合があります。 @@ -66,18 +66,18 @@ bun run dev:gui ## 委任セレクターとスポーンルーティングの違い ダッシュボードの **サブエージェント委任** セレクターは `injectionModel` とオプションの `injectionEffort` を -保存します。選択値は OpenCodex が作成する委任ガイダンスで使われ、そのガイダンスは +保存します。選択値は CodexCommander が作成する委任ガイダンスで使われ、そのガイダンスは `multiAgentGuidanceEnabled` で別に制御されます。モデルを消去すると保存済み effort も消去され、 ネイティブ既定値の同期も無効になります。 -**Codex ネイティブサブエージェント既定値として使用**を有効にすると、OpenCodex が有効な Codex +**Codex ネイティブサブエージェント既定値として使用**を有効にすると、CodexCommander が有効な Codex ルーティングを管理している場合、次回の sync または restart で選択したモデルと effort がネイティブ `[agents]` 既定値として適用されます。外部のユーザー管理 provider 設定は変更しません。この既定値は新しく作成される Codex タスクだけに適用され、このオプション自体が委任を発生させることはありません。既存のユーザー所有 `[agents]` 既定値は上書きせず保持するため、要求した既定値と実際の Codex 既定値が異なる場合があります。 :::caution -2 つのトグルは独立しています。OpenCodex の委任ガイダンスを無効にしてもネイティブ既定値の同期は +2 つのトグルは独立しています。CodexCommander の委任ガイダンスを無効にしてもネイティブ既定値の同期は 無効にならず、ネイティブ既定値の同期を有効にしても委任ガイダンスや委任そのものは有効になりません。 どちらもプロキシがスポーンごとにモデルを変えるルーターではありません。v1/base/v2 の正確な動作は [サブエージェントサーフェス](/ja/guides/sub-agent-surface/)を参照してください。 @@ -103,7 +103,7 @@ Codex タスクだけに適用され、このオプション自体が委任を 順序が上のものから使われ、その上にあるアカウントがすべて使い切られるか利用できなくなって初めて 下の順序へ下がります。順序を変更すると **次の未バインドリクエスト** から適用され、すでにアカウントに 紐づいた thread を移動させることはありません。Codex Desktop(メイン)アカウントも同じように - 並べ替えられるので、**最後** にして予備に回せます。`ocx account priority` でプリセット以外の値を設定した場合も、カード上に + 並べ替えられるので、**最後** にして予備に回せます。`ccx account priority` でプリセット以外の値を設定した場合も、カード上に 選択肢として残ります。 - Thread affinity がリクエストごとにアカウントが揺れるのを防ぎます。クォータ自動切り替えがオンなら長く 実行される thread も定期的に再評価します。関連使用量がしきい値以上で、使用量が確実により低い @@ -127,7 +127,6 @@ GUI はプロキシの JSON 管理 API を使うシンクライアントです | `GET /api/startup-health` | 秘密情報を含まないルーティング、サービス、shim、再起動安全性診断を読み取ります。 | | `GET` / `POST /api/windows-tray` | Windows トレイの導入・表示状態を読み取り、`install`、`start`、`stop`、`uninstall` を実行します。 | | `POST /api/sync` | 共有モデルカタログを再構築し Codex モデルキャッシュを古い状態としてマークします。 | -| `GET /api/update/check` · `POST /api/update/run` · `GET /api/update/status` | 自己更新作業を確認、実行、追跡します。 | | `GET` / `PUT /api/sidecar-settings` | 検索/ビジョンサイドカーモデル設定を読むか変えます。 | | `GET` / `PUT /api/injection-model` | 委任ガイダンスのモデル/effort、ガイダンストグル、Codex ネイティブサブエージェント既定値の同期トグルを読み取りまたは変更します。 | | `GET` / `PUT /api/v2` | サーフェスモード、Codex 機能フラグ、v2 スレッド上限を読むか変えます。 | diff --git a/docs-site/src/content/docs/ja/index.mdx b/docs-site/src/content/docs/ja/index.mdx index 7c44164cea..5965898619 100644 --- a/docs-site/src/content/docs/ja/index.mdx +++ b/docs-site/src/content/docs/ja/index.mdx @@ -1,10 +1,10 @@ --- -title: "opencodex — Codex を任意の LLM 上で" +title: "CodexCommander — Codex を任意の LLM 上で" description: OpenAI Codex & Claude Code 向けの汎用プロバイダープロキシ — Codex CLI、App、SDK と Claude Code で任意の LLM を使えます。 template: splash head: - tag: title - content: "opencodex — Codex を任意の LLM 上で" + content: "CodexCommander — Codex を任意の LLM 上で" - tag: meta attrs: property: og:locale diff --git a/docs-site/src/content/docs/ja/reference/adapters.md b/docs-site/src/content/docs/ja/reference/adapters.md index 0bd13fbc51..646c48472d 100644 --- a/docs-site/src/content/docs/ja/reference/adapters.md +++ b/docs-site/src/content/docs/ja/reference/adapters.md @@ -3,7 +3,7 @@ title: アダプター description: 7つのプロバイダーアダプターの対象、リクエスト構成方式、固有の動作。 --- -**アダプター**は opencodex の内部リクエスト/レスポンスモデルとプロバイダーの wire 形式の間を変換します。すべてのアダプターは `ProviderAdapter` インターフェース(`src/adapters/base.ts`)を実装します。 +**アダプター**は CodexCommander の内部リクエスト/レスポンスモデルとプロバイダーの wire 形式の間を変換します。すべてのアダプターは `ProviderAdapter` インターフェース(`src/adapters/base.ts`)を実装します。 ```ts interface ProviderAdapter { @@ -16,7 +16,7 @@ interface ProviderAdapter { } ``` -`buildRequest` は `OcxParsedRequest` を上流の HTTP リクエストに落とし、`parseStream` / +`buildRequest` は `CodexCommanderParsedRequest` を上流の HTTP リクエストに落とし、`parseStream` / `parseResponse` はプロバイダーのレスポンスを内部 `AdapterEvent` に持ち上げます。`fetchResponse` があると、アダプターがリトライとタイムアウトを直接担います。`runTurn` は 1 回の HTTP fetch とその後のレスポンスストリームでは表現できない伝送方式をサポートします。その後 [`bridge.ts`](/ja/reference/architecture/#ブリッジ) がイベントを Responses SSE に変えます。 ## `openai-chat` @@ -51,7 +51,7 @@ interface ProviderAdapter { 先立って、同じキーで同一リクエストを待機して再送します。カスタム `runTurn` トランスポートは HTTP リトライ ループの対象外です。 -- `forward` URL → `{baseUrl}/responses`。`key` provider はデフォルトで従来の `{baseUrl}/v1/responses` 構築を使います。 +- `forward` URL → `{baseUrl}/responses`。`key` provider のデフォルト URL は `{baseUrl}/v1/responses` です。 - `key` provider は検証済みの相対 `responsesPath` を設定できます。adapter は `baseUrl` 末尾の `/` を 1 つ除き、`{trimmedBaseUrl}{responsesPath}` に送信します。Ark Agent Plan では `baseUrl: "https://ark.cn-beijing.volces.com/api/plan/v3"` と `responsesPath: "/responses"` を使います。 - `forward` モードでは安全なヘッダー許可リスト(`FORWARD_HEADERS`)だけを中継します。authorization、ChatGPT account id、OpenAI beta/originator/session ヘッダーが対象です。この ChatGPT ログイン経路は [サイドカー](/ja/guides/sidecars/) にも使われます。 @@ -119,9 +119,9 @@ filtered incomplete になります。実際のツール呼び出しを伴わな - content-addressed blob で対話状態を再生し、サーバーツール呼び出しを Codex に再マッピングします。protobuf の `GetUsableModels` RPC でリアルタイム Cursor モデルを探し、run リクエストが wire に commit される前だけリトライします。 - `cursor/grok-4.5-fast` は選択可能なモデルとして維持しつつ、Cursor には正規の `grok-4.5` モデルを送信し、個別の `effort` および `fast=true` 値は `requested_model.parameters` に格納します。 -- Cursor ネイティブのローカルファイルシステム/shell/network 実行はデフォルトで拒否します。明示的な `mcpServers` と `desktopExecutor` 統合はそれぞれ別の opt-in です。`unsafeAllowNativeLocalExec` はより広い組み込み executor を有効にし、Codex の承認/サンドボックスルールを迂回します。 +- Cursor ネイティブのローカルファイルシステム/shell/network 実行はデフォルトで拒否します。明示的な `mcpServers` と `desktopExecutor` 統合はそれぞれ別の opt-in です。`nativeLocalExec: "on"` はより広い組み込み executor を有効にし、Codex の承認/サンドボックスルールを迂回します。 -## `azure-openai`(別名: `azure`) +## `azure-openai` **対象:** **Azure OpenAI**。`openai-responses` を包むため、同じく `passthrough: true` です。 **認証:** `api-key` ヘッダーの `key`(Bearer ではない)。 diff --git a/docs-site/src/content/docs/ja/reference/architecture.md b/docs-site/src/content/docs/ja/reference/architecture.md index d1f436e3c6..678adfbfca 100644 --- a/docs-site/src/content/docs/ja/reference/architecture.md +++ b/docs-site/src/content/docs/ja/reference/architecture.md @@ -1,15 +1,15 @@ --- title: アーキテクチャ -description: opencodex の内部構造 — モジュールマップ、AdapterEvent ブリッジ、リクエストパーサー、そしてキャッシュ。 +description: CodexCommander の内部構造 — モジュールマップ、AdapterEvent ブリッジ、リクエストパーサー、そしてキャッシュ。 --- -opencodex は単一の Bun プロセスです。リクエストは OpenAI Responses として入り、内部モデルに正規化され、ルーティングされたのち、アダプターを経由してプロバイダーに送信され、再び Responses SSE にブリッジされます。エンドツーエンドのフローは [動作の仕組み](/ja/getting-started/how-it-works/) を参照してください。 +CodexCommander は単一の Bun プロセスです。リクエストは OpenAI Responses として入り、内部モデルに正規化され、ルーティングされたのち、アダプターを経由してプロバイダーに送信され、再び Responses SSE にブリッジされます。エンドツーエンドのフローは [動作の仕組み](/ja/getting-started/how-it-works/) を参照してください。 ## モジュールマップ ``` src/ -├── cli/ # ocx command dispatch, init, status, provider commands +├── cli/ # ccx command dispatch, init, status, provider commands ├── server/ # Bun.serve, /v1/* proxy, /api/* management API, WS bridge ├── codex/ # Codex config injection, catalog sync, auth/account integration ├── providers/ # provider metadata, API-key pool, quota and labels @@ -19,12 +19,12 @@ src/ ├── lib/ # runtime, process, retry, privacy, token estimate helpers ├── web-search/ # web-search sidecar (synthetic tool, loop, executor, parser) ├── vision/ # vision sidecar (describe + plan) -├── config.ts # ~/.opencodex/config.json, defaults, PID, env resolution +├── config.ts # ~/.codexcommander/config.json, defaults, PID, env resolution ├── router.ts # model id → provider + adapter ├── bridge.ts # AdapterEvent stream → Responses SSE / JSON ├── reasoning-effort.ts # reasoning-effort translation, clamping, and catalog levels ├── responses/ -│ ├── parser.ts # Responses request → OcxParsedRequest +│ ├── parser.ts # Responses request → CodexCommanderParsedRequest │ ├── schema.ts # Zod validation │ └── compaction.ts # remote compaction prompts, envelopes, compact history ├── service.ts # launchd / systemd / Task Scheduler background service @@ -32,14 +32,13 @@ src/ └── index.ts # public entry ``` -以前の大規模なエントリーファイル 3 つは、現在は互換性 facade です。`codex/catalog.ts` は -7 個の `codex/catalog/*.ts` モジュールを、`server/management-api.ts` は 9 個の -`server/management/*.ts` モジュールを、`server/responses.ts` は 5 個の -`server/responses/*.ts` モジュールを接続します。 +`codex/catalog.ts` は 7 個の `codex/catalog/*.ts` モジュールを、 +`server/management-api.ts` は 9 個の `server/management/*.ts` モジュールを、 +`server/responses.ts` は 5 個の `server/responses/*.ts` モジュールを接続します。 ## リクエスト処理フロー -HTTP の境界は `server/index.ts` が担い、Responses データプレーンは `server/responses.ts` facade と +HTTP の境界は `server/index.ts` が担い、Responses データプレーンは `server/responses.ts` と `server/responses/*.ts` モジュールに渡します。 1. `server/index.ts` で CORS と API 認証を確認し、終了待ち状態なら新規リクエストを拒否したのち、リクエストのライフサイクルを記録します。ここで `GET /v1/models`、`POST /v1/responses`、 @@ -60,9 +59,9 @@ HTTP の境界は `server/index.ts` が担い、Responses データプレーン ## パーサー `responses/parser.ts` は入ってくるリクエストを `responses/schema.ts`(Zod)で検証したのち -`OcxParsedRequest` を構成します: +`CodexCommanderParsedRequest` を構成します: -- **Messages** — `input` 項目は正規化された `OcxMessage[]` になります: user / developer / assistant / +- **Messages** — `input` 項目は正規化された `CodexCommanderMessage[]` になります: user / developer / assistant / toolResult。`reasoning` 項目は thinking ブロックになり、`function_call`、`custom_tool_call`、 `tool_search_call` 項目はツール呼び出しになり、それに対応する `*_output` はツール結果になります。 - **Tools** — function ツールはそのまま通過します。**名前空間付き (MCP) ツールは平坦化され**、 @@ -95,7 +94,7 @@ HTTP の境界は `server/index.ts` が担い、Responses データプレーン ## 伝送と compaction -`server/index.ts` はデフォルトで `/v1/responses` を HTTP/SSE で提供します。`websockets` が `false` の状態で Codex が Responses WebSocket アップグレードを試みると、opencodex は `426 upgrade_required` を返し、Codex はそのセッションで HTTP にフォールバックします。`"websockets": true` を設定すると同じエンドポイントがアップグレードを受け入れ WebSocket ブリッジを使います。 +`server/index.ts` はデフォルトで `/v1/responses` を HTTP/SSE で提供します。`websockets` が `false` の状態で Codex が Responses WebSocket アップグレードを試みると、CodexCommander は `426 upgrade_required` を返し、Codex はそのセッションで HTTP にフォールバックします。`"websockets": true` を設定すると同じエンドポイントがアップグレードを受け入れ WebSocket ブリッジを使います。 Codex コンテキスト compaction はルーティングされたモデルでも動作します。`server/responses/compact.ts` は `POST /v1/responses/compact` を内部ルーティング要約ターンとして扱い、圧縮されたヒストリーを返します。 @@ -104,7 +103,7 @@ Codex コンテキスト compaction はルーティングされたモデルで ## キャッシュとカタログ - `codex/model-cache.ts` はリアルタイム `/models` 結果をプロバイダー別にメモリで TTL キャッシュし(デフォルト 5 分、Codex 自身のキャッシュと一致)、fetch が失敗すると stale-fallback を提供します。 -- `codex/catalog.ts` facade が公開する `codex/catalog/sync.ts` は、ルーティングされたモデルを名前空間項目として Codex のカタログにマージし、おすすめの [サブエージェントモデル](/ja/guides/codex-integration/#the-subagent-picker) を先にランク付けし、`disabledModels` をフィルタし、一回限りのバックアップから元のカタログを完全に復元できます。 +- `codex/catalog.ts` が公開する `codex/catalog/sync.ts` は、ルーティングされたモデルを名前空間項目として Codex のカタログにマージし、おすすめの [サブエージェントモデル](/ja/guides/codex-integration/#the-subagent-picker) を先にランク付けし、`disabledModels` をフィルタし、一回限りのバックアップから元のカタログを完全に復元できます。 ## Reasoning effort @@ -118,7 +117,7 @@ Codex カタログは Codex が受け入れるラベル(`low` / `medium` / `hi ## コア型 -内部モデルは `types.ts` にあります: `OcxParsedRequest`、`OcxContext`、`OcxMessage` ユニオン、 -`OcxContentPart`(text / image)、`OcxToolCall`、`OcxTool`、`AdapterEvent`、そして設定型 -(`OcxConfig`、`OcxProviderConfig`)。2 つのヘルパーが広く使われます: `namespacedToolName()` と +内部モデルは `types.ts` にあります: `CodexCommanderParsedRequest`、`CodexCommanderContext`、`CodexCommanderMessage` ユニオン、 +`CodexCommanderContentPart`(text / image)、`CodexCommanderToolCall`、`CodexCommanderTool`、`AdapterEvent`、そして設定型 +(`CodexCommanderConfig`、`CodexCommanderProviderConfig`)。2 つのヘルパーが広く使われます: `namespacedToolName()` と `modelInList()`(`noVisionModels` / `noReasoningModels` に対する寛容な `:size` タグマッチング)。 diff --git a/docs-site/src/content/docs/ja/reference/cli.md b/docs-site/src/content/docs/ja/reference/cli.md index 0086e4c239..f4b9019caf 100644 --- a/docs-site/src/content/docs/ja/reference/cli.md +++ b/docs-site/src/content/docs/ja/reference/cli.md @@ -1,16 +1,16 @@ --- title: CLI リファレンス -description: コマンドディスパッチ、終了コード、およびすべての ocx コマンドファミリーへのリンク。 +description: コマンドディスパッチ、終了コード、およびすべての ccx コマンドファミリーへのリンク。 --- -opencodex CLI は `ocx` です。最初のコマンド名でディスパッチされ、`setup`/`init`、`restore`/`eject`、`models`/`model` などの文書化された別名が同じ操作に達します。不明なコマンドと無効なコマンド形状はエラーです。 +CodexCommander CLI は `ccx` です。最初のコマンド名でディスパッチされ、`setup`/`init`、`restore`/`eject`、`models`/`model` などの文書化された別名が同じ操作に達します。不明なコマンドと無効なコマンド形状はエラーです。 -トップレベルで使用するには、`ocx help` (または `ocx --help` / `ocx -h`) を実行します。ヘルプテーブルに登録されているコマンドに対して、`ocx help <command>`、`ocx <command> --help`、または `ocx <command> -h` を実行します。ヘルプおよびバージョン コマンドは読み取り専用です。これらのコマンドは、Codex または opencodex の状態を開始、停止、インストール、アンインストール、または書き換えません。 +トップレベルで使用するには、`ccx help` (または `ccx --help` / `ccx -h`) を実行します。ヘルプテーブルに登録されているコマンドに対して、`ccx help <command>`、`ccx <command> --help`、または `ccx <command> -h` を実行します。ヘルプおよびバージョン コマンドは読み取り専用です。これらのコマンドは、Codex または CodexCommander の状態を開始、停止、インストール、アンインストール、または書き換えません。 ## コマンドファミリー - [ライフサイクル](/reference/cli/lifecycle/) — セットアップ、プロキシとサービスのライフサイクル、健全性、診断、 -カタログの同期、ダッシュボード、および更新。 +カタログの同期、およびダッシュボード。 - [プロバイダー、アカウント、モデル](/reference/cli/providers-accounts/) — プロバイダー構成、 認証、資格情報プール、クォータ、カスタム モデル、可視性、選択されたモデル、およびコンテキストの上限。 - [エージェント、ルーティング、統合](/reference/cli/agents/) — マルチエージェント コントロール、コンボ、 @@ -20,16 +20,14 @@ opencodex CLI は `ocx` です。最初のコマンド名でディスパッチ 管理コマンドは、2 番目の構成パスを維持するのではなく、記録されたランタイム ポートと ID チェックを使用して、稼働中のプロキシの管理 API をラウンドトリップします。停止したプロキシまたは到達不能なプロキシは HTTP 503 として表され、ゼロ以外の CLI 終了が生成されます。オフライン構成操作として明示的に文書化されているコマンドは、代わりに、稼働中のプロキシを使用せずに設定ファイルを検証および編集できます。 -リストまたはステータスは、明確なデフォルトです。構造化スナップショットには `--json` を使用し、ストリーミング リクエスト ログ フィードには `ocx observe logs --follow --jsonl` を使用します。テーマ、言語、ナビゲーション、その他の純粋に視覚的なブラウザーの状態には、同等の CLI がありません。 Cloudflare Tunnel のセットアップはこのコマンド セットの外にあります。 +リストまたはステータスは、明確なデフォルトです。構造化スナップショットには `--json` を使用し、ストリーミング リクエスト ログ フィードには `ccx observe logs --follow --jsonl` を使用します。テーマ、言語、ナビゲーション、その他の純粋に視覚的なブラウザーの状態には、同等の CLI がありません。 Cloudflare Tunnel のセットアップはこのコマンド セットの外にあります。 ## 終了コードと確認 -成功したコマンドは 0 で終了します。無効な使用法、不明なコマンドまたはリソース、失敗した API 操作、および利用できない必要なサービスは 0 以外で終了します。 `ocx health` は、特にプロキシが正常な場合にのみ 0 で終了し、それ以外の場合は 1 で終了するため、サービス プローブとして使用できます。スクリプトは、人間が判読できる出力をスクレイピングするのではなく、終了コードをテストする必要があります。 +成功したコマンドは 0 で終了します。無効な使用法、不明なコマンドまたはリソース、失敗した API 操作、および利用できない必要なサービスは 0 以外で終了します。 `ccx health` は、特にプロキシが正常な場合にのみ 0 で終了し、それ以外の場合は 1 で終了するため、サービス プローブとして使用できます。スクリプトは、人間が判読できる出力をスクレイピングするのではなく、終了コードをテストする必要があります。 -確認を通知する破壊的な削除、インポート、クレジット消費、更新操作には、非対話型での `--yes` が必要です。このフラグは明示的なオプトインです。これを省略しても、黙ってアクションを確認してはなりません。 +確認を通知する破壊的な削除、インポート、クレジット消費操作には、非対話型での `--yes` が必要です。このフラグは明示的なオプトインです。これを省略しても、黙ってアクションを確認してはなりません。 -## バージョンと内部ディスパッチターゲット +## バージョン -`ocx --version`、`ocx -v`、および `ocx version` は、スクリプト対応バージョンの 1 行を出力して終了します。 - -2 つのディスパッチ ターゲットは通常のヘルプから意図的に省略されています。`__refresh-version [preview]` は切り離されたプロセスで更新通知キャッシュを更新し、`__gui-update-worker <job-id> [latest|preview] [restart]` はダッシュボード更新ジョブを実行します。これらは実装の詳細であり、ユーザー向けの安定したコマンドではありません。ダッシュボードはワーカー PID を記録し、ワーカーが死亡したアクティブなジョブを回復し、PID のない古いアクティブ レコードを 10 分後に古いものとして扱い、ライブ ワーカーを同時更新から保護します。 +`ccx --version`、`ccx -v`、および `ccx version` は、スクリプト対応バージョンの 1 行を出力して終了します。 diff --git a/docs-site/src/content/docs/ja/reference/cli/agents.md b/docs-site/src/content/docs/ja/reference/cli/agents.md index 0cbe43fb3d..12e283b78b 100644 --- a/docs-site/src/content/docs/ja/reference/cli/agents.md +++ b/docs-site/src/content/docs/ja/reference/cli/agents.md @@ -3,19 +3,19 @@ title: CLI エージェント、ルーティング、および統合 description: マルチエージェント、コンボ、可観測性、アクセス、統合、システム、および構成コマンド。 --- -これらのコマンドは、エージェントのポリシーとルーティングを制御し、稼働中のプロキシを検査し、サポートされているクライアントを opencodex に接続します。 +これらのコマンドは、エージェントのポリシーとルーティングを制御し、稼働中のプロキシを検査し、サポートされているクライアントを CodexCommander に接続します。 ## エージェントポリシー -### `ocx agent <status|injection|effort|subagents|fallback|sidecar> ...` +### `ccx agent <status|injection|effort|subagents|fallback|sidecar> ...` ヘッドレス マルチエージェントロスター、エフォート キャップ、プロンプト インジェクション、フォールバック、サイドカー設定を管理します。現在のポリシーには `status` を使用します。サーフェス モード、委任、エフォート、およびフォールバック動作がどのように組み合わされるかについては、[サブエージェントサーフェス](/guides/sub-agent-surface/) を参照してください。 ```bash -ocx agent subagents set ark/model-a,openai/gpt-5.5 +ccx agent subagents set ark/model-a,openai/gpt-5.5 ``` -### `ocx v2 <status|on|off|mode <v1|default|v2>|threads <n>>` +### `ccx v2 <status|on|off|mode <v1|default|v2>|threads <n>>` Codex `multi_agent_v2` 機能フラグとスリーステート マルチエージェント サーフェス モードを管理します。 @@ -30,104 +30,104 @@ Codex `multi_agent_v2` 機能フラグとスリーステート マルチエー | `threads <n>` |アクティブな v1/v2 スレッド制限を少なくとも 1 の整数に設定します。 ```bash -ocx v2 status -ocx v2 mode v1 -ocx v2 mode default -ocx v2 on -ocx v2 threads 16 +ccx v2 status +ccx v2 mode v1 +ccx v2 mode default +ccx v2 on +ccx v2 threads 16 ``` -`mode` サブコマンドは、`multiAgentMode` を opencodex 設定に書き込み、Codex カタログを再同期します。モードとフラグの遷移により、現在の数値スレッド制限が有効な v1/v2 Codex キー間で移動します。移行が失敗すると、元の `config.toml` が復元されます。変更は新しい Codex セッションに適用されますが、実行中のセッションでは固定されたサーフェスが維持されます。 +`mode` サブコマンドは、`multiAgentMode` を CodexCommander 設定に書き込み、Codex カタログを再同期します。モードとフラグの遷移により、現在の数値スレッド制限が有効な v1/v2 Codex キー間で移動します。移行が失敗すると、元の `config.toml` が復元されます。変更は新しい Codex セッションに適用されますが、実行中のセッションでは固定されたサーフェスが維持されます。 ## コンボルーティング -### `ocx combo <list|show|set|remove> ...`・`ocx route combo ...` +### `ccx combo <list|show|set|remove> ...`・`ccx route combo ...` -コンボフェイルオーバーとラウンドロビン仮想モデルを管理します。 `ocx route combo` は階層別名です。 combo は現在サポートされているルーティング リソースです。ターゲットは`provider/model[:weight],provider/model[:weight]`を使用します。 +コンボフェイルオーバーとラウンドロビン仮想モデルを管理します。 `ccx route combo` は階層別名です。 combo は現在サポートされているルーティング リソースです。ターゲットは`provider/model[:weight],provider/model[:weight]`を使用します。 ```bash -ocx combo list -ocx route combo set reliable --targets ark/model-a:2,openai/gpt-5.5 +ccx combo list +ccx route combo set reliable --targets ark/model-a:2,openai/gpt-5.5 ``` ルーティングの動作と設定ガイダンスについては、「[コンボ](/guides/combos/)」を参照してください。 ## 可観測性とデバッグ -### `ocx observe <logs|usage|storage|memory|debug|claude-inbound|injection> ...` +### `ccx observe <logs|usage|storage|memory|debug|claude-inbound|injection> ...` プロキシ リクエスト、使用状況、ストレージ、メモリ、およびデバッグ データを検査します。直接のエイリアスは次のとおりです。 |別名 |同等のリソース | | --- | --- | -| `ocx logs [filters] [--follow] [--json|--jsonl]` | `ocx observe logs` | -| `ocx usage [--range <7d|30d|all>] [--surface <all|codex|claude|grok>] [--json]` | `ocx observe usage` | -| `ocx storage [--json]` | `ocx observe storage` | -| `ocx memory [--json]` | `ocx observe memory` | +| `ccx logs [filters] [--follow] [--json|--jsonl]` | `ccx observe logs` | +| `ccx usage [--range <7d|30d|all>] [--surface <all|codex|claude|grok>] [--json]` | `ccx observe usage` | +| `ccx storage [--json]` | `ccx observe storage` | +| `ccx memory [--json]` | `ccx observe memory` | ```bash -ocx observe usage --range 30d --json +ccx observe usage --range 30d --json ``` -### `ocx debug <provider|usage|injection|claude> <on|off|status|reset|logs [-f]>` +### `ccx debug <provider|usage|injection|claude> <on|off|status|reset|logs [-f]>` 実行中のプロキシの管理 API を通じて、ランタイム デバッグ オーバーライドを読み取りまたは変更します。 ```bash -ocx debug provider on|off|status|reset -ocx debug provider logs [-f|--follow] -ocx debug usage on|off|status|reset -ocx debug usage logs [-f|--follow] +ccx debug provider on|off|status|reset +ccx debug provider logs [-f|--follow] +ccx debug usage on|off|status|reset +ccx debug usage logs [-f|--follow] ``` -スコープがない場合、`ocx debug` は使用状況を出力し、プロキシが停止すると、次回起動環境がデフォルトになります。プロバイダーのデバッグのデフォルトは `OCX_DEBUG=1` です (従来の `OCX_DEBUG_FRAMES=1` も機能します)。使用法デバッグのデフォルトは `OPENCODEX_USAGE_DEBUG=1` からです。 +スコープがない場合、`ccx debug` は使用状況を出力し、プロキシが停止すると、次回起動環境がデフォルトになります。プロバイダーのデバッグのデフォルトは `CCX_DEBUG=1` です。使用法デバッグのデフォルトは `CODEXCOMMANDER_USAGE_DEBUG=1` からです。 ## APIアクセス -### `ocx access <key|endpoints|models|test> ...` +### `ccx access <key|endpoints|models|test> ...` -OpenCodex アドミッション API キーを管理し、外部エンドポイントとモデルを検査します。 `ocx api-key <list|create|remove> ...` は `ocx access key` の別名です。 +CodexCommander アドミッション API キーを管理し、外部エンドポイントとモデルを検査します。 `ccx api-key <list|create|remove> ...` は `ccx access key` の別名です。 ```bash -ocx access key create deployment +ccx access key create deployment ``` ## クライアントの統合 -### `ocx integration <claude|grok> ...` +### `ccx integration <claude|grok> ...` サポートされている Claude と Grok の統合を管理します。以下の直接コマンド ファミリは、クライアント固有のコントロールを公開します。 -### `ocx claude [claude args...]` +### `ccx claude [claude args...]` -プロキシが実行されていることを確認し、`ANTHROPIC_BASE_URL`、`ANTHROPIC_AUTH_TOKEN`、`CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1`、および `config.claudeCode` のモデル スロットを使用してクロード コードを起動します。ルーティングされたモデルは、Claude Code 2.1.129 以降の安定したスロット エイリアスを介してネイティブ `/model` ピッカーに表示されます。古いバージョンでは、`ANTHROPIC_MODEL` または `/model <id>` で選択します。ユーザーがエクスポートした `ANTHROPIC_*` 変数が常に優先されます。 +プロキシが実行されていることを確認し、`ANTHROPIC_BASE_URL`、`ANTHROPIC_AUTH_TOKEN`、`CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1`、および `config.claudeCode` の現在の認証/ヘルパー設定を使用して Claude Code を起動します。ルーティングされたモデルは、Claude Code 2.1.129 以降の安定したエイリアスを介してネイティブ `/model` ピッカーに表示されます。古いバージョンでは、`ANTHROPIC_MODEL` または `/model <id>` で選択します。ユーザーがエクスポートした `ANTHROPIC_*` 変数が常に優先されます。 Claude デスクトップ プロファイル コマンドは次のとおりです。 ```text -ocx claude desktop [apply] Save and apply the four-family profile -ocx claude desktop show [--json] Show routes, families, and defaults -ocx claude desktop move <route> <family> [--default] -ocx claude desktop default <family> <route|none> -ocx claude desktop export <path|-> Export versioned JSON (`-` = stdout) -ocx claude desktop import <path> [--apply] Validate and import JSON +ccx claude desktop apply Save and apply the four-family profile +ccx claude desktop show [--json] Show routes, families, and defaults +ccx claude desktop move <route> <family> [--default] +ccx claude desktop default <family> <route|none> +ccx claude desktop export <path|-> Export versioned JSON (`-` = stdout) +ccx claude desktop import <path> [--apply] Validate and import JSON ``` -ファミリは `opus`、`fable`、`sonnet`、および `haiku` です。新しいルートは `opus` で始まります。 `none` は、そのファミリーが空の場合にのみ有効です。従来の適用フラグ `--static`、`--hybrid`、および `--discovery-only` は引き続きサポートされます。クロードコードの設定には`ocx claude config <status|set> ...`を使用してください。 +ファミリは `opus`、`fable`、`sonnet`、および `haiku` です。新しいルートは `opus` で始まります。`none` は、そのファミリーが空の場合にのみ有効です。Claude Code の設定には `ccx claude config <status|set> ...` を使用してください。 -### `ocx opencode [opencode args...]` +### `ccx opencode [opencode args...]` -プロキシが実行されていることを確認し、OpenCode のインライン ランタイム層 (`OPENCODE_CONFIG_CONTENT`) で生成された `provider.opencodex` ブロックを使用してオープンコードを起動します。既存のインライン設定は保持され、今回の起動では `provider.opencodex` のみが置き換えられます。グローバルまたはプロジェクトの `opencode.json` ファイルは、既存の上書きについて警告するために読み取られることがありますが、ディスク上のファイルは変更されません。ルーティングされたモデルは `opencodex/<provider>/<model>` として表示されます。このランチャーは後のプレーン `opencode` 起動を変更せず、`provider.opencodex` を永続化する経路は別の opt-in ダッシュボード統合だけです。 +プロキシが実行されていることを確認し、OpenCode のインライン ランタイム層 (`OPENCODE_CONFIG_CONTENT`) で生成された `provider.codexcommander` ブロックを使用してオープンコードを起動します。既存のインライン設定は保持され、今回の起動では `provider.codexcommander` のみが置き換えられます。グローバルまたはプロジェクトの `opencode.json` ファイルは、既存の上書きについて警告するために読み取られることがありますが、ディスク上のファイルは変更されません。ルーティングされたモデルは `codexcommander/<provider>/<model>` として表示されます。このランチャーは後のプレーン `opencode` 起動を変更せず、`provider.codexcommander` を永続化する経路は別の opt-in ダッシュボード統合だけです。 -### `ocx grok <status|exclude|include|set|clear|apply> ...` +### `ccx grok <status|exclude|include|set|clear|apply> ...` Grok Build モデル フェンスを管理および適用します。 ## クライアント設定のエクスポート -### `ocx export --client <opencode|pi>` +### `ccx export --client <opencode|pi>` -実行中のプロキシに接続されているクライアント設定を出力します。 opencode と [円周率](/guides/pi/) は環境変数ではなく独自の JSON 設定からプロバイダーを読み取るため、このコマンドは `opencodex` プロバイダー ブロック (ベース URL、モデル リスト、クライアントの環境参照) をシリアル化し、そのファイルにマージできるようにします。 +実行中のプロキシに接続されているクライアント設定を出力します。 opencode と [円周率](/guides/pi/) は環境変数ではなく独自の JSON 設定からプロバイダーを読み取るため、このコマンドは `codexcommander` プロバイダー ブロック (ベース URL、モデル リスト、クライアントの環境参照) をシリアル化し、そのファイルにマージできるようにします。 プロキシが実行されている必要があります。このコマンドはライブ ポートを解決し、`/api/models` を読み取り、Codex が現在認識できるモデルのみを出力します。 @@ -139,22 +139,22 @@ Grok Build モデル フェンスを管理および適用します。 | `--force` | `--out` が既存のファイルを置き換えることを許可します。 | ```bash -ocx export --client opencode # config plus destination, merge warning, and counts -ocx export --client pi --json > pi-models.json # byte-exact JSON for a pipe or a diff -ocx export --client opencode --out ~/opencodex-opencode.json +ccx export --client opencode # config plus destination, merge warning, and counts +ccx export --client pi --json > pi-models.json # byte-exact JSON for a pipe or a diff +ccx export --client opencode --out ~/codexcommander-opencode.json ``` `--json` がない場合、JSON が先頭に続き、正規の宛先パス、マージ警告、環境エクスポート行、およびコンテキスト制限を省略する行数を含むモデル数が続きます (クライアントはこれらに対して独自のデフォルトを適用します)。 |クライアント |正規の宛先 |ダウンロードファイル名 |環境変数 | | --- | --- | --- | --- | -| `opencode` | `~/.config/opencode/opencode.json` (設定すると `XDG_CONFIG_HOME` が勝ち) | `opencode.json` | `OPENCODEX_OPENCODE_API_KEY` | -| `pi` | `~/.pi/agent/models.json` | `pi-models.json` | `OPENCODEX_API_KEY` | +| `opencode` | `~/.config/opencode/opencode.json` (設定すると `XDG_CONFIG_HOME` が勝ち) | `opencode.json` | `CODEXCOMMANDER_OPENCODE_API_KEY` | +| `pi` | `~/.pi/agent/models.json` | `pi-models.json` | `CODEXCOMMANDER_API_KEY` | -2 つの環境変数名は異なり、各クライアントは独自の名前のみを補間します。 opencode は `{env:OPENCODEX_OPENCODE_API_KEY}` を読み取ります。 Pi は `$OPENCODEX_API_KEY` を読み取ります。 +2 つの環境変数名は異なり、各クライアントは独自の名前のみを補間します。 opencode は `{env:CODEXCOMMANDER_OPENCODE_API_KEY}` を読み取ります。 Pi は `$CODEXCOMMANDER_API_KEY` を読み取ります。 :::caution[マージし、決して置き換えないでください] -`ocx export` は実際のクライアント設定を書き込むことはありません。宛先は手動でマージできるように出力されます。`--out` は、`--force` なしで既存のファイルを上書きすることを拒否します。これは、設定を置き換えると、その中にすでに含まれている他のプロバイダー、エージェント、および MCP エントリが破壊されるためです。 +`ccx export` は実際のクライアント設定を書き込むことはありません。宛先は手動でマージできるように出力されます。`--out` は、`--force` なしで既存のファイルを上書きすることを拒否します。これは、設定を置き換えると、その中にすでに含まれている他のプロバイダー、エージェント、および MCP エントリが破壊されるためです。 ::: キーはシリアル化されません。設定にはクライアントの環境参照のみが含まれるため、シークレットは環境内に残ります。ループバック プロキシ (`127.0.0.1`、デフォルト) にはアドミッション キーはまったく必要ありません。参照は単に使用されないだけです。プロキシがループバックを超えてバインドする場合にのみ変数を設定します。アドミッションキーの発行方法については、[リモートアクセス](/reference/configuration/#remote-access) を参照してください。上流プロバイダー自体のキーは完全に別のものであり、[プロバイダー](/guides/providers/) ごとに構成されます。 @@ -163,14 +163,14 @@ ocx export --client opencode --out ~/opencodex-opencode.json ## ランタイムと構成 -### `ocx system <status|settings|startup|diagnostics|sync|update> ...` +### `ccx system <status|settings|startup|diagnostics|sync> ...` -ヘッドレス ランタイムの設定、起動、同期、診断、更新を管理します。 +ヘッドレス ランタイムの設定、起動、同期、診断を管理します。 ```bash -ocx system settings --stream-mode eager-relay +ccx system settings --stream-mode eager-relay ``` -### `ocx config <show|get|set|unset|validate|export|import> ...` +### `ccx config <show|get|set|unset|validate|export|import> ...` -検証された OpenCodex 設定を検査し、安全に変更します。 `show` および `get` はシークレットをマスクします。インポートは書き込む前に検証され、`--yes` が必要です。 +検証された CodexCommander 設定を検査し、安全に変更します。 `show` および `get` はシークレットをマスクします。インポートは書き込む前に検証され、`--yes` が必要です。 diff --git a/docs-site/src/content/docs/ja/reference/cli/lifecycle.md b/docs-site/src/content/docs/ja/reference/cli/lifecycle.md index 0905507adc..162a66f7bc 100644 --- a/docs-site/src/content/docs/ja/reference/cli/lifecycle.md +++ b/docs-site/src/content/docs/ja/reference/cli/lifecycle.md @@ -1,69 +1,65 @@ --- title: CLI ライフサイクル -description: セットアップ、開始、停止、サービス、診断、同期、および更新コマンド。 +description: セットアップ、開始、停止、サービス、診断、および同期コマンド。 --- -これらのコマンドは、ローカル opencodex プロキシとその Codex 統合をインストール、実行、検査、修復、および更新します。 +これらのコマンドは、ローカル CodexCommander プロキシとその Codex 統合をインストール、実行、検査、および修復します。 ## 設定 -### `ocx init`・`ocx setup` +### `ccx init`・`ccx setup` -対話型セットアップ ウィザード (`setup` は `init` のエイリアスです)。プロバイダー (プリセットまたはカスタム)、API キー (リテラルまたは `${ENV}`)、デフォルトのモデル、およびプロキシ ポートの入力を求めるプロンプトが表示されます。 `~/.opencodex/config.json` を保存します。オプションでプロキシを `$CODEX_HOME/config.toml` (デフォルトは `~/.codex/config.toml`) に挿入します。オプションで Codex 自動起動シムをインストールします。 +対話型セットアップ ウィザード (`setup` は `init` のエイリアスです)。プロバイダー (プリセットまたはカスタム)、API キー (リテラルまたは `${ENV}`)、デフォルトのモデル、およびプロキシ ポートの入力を求めるプロンプトが表示されます。 `~/.codexcommander/config.json` を保存します。オプションでプロキシを `$CODEX_HOME/config.toml` (デフォルトは `~/.codex/config.toml`) に挿入します。オプションで Codex 自動起動シムをインストールします。 ## プロキシのライフサイクル -### `ocx start [--port <port>]` +### `ccx start [--port <port>]` -プロキシ サーバー (優先ポート `10100`) を起動します。そのポートが占有されている場合、opencodex は別の使用可能なポートを選択して記録します。 PID/ランタイムポートの状態を書き込み、2 番目のライブインスタンスの起動を拒否します。開始時に、各プロバイダーのモデルを Codex のカタログに同期します。マネージド サービス (`OCX_SERVICE=1`) として起動されていない限り、シャットダウン時にネイティブ Codex が復元されます。 +プロキシ サーバー (優先ポート `10100`) を起動します。そのポートが占有されている場合、CodexCommander は別の使用可能なポートを選択して記録します。 PID/ランタイムポートの状態を書き込み、2 番目のライブインスタンスの起動を拒否します。開始時に、各プロバイダーのモデルを Codex のカタログに同期します。マネージド サービス (`CCX_SERVICE=1`) として起動されていない限り、シャットダウン時にネイティブ Codex が復元されます。 ```bash -ocx start -ocx start --port 8080 +ccx start +ccx start --port 8080 ``` -### `ocx stop` +### `ccx stop` -実行中のプロキシを (PID によって) 停止し、PID ファイルを削除して、ネイティブ Codex を復元します。マネージド バックグラウンド サービスがインストールされている場合、`ocx stop` はそれを最初に停止するため、プロキシを再起動できません。同じアクションは、Web ダッシュボードの **停止** ボタン (`POST /api/stop`) から実行できます。 +実行中のプロキシを (PID によって) 停止し、PID ファイルを削除して、ネイティブ Codex を復元します。マネージド バックグラウンド サービスがインストールされている場合、`ccx stop` はそれを最初に停止するため、プロキシを再起動できません。同じアクションは、Web ダッシュボードの **停止** ボタン (`POST /api/stop`) から実行できます。 -### `ocx restart` +### `ccx restart` `stop` に続いて `ensure` を実行します。プロキシ/サービスを停止し、ネイティブ Codex を復元し、バックグラウンドでプロキシを起動し、ライブ ポートを Codex に同期します。 -### `ocx ensure` +### `ccx ensure` バックグラウンド プロキシが実行されていることを冪等的に確認してから、そのライブ モデル カタログを同期します。 `codexAutoStart` が `false` の場合、自動起動が無効であることが出力され、何も行われません。 -### `ocx restore [back]`・`ocx eject [back]` +### `ccx restore [back]`・`ccx eject [back]` プロキシを停止せずに**ネイティブ Codex を復元します。挿入された設定行とルーティングされたカタログ エントリを削除し、プレーンな `codex` が再びネイティブに動作するようにします。 `eject` は `restore` の別名です。 プロキシのライフサイクルを変更せずに、既に実行されているプロキシでプレーン `codex` を再指定するには、`back` をどちらかのスペルに渡します。 ```bash -ocx restore back -ocx eject back +ccx restore back +ccx eject back ``` -### `ocx recover-history --legacy-openai` +### `ccx uninstall`・`ccx remove` -可逆バックアップ サポートが存在する前に Codex App 履歴を再マップした古い開発ビルドの明示的なリカバリ。履歴データベースがロックされている場合は、まず Codex を閉じてください。 - -### `ocx uninstall`・`ocx remove` - -すべての復元手順が成功した場合にのみ、サービスとプロキシを停止し、サービスと Codex シムを削除し、ネイティブ Codex を復元してから、opencodex ローカル設定を削除します。 `remove` は `uninstall` の別名です。設定のクリーンアップには、新規インストールによって作成された所有権メタデータが必要です。従来のディレクトリまたは共有ディレクトリはそのまま残ります。 +すべての復元手順が成功した場合にのみ、サービスとプロキシを停止し、サービスと Codex シムを削除し、ネイティブ Codex を復元してから、CodexCommander ローカル設定を削除します。 `remove` は `uninstall` の別名です。設定のクリーンアップには正規の所有権メタデータが必要です。所有されていないディレクトリまたは共有ディレクトリはそのまま残ります。 ## ステータスと健康状態 -### `ocx status [--json]` +### `ccx status [--json]` 読み取り専用の診断概要を出力します: プロキシ PID、`/healthz` 到達可能性、ダッシュボード URL、構成パス、デフォルト プロバイダー、Codex 自動起動設定、サービス状態、シム状態、および編集された有効な Codex ホーム。明示的で信頼性の高い Windows Orca ランタイム ホーム署名のみが、実用的なアプリとホームの不一致の警告を追加します。 `CODEX_HOME` が自動的に変更されることはありません。 人間の出力には、OAuth ログイン概要の後の **OAuth health** ブロックも含まれます。つまり、既知のすべてのアカウントが正常な場合は `OAuth health: ok`、または正常でないアカウントごとに 1 行が編集された `OAuth health: warning` (プロバイダー、マスクされたアカウント ID、再認証が必要、レートまたはクォータの制限、または更新の競合などのステータス) と、オプションの `Action:` ヒントが含まれます。アカウント ID は編集されます。トークンと電子メールは決して印刷されません。 `--json` 契約には現在、このヘルス ブロックは含まれていません。 ```bash -ocx status -ocx status --json +ccx status +ccx status --json ``` 省略形の例: @@ -84,8 +80,8 @@ ocx status --json "url": "http://localhost:10100/" }, "paths": { - "config": "/Users/example/.opencodex/config.json", - "pid": "/Users/example/.opencodex/ocx.pid", + "config": "/Users/example/.codexcommander/config.json", + "pid": "/Users/example/.codexcommander/codexcommander.pid", "runtime": "/path/to/bun" }, "runtime": { @@ -101,7 +97,7 @@ ocx status --json "codexAutostart": true, "defaultProvider": "openai", "service": { - "summary": "not installed (logs: /Users/example/.opencodex/service.log)" + "summary": "not installed (logs: /Users/example/.codexcommander/service.log)" }, "codexShim": { "summary": "Codex autostart shim: not installed" @@ -111,16 +107,16 @@ ocx status --json 実際のオブジェクトには、`listen` (ポート、ホスト名、ランタイム/構成ソース)、構成ロード診断、およびバンドルされた Codex プラグイン診断も含まれています。 JSON スキーマは加算専用です。将来のバージョンではフィールドが追加される可能性がありますが、既存のフィールドは安定したままになるはずです。 API キー、OAuth トークン、認証ヘッダー、リクエスト コンテンツ、電子メール、アカウント ID は意図的に除外されます。 -### `ocx health [--json]` +### `ccx health [--json]` 稼働中のプロキシの ID を確認します。ヒューマン出力は PID/ポートをレポートします。 `--json` は `{ok, pid, port}` を出力します。このコマンドは正常な場合のみ 0 で終了し、それ以外の場合は 1 で終了するため、サービス プローブに適しています。 -### `ocx ready [--json] [--wait [--timeout <seconds>]]` +### `ccx ready [--json] [--wait [--timeout <seconds>]]` 認証不要の `GET /readyz` エンドポイントで同期後の準備状態を確認します。準備完了時は `200`、 `pending` または終端状態の `failed` では `Retry-After: 1` とともに `503` を返します。HTTP の -サニタイズ済み識別フィールドは `{service, version, uptime, pid, port, status}` です。`/readyz` がない -旧プロキシは `unreachable` として fail-closed し、`/healthz` は readiness ではなく別の liveness 確認です。 +サニタイズ済み識別フィールドは `{service, version, uptime, pid, port, status}` です。`/healthz` は +readiness ではなく別の liveness 確認です。 デフォルトでは 1 回だけ probe します。`--wait` は準備完了または timeout まで polling しますが、 終端 `failed` を確認すると即座に終了します。デフォルト timeout は 45 秒で、`--timeout <seconds>` には `--wait` が必要です(1〜300 秒の正の整数)。CLI JSON は @@ -128,29 +124,29 @@ ocx status --json いずれかです。終了コードは ready が 0、not-ready/pending/failed/timeout/unreachable が 1、 不正な引数が 64 です。 -### `ocx doctor` +### `ccx doctor` -読み取り専用環境と接続の診断を実行します: 状態パスとファイル システム タイプ、WSL デュアル インストール、プロキシ環境/構成、ChatGPT の到達可能性、Codex プラグインとプロジェクト設定の警告、保留中の履歴の移行。 Codex のアプリとホームのターゲット設定セクションでは、Windows Orca ランタイムとホームの狭い不一致も検出し、該当する場合はサービスの移行について説明します。この診断によって表示されるパスでは、OS ユーザー名が編集されます。医師は修復ヒントを出力しますが、適用しません。 +読み取り専用環境と接続の診断を実行します: 状態パスとファイル システム タイプ、WSL デュアル インストール、プロキシ環境/構成、ChatGPT の到達可能性、Codex プラグインとプロジェクト設定の警告。Codex のアプリとホームのターゲット設定セクションでは、Windows Orca ランタイムとホームの狭い不一致も検出し、該当する場合は手動のアンインストール、環境設定、再インストール手順を表示します。この診断によって表示されるパスでは、OS ユーザー名が編集されます。Doctor は修復ヒントを出力しますが、適用しません。 -**OAuth の信頼性** セクションでは、資格情報ストレージが書き込み可能かどうか、リフレッシュ シングルフライト/ロック ファイルが `OPENCODEX_HOME` で作成できるかどうか、回復 `Action:` を持つ正常でない OAuth または Codex プール アカウント (編集された ID)、および Codex 転送パスが公式クライアント メタデータを作成しない静的 OK が報告されます。 Doctor は資格情報を変更したり、修復を適用したりすることはありません。 +**OAuth の信頼性** セクションでは、資格情報ストレージが書き込み可能かどうか、リフレッシュ シングルフライト/ロック ファイルが `CODEXCOMMANDER_HOME` で作成できるかどうか、回復 `Action:` を持つ正常でない OAuth または Codex プール アカウント (編集された ID)、および Codex 転送パスが公式クライアント メタデータを作成しない静的 OK が報告されます。 Doctor は資格情報を変更したり、修復を適用したりすることはありません。 ## カタログの同期 -### `ocx sync [--restart-codex]` +### `ccx sync [--restart-codex]` 構成されているすべてのプロバイダーからライブ モデル リストを取得し、マージされたカタログを Codex に再挿入します。プロバイダーを追加した後、または利用可能なモデルを更新するために実行します。 -存続期間の長い Codex `app-server` プロセスがまだ実行されている場合、`ocx sync` は、`opencodex-catalog.json` / `models_cache.json` が更新されても、以前のメモリ内モデル リストを提供し続ける可能性があることを警告します。現在のユーザーが所有する一致する `codex … app-server` および `codex-code-mode-host` プロセスにのみ `SIGTERM` を送信するには、`--restart-codex` を渡します (アクティブなターンが中断される可能性があります)。広範な `pkill -f codex` 一致は意図的に回避されます。 +存続期間の長い Codex `app-server` プロセスがまだ実行されている場合、`ccx sync` は、`codexcommander-catalog.json` / `models_cache.json` が更新されても、以前のメモリ内モデル リストを提供し続ける可能性があることを警告します。現在のユーザーが所有する一致する `codex … app-server` および `codex-code-mode-host` プロセスにのみ `SIGTERM` を送信するには、`--restart-codex` を渡します (アクティブなターンが中断される可能性があります)。広範な `pkill -f codex` 一致は意図的に回避されます。 -### `ocx sync-cache [--restart-codex]` +### `ccx sync-cache [--restart-codex]` -Codex のローカル モデル ピッカー キャッシュを無効にし、アクティブな opencodex カタログから再構築されるようにします。 `ocx sync` と同じ、古い `app-server` 警告とオプションの `--restart-codex` 動作が適用されます。 +Codex のローカル モデル ピッカー キャッシュを無効にし、アクティブな CodexCommander カタログから再構築されるようにします。 `ccx sync` と同じ、古い `app-server` 警告とオプションの `--restart-codex` 動作が適用されます。 ## バックグラウンドサービス -### `ocx service [install|repair|start|stop|status|uninstall|remove]` +### `ccx service [install|repair|start|stop|status|uninstall|remove]` -opencodex を、ログイン時に自動起動し、クラッシュ時に自動再起動するログイン管理バックグラウンド サービス (macOS **launchd**、Linux **systemd ユーザー ユニット**、Windows **タスク スケジューラ**) として実行します。サービスは `OCX_SERVICE=1` を設定して実行されるため、再起動によって Codex 設定が変更されることはありません。 +CodexCommander を、ログイン時に自動起動し、クラッシュ時に自動再起動するログイン管理バックグラウンド サービス (macOS **launchd**、Linux **systemd ユーザー ユニット**、Windows **タスク スケジューラ**) として実行します。サービスは `CCX_SERVICE=1` を設定して実行されるため、再起動によって Codex 設定が変更されることはありません。 |サブコマンド |アクション | | --- | --- | @@ -164,22 +160,22 @@ opencodex を、ログイン時に自動起動し、クラッシュ時に自動 | `remove` | `uninstall`の別名。 | ```bash -ocx service -ocx service install -ocx service repair -ocx service status -ocx service uninstall +ccx service +ccx service install +ccx service repair +ccx service status +ccx service uninstall ``` -Windows では、`ocx service status` は、ID 検証済みの OpenCodex プロキシの到達可能性とは別に、タスク スケジューラの登録を報告します。ローカライズされた `schtasks` テーブルは出力されないため、概要は Windows コード ページ間で読み取れるままです。 +Windows では、`ccx service status` は、ID 検証済みの CodexCommander プロキシの到達可能性とは別に、タスク スケジューラの登録を報告します。ローカライズされた `schtasks` テーブルは出力されないため、概要は Windows コード ページ間で読み取れるままです。 -Windows では、タスク スケジューラ エントリを作成するには昇格が必要です。認識されたローカライズされたアクセス拒否テキストは、既存のガイダンス パスを維持します。そのテキストが判読できない場合、フォールバックには、所有されているコマンド形状 `/create /tn opencodex-proxy /xml <non-empty-path> /f`、ステータス 1、および確認済みの非昇格トークンが必要です。ダッシュボードのスタートアップ セーフティ アクションは、UAC を自動的に要求できるようになります。そのフォールバックがトークンの状態を判断できない場合、元のスケジューラ エラーが保持されます。外部タスクおよび操作は、自動昇格マーカーを発行することはできません。ダッシュボードの UAC プロンプトを承認するか、管理者特権の PowerShell ウィンドウで `ocx service install` を再実行します。 +Windows では、タスク スケジューラ エントリを作成するには昇格が必要です。認識されたローカライズされたアクセス拒否テキストは、既存のガイダンス パスを維持します。そのテキストが判読できない場合、フォールバックには、所有されているコマンド形状 `/create /tn codexcommander-proxy /xml <non-empty-path> /f`、ステータス 1、および確認済みの非昇格トークンが必要です。ダッシュボードのスタートアップ セーフティ アクションは、UAC を自動的に要求できるようになります。そのフォールバックがトークンの状態を判断できない場合、元のスケジューラ エラーが保持されます。外部タスクおよび操作は、自動昇格マーカーを発行することはできません。ダッシュボードの UAC プロンプトを承認するか、管理者特権の PowerShell ウィンドウで `ccx service install` を再実行します。 -### `ocx codex-shim <install|status|uninstall|remove>` +### `ccx codex-shim <install|status|uninstall|remove>` 軽量の自動起動スクリプトを使用して、スクリプトベースの `codex` ランチャーを PATH 上にラップします。実際の `codex.exe` ターゲットは、正確な実行可能呼び出しの破損を避けるため、変更されないまま残されます。 -完了した外部 Codex アップデートがインストールされている shim を上書きした場合、次の通常の `ocx` コマンドは安定した新しいランチャーをバックアップし、ディスパッチ前に shim を復元します。まだ変更中のランチャーは変更されず、後で再試行されます。修復の失敗は、要求されたコマンドを失敗させることなく警告します。手動フォールバック: `ocx codex-shim install`。 `codexShimAutoRestore` を `false` に設定するか、プロセス レベルのオプトアウトの場合は `OPENCODEX_CODEX_SHIM_AUTO_RESTORE=0` を設定します。 +完了した外部 Codex アップデートがインストールされている shim を上書きした場合、次の通常の `ccx` コマンドは安定した新しいランチャーをバックアップし、ディスパッチ前に shim を復元します。まだ変更中のランチャーは変更されず、後で再試行されます。修復の失敗は、要求されたコマンドを失敗させることなく警告します。手動フォールバック: `ccx codex-shim install`。 `codexShimAutoRestore` を `false` に設定するか、プロセス レベルのオプトアウトの場合は `CODEXCOMMANDER_CODEX_SHIM_AUTO_RESTORE=0` を設定します。 |サブコマンド |アクション | | --- | --- | @@ -189,34 +185,21 @@ Windows では、タスク スケジューラ エントリを作成するには | `status` |シムの状態 (インストール済み、古い、または欠落) を報告します。 | ```bash -ocx codex-shim install -ocx codex-shim status -ocx codex-shim uninstall +ccx codex-shim install +ccx codex-shim status +ccx codex-shim uninstall ``` :::tip[サービス vs シム] -常時オンのバックグラウンド プロキシには `ocx service` を使用します (推奨)。デーモンを使用しない軽量のオンデマンド起動には、`ocx codex-shim` を使用します。プロキシは、`codex` が起動された場合にのみ起動します。 +常時オンのバックグラウンド プロキシには `ccx service` を使用します (推奨)。デーモンを使用しない軽量のオンデマンド起動には、`ccx codex-shim` を使用します。プロキシは、`codex` が起動された場合にのみ起動します。 ::: -### `ocx tray <install|start|stop|status|uninstall|remove> [--json] [--no-start]` +### `ccx tray <install|start|stop|status|uninstall|remove> [--json] [--no-start]` Windows ステータス トレイ アイコンをインストールして制御します。 Windows ログイン時に開始され、ワンクリックでプロキシ コントロールを提供します。 `start` および `stop` はアイコンのみを制御します。そのメニューを使用してプロキシを制御します。 `--no-start` は `install` に適用され、トレイをすぐに起動せずにインストールします。 ## ダッシュボード -### `ocx gui` +### `ccx gui` `http://localhost:<port>` で [ウェブダッシュボード](/guides/web-dashboard/) を開き、プロキシが実行されていない場合は自動起動します。 - -## 更新 - -### `ocx update [--tag latest|preview]` - -npm から opencodex を自己更新します。安定したインストールでは `@latest` を使用します。 `--tag latest|preview` を渡さない限り、プレビュー インストールは `@preview` に残ります。ソース チェックアウトを検出し、代わりに `git pull && bun install` を使用するように指示しますが、そのタグの最新バージョンをすでに使用している場合は何もしません。実行中のプロキシは、ファイルが置き換えられる前に停止されます。インストールされたサービスは再構築されて自動的に開始されますが、フォアグラウンド インストールでは次のステップとして `ocx start` が出力されます。 - -```bash -ocx update -ocx update --tag preview -``` - -新しいバージョンは、[リリースワークフロー](https://github.com/lidge-jun/opencodex/actions/workflows/release.yml) が npm に公開すると利用可能になります。 diff --git a/docs-site/src/content/docs/ja/reference/cli/providers-accounts.md b/docs-site/src/content/docs/ja/reference/cli/providers-accounts.md index e090809d83..2f25ca2fb1 100644 --- a/docs-site/src/content/docs/ja/reference/cli/providers-accounts.md +++ b/docs-site/src/content/docs/ja/reference/cli/providers-accounts.md @@ -7,7 +7,7 @@ description: プロバイダー構成、資格情報、クォータ、および ## プロバイダー -### `ocx provider <subcommand>` +### `ccx provider <subcommand>` 非対話型のプロバイダー管理。レジストリ エントリは名前によってシードされます。カスタム名には `--adapter` と `--base-url` の両方が必要です。 @@ -26,13 +26,13 @@ description: プロバイダー構成、資格情報、クォータ、および | `account-mode` | `pool`、`direct`、`--json` |プールされた Codex アカウント ルーティングまたは直接の Codex アカウント ルーティングを選択します。 | ```bash -ocx provider list --json -ocx provider test ark -ocx provider add anthropic --api-key sk-ant-... --set-default --sync -ocx provider add local-dev --adapter openai-chat --base-url http://localhost:11434/v1 -ocx provider show anthropic --json -ocx models --provider anthropic --json -ocx models live --provider ark --json +ccx provider list --json +ccx provider test ark +ccx provider add anthropic --api-key sk-ant-... --set-default --sync +ccx provider add local-dev --adapter openai-chat --base-url http://localhost:11434/v1 +ccx provider show anthropic --json +ccx models --provider anthropic --json +ccx models live --provider ark --json ``` :::caution[カスタムヘッダーは認証情報の経路ではありません] @@ -54,29 +54,29 @@ ocx models live --provider ark --json ## 認証 -### `ocx login <provider>` +### `ccx login <provider>` -プロバイダーの登録済みログインフローを開始します。プロバイダーに応じて、OAuth ログインはブラウザーを開くか、サインイン済みのネイティブ CLI セッションを取り込みまたはリンクします。`~/.opencodex/` に保存された OpenCodex 所有の認証情報は自動更新されます。リンクされた Grok/Kimi CLI のアクセス世代は読み取り専用で採用され、更新の責任はネイティブ CLI に残ります。API キーログインプロバイダーはキーダッシュボードを開き、キーの入力を求め、可能な場合は検証し、結果のプロバイダー設定を保存します。名前がないか不明な場合、このコマンドは現在受け付ける OAuth および API キーのプロバイダー ID を出力します。 +プロバイダーの登録済みログインフローを開始します。プロバイダーに応じて、OAuth ログインはブラウザーを開くか、サインイン済みのネイティブ CLI セッションを取り込みまたはリンクします。`~/.codexcommander/` に保存された CodexCommander 所有の認証情報は自動更新されます。リンクされた Grok/Kimi CLI のアクセス世代は読み取り専用で採用され、更新の責任はネイティブ CLI に残ります。API キーログインプロバイダーはキーダッシュボードを開き、キーの入力を求め、可能な場合は検証し、結果のプロバイダー設定を保存します。名前がないか不明な場合、このコマンドは現在受け付ける OAuth および API キーのプロバイダー ID を出力します。 -`ocx status` / `ocx doctor` が再認証が必要であるか、端末の更新失敗を報告した後、同じコマンドを使用して **再認証**します (またはダッシュボードで再認証を使用します)。 Codex プール アカウントはパブリック `ocx login` プロバイダーではありません。代わりに、ダッシュボード Codex アカウント プール (再認証) またはヘッドレス `ocx account reauth` フローを介して再認証します。 +`ccx status` / `ccx doctor` が再認証が必要であるか、端末の更新失敗を報告した後、同じコマンドを使用して **再認証**します (またはダッシュボードで再認証を使用します)。 Codex プール アカウントはパブリック `ccx login` プロバイダーではありません。代わりに、ダッシュボード Codex アカウント プール (再認証) またはヘッドレス `ccx account reauth` フローを介して再認証します。 ```bash -ocx login xai -ocx login anthropic +ccx login xai +ccx login anthropic ``` -### `ocx logout <provider>` +### `ccx logout <provider>` 保存されているプロバイダーの OAuth 資格情報を削除します。 ## アカウントとキープール -### `ocx account <subcommand>` +### `ccx account <subcommand>` 実行中のプロキシを介してプロバイダー アカウントと API キー プールを一覧表示し、切り替えます。出荷されたヘルプ画面は次のとおりです。 ```text -Usage: ocx account <list|current|use|refresh|auto-switch|priority|login|reauth|code|cancel|remove|add-key|reset-credits> ... +Usage: ccx account <list|current|use|refresh|auto-switch|priority|login|reauth|code|cancel|remove|add-key|reset-credits> ... list [provider] Codex account pool, OAuth accounts and API keys (identifiers shown masked as the API returns them). current <provider> Show the active account or key. @@ -111,7 +111,7 @@ Codex pool selection applies to the next request after clearing existing affinit } ``` -### `ocx account list [provider] [--json] [--all]` +### `ccx account list [provider] [--json] [--all]` プロバイダーを使用しない場合、Codex プール、OAuth アカウント、および設定された API キー プールが一覧表示されます。 `--all` が存在しない限り、空のプロバイダーはスキップされます。プロバイダーを使用すると、その資格情報ファミリーのみがリストされます。人間の出力では `PROVIDER TYPE ID PLAN/LABEL PRIORITY STATUS` を使用します。手動で選択した Codex 行には `selected` というマークが付けられます。保存された Kiro アカウントが存在する場合、出力には、Kiro には 1 つのログイン スロットがあり、再度サインインすると現在のアカウントが置き換えられることが示されます。結果が空であっても成功です。 `--json` は次を返します: @@ -119,7 +119,7 @@ Codex pool selection applies to the next request after clearing existing affinit { accounts: AccountRow[], notes: string[] } ``` -### `ocx account current <provider> [--json]` +### `ccx account current <provider> [--json]` アクティブなアカウントまたはキーを表示します。手動ピンのない Codex プールは、優先度を考慮した自動選択を報告します。最も優先度の高い適格ティアが選ばれ、そのティア内でクォータルーティングのもと最低使用量のアカウントが選ばれます。アクティブな認証情報を持たない別のファミリーは、その状態を報告し、依然として 0 を終了します。`--json` は次を返します。 @@ -127,10 +127,10 @@ Codex pool selection applies to the next request after clearing existing affinit { provider, type, activeId: string | null, autoSwitchThreshold?: number, account: AccountRow | null } ``` -### `ocx account use <provider> <account-or-key-id|main> [--json]` +### `ccx account use <provider> <account-or-key-id|main> [--json]` 既存の Codex アカウント、OAuth アカウント、または API key を選びます。`openai` で `main` は Codex App ログインを -選択します。Codex Pool の選択は process-local affinity を消去し、既存の表示タスクを含む次のリクエストから適用されます。プロキシ再起動や affinity eviction 後もタスクは未紐付けになり得ますが、処理中のリクエストは取得済みアカウントを維持します。この選択は Pool routing のみを制御し、Direct mode は caller-owned/native main credential を使い続けます。使用量ベースのプロアクティブ切り替え、401/403 再認証、429/retry-after cooldown、除外、出力前 429/402 の障害回復により、後で別の適格 Pool アカウントが選ばれる場合があります。これらの回復経路は使用量ベース切り替えが off でも有効です。アカウント変更後も OpenCodex は会話コンテキストを再生しますが、provider prompt cache は再ウォームアップが必要な場合があります。 +選択します。Codex Pool の選択は process-local affinity を消去し、既存の表示タスクを含む次のリクエストから適用されます。プロキシ再起動や affinity eviction 後もタスクは未紐付けになり得ますが、処理中のリクエストは取得済みアカウントを維持します。この選択は Pool routing のみを制御し、Direct mode は caller-owned/native main credential を使い続けます。使用量ベースのプロアクティブ切り替え、401/403 再認証、429/retry-after cooldown、除外、出力前 429/402 の障害回復により、後で別の適格 Pool アカウントが選ばれる場合があります。これらの回復経路は使用量ベース切り替えが off でも有効です。アカウント変更後も CodexCommander は会話コンテキストを再生しますが、provider prompt cache は再ウォームアップが必要な場合があります。 不明なプロバイダーや id は終了コード 1 です。`--json` は次を返します。 **401/403** では、そのアカウントへのプロセスローカルな affinity を解除し、再認証を要求します。 **429** では `Retry-After` を尊重してアカウントの cooldown を開始し、affinity を解除したうえで、 @@ -141,13 +141,13 @@ Codex pool selection applies to the next request after clearing existing affinit { ok: true, provider, type, activeId } ``` -### `ocx account refresh <provider> [--json]` +### `ccx account refresh <provider> [--json]` -Codex プールの場合は、`ocx account refresh openai [--json]` を使用します。アカウント クォータを強制的に更新し、利用可能な週次/月次のパーセンテージとリセット時間を出力します。不足しているクォータ データは、0% ではなく不明として報告されます。その JSON エンベロープは `{ accounts: AccountRow[] }` で、Codex の各行に `quota` があります。 +Codex プールの場合は、`ccx account refresh openai [--json]` を使用します。アカウント クォータを強制的に更新し、利用可能な週次/月次のパーセンテージとリセット時間を出力します。不足しているクォータ データは、0% ではなく不明として報告されます。その JSON エンベロープは `{ accounts: AccountRow[] }` で、Codex の各行に `quota` があります。 OAuth プロバイダーと API キー プロバイダーの場合、これによりプロバイダー クォータ レポート エンドポイントが強制的に更新されます。これは、トークンの再ログインや単純なアカウント リストの再読み取りではありません。 `--json` は `{ provider, report: ProviderQuotaReport | null }` を返します。サポートされているクォータ レポートがないプロバイダーは、`no quota report available for <provider>` を出力して 0 を終了します。不明なプロバイダーと管理 API のエラーは 1 を終了します。失敗またはタイムアウトしたアップストリーム クォータ プローブは、代わりに null または古いレポートに劣化し (終了 0)、ダッシュボードのクォータ バーと一致します。 -### `ocx account auto-switch <provider> <on|off|status|threshold <0-100>> [--json]` +### `ccx account auto-switch <provider> <on|off|status|threshold <0-100>> [--json]` `openai` Codex アカウント プールのみを制御します。 `on` は 80% を設定し、`off` は 0% を設定します。`status` は現在の値を読み取り、`threshold <n>` は 0 ~ 100 の整数を受け入れます。他のプロバイダーと無効な値は 1 を終了します。`--json` は次を返します。 @@ -155,12 +155,12 @@ OAuth プロバイダーと API キー プロバイダーの場合、これに { provider, autoSwitchThreshold: number, enabled: boolean } ``` -### `ocx account priority <provider> <account-id|main> [<-100..100|first|earlier|normal|later|last|reset>] [--json]` +### `ccx account priority <provider> <account-id|main> [<-100..100|first|earlier|normal|later|last|reset>] [--json]` Codex pool のアカウント別選択順を読み書きします。**値が大きいほど先に使われ**、既定は `0`、範囲は `-100` から `100` です。順序を持つのは `openai` の Codex pool だけなので、他のプロバイダーは終了コード 1 です。`main` は Codex Desktop ログインを指し、他の pool アカウントと同じように並べ替えられます。 -`ocx account priority openai main last` とすれば予備として最後に回せます。 +`ccx account priority openai main last` とすれば予備として最後に回せます。 プリセット語は小さな整数の別名です。`first` が `+2`、`earlier` が `+1`、`normal` が `0`、`later` が `-1`、`last` が `-2` です。`reset` は既定に戻し、保存されたエントリを削除します。**値を省略すると @@ -178,11 +178,11 @@ preemption が未バインドリクエストを直ちに引き上げます。既 ``` -### `ocx account login|reauth|code|cancel ...` +### `ccx account login|reauth|code|cancel ...` -ヘッドレス シェルからブラウザベースまたは手動コードのアカウント認証を実行します。プロバイダー固有のコマンド形式には `ocx account --help` を使用します。 +ヘッドレス シェルからブラウザベースまたは手動コードのアカウント認証を実行します。プロバイダー固有のコマンド形式には `ccx account --help` を使用します。 -### `ocx account remove <provider> <id|main> --yes [--json]` +### `ccx account remove <provider> <id|main> --yes [--json]` この保護された非対話型削除には `--yes` が必要です。削除する前に、ID が存在することが確認されます。 ID が欠落している場合は、DELETE を送信せずに 1 が終了します。メインの Codex App ログインは削除できないため、`remove openai main --yes` は拒否されます。削除後、ファミリーは再度読み取られます。固定された Codex アカウントを削除すると、ピンがクリアされ、自動選択に戻ります。 OAuth は最初に残ったアカウントを昇格させるか、何も報告しません。 API キー プールは、最初に残っているキーを昇格するか、何も報告しません。 `--json` の成功と失敗の形状は次のとおりです。 @@ -191,32 +191,32 @@ preemption が未バインドリクエストを直ちに引き上げます。既 { error: string } // stderr, exit 1 ``` -### `ocx account add-key <provider> [--label <label>] [--json]` +### `ccx account add-key <provider> [--label <label>] [--json]` API キー プロバイダーのキーを追加してアクティブ化します。キーは、非 TTY パイプ/リダイレクトされた標準入力からの読み取り専用です。インタラクティブ TTY 入力、空の入力、OAuth/Codex プロバイダー、および API エラー終了 1。キーがラベル内に表示される場合も含め、キーがエコーされることはありません。シークレット マネージャーまたはヒア文字列を使用することをお勧めします。 ```bash -ocx account add-key openrouter --label personal <<< "$OPENROUTER_API_KEY" -security find-generic-password -w openrouter | ocx account add-key openrouter --json +ccx account add-key openrouter --label personal <<< "$OPENROUTER_API_KEY" +security find-generic-password -w openrouter | ccx account add-key openrouter --json ``` `--json` は `{ ok: true, id: string | null, label?: string }` を返しますが、キーは決して含まれません。 -### `ocx account reset-credits <id|main> [--consume --yes]` +### `ccx account reset-credits <id|main> [--consume --yes]` アカウントの Codex リセット クレジットを検査します。クレジットの消費は破壊的であり、`--consume` と `--yes` の両方が必要です。 -### `ocx account main <subcommand>` +### `ccx account main <subcommand>` -OpenCodex のアカウントプールルーティングを変更せずに、名前付きのネイティブ Codex メインログインプロファイルを管理します。 +CodexCommander のアカウントプールルーティングを変更せずに、名前付きのネイティブ Codex メインログインプロファイルを管理します。 ```text -ocx account main doctor [--json] -ocx account main list [--json] -ocx account main register <label> [--json] -ocx account main add <label> -ocx account main switch <profile-id-or-label> --yes [--json] -ocx account main recover [--rollback --yes] [--json] +ccx account main doctor [--json] +ccx account main list [--json] +ccx account main register <label> [--json] +ccx account main add <label> +ccx account main switch <profile-id-or-label> --yes [--json] +ccx account main recover [--rollback --yes] [--json] ``` 各変更コマンドは、実行中のプロキシが返す正規化済みの有効な `CODEX_HOME` を表示します。このパスは @@ -225,21 +225,19 @@ ocx account main recover [--rollback --yes] [--json] バージョン 1 はファイルベースの Codex 認証をサポートし、保存したプロファイルを AES-256-GCM で暗号化し、暗号鍵を OS の資格情報ストアに保持します。`add` は、生成された資格情報を取り込む前に公式 Codex ログインをステージングします。プロファイルを切り替える前に Codex を終了してください。切り替えに成功するとローカルのタスクと履歴は保持されますが、続行する前に Codex の再起動が必要です。`doctor` でプロファイル状態を確認し、`recover` で中断した切り替えを完了またはロールバックできます。`switch` にはプロファイル ID またはラベルを指定できます。 -v1 の復旧マトリクスが対象とするのは、トランザクションファイルの rename による公開後に OpenCodex プロセスが終了した場合です。OS またはカーネルのクラッシュや突然の電源断に対する永続性は保証しません。`atomicWriteFileAsync()` はファイルまたは親ディレクトリに `fsync` を実行しません。 +v1 の復旧マトリクスが対象とするのは、トランザクションファイルの rename による公開後に CodexCommander プロセスが終了した場合です。OS またはカーネルのクラッシュや突然の電源断に対する永続性は保証しません。`atomicWriteFileAsync()` はファイルまたは親ディレクトリに `fsync` を実行しません。 -暗号化された vault、切り替えジャーナル、復旧マーカー、および journal-quarantine ファイルは、正規の `<real CODEX_HOME>/.opencodex-native-main-profiles` ディレクトリに保存されます。そのため、その Codex ホームを共有するすべての OpenCodex インスタンスは、同じ 1 つの所有者と同じ 1 つの復旧状態を参照します。平文のログインステージングは、各 `<OPENCODEX_HOME>/native-main-profile-staging` ディレクトリ配下にそれぞれ分離されたままです。 +暗号化された vault、切り替えジャーナル、復旧マーカー、および journal-quarantine ファイルは、正規の `<real CODEX_HOME>/.codexcommander-native-main-profiles` ディレクトリに保存されます。そのため、その Codex ホームを共有するすべての CodexCommander インスタンスは、同じ 1 つの所有者と同じ 1 つの復旧状態を参照します。平文のログインステージングは、各 `<CODEXCOMMANDER_HOME>/native-main-profile-staging` ディレクトリ配下にそれぞれ分離されたままです。 -native-main トラフィックまたはジャーナル復旧を受け入れる前に、ライフタイム所有者が資格情報に対する排他的な権利を取得し、名前が正確に `auth.json.ocx.<pid>.<sequence>.tmp` と一致するクラッシュ残留ファイルだけを削除します。各候補は、変更されていない正規の `CODEX_HOME` 配下にあり、ハードリンク数が 1 の通常ファイルであり続けなければなりません。その内容を切り詰め、フラッシュしてからリンクを解除します。リンクまたは再解析ポイントへのすり替え、ファイル識別情報の変化、その他の曖昧さがある場合は native-main トラフィックを引き続き拒否し、名前が似ているだけのファイルは自動的には決して削除しません。これは、協調動作する OpenCodex のクラッシュから保護するためのものであり、同じ OS ユーザーとしてすでに実行中の悪意あるプロセスから保護するものではありません。そのユーザーと `CODEX_HOME` を格納するファイルシステムは引き続き信頼対象であり、切り詰めによってコピーオンライト方式のストレージ、スナップショット、または SSD の残留データから物理的に消去されることは保証されません。 - -プレビュー版では `<OPENCODEX_HOME>/native-main-profiles` を使用していました。このレイアウトが暗黙にインポートされることはありません。`doctor` が旧形式のプロファイル状態を報告した場合は、同じ `CODEX_HOME` を共有するすべての OpenCodex プロキシを停止してください。そのうえで、該当する `*.vault.json`、`*.journal.json`、復旧マーカー、および参照されている journal-quarantine ファイルをバックアップし、所有者だけがアクセスできる権限を維持したまま、すべて一緒に正規ディレクトリへ移動してください。別の方法として、古いプレビュー版の一式を削除し、`ocx account main register` を再度実行することもできます。同じ `CODEX_HOME` を共有するプロキシが 1 つでも稼働している間は、複数の旧ルートから 1 つを選ぶことも、両方のレイアウトを併用することも避けてください。Windows では、以前の大文字小文字を区別しないホーム識別子に紐付いたプレビュー状態は、移動せずリセットする必要があります。暗号化された AAD と OS キーリングの識別子は、意図的に再利用されないためです。 +native-main トラフィックまたはジャーナル復旧を受け入れる前に、ライフタイム所有者が資格情報に対する排他的な権利を取得し、名前が正確に `auth.json.ccx.<pid>.<sequence>.tmp` と一致するクラッシュ残留ファイルだけを削除します。各候補は、変更されていない正規の `CODEX_HOME` 配下にあり、ハードリンク数が 1 の通常ファイルであり続けなければなりません。その内容を切り詰め、フラッシュしてからリンクを解除します。リンクまたは再解析ポイントへのすり替え、ファイル識別情報の変化、その他の曖昧さがある場合は native-main トラフィックを引き続き拒否し、名前が似ているだけのファイルは自動的には決して削除しません。これは、協調動作する CodexCommander のクラッシュから保護するためのものであり、同じ OS ユーザーとしてすでに実行中の悪意あるプロセスから保護するものではありません。そのユーザーと `CODEX_HOME` を格納するファイルシステムは引き続き信頼対象であり、切り詰めによってコピーオンライト方式のストレージ、スナップショット、または SSD の残留データから物理的に消去されることは保証されません。 ## モデル -### `ocx models [subcommand]`・`ocx model <subcommand>` +### `ccx models [subcommand]`・`ccx model <subcommand>` -`ocx model` は `ocx models` の別名です。サブコマンドを使用しない場合、構成されたプロバイダーに静的にシードされたモデルを一覧表示します。 `--provider` は 1 つの構成済みプロバイダーをフィルターし、`--json` はモデル メタデータを返します。 `live` は実行中のカタログを読み取ります。 `add`、`edit`、`remove`、および `list-custom` は手動カタログ エントリを管理します。 `enable`、`disable`、および `provider` は可視性を制御します。 `selected` はプロバイダー許可リストを制御します。 `context` はプロバイダーのコンテキストの上限を制御します。 `shadow` はバックグラウンドのシャドウ コール インターセプトを管理します。 +`ccx model` は `ccx models` の別名です。サブコマンドを使用しない場合、構成されたプロバイダーに静的にシードされたモデルを一覧表示します。 `--provider` は 1 つの構成済みプロバイダーをフィルターし、`--json` はモデル メタデータを返します。 `live` は実行中のカタログを読み取ります。 `add`、`edit`、`remove`、および `list-custom` は手動カタログ エントリを管理します。 `enable`、`disable`、および `provider` は可視性を制御します。 `selected` はプロバイダー許可リストを制御します。 `context` はプロバイダーのコンテキストの上限を制御します。 `shadow` はバックグラウンドのシャドウ コール インターセプトを管理します。 -ダッシュボードが提供するモデルごとの操作はすべてここで利用できるため、ヘッドレスインストールではカタログを管理するために GUI が必要ありません。 `add`、`remove`、および `list-custom` は設定ファイルに対して機能し、カタログ同期を通じて実行中のプロキシに適用されます。残りはライブ管理 API と通信し、プロキシが実行されている必要があります (`ocx start`、またはインストールされたサービス)。 +ダッシュボードが提供するモデルごとの操作はすべてここで利用できるため、ヘッドレスインストールではカタログを管理するために GUI が必要ありません。 `add`、`remove`、および `list-custom` は設定ファイルに対して機能し、カタログ同期を通じて実行中のプロキシに適用されます。残りはライブ管理 API と通信し、プロキシが実行されている必要があります (`ccx start`、またはインストールされたサービス)。 |サブコマンド |サポートされているフラグ |アクション | | --- | --- | --- | @@ -254,18 +252,18 @@ native-main トラフィックまたはジャーナル復旧を受け入れる | `provider <name> <on\|off>` | `--json` | 1 つのプロバイダーのすべてのモデルを 1 回の書き込みで有効または無効にします。 | | `selected <provider>` | `--set <id,id...>`、`--clear`、`--json` |プロバイダー モデルのホワイトリストを読み取るか置き換えます。 `--clear` はホワイトリストを削除し、すべてのモデルが提供されるようにします。 | | `context <status\|value <tokens>\|provider <name> <on\|off>\|all <on\|off>>` | `--json` |コンテキスト ウィンドウ キャップをグローバルに、またはプロバイダーごとに読み取りまたは設定します。 | -| `shadow <status\|set> [model\|-]` | `--enabled <on\|off>`、`--json` | Codex のバックグラウンド ヘルパー呼び出しの置換モデルを読み取るか、設定します。 `-` はモデルをクリアします。 `status` は `sourceModels` も報告し、プロキシがインターセプトするヘルパースラッグを示します (デフォルト: `gpt-5.6-luna`; 0.144.x 以前のクライアントが使用した `gpt-5.4-mini` は明示的な `sourceModels` オーバーライドで復元できます)。 | +| `shadow <status\|set> [model\|-]` | `--enabled <on\|off>`、`--json` | Codex のバックグラウンド ヘルパー呼び出しの置換モデルを読み取るか、設定します。 `-` はモデルをクリアします。 `status` は `sourceModels` も報告し、プロキシがインターセプトするヘルパースラッグを示します (デフォルト: `gpt-5.6-luna`; 明示的なオーバーライドは現在のカスタム ヘルパー ID にのみ使用します)。 | ```bash -ocx models live --json # what Codex can actually see right now -ocx models disable anthropic/claude-haiku-4 # hide one routed model -ocx models enable gpt-5.6-sol # no slash, so it is treated as native -ocx models provider zenmux off # hide a noisy provider wholesale -ocx models selected anthropic --set claude-opus-5,claude-fable-5 -ocx models selected anthropic --clear # drop the allowlist again -ocx models add deepseek deepseek-v4 --display-name 'DeepSeek V4' --context-window 128000 --modalities text,image -ocx models list-custom --json # read the custom-id for edit/remove -ocx models remove deepseek/deepseek-v4 --yes +ccx models live --json # what Codex can actually see right now +ccx models disable anthropic/claude-haiku-4 # hide one routed model +ccx models enable gpt-5.6-sol # no slash, so it is treated as native +ccx models provider zenmux off # hide a noisy provider wholesale +ccx models selected anthropic --set claude-opus-5,claude-fable-5 +ccx models selected anthropic --clear # drop the allowlist again +ccx models add deepseek deepseek-v4 --display-name 'DeepSeek V4' --context-window 128000 --modalities text,image +ccx models list-custom --json # read the custom-id for edit/remove +ccx models remove deepseek/deepseek-v4 --yes ``` スラッシュの付いたモデル セレクターはルーティングされます (`anthropic/claude-opus-5`)。裸の ID はネイティブ OpenAI モデルとして扱われるため、`--native` は、ルーティングされているように見える ID の読み取りを強制する場合にのみ必要です。 diff --git a/docs-site/src/content/docs/ja/reference/configuration.md b/docs-site/src/content/docs/ja/reference/configuration.md index df2527ef86..2a087715ed 100644 --- a/docs-site/src/content/docs/ja/reference/configuration.md +++ b/docs-site/src/content/docs/ja/reference/configuration.md @@ -1,27 +1,27 @@ --- title: 設定リファレンス -description: opencodex が設定を保存する場所、編集の適用方法、およびすべての設定領域へのリンク。 +description: CodexCommander が設定を保存する場所、編集の適用方法、およびすべての設定領域へのリンク。 --- -opencodex は、永続的な設定を `$OPENCODEX_HOME/config.json` (通常は `~/.opencodex/config.json`) に保存します。 Windows では、デフォルトは `%USERPROFILE%\.opencodex\config.json` です。 +CodexCommander は、永続的な設定を `$CODEXCOMMANDER_HOME/config.json` (通常は `~/.codexcommander/config.json`) に保存します。 Windows では、デフォルトは `%USERPROFILE%\.codexcommander\config.json` です。 ## 設定の編集方法 タスクに合った編集チャンネルを選択してください。 - **ダッシュボード:** ガイド付きプロバイダー、モデル、エージェント、アクセス、ストレージ設定には Web UI を使用します。 -- **CLI:** `ocx init` は初期ファイルを作成しますが、`ocx provider`、`ocx models`、 -`ocx combo`、`ocx agent`、および `ocx config` は、独自の設定を更新または検査します。 +- **CLI:** `ccx init` は初期ファイルを作成しますが、`ccx provider`、`ccx models`、 +`ccx combo`、`ccx agent`、および `ccx config` は、独自の設定を更新または検査します。 - **ファイル:** 専用の UI または CLI コマンドを使用せずに、フィールドに対して `config.json` を直接編集します。ファイルは次のとおりです。 有効な JSON を維持します。 ダッシュボード、管理 API、および変更可能な CLI コマンドはすべて同じファイルに保持されます。それらのチャンネルを優先するか、手動で編集する前にプロキシを停止してください。実行中のプロセスは設定をメモリに保持するため、後でライブ保存すると、スナップショットから無関係な手動編集を書き換えることができます。ライブ保存では、外部で編集された `claudeCode` とリスナー バインディング フィールドがマージされ、これらのパスには明示的な競合保護が設定されていますが、その保護はすべてのサブツリーをカバーするわけではありません。 -ファイルを解析できない場合、opencodex はファイルを `config.json.invalid-<timestamp>` としてバックアップし、コンソールに警告を表示し、デフォルトで起動します。欠落しているファイルでも、新規インストールのデフォルトである 1 つの `openai` フォワード プロバイダーが使用されます。 +ファイルを解析できない場合、CodexCommander はファイルを `config.json.invalid-<timestamp>` としてバックアップし、コンソールに警告を表示し、デフォルトで起動します。欠落しているファイルでも、新規インストールのデフォルトである 1 つの `openai` フォワード プロバイダーが使用されます。 ## 優先順位とデフォルト -`config.json` の有効な値は、組み込みのデフォルトをオーバーライドします。省略可能なフィールドが欠落している場合は、ドメイン ページに記載されているデフォルトが使用されます。 `OPENCODEX_HOME` は、デフォルトの構成ディレクトリよりも優先されます。 `apiKey: "${PROVIDER_API_KEY}"` などの環境参照を受け入れるフィールドは、リクエスト時にその変数を解決します。送信プロキシの場合、すでに設定されている `HTTP_PROXY` または `HTTPS_PROXY` が最上位の `proxy` フィールドよりも優先されます。 +`config.json` の有効な値は、組み込みのデフォルトをオーバーライドします。省略可能なフィールドが欠落している場合は、ドメイン ページに記載されているデフォルトが使用されます。 `CODEXCOMMANDER_HOME` は、デフォルトの構成ディレクトリよりも優先されます。 `apiKey: "${PROVIDER_API_KEY}"` などの環境参照を受け入れるフィールドは、リクエスト時にその変数を解決します。送信プロキシの場合、すでに設定されている `HTTP_PROXY` または `HTTPS_PROXY` が最上位の `proxy` フィールドよりも優先されます。 ルーティングには独自の順序付けされた解決ルールがあります。 [ルーティング](/reference/configuration/routing/)を参照してください。 @@ -41,5 +41,5 @@ opencodex は、永続的な設定を `$OPENCODEX_HOME/config.json` (通常は ` API キーには `${ENV_VAR}` 参照を優先します。リテラルの `apiKey`、`apiKeyPool[].key`、および `apiKeys[].key` 値は秘密です。コミットしたり、ログに貼り付けたり、共有したりしないでください。 OAuth およびフォワード プロバイダー トークンは、`config.json` ではなく別の資格情報ストアに保存されます。アカウント ID と電子メールも非公開にしておく必要があります。サポートされている場合は、パブリック セレクター エイリアスを使用します。 :::note[アトミック書き込み] -opencodex は、一時ファイルを介して管理対象の `config.toml` および `opencodex-catalog.json` ファイルを書き込み、その後名前を変更します (`atomicWriteFile`)。これにより、`ocx stop` やプロキシ シャットダウン ハンドラーなどの同時ライターが Codex を同時に復元するときに、部分的なファイルが生成されるのを防ぎます。 +CodexCommander は、一時ファイルを介して管理対象の `config.toml` および `codexcommander-catalog.json` ファイルを書き込み、その後名前を変更します (`atomicWriteFile`)。これにより、`ccx stop` やプロキシ シャットダウン ハンドラーなどの同時ライターが Codex を同時に復元するときに、部分的なファイルが生成されるのを防ぎます。 ::: diff --git a/docs-site/src/content/docs/ja/reference/configuration/agents.md b/docs-site/src/content/docs/ja/reference/configuration/agents.md index fde4adb41d..7282cf5eba 100644 --- a/docs-site/src/content/docs/ja/reference/configuration/agents.md +++ b/docs-site/src/content/docs/ja/reference/configuration/agents.md @@ -3,7 +3,7 @@ title: エージェント構成 description: マルチエージェント サーフェス、委任ガイダンス、優先モデル、フォールバック チェーン、ネイティブとデフォルトの同期、およびエフォート キャップ。 --- -エージェント設定は、どの Codex コラボレーション サーフェスをアドバタイズするか、および opencodex が委任された作業をどのようにガイド、ルーティング、制限するかを制御します。 +エージェント設定は、どの Codex コラボレーション サーフェスをアドバタイズするか、および CodexCommander が委任された作業をどのようにガイド、ルーティング、制限するかを制御します。 ## エージェントフィールド @@ -11,18 +11,18 @@ description: マルチエージェント サーフェス、委任ガイダンス | --- | --- | --- | --- | | `multiAgentMode?` | `"v1" \| "default" \| "v2"` | `"default"` | `v1` はすべてのカタログ モデルを v1 としてスタンプします。 `v2` はすべてのモデルを v2 としてスタンプします。 `default` はアップストリーム ピン (Sol/Terra v2、Luna v1) を復元し、それ以外の場合はネイティブの `multi_agent_v2` フラグに従います。新しいセッションに適用されます。 | | `multiAgentV2MessageDelivery?` | `"encrypted" \| "plaintext"` | `"encrypted"` | V2 親メッセージの配信方針です。`encrypted` は ChatGPT の予約済み暗号化契約を維持します。実験的な `plaintext` は以降の V2 親リクエストを複数プロバイダー互換にし、その親の全委任メッセージを平文にします。ルーティングされた親のメッセージ呼び出しにも Codex の平文マーカーを付与します。変更後は新しいセッションを開始してください。 | -| `subagentModels?` | `string[]` | `gpt-5.5`、`gpt-5.6-sol`、`gpt-5.6-terra`、`gpt-5.6-luna`、`gpt-5.4-mini` | 最大 5 つの bare native id、account-qualified `<selector>/<native-openai-model>` id、または routed `provider/model` id をサブエージェント ピッカーで優先公開します。ダッシュボードは account-qualified を含む設定済みの exact selector を保持し、保存された項目のうち実際に公開されたものと除外されたものを表示します。現在のカタログにない選択には `ocx agent subagents set` を使用するか、設定を直接編集してください。明示的な空リストも保持されます。 | +| `subagentModels?` | `string[]` | `gpt-5.5`、`gpt-5.6-sol`、`gpt-5.6-terra`、`gpt-5.6-luna`、`gpt-5.4-mini` | 最大 5 つの bare native id、account-qualified `<selector>/<native-openai-model>` id、または routed `provider/model` id をサブエージェント ピッカーで優先公開します。ダッシュボードは account-qualified を含む設定済みの exact selector を保持し、保存された項目のうち実際に公開されたものと除外されたものを表示します。現在のカタログにない選択には `ccx agent subagents set` を使用するか、設定を直接編集してください。明示的な空リストも保持されます。 | | `injectionModel?` | `string` | — |プロキシ作成の v2 委任ガイダンスで使用される、優先されるネイティブまたはルーティングされたサブエージェント モデル。 | | `injectionEffort?` | `string` | — |優先努力 (`low` ~ `ultra`)。`injectionModel` でのみ意味があります。 | | `injectionPrompt?` | `string` | — | 組み込みの v2 ガイダンス本文を置き換えます。`{{model}}`、`{{effort}}`、`{{roster}}`、`{{fallback}}`をサポートします。`injectionModel` が設定されていればカスタムプロンプトが生成されます。 | -| `multiAgentGuidanceEnabled?` | `boolean` | `true` | opencodex が作成した v1/v2 開発者ガイダンスのみを制御します。ネイティブ エージェントのデフォルト、ツール、ルーティング、ロスター、またはエフォート キャップは変更されません。 | +| `multiAgentGuidanceEnabled` | `boolean` | `true` | CodexCommander が作成した v1/v2 開発者ガイダンスのみを制御します。ネイティブ エージェントのデフォルト、ツール、ルーティング、ロスター、またはエフォート キャップは変更されません。 | | `syncCodexSubagentDefaults?` | `boolean` | `false` |同期/再起動中に、Codex のネイティブ デフォルトとして `injectionModel` およびオプションの `injectionEffort` を書き込むようにオプトインします。 `injectionModel`が必要です。 | | `subagentModelFallback?` | `string[]` | `[]` |生成された子ターンの優先順位付きグローバル フォールバック モデル。 | | `subagentModelFallbackPollMs?` | `number` | `60000` |可用性プローブのキャッシュ間隔。 1000 ミリ秒未満の値はデフォルトに戻ります。 | | `effortCap?` | `string` | — | v2 のメイン ターンとマークされた子ターンの条件を満たすためのハード シーリング。 `low` ~ `ultra` を受け入れます。 | | `subagentEffortCap?` | `string` | — |スポーンされた子のターンのみの追加の上限。両方の上限が適用される場合は、低い方が優先されます。 | -ダッシュボードまたは `ocx v2 status|on|off|mode <v1|default|v2>|threads <n>` でサーフェスを管理します。モードの変更は新しいセッションに適用されます。 `maxConcurrentThreadsPerSession` は `PUT /api/v2` フィールドであり、`config.json` キーではありません。 `ocx v2 threads <n>` は、v2 が有効になった後、Codex の `$CODEX_HOME/config.toml` の `[features.multi_agent_v2]` の下に `max_concurrent_threads_per_session` を書き込みます。 +ダッシュボードまたは `ccx v2 status|on|off|mode <v1|default|v2>|threads <n>` でサーフェスを管理します。モードの変更は新しいセッションに適用されます。 `maxConcurrentThreadsPerSession` は `PUT /api/v2` フィールドであり、`config.json` キーではありません。 `ccx v2 threads <n>` は、v2 が有効になった後、Codex の `$CODEX_HOME/config.toml` の `[features.multi_agent_v2]` の下に `max_concurrent_threads_per_session` を書き込みます。 管理 API は、`GET`/`PUT /api/v2`、`/api/injection-model`、`/api/effort-caps`、`/api/subagent-models`、および `/api/subagent-model-fallback` を公開します。インジェクションモデルの更新は部分的です。カスタム プロンプトは、その API の `prompt` フィールドです。 @@ -48,7 +48,7 @@ V1 ガイダンスは、`max` または `ultra` でのみプロアクティブ 2. ロールレベル `model_fallback` から `$CODEX_HOME/agents/*.toml`;それから 3. グローバル `subagentModelFallback` エントリ。 -opencodex は、無効、ルーティング不能、異常、冷却期間、またはクォータしきい値の候補をスキップします。可用性スナップショットは `subagentModelFallbackPollMs` に対してキャッシュされます。暗号化された子タスクは、チェーンを正規のネイティブ ChatGPT ターゲットに制限できます。暗号化されたペイロードを読み取ることができる人がいない場合、読み取り不可能な暗号文が別の場所にルーティングされる代わりに、リクエストは失敗します。 +CodexCommander は、無効、ルーティング不能、異常、冷却期間、またはクォータしきい値の候補をスキップします。可用性スナップショットは `subagentModelFallbackPollMs` に対してキャッシュされます。暗号化された子タスクは、チェーンを正規のネイティブ ChatGPT ターゲットに制限できます。暗号化されたペイロードを読み取ることができる人がいない場合、読み取り不可能な暗号文が別の場所にルーティングされる代わりに、リクエストは失敗します。 ```json { @@ -68,6 +68,6 @@ opencodex は、無効、ルーティング不能、異常、冷却期間、ま キャップは v2 コラボレーション機能にのみ適用されます。メイン ターンは、そのツールが v2 を公開するときに資格を持ちますが、子ターンは、リーフ ツールがコラボレーションを公開しなくなった場合でも、`x-codex-turn-metadata` に正確な codex-rs `x-openai-subagent: collab_spawn` または `"subagent_kind": "thread_spawn"` マーカーが含まれるときに資格を持ちます。 V1 メイン ターン、`multiAgentMode: "v1"`、圧縮、レビュー、およびメモリ統合ターンはバイパス キャップです。 -キャップは労力を軽減するだけです。これらは、キャップまたはキャップの下で宣伝されている最も高い段にスナップします。モデルにエフォート制御がない場合、またはサポートされているラングフィットがない場合、opencodex はエフォートを削除し、プロバイダーのデフォルトを適用します。 `max` および `ultra` が受け入れられますが、ダッシュボードでは `low` から `xhigh` が提供されます。 +キャップは労力を軽減するだけです。これらは、キャップまたはキャップの下で宣伝されている最も高い段にスナップします。モデルにエフォート制御がない場合、またはサポートされているラングフィットがない場合、CodexCommander はエフォートを削除し、プロバイダーのデフォルトを適用します。 `max` および `ultra` が受け入れられますが、ダッシュボードでは `low` から `xhigh` が提供されます。 v1、デフォルト、および v2 の動作に関する初心者向けの説明については、「[サブエージェントサーフェス](/guides/sub-agent-surface/)」を参照してください。 diff --git a/docs-site/src/content/docs/ja/reference/configuration/providers.md b/docs-site/src/content/docs/ja/reference/configuration/providers.md index d453ada04a..59dfd23b17 100644 --- a/docs-site/src/content/docs/ja/reference/configuration/providers.md +++ b/docs-site/src/content/docs/ja/reference/configuration/providers.md @@ -3,14 +3,13 @@ title: プロバイダーの構成 description: プロバイダー エントリ、認証、エンドポイント、モデル カタログ、クォータ、コンテキスト キャップ、およびプロバイダー固有のオプション。 --- -プロバイダーは、opencodex に、モデルが存在する場所、モデルが通信するワイヤー アダプター、およびリクエストの認証方法を伝えます。 +プロバイダーは、CodexCommander に、モデルが存在する場所、モデルが通信するワイヤー アダプター、およびリクエストの認証方法を伝えます。 ## プロバイダー関連のトップレベルフィールド |フィールド |タイプ |デフォルト |意味 | | --- | --- | --- | --- | -| `providers` | `Record<string, OcxProviderConfig>` | — |プロバイダー名からプロバイダー設定へのマップ。 | -| `openaiProviderTierVersion?` | `2` |移行によって設定される |単一のオプション対応 OpenAI プロジェクションを完了としてマークします。 | +| `providers` | `Record<string, CodexCommanderProviderConfig>` | — |プロバイダー名からプロバイダー設定へのマップ。 | | `disabledModels?` | `string[]` | — | Codex catalog と `/v1/models` から非表示にする model。直接の proxy 呼び出しはブロックしません。routed id は一覧から削除されます。account-qualified native id は該当する selector row だけを非表示にし、bare native GPT id は bare row とその model の全 account-selector row を非表示にします。Models ページに表示されるのは bare native 行と routed 行だけです。selector-qualified 行を 1 つだけ非表示にするには、この設定フィールドを直接編集してください。 | | `providerContextCaps?` | `Record<string, number>` | `{}` |プロバイダーごとの Codex に表示されるコンテキストの上限。キャップは既知のコンテキスト ウィンドウを下げるだけです。 | | `contextCapValue?` | `number` | `350000` |ダッシュボードのコンテキストキャップ コントロールで使用される値。これを変更すると、有効になっているすべての `providerContextCaps` エントリが更新されます。 | @@ -18,16 +17,16 @@ description: プロバイダー エントリ、認証、エンドポイント、 | `pausedCodexAccountIds?` | `string[]` | `[]` |再開するまでプールの選択から除外されるアカウント (一時停止時のメイン `__main__` アカウントを含む)。 | | `codexAccountNamespaces?` | `Record<string, string>` | — | 任意の公開 model selector を保存済み Codex アカウント target に対応付ける任意の map。target が存在する各 selector は Codex picker に個別の `<selector>/<native-openai-model>` row を追加し、各 row はそのアカウントだけを使用します。selector が 1 つでも有効な場合、bare native row は picker で非表示になりますが、明示的に無効化されない限り id は引き続き routing でき、raw `/v1/models` にも表示されます。 | | `activeCodexAccountId?` | `string` | — |次のリクエスト用に手動で選択されたプール アカウント。選択するとスレッドのアフィニティがクリアされます。実行中のリクエストでは、取得された資格情報が保持されます。 | -| `codexAccountPriorities?` | `Record<string,number>` | — | Codex pool のアカウント別選択順。アカウント ID → `-100` から `100` の整数で、**大きいほど先に使われ**、未設定は `0` です。これは eligibility ではなく順序の境界です。選択は適格なアカウントを、まだ quota に余裕がある最上位 tier に絞り込み、その tier の中を `accountPoolStrategy` が選びます。tier が飛ばされるのは、そのメンバー全員が `autoSwitchThreshold` 超過、cooldown 中、soft-avoid、一時停止、または再認証待ちのときだけで、usage 不明が tier を drain させることはありません。順序付けが不適格なアカウントを選択可能にすることはなく、すでにアカウントが結び付いた thread を再 bind することもありません。メインの `__main__` も同じ条件で参加するため、Codex Desktop ログインを最後に使わせられます。エントリが 1 つもなければ挙動は従来どおりです。map が不正な場合は警告を出して順序付けを無効にします(config の修復処理は走りません)。`ocx account priority` と Codex Auth ページで管理します。 | +| `codexAccountPriorities?` | `Record<string,number>` | — | Codex pool のアカウント別選択順。アカウント ID → `-100` から `100` の整数で、**大きいほど先に使われ**、未設定は `0` です。これは eligibility ではなく順序の境界です。選択は適格なアカウントを、まだ quota に余裕がある最上位 tier に絞り込み、その tier の中を `accountPoolStrategy` が選びます。tier が飛ばされるのは、そのメンバー全員が `autoSwitchThreshold` 超過、cooldown 中、soft-avoid、一時停止、または再認証待ちのときだけで、usage 不明が tier を drain させることはありません。順序付けが不適格なアカウントを選択可能にすることはなく、すでにアカウントが結び付いた thread を再 bind することもありません。メインの `__main__` も同じ条件で参加するため、Codex Desktop ログインを最後に使わせられます。エントリが 1 つもなければ、すべてのアカウントの優先度は `0` です。map が不正な場合は警告を出して順序付けを無効にします(config の修復処理は走りません)。`ccx account priority` と Codex Auth ページで管理します。 | | `autoSwitchThreshold?` | `number` | `80` | 使用量ベースのプロアクティブ切り替えしきい値。`quota` は紐付け済み/未紐付けタスクの次のリクエストを再評価でき、`fill-first` は未紐付け割り当ての使い切り基準としてのみ使用し、通常の `round-robin` 選択は使用しません。既知の 5 時間、週次、30 日 quota window の最大スコアを使います。`0` は使用量ベースの切り替えだけを無効にし、未紐付け割り当てや障害回復は無効にしません。 | | `accountPoolStrategy?` | `"quota" \| "round-robin" \| "fill-first"` | `"quota"` | 新規/未紐付け Codex リクエストの割り当て戦略。live な `(parent thread id, quota scope)` affinity がなければ未紐付けで、プロキシ再起動や affinity リセット後は既存の表示タスクも未紐付けになり得ます。`quota` はアクティブアカウントがなければ既知 usage 最小の適格アカウントを選び、適格なアクティブアカウントが `autoSwitchThreshold` 未満なら維持します。しきい値到達後は、未紐付けリクエストまたは紐付け済みタスクの次のリクエストを usage の低い適格アカウントへ移せます。`round-robin` は未紐付けリクエストを均等分散し、`fill-first` は cooldown、使用不可、または drain threshold までアクティブアカウントへ割り当てます。 | | `accountPoolStickyLimit?` | `number` | `1` | 1 回の round-robin 選択で次へ進む前に保持する新規/未紐付けタスク割り当て数。カウンターは上流の成功後ではなくタスクの紐付け時に増えます。範囲 1–100。`accountPoolStrategy` が `round-robin` のときのみ。 | | `upstreamFailoverThreshold?` | `number` | `3` |今後の新しいセッションがフェイルオーバーする前に一時的なエラーが連続して発生する。 `0` を無効に設定します。実証済みの接続前DNS/TCP到達不能障害はprovider-host単位で記録され、アカウントの健全性、クールダウン、スレッド/セッションの親和性、アクティブアカウントの選択、Poolルーティングには影響せず、この閾値にもカウントされません。 | | `modelCacheTtlMs?` | `number` | `300000` |プロバイダーごとの `/models` キャッシュの鮮度ウィンドウ。 | | `cacheRetention?` | `"none" \| "short" \| "long"` | `"short"` | Anthropic プロンプト キャッシュ ポリシー: 無効、5 分間の一時的、または 1 時間の延長。 | -| `tokenGuardian?` | `OcxTokenGuardianConfig` |オフ |オプションのプロアクティブな OAuth 更新および Codex アカウントのウォームアップ ポリシー。 | +| `tokenGuardian?` | `CodexCommanderTokenGuardianConfig` |オフ |オプションのプロアクティブな OAuth 更新および Codex アカウントのウォームアップ ポリシー。 | -selector 名はユーザーが選ぶ公開 label であり、opencodex はアカウント role の意味を付与しません。 +selector 名はユーザーが選ぶ公開 label であり、CodexCommander はアカウント role の意味を付与しません。 `codexAccountNamespaces` のキーは長さ 1〜64 文字、先頭と末尾は ASCII 英数字、内部には英数字、`.`、`_`、`-` を使用でき、予約済み JavaScript object 名は拒否されます。 値は有効な pool account id(内部 `__main__` は不可)、または Codex Desktop アカウントを示す @@ -41,17 +40,15 @@ namespace 付き combo alias はその namespace prefix に selector を再利 `openai` および `openai-apikey` は固定予約 ID です。 `openai.codexAccountMode` はデフォルトでは `"pool"` で、メインアカウントと追加アカウント全体を選択します。 `"direct"` は、現在の呼び出し元/メイン ログインのみを使用します。 API は、設定された API キーまたはキー プールのみを使用します。ベア モデルまたは `openai-apikey/<model>` を使用します。クロスルート認証情報のフォールバックはありません。 API GPT-5.6 行は 1,050,000 コンテキスト / 最大 922,000 入力メタデータを伝送し、Pro 仮想 ID は `reasoning.mode: "pro"` を使用してベース ワイヤー モデルに書き換えられます。 -`openaiProviderTierVersion: 2` は、現在の単一プロバイダーの投影をマークします。出荷された v1 設定を移行する前に、opencodex は別のバックアップを置き換えずに `config.json.pre-openai-tiers-v2.bak` を作成し、既知の名前空間で選択された既知のレガシー ID を裸の ID に書き換えます。 - -## プロバイダーエントリー (`OcxProviderConfig`) +## プロバイダーエントリー (`CodexCommanderProviderConfig`) |フィールド |タイプ |意味 | | --- | --- | --- | -| `adapter` | `string` | `openai-chat`、`openai-responses`、`anthropic`、`google`、`kiro`、`cursor`、`azure-openai` (または別名 `azure`) のいずれか。 | +| `adapter` | `string` | `openai-chat`、`openai-responses`、`anthropic`、`google`、`kiro`、`cursor`、`azure-openai` のいずれか。 | | `baseUrl` | `string` |アップストリーム API のベース URL。ほとんどの組み込み固定エンドポイントは不一致を無視します。衝突安全キー プリセットは、古い同じ名前のカスタム宛先を保持します。 | | `responsesPath?` | `string` |キー認証 `openai-responses` リクエストの相対リソース パス。 `/` で始まり、スキーム、クエリ、またはフラグメントが含まれていない必要があります。 | | `supportsServiceTier?` | `boolean` | `service_tier` ケイパビリティの 3 状態です。`true`: fast モードが注入でき、呼び出し元の値も保持されます。`false`: フィールドは削除され、注入もされません (非対応と文書化されたアップストリームには送りません)。未設定: 未分類 — 呼び出し元の値はそのまま保持され、fast モードは注入しません。レジストリは正規 OpenAI (`true`)、DeepSeek、Volcengine Ark (`false`) を分類します。実際にティアをサポートするカスタム ゲートウェイにのみ明示的に設定してください。 | -| `preserveResponsesReasoningContent?` | `boolean` | リプレイされる Responses reasoning アイテムの平文 reasoning コンテンツを消去せずに保持します (消去は ChatGPT バックエンドのルールです)。DeepSeek のように reasoning リプレイを受け入れるアップストリームで有効にしてください。プロキシ生成の `ocxr1` エンベロープは常に削除されます。 | +| `preserveResponsesReasoningContent?` | `boolean` | リプレイされる Responses reasoning アイテムの平文 reasoning コンテンツを消去せずに保持します (消去は ChatGPT バックエンドのルールです)。DeepSeek のように reasoning リプレイを受け入れるアップストリームで有効にしてください。プロキシ生成の `ccxr1` エンベロープは常に削除されます。 | | `disabled?` | `boolean` |プロバイダーをディスク上に保持しますが、ルーティングおよびモデル/カタログのリストからは除外します。 | | `apiKey?` | `string` | API キー、またはリクエスト時に解決される `${ENV_VAR}` / `$ENV_VAR` 参照。 | | `apiKeyTransport?` | `"x-api-key" \| "bearer"` | Anthropic キーのヘッダー スタイル。デフォルトはネイティブ `x-api-key` です。キー認証 `anthropic` プロバイダーにのみ有効です。 | @@ -103,16 +100,15 @@ namespace 付き combo alias はその namespace prefix に selector を再利 | `location?` | `string` |頂点の位置。環境フォールバックは `GOOGLE_CLOUD_LOCATION` です。 | | `mcpServers?` | `Record<string, CursorMcpServerConfig>` |カーソルのみ: 標準入出力またはストリーミング可能な HTTP MCP サーバー。 | | `desktopExecutor?` | `DesktopExecutorConfig` |カーソルのみ: 外部コンピュータ使用および画面録画コマンド。 | -| `unsafeAllowNativeLocalExec?` | `boolean` |カーソルのレガシー ブール値。新しいフィールドが設定されていない場合のみ、`nativeLocalExec: "on"` と同等です。 | -| `nativeLocalExec?` | `"off" \| "codex-sandbox" \| "on"` |カーソルのローカル実行ポリシー。 `off` がデフォルトです。 `codex-sandbox` は現在、`off` と同様にフェールクローズされます。 | +| `nativeLocalExec?` | `"off" \| "on"` |カーソルのローカル実行ポリシー。 `off` がデフォルトです。 | -API キープロバイダーは、リテラルキーまたは環境参照を保持する場合があります。 OAuth プロバイダーは、`ocx login` によって設定された資格情報ストアを使用します。サブスクリプションに基づくクロード コードの起動動作は、[`claudeCode.authMode`](/reference/configuration/server/#claude-code) で構成されます。 +API キープロバイダーは、リテラルキーまたは環境参照を保持する場合があります。 OAuth プロバイダーは、`ccx login` によって設定された資格情報ストアを使用します。サブスクリプションに基づくクロード コードの起動動作は、[`claudeCode.authMode`](/reference/configuration/server/#claude-code) で構成されます。 ## プロバイダーによるアウトバウンドの安全性診断 -ダッシュボード接続テストとライブ モデル検出では、制限された GET 専用トランスポートが使用されます。送信プロキシを使用しない場合、opencodex はホスト名を一度解決し、その検証されたアドレスにのみ接続します。 HTTPS は元のホスト、SNI、および証明書の検証を保持します。プロバイダー設定では証明書チェックを無効にすることはできません。 +ダッシュボード接続テストとライブ モデル検出では、制限された GET 専用トランスポートが使用されます。送信プロキシを使用しない場合、CodexCommander はホスト名を一度解決し、その検証されたアドレスにのみ接続します。 HTTPS は元のホスト、SNI、および証明書の検証を保持します。プロバイダー設定では証明書チェックを無効にすることはできません。 -`HTTP_PROXY`、`HTTPS_PROXY`、または `ALL_PROXY` が適用される場合、これらの操作は Bun のネイティブ フェッチを維持します。 URL とリテラル アドレスのチェックは引き続き実行されますが、プロキシが最終ルート、DNS 応答、ピアを選択するため、opencodex はそのピアを固定したり検証したりできません。これは明示的なセキュリティ制限です。 +`HTTP_PROXY`、`HTTPS_PROXY`、または `ALL_PROXY` が適用される場合、これらの操作は Bun のネイティブ フェッチを維持します。 URL とリテラル アドレスのチェックは引き続き実行されますが、プロキシが最終ルート、DNS 応答、ピアを選択するため、CodexCommander はそのピアを固定したり検証したりできません。これは明示的なセキュリティ制限です。 プライベート/ローカル宛先には `allowPrivateNetwork: true` が必要で、送信プロキシがアクティブな場合は、一致する `NO_PROXY` エントリが必要です。ループバックは自動的に追加されます。 CIDR エントリは解釈されないため、各 LAN ホストを明示的にリストします。マッチャーは、正確なホスト、ドメイン サフィックス、オプションのポート、括弧で囲まれた IPv6、および `*` をサポートします。たとえば、`192.168.1.50` を明示的にリストします。メタデータとリンクローカル宛先はブロックされたままになります。診断リクエストはリダイレクトを拒否し、資格情報が剥奪されたターゲットを報告します。通常のプロバイダー要求のリダイレクト レビューは、この診断ガードとは独立したままになります。 @@ -155,14 +151,14 @@ affinity を維持します。これらの戦略は provider enforcement を回 有効にすると、429 レコードは `Retry-After` またはデフォルトのバックオフからの制限されたクールダウンを記録し、リクエスト内でローテーションする可能性があります。アフィニティはプロセスローカルであり、サイズ制限があります。資格情報 401/403 は、アカウントに再認証が必要であることをマークします。すべての対象となるアカウントが冷却されている場合、クライアントは、既知の場合、認証エラーではなく、`Retry-After` を含む 429 を受け取ります。 :::caution[実験的] -Anthropic アカウント ポリシーのリスクを理解していない限り、これは無効のままにしてください。不明な場合は、`ocx account use anthropic <id>` を手動で切り替えることをお勧めします。 +Anthropic アカウント ポリシーのリスクを理解していない限り、これは無効のままにしてください。不明な場合は、`ccx account use anthropic <id>` を手動で切り替えることをお勧めします。 ::: ### 管理されたレコードの形状 `apiKeys[]` エントリには、`id`、`name`、生成された `key`、および ISO `createdAt` 文字列が含まれます。 `codexAccounts[]` エントリには `id`、`email`、および `isMain` が必要で、オプションの `plan`、`chatgptAccountId`、およびプライバシー セーフな `logLabel` が必要です。これらのレコードは通常、ダッシュボードで管理されます。 -### `tokenGuardian` (`OcxTokenGuardianConfig`) +### `tokenGuardian` (`CodexCommanderTokenGuardianConfig`) |フィールド |タイプ |デフォルト |意味 | | --- | --- | --- | --- | @@ -189,7 +185,7 @@ Anthropic アカウント ポリシーのリスクを理解していない限り アダプターは、解決された URL を後で調整できます。たとえば、Kiro は、インポートされた資格情報の正規 `runtime.{region}.kiro.dev` の API リージョンに従います。 [アダプター](/reference/adapters/)を参照してください。 -ルーティングで `baseUrl` が破棄されると、opencodex はレジストリ エンドポイントと構成された起点のみをログに記録します。構成されたパス自体に資格情報が含まれる場合があります。未使用の URL を削除するか、目的のリージョンに一致するプロバイダー エントリを選択します。 `alibaba-token-plan` は北京に固定されていますが、`alibaba-token-plan-intl` は国際エンドポイントをカバーしています。 +ルーティングで `baseUrl` が破棄されると、CodexCommander はレジストリ エンドポイントと構成された起点のみをログに記録します。構成されたパス自体に資格情報が含まれる場合があります。未使用の URL を削除するか、目的のリージョンに一致するプロバイダー エントリを選択します。 `alibaba-token-plan` は北京に固定されていますが、`alibaba-token-plan-intl` は国際エンドポイントをカバーしています。 壊れた `openai-responses` ゲートウェイの場合、修復はプロバイダー オブジェクトに属します。 @@ -214,7 +210,7 @@ Anthropic アカウント ポリシーのリスクを理解していない限り ## Cursor プロバイダー (`adapter: "cursor"`) -カーソルブリッジは実験的なものです。 `ocx login cursor` の後に、`providers.cursor` を追加または編集します。ピッカーはカーソル固有のモデル パラメーターをレンダリングできないため、カーソル ルーターの最適化ラダーは別の Codex ID として公開されます。 +カーソルブリッジは実験的なものです。 `ccx login cursor` の後に、`providers.cursor` を追加または編集します。ピッカーはカーソル固有のモデル パラメーターをレンダリングできないため、カーソル ルーターの最適化ラダーは別の Codex ID として公開されます。 |Codexモデル |カーソル ルーターモード | | --- | --- | @@ -230,9 +226,6 @@ Anthropic アカウント ポリシーのリスクを理解していない限り - `"off"` (デフォルト) は、カーソルネイティブの `read`、`write`、`delete`、`ls`、`grep`、`shell`、および `fetch`実行。 - `"on"` は、信頼できるローカルでの実行を選択し、Codex 承認/サンドボックス セマンティクスをバイパスします。 -- `"codex-sandbox"` は互換性のために残されていますが、`"off"` と同様にフェールクローズされます。散文のリクエストは -信頼できるサンドボックス証明書ではありません。 - ```json { "providers": { @@ -247,7 +240,7 @@ Anthropic アカウント ポリシーのリスクを理解していない限り } ``` -最上位ではなく、`providers.cursor` にフィールドを設定します。ダッシュボードで **プロバイダー > カーソル > JSON の編集** を使用し、保存して再起動します。従来の `unsafeAllowNativeLocalExec: true` は、`nativeLocalExec` が設定されていない場合にのみ `nativeLocalExec: "on"` と等しくなります。 MCP、画面録画、およびコンピューターの使用は、`mcpServers` および `desktopExecutor` によって個別に制御されます。 +最上位ではなく、`providers.cursor` にフィールドを設定します。ダッシュボードで **プロバイダー > カーソル > JSON の編集** を使用し、保存して再起動します。MCP、画面録画、およびコンピューターの使用は、`mcpServers` および `desktopExecutor` によって個別に制御されます。 各 `mcpServers.<name>` は、`command` (stdio) または `url` (ストリーミング可能な HTTP) のいずれかを受け入れます。 Stdio は `args`、`env`、および `cwd` も受け入れます。 HTTP は `headers` を受け入れます。どちらも `enabled` (デフォルトは true) と `toolPrefix` をサポートします。 `desktopExecutor` は、`computerUseCommand`、`recordScreenCommand`、`cwd`、`env`、および `timeoutMs` (デフォルトは `30000`) を受け入れます。コマンドは `sh -c` を通じて実行され、stdin から 1 つの JSON リクエストを読み取り、1 つの JSON 結果を stdout に書き込む必要があります。 @@ -283,7 +276,7 @@ OpenRouter は、複数の推論プロバイダーを通じて 1 つのモデル } ``` -モデル キーは、外部の opencodex プロバイダー プレフィックスを除いた、正確なネイティブ OpenRouter ID です。 `openrouter/anthropic-claude-sonnet-5` を選択すると、モデル ルールを適用する前のネイティブ `anthropic/claude-sonnet-5` が復元されます。 +モデル キーは、外部の CodexCommander プロバイダー プレフィックスを除いた、正確なネイティブ OpenRouter ID です。 `openrouter/anthropic-claude-sonnet-5` を選択すると、モデル ルールを適用する前のネイティブ `anthropic/claude-sonnet-5` が復元されます。 ## 静的モデルのホワイトリスト diff --git a/docs-site/src/content/docs/ja/reference/configuration/routing.md b/docs-site/src/content/docs/ja/reference/configuration/routing.md index 2eda8fa3c7..310965147a 100644 --- a/docs-site/src/content/docs/ja/reference/configuration/routing.md +++ b/docs-site/src/content/docs/ja/reference/configuration/routing.md @@ -10,11 +10,11 @@ description: デフォルトのプロバイダーの選択、モデルの解決 |フィールド |タイプ |デフォルト |意味 | | --- | --- | --- | --- | | `defaultProvider` | `string` | `"openai"` |以前のモデルのルールが一致しない場合に使用される最終プロバイダー。有効な構成済みプロバイダーを指定する必要があります。 | -| `combos?` | `Record<string, OcxComboConfig>` | `{}` |注文されたプロバイダー/モデル ターゲットから構築された仮想 `combo/<id>` モデル。 | +| `combos?` | `Record<string, CodexCommanderComboConfig>` | `{}` |注文されたプロバイダー/モデル ターゲットから構築された仮想 `combo/<id>` モデル。 | ## モデルの解決順序 -opencodex は、要求されたモデルを次の順序で解決します。 +CodexCommander は、要求されたモデルを次の順序で解決します。 1. 設定済みの `<account-selector>/<native-openai-model>` namespace。対応する保存済み Codex アカウントだけに routing され、無効または利用不能な exact target は fail closed します。 2. 正規の `combo/<id>` または構成されたコンボ エイリアス。正規 ID は、エイリアスが一致する前に優先されます。 @@ -77,7 +77,7 @@ selector の後には bare native OpenAI-family id だけを指定できます ### カタログの適格性 -コンボは、リストに表示できない場合でも、直接ルーティング可能です。 `ocx sync`、`/v1/models`、および Codex ピッカーは、すべてのターゲットが交差できる機能を公開している場合にのみリストします。 +コンボは、リストに表示できない場合でも、直接ルーティング可能です。 `ccx sync`、`/v1/models`、および Codex ピッカーは、すべてのターゲットが交差できる機能を公開している場合にのみリストします。 - ライブメタデータ、レジストリヒント、またはプロバイダーからの正の `contextWindow` `modelContextWindows` / `contextWindow`;そして @@ -89,7 +89,7 @@ selector の後には bare native OpenAI-family id だけを指定できます 明示的に要求された `policy/<id>`(または設定されたエイリアス)が、固定された候補許可リストの中から、ハードな能力要件と決定的で説明可能なスコアリングで選択します。既存のモデル ID が暗黙的にプロファイルを通ることはありません。`candidates`(明示的な許可リスト)、オプションの `alias`、`require`(`minContextWindow`、`minQuotaHeadroom`、`tools`、`imageInput`、`structuredOutput`、`localOnly`、`remoteAllowed`、`encryptedCodexTasks`、`reasoningEffort`、`serviceTier`)、`optimize`(latency/health/cost/quota の重み)、`limits.maxEstimatedCostUsd`、`unknownEvidence`(allow/penalize/exclude)をサポートします。未知はゼロや無料にはなりません。 -CLI: `ocx route policy list`、`ocx route policy show <id>`、`ocx route policy dry-run <id> --model-context <tokens> --tools`、`ocx route policy evaluate <id>`。 +CLI: `ccx route policy list`、`ccx route policy show <id>`、`ccx route policy dry-run <id> --model-context <tokens> --tools`、`ccx route policy evaluate <id>`。 コンボは明示的な順序・重み付きターゲットのルーティングとフェイルオーバーです。ポリシープロファイルは、候補間の証拠に基づく選択です。 @@ -102,8 +102,8 @@ CLI: `ocx route policy list`、`ocx route policy show <id>`、`ocx route policy 返される履歴とルート決定ペイロードは、マスク済みのリクエストメタデータのみを公開します(例: 不透明な `apiKeyId` ラベル)。資格情報、生のプロンプト本文、プロバイダのシークレットは含みません。 -CLI: `ocx logs explain <request-id>`、`ocx logs rebuild-index`、`ocx logs index-status`。 +CLI: `ccx logs explain <request-id>`、`ccx logs rebuild-index`、`ccx logs index-status`。 -## 移行 +## 既存データ -`routingProfiles` は任意の追加設定です。既存の設定ファイルと古い `usage.jsonl` 行はそのまま読み込めます。インデックスは使い捨てで、削除すると次回クエリ時に `usage.jsonl` から自動再構築されます。自動チューニングは行われません。 +`routingProfiles` は任意の追加設定です。既存の設定ファイルと、`routeDecision` を持たない `usage.jsonl` 行も読み込めます。インデックスは使い捨てで、削除すると次回クエリ時に `usage.jsonl` から自動再構築されます。自動チューニングは行われません。 diff --git a/docs-site/src/content/docs/ja/reference/configuration/server.md b/docs-site/src/content/docs/ja/reference/configuration/server.md index d702ec8839..e6c4011465 100644 --- a/docs-site/src/content/docs/ja/reference/configuration/server.md +++ b/docs-site/src/content/docs/ja/reference/configuration/server.md @@ -10,42 +10,39 @@ description: リスナー、リモート アクセス、アドミッション |フィールド |タイプ |デフォルト |意味 | | --- | --- | --- | --- | | `port` | `number` | `10100` |プロキシリッスンポート。 | -| `hostname?` | `string` | `"127.0.0.1"` |バインドアドレス。非ループバック バインドには `OPENCODEX_API_AUTH_TOKEN` が必要です。 | +| `hostname?` | `string` | `"127.0.0.1"` |バインドアドレス。非ループバック バインドには `CODEXCOMMANDER_API_AUTH_TOKEN` が必要です。 | | `proxy?` | `string` | — |送信 HTTP(S) プロキシ URL または `${ENV_VAR}`。これらの変数が設定されていない場合にのみ、`HTTP_PROXY` / `HTTPS_PROXY` に適用されます。ループバックは `NO_PROXY` に残ります。 | | `stallTimeoutSec?` | `number` | `300` | `response.incomplete` より前にアップストリーム データがない秒数。最小 1。 | `connectTimeoutMs?` | `number` | `200000` |試行ごとの DNS/TCP/TLS/最終ヘッダーの期限。本体が生成される前に終了します。 | | `shutdownTimeoutMs?` | `number` | `5000` |アクティブなターンが中止される前の正常な排出期限。 | | `websockets?` | `boolean` | `false` |応答 WebSocket パスとして `supports_websockets` をアドバタイズします。 False は HTTP/SSE を維持します。 | | `corsAllowOrigins?` | `string[]` | `[]` | 追加の正確な CORS origin。ループバック origin は常に許可します。`chrome-extension://<extension-id>` など authority ベースのブラウザー拡張 origin に対応し、`*` はワイルドカードではありません。Firefox と Safari は拡張 UUID を(インストール/ブラウザー起動ごとに)再生成するため、origin が変わったらエントリを更新してください。 | -| `apiKeys?` | `OcxApiKey[]` | `[]` |生成された `ocx_…` 資格情報は、非ループバック バインドでの管理およびデータ プレーン認証によって受け入れられました。ダッシュボードで管理。 | +| `apiKeys?` | `CodexCommanderApiKey[]` | `[]` | 非ループバック バインドのデータプレーン認証で受け入れる、生成済みの `ccx_data_…` 資格情報。ダッシュボードで管理され、`/api/*` の認証には使用できません。 | | `storageCleanupPolicy?` | `StorageCleanupPolicy` |無効 |アーカイブされたセッションのクリーンアップ ポリシーをオプトインします。暗黙的に有効になることはありません。 | | `appOwnedMemoryBudgetMb?` | `number` | `256` |排除可能なアプリ所有のログ、キャッシュ、BLOB、および継続ペイロードの MiB の上限。範囲は 64 ~ 4096。 RSSキャップではありません。 | -| `codexAutoStart?` | `boolean` | `true` | Codex を起動する前に、Codex シムで `ocx ensure` を実行させます。 False を指定すると、操作が行われないことが保証されます。 | -| `codexShimAutoRestore?` | `boolean` | `true` |完了した外部 Codex アップデートによってインストールされたシムが置き換えられた後、インストールされているシムを復元します。環境オプトアウト: `OPENCODEX_CODEX_SHIM_AUTO_RESTORE=0`。 | -| `syncResumeHistory?` | `boolean` | `true` | Codex App 履歴の互換性を元に戻すことができます。元のメタデータは `ocx stop` / `ocx restore` によってバックアップおよび復元されます。 | -| `shadowCallIntercept?` | `{ enabled?: boolean; model?: string; sourceModels?: string[] }` |オフ |認識された Codex ヘルパー/シャドウ呼び出しを、少ない労力で選択したモデルにリダイレクトします。デフォルトのソースプレフィックスは `gpt-5.6-luna` です。0.144.x 以前のクライアントでは `gpt-5.4-mini` が使われており、`sourceModels` で復元できます。 | -| `webSearchSidecar?` | `OcxWebSearchSidecarConfig` |使用可能な場合はオン | Web 検索サイドカー オプション。 | -| `visionSidecar?` | `OcxVisionSidecarConfig` |使用可能な場合はオン |画像説明サイドカー オプション。 | -| `images?` | `OcxImagesConfig` | OpenAI の自動選択 | Codex `image_gen` のスタンドアロン イメージ リレー オプション。 | - -バックアップ サポートが存在する前に古い開発ビルドで再開履歴メタデータが変更された場合は、`ocx recover-history --legacy-openai` を実行してネイティブ プロバイダーの回復を強制します。 +| `codexAutoStart?` | `boolean` | `true` | Codex を起動する前に、Codex シムで `ccx ensure` を実行させます。 False を指定すると、操作が行われないことが保証されます。 | +| `codexShimAutoRestore?` | `boolean` | `true` |完了した外部 Codex アップデートによってインストールされたシムが置き換えられた後、インストールされているシムを復元します。環境オプトアウト: `CODEXCOMMANDER_CODEX_SHIM_AUTO_RESTORE=0`。 | +| `shadowCallIntercept?` | `{ enabled?: boolean; model?: string; sourceModels?: string[] }` |オフ |認識された Codex ヘルパー/シャドウ呼び出しを、少ない労力で選択したモデルにリダイレクトします。デフォルトのソースプレフィックスは `gpt-5.6-luna` です。`sourceModels` は現在のカスタムソースを明示的に指定するためのオーバーライドです。 | +| `webSearchSidecar?` | `CodexCommanderWebSearchSidecarConfig` |使用可能な場合はオン | Web 検索サイドカー オプション。 | +| `visionSidecar?` | `CodexCommanderVisionSidecarConfig` |使用可能な場合はオン |画像説明サイドカー オプション。 | +| `images?` | `CodexCommanderImagesConfig` | OpenAI の自動選択 | Codex `image_gen` のスタンドアロン イメージ リレー オプション。 | ## リモートアクセス デフォルトの `127.0.0.1` バインドはループバックのみです。 `0.0.0.0` などの非ループバック アドレスには、`/api/*` とデータ プレーンの両方でトークン認証が必要です。開始する前にトークンをエクスポートします。 ```bash -export OPENCODEX_API_AUTH_TOKEN="your-secret-token" -ocx start +export CODEXCOMMANDER_API_AUTH_TOKEN="your-secret-token" +ccx start ``` -プロキシは、この変数がないとリモート バインドを拒否します。バックグラウンド サービスの場合は、`ocx service install` の前にエクスポートして、launchd、systemd、またはタスク スケジューラがそれを受信できるようにします。クライアントは以下を送信する必要があります: +プロキシは、この変数がないとリモート バインドを拒否します。バックグラウンド サービスの場合は、`ccx service install` の前にエクスポートして、launchd、systemd、またはタスク スケジューラがそれを受信できるようにします。クライアントは以下を送信する必要があります: ```text -x-opencodex-api-key: your-secret-token +x-codexcommander-api-key: your-secret-token ``` -|エンドポイント | `Authorization: Bearer` | `x-opencodex-api-key` | `x-api-key` | +|エンドポイント | `Authorization: Bearer` | `x-codexcommander-api-key` | `x-api-key` | | --- | --- | --- | --- | | `/v1/responses` |受け入れられません | **必須** |受け入れられません | | `/v1/chat/completions` |受け入れられません | **必須** |受け入れられません | @@ -66,7 +63,7 @@ x-opencodex-api-key: your-secret-token ssh -L 20100:localhost:10100 you@remote ``` -任意のローカル ポートが機能します。ホストが `localhost`、`127.0.0.1`、または `::1` に解決されるリクエストは、ポートに関係なくループバックのままであるため、`http://localhost:20100/v1` が機能します。そのベース URL をクライアントに設定します。 `ocx` は、デフォルトのローカル `127.0.0.1` アドレスのみを管理対象クライアント設定に書き込みます。 +任意のローカル ポートが機能します。ホストが `localhost`、`127.0.0.1`、または `::1` に解決されるリクエストは、ポートに関係なくループバックのままであるため、`http://localhost:20100/v1` が機能します。そのベース URL をクライアントに設定します。 `ccx` は、デフォルトのローカル `127.0.0.1` アドレスのみを管理対象クライアント設定に書き込みます。 プロバイダー OAuth コールバックは、固定リモート ポートでリッスンします。リモート マシンにログインするか、そのポートも転送します。 @@ -84,21 +81,20 @@ ssh -L 20100:localhost:10100 -L 1455:localhost:1455 you@remote ## Claude Code (`claudeCode`) -これらの設定は、`/v1/messages`、`ocx claude` ランチャー、および Claude ダッシュボード ページを制御します。 +これらの設定は、`/v1/messages`、`ccx claude` ランチャー、および Claude ダッシュボード ページを制御します。 |キー |タイプ |デフォルト |説明 | | --- | --- | --- | --- | | `claudeCode.bodyStallSec?` | `number` | `90` |合計時間ではなく、読み取り保留中のネイティブ パススルー ボディの非アクティブ バジェット (秒単位)。最小 1。正確には `0` が無効になります。 | | `claudeCode.bodyMaxBytes?` | `number` | `67108864` |ストリーミングおよびバッファリングされた応答の累積的なネイティブ パススルー ボディ キャップ。まさに `0` が無効になります。 | | `claudeCode.authMode?` | `"proxy" \| "subscription"` |自動 |起動による `ANTHROPIC_AUTH_TOKEN` の処理方法。起動ごとに認証を自動検出します。明示的な値は決してオーバーライドされません。 | -| `claudeCode.authModeMigratedAt?` | `string` |設定を解除する |内部のワンタイムアップグレードマーカー。手動で設定しないでください。 | -| `claudeCode.subagentEffort?` | `"low" \| "medium" \| "high" \| "xhigh" \| "max"` |継承 |生成された `~/.claude/agents/ocx-*.md` に書き込まれる作業量。 Codex のガイダンスおよびプロキシの上限とは別のものです。 `ocx claude` を通じて再起動して再生成します。 | +| `claudeCode.subagentEffort?` | `"low" \| "medium" \| "high" \| "xhigh" \| "max"` |継承 |生成された `~/.claude/agents/ccx-*.md` に書き込まれる作業量。 Codex のガイダンスおよびプロキシの上限とは別のものです。 `ccx claude` を通じて再起動して再生成します。 | 自動認証では、保存されているクロード認証が見つかった場合はサブスクリプションが選択され、見つからない場合はプロキシが選択され、検出が決定的でない場合は警告付きのサブスクリプションが選択されます。 [クロードコード認証モード](/guides/claude-code/#auth-mode)を参照してください。 ## シャドウコール -Codex は、タイトルやコミット メッセージなどのタスクに小さなヘルパー モデルを使用します。 `shadowCallIntercept` を有効にして、認識されたソース モデル プレフィックスを別の構成済みモデルにリダイレクトします。交換作業は少ない労力で実行されます。クライアントが異なるヘルパー ID を使用する場合にのみ、`sourceModels` を設定します。 +Codex は、タイトルやコミット メッセージなどのタスクに小さなヘルパー モデルを使用します。 `shadowCallIntercept` を有効にして、認識されたソース モデル プレフィックスを別の構成済みモデルにリダイレクトします。交換作業は少ない労力で実行されます。`sourceModels` は現在のカスタムソースを明示的に指定する場合にのみ設定します。`x-codex-turn-metadata` で認識されたメンテナンス要求だけが対象となり、通常のターンと、メタデータがない、壊れている、または認識できない要求はインターセプトされません。 ```json { @@ -112,7 +108,7 @@ Codex は、タイトルやコミット メッセージなどのタスクに小 ## サイドカー -### `images` (`OcxImagesConfig`) +### `images` (`CodexCommanderImagesConfig`) |フィールド |タイプ |デフォルト |意味 | | --- | --- | --- | --- | @@ -121,13 +117,13 @@ Codex は、タイトルやコミット メッセージなどのタスクに小 プロバイダーが見つからない、無効になっている、互換性がない、または使用可能なキーがない場合、明示的な選択は失敗して閉じられます。別の有料アップストリームにフォールバックすることはありません。エンドポイントは、Codex が期待する OpenAI Images API パスと応答形状を実装する必要があります。 -### `webSearchSidecar` (`OcxWebSearchSidecarConfig`) +### `webSearchSidecar` (`CodexCommanderWebSearchSidecarConfig`) |フィールド |タイプ |デフォルト |意味 | | --- | --- | --- | --- | | `enabled?` | `boolean` |使用可能な場合はオン |マスタースイッチ。 | | `backend?` | `"openai" \| "anthropic"` |自動 |明示的な勝利。それ以外の場合は使用可能な保存された Anthropic OAuth は `anthropic` を選択し、次に `openai` を選択します。 | -| `model?` | `string` |バックエンド依存 | OpenAI の場合は `gpt-5.6-luna`、Anthropic の場合は `claude-sonnet-5`。従来の明示的な `gpt-5.4-mini` は開始時に移行されます。 | +| `model?` | `string` |バックエンド依存 | OpenAI の場合は `gpt-5.6-luna`、Anthropic の場合は `claude-sonnet-5`。 | | `reasoning?` | `string` | `low` |サイドカーの取り組み。 `minimal` は Web 検索で拒否されます。 | | `maxSearchesPerTurn?` | `number` | `3` |メインモデルのターンごとに許可される実際の検索。 | | `routedModelStallTimeoutMs?` | `number` | `200000` |設定ファイルのみのルーテッド モデルの raw ボディの非アクティブ期限。整数 1 ~ 2147483647。空でないすべてのチャンクがリセットされます。 | @@ -137,7 +133,7 @@ OpenAI バックエンドには、ChatGPT ログインと有効な ChatGPT `forw 検索は 4 つのクロック (ベース `stallTimeoutSec`、`connectTimeoutMs`、ルーテッド モデルの非アクティビティ、ホスト型検索のタイムアウト) によって制御されます。有効なブリッジ ウォッチドッグは、最大プラス 30 秒です。ルート ストールは非アクティブ ガードであり、総生成期限ではありません。 -### `visionSidecar` (`OcxVisionSidecarConfig`) +### `visionSidecar` (`CodexCommanderVisionSidecarConfig`) |フィールド |タイプ |デフォルト |意味 | | --- | --- | --- | --- | @@ -149,4 +145,4 @@ OpenAI バックエンドには、ChatGPT ログインと有効な ChatGPT `forw Vision は、プロバイダーの `noVisionModels` のモデルに送信された画像に対してのみアクティブになります。 OpenAI には、検索と同じログイン/転送要件があります。明示的に選択された Anthropic は、使用可能な認証情報がないと失敗します。成功した `data:` 記述では、バックエンド、モデル、詳細、画像バイト、および正規化されたメッセージ コンテキストをキーとした境界付きキャッシュが使用されます。ヒットと同じターンの重複は制限を消費しません。リモート `https:` イメージと失敗した説明、または空の説明はキャッシュされません。 -Anthropic OAuth サイドカーは、opencodex の既存のクロード コード OAuth フィンガープリントを再利用します。対象のアカウントとワークロードをソークテストします。 +Anthropic OAuth サイドカーは、CodexCommander の既存のクロード コード OAuth フィンガープリントを再利用します。対象のアカウントとワークロードをソークテストします。 diff --git a/docs-site/src/content/docs/ja/reference/management-api.md b/docs-site/src/content/docs/ja/reference/management-api.md index 32941d4dc2..c00ccb0094 100644 --- a/docs-site/src/content/docs/ja/reference/management-api.md +++ b/docs-site/src/content/docs/ja/reference/management-api.md @@ -1,25 +1,25 @@ --- title: 管理 API -description: opencodex コントロール プレーンの認証、エラー、エンドポイント参照。 +description: CodexCommander コントロール プレーンの認証、エラー、エンドポイント参照。 --- -Management API は opencodex のコントロール プレーンです。 `http://localhost:10100` のダッシュボードはそのクライアントの 1 つです。 headless `ocx` プロバイダー、モデル、コンボ、アカウント、設定、診断、ライフサイクル コマンドもクライアントです。 API はプロキシの実行中にのみ使用できます。 +Management API は CodexCommander のコントロール プレーンです。 `http://localhost:10100` のダッシュボードはそのクライアントの 1 つです。 headless `ccx` プロバイダー、モデル、コンボ、アカウント、設定、診断、ライフサイクル コマンドもクライアントです。 API はプロキシの実行中にのみ使用できます。 対話型クライアントには [ウェブダッシュボード](/guides/web-dashboard/) を使用するか、自動化を構築する場合はこのリファレンスを使用します。永続値は最終的に [構成](/reference/configuration/) に従います。 ## 認証モデル -Management API には、データプレーン API キーとは独立した独自の管理者資格情報があります。起動時に、opencodex は次の順序で解決します。 +Management API には、データプレーン API キーとは独立した独自の管理者資格情報があります。起動時に、CodexCommander は次の順序で解決します。 -1. `OPENCODEX_ADMIN_AUTH_TOKEN`、設定時。 -2. 強化されたシークレット ファイル内に生成された `ocx_admin_*` トークン。 +1. `CODEXCOMMANDER_ADMIN_AUTH_TOKEN`、設定時。 +2. 強化されたシークレット ファイル内に生成された `ccx_admin_*` トークン。 ファイルベースのトークンは、そのディレクトリとファイルのアクセス許可または ACL が強化された後にのみ受け入れられます。それが保証できない場合、環境トークンが提供されるかファイルの状態が修復されるまで、管理認証は失敗して閉じられ、API は 503 を返します。 管理者トークンを次のいずれかの形式で送信します。 ```http -X-OpenCodex-API-Key: <admin-token> +X-CodexCommander-API-Key: <admin-token> ``` ```http @@ -32,7 +32,7 @@ Authorization: Bearer <admin-token> ### ループバック ダッシュボード セッション -ループバック バインドでは、ダッシュボード ブートストラップは有効期間の短い `ocx_session_*` 資格情報を受け取ることができます。各セッションは 5 分間続き、正確なダッシュボードのオリジンにバインドされます。安全なリクエストはそのオリジンと一致する必要があります。安全でないメソッドには、ブラウザ `Origin` とセッションの CSRF トークンも必要です。 +ループバック バインドでは、ダッシュボード ブートストラップは有効期間の短い `ccx_session_*` 資格情報を受け取ることができます。各セッションは 5 分間続き、正確なダッシュボードのオリジンにバインドされます。安全なリクエストはそのオリジンと一致する必要があります。安全でないメソッドには、ブラウザ `Origin` とセッションの CSRF トークンも必要です。 リモート バインドを含むデータ プレーン認証が必要な場合、セッションの発行は無効になります。リモート オペレーターは、生の管理トークンを使用して認証する必要があります。ループバック スタイルの GUI セッションは作成されません。 @@ -42,7 +42,7 @@ Authorization: Bearer <admin-token> |ステータス |タイプまたはコード |意味 | | --- | --- | --- | -| 401 | `opencodex admin token required` |管理者トークンまたは GUI セッションが欠落している、無効である、期限切れである、オリジンが一致しない、または CSRF 証拠が欠落している。 +| 401 | `codexcommander admin token required` |管理者トークンまたは GUI セッションが欠落している、無効である、期限切れである、オリジンが一致しない、または CSRF 証拠が欠落している。 | 403 | `cross-origin request blocked` |リクエストの送信元が管理許可リストの外にあります。 | 404 | `not_found` |メソッドとパスに一致する管理ルートはありません。 | 413 | `request body too large` | POST、PUT、または PATCH 本文が 2 MiB の管理制限を超えています。 @@ -65,7 +65,7 @@ Authorization: Bearer <admin-token> | `PUT /api/grok/selection` |除外された Grok モデルを永続化します。 400 個の無効な選択またはサイズが大きすぎる選択 | | `POST /api/grok/apply` |管理された同期を通じて永続的な Grok 設定を適用する | 409 `grok_apply_busy`; 400/500 適用失敗 | | `GET, PUT /api/claude-desktop` | Claude Desktop のルーティング/ネイティブ プロファイルを読み取るか永続化する | 400 無効または使用できない割り当て | -| `POST /api/claude-desktop/apply` |保存したプロファイルを Claude Desktop の管理対象設定に書き込みます。 400/500 書き込み失敗 | +| `POST /api/claude-desktop/apply` | 保存したプロファイルを Claude Desktop の管理対象設定に書き込みます。JSON オブジェクトと明示的な `mode`(`static`、`hybrid`、`discovery`)が必要です | 400 body/mode 不正、500 書き込み失敗 | | `GET /api/claude-desktop/status` |保存済みプロファイルと適用済みプロファイルおよびデスクトップの健全性を検査する | 400 ステータス読み取り失敗 | | `GET, PUT /api/claude-code` |クロード コードのゲートウェイ、認証モード、モデル マップ、コンテキスト、エージェント、サイドカー設定の読み取りまたは更新 | 400 無効なフィールドまたは図形 | @@ -93,9 +93,6 @@ Authorization: Bearer <admin-token> | `GET, POST /api/windows-tray` | Windows トレイの状態を読み取るか、インストール/起動/停止/アンインストールする | 400 のサポートされていないプラットフォーム/アクション。 500 操作失敗 | | `GET /api/diagnostics/project-config` |キャッシュされたプロジェクト設定の読み取りに関する警告 | — | | `POST /api/sync` | 現在のモデルカタログを Codex に同期し、`catalogQuality`、`rehydrated`、Codex app-server の `catalogState`、必要な再起動ヒントを返す | 409 書き込み権限の拒否、500 同期失敗 | -| `GET /api/update/check` | `latest` または `preview` 更新チャネルを確認してください。 400 無効なタグ | -| `POST /api/update/run` |更新ジョブを開始し、必要に応じて再起動します。 400 無効な本文。ジョブ固有の競合/エラーのステータス | -| `GET /api/update/status` | ID によって更新ジョブをポーリングする | 404 不明なジョブ | | `GET, PUT /api/sidecar-settings` | Web 検索およびビジョンのサイドカー モデル/バックエンド設定の読み取りまたは更新 | 400 無効な形状、バックエンド、または制限 | | `GET, PUT /api/shadow-call-settings` |シャドウ コール インターセプト設定の読み取りまたは更新 | 400 無効な形状または値 | @@ -175,12 +172,6 @@ Authorization: Bearer <admin-token> `provider_has_dependent_combos` は安全バリアです。プロバイダーを削除する前に、依存するコンボを削除または編集してください。 -### サイドバー - -|メソッドとパス |目的 |注目すべきエラー | -| --- | --- | --- | -| `GET /api/update/badge` |安価なサイドバーの更新バッジの状態を読む | — | - ### システムのライフサイクル |メソッドとパス |目的 |注目すべきエラー | @@ -200,7 +191,7 @@ Authorization: Bearer <admin-token> | `PUT /api/codex-auth/accounts/pause` | 1 つのアカウントを一時停止または再開する | 400 無効なアカウント/状態。 404 アカウントが見つかりません | | `PUT /api/codex-auth/accounts/pause-exhausted` |クォータを使い果たしたアカウントを一時停止する |ミューテーションロックの失敗は 503 になります | | `POST /api/codex-auth/accounts/clear-cooldown` | 1 つのアカウントまたはすべてのアカウントのランタイム クールダウンをクリアする | 400 無効な ID | -| `GET, PUT /api/codex-auth/active` |アクティブなアカウントを読み取るか選択します | 400 アカウントが無効または欠落しています。 409 一時停止/レガシー行の競合 | +| `GET, PUT /api/codex-auth/active` |アクティブなアカウントを読み取るか選択します | 400 アカウントが無効または欠落しています。409 一時停止されたアカウント | | `PUT /api/codex-auth/auto-switch` |自動アカウント切り替えのクォータしきい値を設定する | 400 無効なしきい値 | | `PUT, PATCH /api/codex-auth/pool-strategy` | Codex アカウントプールの選択戦略を更新 | 400 無効な戦略/構成 | | `PUT /api/codex-auth/failover` |アカウントのフェイルオーバーしきい値を設定する | 400 無効なしきい値 | @@ -216,4 +207,4 @@ Authorization: Bearer <admin-token> ## クライアントの選択 -通常の管理では、[ウェブダッシュボード](/guides/web-dashboard/) が最も安全なガイド付きワークフローを提供します。ヘッドレス ホストとオートメーションの場合は、対応する `ocx` コマンドを使用します。これらのコマンドは、これと同じライブ API を呼び出し、プロキシに到達できない場合、または操作が失敗した場合にゼロ以外の結果を返します。ダイレクト HTTP は、上記の正確なエンドポイント コントラクトを必要とする統合に最も役立ちます。 +通常の管理では、[ウェブダッシュボード](/guides/web-dashboard/) が最も安全なガイド付きワークフローを提供します。ヘッドレス ホストとオートメーションの場合は、対応する `ccx` コマンドを使用します。これらのコマンドは、これと同じライブ API を呼び出し、プロキシに到達できない場合、または操作が失敗した場合にゼロ以外の結果を返します。ダイレクト HTTP は、上記の正確なエンドポイント コントラクトを必要とする統合に最も役立ちます。 diff --git a/docs-site/src/content/docs/ja/reference/proxy-formats.md b/docs-site/src/content/docs/ja/reference/proxy-formats.md index e010110470..913c8a1037 100644 --- a/docs-site/src/content/docs/ja/reference/proxy-formats.md +++ b/docs-site/src/content/docs/ja/reference/proxy-formats.md @@ -3,7 +3,7 @@ title: プロキシ API 形式 description: 応答、チャット完了、人為的メッセージ、モデル カタログ、WebSocket、リアルタイム、および圧縮サーフェスのワイヤ レベルのリファレンス。 --- -opencodex は、複数のクライアント方言で 1 つのローカル プロキシを表示します。 Codex クライアントは Responses API を話すことができ、OpenAI 互換アプリは Chat Completions を話すことができ、Claude Code は Anthropic Messages を話すことができます。すべての上流プロバイダーがあらゆる形式を実装する必要はありません。 +CodexCommander は、複数のクライアント方言で 1 つのローカル プロキシを表示します。 Codex クライアントは Responses API を話すことができ、OpenAI 互換アプリは Chat Completions を話すことができ、Claude Code は Anthropic Messages を話すことができます。すべての上流プロバイダーがあらゆる形式を実装する必要はありません。 通常の変換パスは次のとおりです。 @@ -28,7 +28,7 @@ provider events → internal adapter events → client dialect ## `POST /v1/responses` -これは、ネイティブの opencodex データプレーン形状です。リクエスト本文は、空ではない `model` を持つ JSON オブジェクトである必要があります。 `input` は文字列または応答項目の配列です。 +これは、ネイティブの CodexCommander データプレーン形状です。リクエスト本文は、空ではない `model` を持つ JSON オブジェクトである必要があります。 `input` は文字列または応答項目の配列です。 ### 受け入れられたリクエストフィールド @@ -144,7 +144,7 @@ WebSocket が無効になっている場合、アップグレード試行では ## `POST /v1/live` とRealtime サイドバンド -`POST /v1/live` は、ChatGPT/Codex アプリのフレームレス通話作成サーフェスを受け入れます。 `POST /v1/realtime/calls` は、OpenAI Realtime 呼び出し作成サーフェスを受け入れます。 opencodex は、適格な OpenAI ファミリ ルートを選択し、アップストリーム認証モードのコール作成リクエストを正規化し、制限付き応答を中継します。 +`POST /v1/live` は、ChatGPT/Codex アプリのフレームレス通話作成サーフェスを受け入れます。 `POST /v1/realtime/calls` は、OpenAI Realtime 呼び出し作成サーフェスを受け入れます。 CodexCommander は、適格な OpenAI ファミリ ルートを選択し、アップストリーム認証モードのコール作成リクエストを正規化し、制限付き応答を中継します。 コールの作成後、クライアントはサポートされている受信フォームを使用してサイドバンド WebSocket に参加できます。 @@ -161,7 +161,7 @@ WebSocket が無効になっている場合、アップグレード試行では |ルートの種類 |行動 | | --- | --- | | Canonical ChatGPT または公式 OpenAI ルート |解決されたアカウントとモデル認証を使用して、リクエストをネイティブ `/responses/compact` エンドポイントに転送します。 -|その他の配線モデル | `compaction_trigger` を使用して内部、非ストリーミング、ツール不要の圧縮ターンを実行します。 `encrypted_content` が `ocx1:` エンベロープである合成 `compaction` アイテムが 1 つだけ必要です。その概要を v1 置換履歴にデコードします。 +|その他の配線モデル | `compaction_trigger` を使用して内部、非ストリーミング、ツール不要の圧縮ターンを実行します。 `encrypted_content` が `ccx1:` エンベロープである合成 `compaction` アイテムが 1 つだけ必要です。その概要を v1 置換履歴にデコードします。 ネイティブ コンパクト応答は、宣言された `Content-Length` がすでに制限を超えている応答を含め、最大 32 MiB でバッファリングされます。コンパクト固有の障害には次のようなものがあります。 @@ -172,11 +172,11 @@ WebSocket が無効になっている場合、アップグレード試行では | 499 | `client_cancelled` | | 転送またはバッファリング中にクライアントがキャンセルされました。 | 502 | `compact_response_too_large` |ネイティブ コンパクト出力が 32 MiB を超えました | | 502 | `upstream_error` |接続、読み取り、または合成圧縮ターンの失敗 | -| 502 | `invalid_response_error` |合成ターンでは、有効な空でない `ocx1:` 圧縮項目が 1 つだけ生成されませんでした。 +| 502 | `invalid_response_error` |合成ターンでは、有効な空でない `ccx1:` 圧縮項目が 1 つだけ生成されませんでした。 ## 認証マトリックス -ループバックのみのバインドでは、データ プレーンのアドミッションに設定されたキーは必要ありません。リモート バインドでは、以下のマトリックスを使用します。 「専用」とは `X-OpenCodex-API-Key` を意味します。他の列は `Authorization: Bearer ...` と `x-api-key` を意味します。 +ループバックのみのバインドでは、データ プレーンのアドミッションに設定されたキーは必要ありません。リモート バインドでは、以下のマトリックスを使用します。 「専用」とは `X-CodexCommander-API-Key` を意味します。他の列は `Authorization: Bearer ...` と `x-api-key` を意味します。 |表面 |専用 |ベアラー | `x-api-key` | | --- | --- | --- | --- | @@ -209,6 +209,6 @@ Anthropic オリジンの失敗は Anthropic のエラー エンベロープで ## 暗号化されたコンテンツの健全性 -プロキシは、本物のバックエンド暗号文を不透明なものとして扱います。構造的に有効な暗号文はバイト単位で保存されます。opencodex は暗号文を復号したり、その内容を変換したり、別のプロバイダー用に再暗号化したりしません。 +プロキシは、本物のバックエンド暗号文を不透明なものとして扱います。構造的に有効な暗号文はバイト単位で保存されます。CodexCommander は暗号文を復号したり、その内容を変換したり、別のプロバイダー用に再暗号化したりしません。 -一部のエージェント フックはこれまで、プレーンテキストの制御テキストを `encrypted_content` スロットに配置していました。互換性を確保するために、プロキシは、構造的に有効な Fernet の実行を変更せずに保持しながら、プレーンテキストをテキスト部分に分割します。 `agent_message` が修復中にすべての暗号化された部分を失った場合、それは通常のユーザー メッセージになります。現在の v2 タスクが完全に暗号化されたままであるが、選択したルーティングされたターゲットがネイティブ ChatGPT 暗号文を読み取ることができない場合、opencodex は読み取り不能なバイトをそのプロバイダーに送信する代わりに `unreadable_encrypted_agent_task` で失敗します。ワーカー タスクに関するクライアントの動作については、[サブエージェントサーフェス](/guides/sub-agent-surface/) を参照してください。 +一部のエージェント フックはプレーンテキストの制御テキストを `encrypted_content` スロットに配置します。プロキシは、構造的に有効な Fernet の実行を変更せずに保持しながら、プレーンテキストをテキスト部分に分割します。 `agent_message` が修復中にすべての暗号化された部分を失った場合、それは通常のユーザー メッセージになります。現在の v2 タスクが完全に暗号化されたままであるが、選択したルーティングされたターゲットがネイティブ ChatGPT 暗号文を読み取ることができない場合、CodexCommander は読み取り不能なバイトをそのプロバイダーに送信する代わりに `unreadable_encrypted_agent_task` で失敗します。ワーカー タスクに関するクライアントの動作については、[サブエージェントサーフェス](/guides/sub-agent-surface/) を参照してください。 diff --git a/docs-site/src/content/docs/ja/troubleshooting/windows-memory.md b/docs-site/src/content/docs/ja/troubleshooting/windows-memory.md index 4b7d30af89..6af50d29ab 100644 --- a/docs-site/src/content/docs/ja/troubleshooting/windows-memory.md +++ b/docs-site/src/content/docs/ja/troubleshooting/windows-memory.md @@ -1,13 +1,13 @@ --- title: Windows メモリの増加 -description: Windows 上で bun プロセスが何ギガバイトもの RAM に増加する可能性がある理由、opencodex が現在それに対して行っていること、およびアップストリームの Bun 修正がリリースされるまでのオプション。 +description: Windows 上で bun プロセスが何ギガバイトもの RAM に増加する可能性がある理由、CodexCommander が現在それに対して行っていること、およびアップストリームの Bun 修正がリリースされるまでのオプション。 --- -一部の Windows ユーザーは、opencodex の背後にある `bun` プロセスが、長時間のストリーミング セッション中に数ギガバイトの RSS に増加するのを目にします (問題 [#314](https://github.com/lidge-jun/opencodex/issues/314) として報告されています)。このページでは、実際に何が起こっているのか、そしてそれに対して何ができるのかを率直に説明します。 +一部の Windows ユーザーは、CodexCommander の背後にある `bun` プロセスが、長時間のストリーミング セッション中に数ギガバイトの RSS に増加するのを目にします (問題 [#314](https://github.com/pavelhov/CodexCommander/issues/314) として報告されています)。このページでは、実際に何が起こっているのか、そしてそれに対して何ができるのかを率直に説明します。 ## 根本原因: アップストリームの Bun ランタイムの問題 -opencodex には Bun ランタイム (現在 **1.3.14**) がバンドルされています。メモリの増加は、プロキシでの JavaScript レベルのリークではなく、アップストリームの既知の Bun の問題によって引き起こされます。 +CodexCommander には Bun ランタイム (現在 **1.3.14**) がバンドルされています。メモリの増加は、プロキシでの JavaScript レベルのリークではなく、アップストリームの既知の Bun の問題によって引き起こされます。 |パン問題 |状態 (2026-07-23 確認) | |---|---| @@ -15,19 +15,19 @@ opencodex には Bun ランタイム (現在 **1.3.14**) がバンドルされ | [#32111](https://github.com/oven-sh/bun/issues/32111) — クライアントが非同期プル ストリームを中止するとクラッシュします。 2026 年 6 月 21 日にマージされた [PR #32120](https://github.com/oven-sh/bun/pull/32120) を修正。 1.3.14 には存在しないと想定されています。注: このクラッシュは **Windows 固有のものではありません** (macOS/Linux でも再現されました)。 | [PR #31654](https://github.com/oven-sh/bun/pull/31654) — `node:net` ソケット ハンドルのリーク |上流はまだ **営業中** | -Windows では、#32111 クラッシュを回避するために、opencodex は保守的なコード パスで応答をストリーミングし続ける必要があります。そのパスはバックプレッシャーの問題に最もさらされるパスです。低速または停止したクライアントは、JavaScript がバインドできないネイティブ メモリにアップストリーム データをバッファリングしているランタイムを残す可能性があります。 +Windows では、#32111 クラッシュを回避するために、CodexCommander は保守的なコード パスで応答をストリーミングし続ける必要があります。そのパスはバックプレッシャーの問題に最もさらされるパスです。低速または停止したクライアントは、JavaScript がバインドできないネイティブ メモリにアップストリーム データをバッファリングしているランタイムを残す可能性があります。 -## opencodex の現在の対応 +## CodexCommander の現在の対応 制限付きの緩和と可視性 — **修正ではありません**。バンドルされた 1.3.14 ランタイムでは、リーク自体は上流の問題のままです。 - **メモリ ウォッチドッグ** - プロキシは、毎分自身のメモリをサンプリングし、ログに記録します。 観測されたメモリが 4 GiB を超えると、レート制限の警告が表示されます。 Windows ワーキング セット/RSS カウンターがコミットされた外部保持を過小報告する可能性があるため、観測されたメモリは RSS、`external`、および `arrayBuffers` の最大値になります (これらの合計ではありません)。 -- **`ocx doctor`** — 「メモリ / ランタイム」セクションには *サービス* が表示されます +- **`ccx doctor`** — 「メモリ / ランタイム」セクションには *サービス* が表示されます プロセスの Bun バージョン、RSS、外部/ArrayBuffers カウンター、JS ヒープ コンテキスト、およびストリーム モードの決定。バンドルされている Bun 1.3.14 ランタイムでは、`heapUsed` / `jscHeap` 単独ではリーク識別子ではありません。アプリレベルのリークを割り当てる前に、観察されたメモリを `responseState` および繰り返しサンプルと比較します。 - **`GET /api/system/memory`** — 認証済みの同じデータ -ダッシュボードまたはスクリプトの管理 API。 RSS/ヒープ/外部カウンターとともに、プロキシのメモリ内 `previous_response_id` 継続ストアのスカラー `responseState` ブロック (エントリ数、シリアル化された合計/最大バイト数、最も古いエントリの経過時間) を報告します。これはさらに成長に起因します。観察された記憶の上昇下での `responseState.totalBytes` の上昇は会話の保持を指します (長い `store:false` チェーンはターンごとに再拡張します)。一方、観察された記憶の上昇の下での横ばいの `responseState` はそのストアから遠ざかることを示します。値はスカラーのみであり、リクエスト本文、トークン、パス、アカウント識別子はありません。また、読み取りには副作用はありません (プルーニングや削除は行われません)。ダッシュボードの **メモリ可観測性** カードは同じフィールドをレンダリングし、確認ゲート付き **ドレインと再起動** アクションを提供します。現在のアクティブ ターン数を表示し、アクティブ ターンを最大 60 秒待機し (既存の 503 + `Retry-After` ドレインを再利用)、残りのターンを中止し、ライブ ポート (または障害専用サービス スーパーバイザ) 上の `ocx start` 経由でプロキシを再起動します。 respawn)Codex インジェクションを破棄せずに。これは、`POST /api/stop` の短いドレインよりも長く、情報に基づいたリサイクルです。 -- **ゲートされた代替ストリーム パス** — tee と JavaScript rewrite の連鎖を取り除く、有界の single-reader relay です。Windows の rewrite トラフィックでは既に使用され、通常の Windows トラフィックは引き続きランタイム ゲートに従います。macOS では、opt-in の plaintext V2 collaboration が実際に client rewrite を有効化し、検証済みの bundled Bun 1.3.14 を使用している場合に限り、`auto` が同期 `pull()` の正確な relay を選びます。これは [#1127](https://github.com/lidge-jun/opencodex/issues/1127) の terminal delivery hang を直す限定的な経路であり、Bun 1.3.14 に汎用の #32111 修正が含まれるとは主張しません。他の macOS rewrite は明示的 opt-in のままです。memory endpoint は in-flight、cancel、abort、error、queue watermark のスカラー counter だけを公開し、body や request identity は含みません。 +ダッシュボードまたはスクリプトの管理 API。 RSS/ヒープ/外部カウンターとともに、プロキシのメモリ内 `previous_response_id` 継続ストアのスカラー `responseState` ブロック (エントリ数、シリアル化された合計/最大バイト数、最も古いエントリの経過時間) を報告します。これはさらに成長に起因します。観察された記憶の上昇下での `responseState.totalBytes` の上昇は会話の保持を指します (長い `store:false` チェーンはターンごとに再拡張します)。一方、観察された記憶の上昇の下での横ばいの `responseState` はそのストアから遠ざかることを示します。値はスカラーのみであり、リクエスト本文、トークン、パス、アカウント識別子はありません。また、読み取りには副作用はありません (プルーニングや削除は行われません)。ダッシュボードの **メモリ可観測性** カードは同じフィールドをレンダリングし、確認ゲート付き **ドレインと再起動** アクションを提供します。現在のアクティブ ターン数を表示し、アクティブ ターンを最大 60 秒待機し (既存の 503 + `Retry-After` ドレインを再利用)、残りのターンを中止し、ライブ ポート (または障害専用サービス スーパーバイザ) 上の `ccx start` 経由でプロキシを再起動します。 respawn)Codex インジェクションを破棄せずに。これは、`POST /api/stop` の短いドレインよりも長く、情報に基づいたリサイクルです。 +- **ゲートされた代替ストリーム パス** — tee と JavaScript rewrite の連鎖を取り除く、有界の single-reader relay です。Windows の rewrite トラフィックでは既に使用され、通常の Windows トラフィックは引き続きランタイム ゲートに従います。macOS では、opt-in の plaintext V2 collaboration が実際に client rewrite を有効化し、検証済みの bundled Bun 1.3.14 を使用している場合に限り、`auto` が同期 `pull()` の正確な relay を選びます。これは [#1127](https://github.com/pavelhov/CodexCommander/issues/1127) の terminal delivery hang を直す限定的な経路であり、Bun 1.3.14 に汎用の #32111 修正が含まれるとは主張しません。他の macOS rewrite は明示的 opt-in のままです。memory endpoint は in-flight、cancel、abort、error、queue watermark のスカラー counter だけを公開し、body や request identity は含みません。 これらの変更による実際の RSS の改善は **Windows ユーザーによる検証を待っています**。リークが修正されたとは主張しません。 @@ -36,12 +36,12 @@ Windows では、#32111 クラッシュを回避するために、opencodex は ## 選択肢 1. **バンドルされたランタイム更新を待ちます。** Bun が検証可能にリリースされたら -修正が適用され、opencodex はバンドルされたランタイムを更新し、Windows の no-rewrite stream path が自動的にオンになります。上記の macOS plaintext-V2 `auto` 例外は、これとは独立して特定の Bun バージョンに固定されています。 +修正が適用され、CodexCommander はバンドルされたランタイムを更新し、Windows の no-rewrite stream path が自動的にオンになります。上記の macOS plaintext-V2 `auto` 例外は、これとは独立して特定の Bun バージョンに固定されています。 -2. **`OPENCODEX_BUN_PATH` を使用して信頼できる Bun ランタイムを実行します。** これは -未検証の領域 — 私たちがテストしていないランタイムで opencodex を実行しています。自己責任で。サービスのインストールにとって重要: オーバーライドは、サービスの開始時ではなく、**サービス アーティファクトの生成時に**読み込まれます。環境変数を設定し、同じシェルから `ocx service repair` を再実行すると、パスが永続サービス定義に組み込まれます。 env を設定するだけでは、すでにインストールされているサービスには何も影響しません。 +2. **`CCX_BUN_PATH` を使用して信頼できる Bun ランタイムを実行します。** これは +未検証の領域 — 私たちがテストしていないランタイムで CodexCommander を実行しています。自己責任で。サービスのインストールにとって重要: オーバーライドは、サービスの開始時ではなく、**サービス アーティファクトの生成時に**読み込まれます。環境変数を設定し、同じシェルから `ccx service repair` を再実行すると、パスが永続サービス定義に組み込まれます。 env を設定するだけでは、すでにインストールされているサービスには何も影響しません。 3. **`streamMode: "eager-relay"` を使用して有界リレーにオプトインします。** 2 つの方法: -`config.json` を編集する (`"streamMode": "eager-relay"` を追加する) か、管理 API を呼び出します。`PUT /api/settings` と `{"streamMode":"eager-relay"}` は、再起動せずに新しいターンに適用されます。 **クラッシュのリスク警告:** Bun 1.3.14 の汎用 async-pull stream は引き続き #32111 の影響を受けるため、未検証の形状に eager relay を強制すると、どの OS でもプロセスがクラッシュする可能性があります。サービス マネージャーは再起動しますが、実行中のリクエストは失敗します。`"legacy-tee"` は tee を固定し、macOS plaintext-V2 の auto 例外も無効にします。Windows の `"auto"` (デフォルト) はランタイム ゲートに従います。macOS の `"auto"` は、検証済みの plaintext-V2 collaboration rewrite だけを例外として tee を維持し、明示的な `"eager-relay"` は他の適格な SSE ターンを opt-in します。 +`config.json` を編集する (`"streamMode": "eager-relay"` を追加する) か、管理 API を呼び出します。`PUT /api/settings` と `{"streamMode":"eager-relay"}` は、再起動せずに新しいターンに適用されます。 **クラッシュのリスク警告:** Bun 1.3.14 の汎用 async-pull stream は引き続き #32111 の影響を受けるため、未検証の形状に eager relay を強制すると、どの OS でもプロセスがクラッシュする可能性があります。サービス マネージャーは再起動しますが、実行中のリクエストは失敗します。`"safe-tee"` は tee を固定し、macOS plaintext-V2 の auto 例外も無効にします。Windows の `"auto"` (デフォルト) はランタイム ゲートに従います。macOS の `"auto"` は、検証済みの plaintext-V2 collaboration rewrite だけを例外として tee を維持し、明示的な `"eager-relay"` は他の適格な SSE ターンを opt-in します。 -これらのいずれかを実際の Windows ワークロードで試した場合は、[#314](https://github.com/lidge-jun/opencodex/issues/314) の `ocx doctor` メモリ セクションの前後を報告してください。これがまさにこの軽減策が待っている検証です。 +これらのいずれかを実際の Windows ワークロードで試した場合は、[#314](https://github.com/pavelhov/CodexCommander/issues/314) の `ccx doctor` メモリ セクションの前後を報告してください。これがまさにこの軽減策が待っている検証です。 diff --git a/docs-site/src/content/docs/ko/benchmarks/index.mdx b/docs-site/src/content/docs/ko/benchmarks/index.mdx index 8dbe7781b2..c634d479b0 100644 --- a/docs-site/src/content/docs/ko/benchmarks/index.mdx +++ b/docs-site/src/content/docs/ko/benchmarks/index.mdx @@ -3,7 +3,7 @@ title: 벤치마크 description: 공개 코딩 에이전트 벤치마크 스냅샷 — 작업당 비용 대비 능력, 보드별 출처 표기. --- -공개 리더보드를 **수동으로 갱신하는 정적 스냅샷**입니다 — OpenCodex 실시간 +공개 리더보드를 **수동으로 갱신하는 정적 스냅샷**입니다 — CodexCommander 실시간 미터링이 아닙니다. 보드마다 출처, 캡처 날짜, 라이선스 메모를 달았고, 점수/$ 순위는 모든 행에 출처가 측정한 작업당 비용이 있는 보드에서만 표시합니다. diff --git a/docs-site/src/content/docs/ko/contributing.md b/docs-site/src/content/docs/ko/contributing.md index 8841fcc742..8821a38b99 100644 --- a/docs-site/src/content/docs/ko/contributing.md +++ b/docs-site/src/content/docs/ko/contributing.md @@ -1,13 +1,12 @@ --- title: 기여하기 -description: opencodex 개발 환경, 구조, 컨벤션, 프로바이더와 어댑터 추가 방법. +description: CodexCommander 개발 환경, 구조, 규칙, 프로바이더와 어댑터 추가 방법. --- ## 설정 ```bash -git clone https://github.com/pavelhov/opencodex.git -cd opencodex +cd /path/to/CodexCommander bun install bun run dev:proxy # 개발 모드 프록시 API bun run dev:gui # 대시보드 dev 서버(다른 터미널) @@ -44,12 +43,9 @@ subsystem의 기존 테스트 근처에 집중된 회귀 테스트를 추가하 cd docs-site && bun install && bun dev ``` -## 문서 배포 +## 문서 사이트 -공개 문서는 GitHub Pages의 <https://opencodex.me/ko/>에 게시됩니다. -`.github/workflows/deploy-docs.yml`은 `main` push에서 `docs-site/**`나 워크플로 자체가 바뀌면 -실행됩니다. `docs-site`를 빌드한 뒤 생성된 사이트를 배포합니다. 문서 변경을 push하기 전에 다음을 -실행하세요. +문서는 `docs-site/`에 있으며 현재 게시된 호스트는 없습니다. 문서 PR을 열기 전에 로컬에서 빌드하세요. ```bash cd docs-site @@ -57,41 +53,31 @@ bun install --frozen-lockfile bun run build ``` -## CI와 릴리즈 +게시 자동화는 이 저장소에 포함되어 있지 않습니다. -GitHub Actions는 필요한 작업만 수행합니다. +## 지속적 통합 -- **Cross-platform CI**(`.github/workflows/ci.yml`)는 런타임, 테스트, 패키지, 스크립트, - TypeScript, 워크플로 파일이 바뀐 pull request와 `main` push에서 실행됩니다. Bun matrix는 Linux, - Windows, macOS에서 install, typecheck, tests, privacy scan, release helper build smoke, GUI build, - `ocx help`를 검사합니다. 별도의 3개 OS lane은 번들 런타임을 사용해 Bun을 따로 설치하지 않아도 - npm global install이 동작하는지 확인합니다. -- **Release**(`.github/workflows/release.yml`)는 수동으로 실행합니다. 두 번째 전체 CI 파이프라인이 - 아니며, dry-run이나 publish 전에 정확한 릴리즈 커밋(`GITHUB_SHA`)에서 Cross-platform CI가 - 성공했는지 확인합니다. +모든 pull request와 `main`으로의 모든 push에는 자동 검사가 **하나** 있습니다: **`ci`** +(`.github/workflows/ci.yml`). 일반 기여에 필요한 자동화는 이것뿐입니다. -릴리즈에는 helper를 사용하세요. +저장소 관리자는 보호 규칙이 의도한 관리 작업을 막을 때 GitHub ruleset **Always-allow** +bypass를 사용할 수 있습니다. 관리자 복구와 예외 유지보수용이며, 기여자 작업의 리뷰를 +대체하지 않습니다. -```bash -bun run release <version> # 버전 bump를 commit/push, publish workflow는 기본 dry-run -bun run release <version> --publish # CI-gated dry-run을 확인한 뒤 실제 publish -bun run release:watch # 가장 최근 Release workflow run 감시 -``` - -## 브랜치 +## 브랜치와 pull request -- `dev` — 유일한 통합 대상. 모든 PR을 여기로 올립니다. -- `main` — 릴리즈 전용. `dev`에서 메인테이너가 승격시킬 때만 움직이며, 기능 PR을 직접 - 올리지 않습니다. -- `preview` — 프리릴리즈 트레인. +- **`main`이 유일한 default/통합/PR 대상입니다.** 기능·수정 PR은 `main`으로 여세요. +- 현재 **`main` tip**에서 브랜치를 따세요. +- 설명에는 무엇을 왜 바꿨는지와 검증 방법(실행한 명령과 결과)을 적으세요. 비어 있거나 + placeholder만 있는 설명은 리뷰 준비가 아닙니다. +- 대시보드 UI를 건드리면 설명에 스크린샷을 넣으세요. +- 동작 변경에는 해당 서브시스템 기존 테스트 근처에 집중 회귀 테스트가 필요합니다. 공유 + 라우팅/어댑터/설정/서버 변경은 전체 suite를 통과해야 합니다. -Go 네이티브 포트를 담당했던 `dev2-go`는 정리했고, 두 라인을 동시에 유지하던 정책도 -함께 끝났습니다. 히스토리는 -[lidge-jun/opencodex-go-archive](https://github.com/lidge-jun/opencodex-go-archive)에 -읽기 전용으로 남아 있습니다. 지금은 `dev`의 Bun 네이티브 TypeScript가 단일 런타임입니다. +`main`의 Bun 네이티브 TypeScript가 단일 런타임 라인입니다. -리베이스 PR은 환영합니다. 오래된 브랜치를 현재 head 위로 리베이스하는 것은 잡음이 아니라 -정상적인 기여입니다. 설명란에 출처 커밋을 적어주세요. +리베이스 PR은 환영합니다. 오래된 브랜치를 현재 head로 맞추는 것은 평범한 유지보수입니다. +설명에 출처 커밋을 적어 주세요. ## 컨벤션 @@ -102,7 +88,7 @@ Go 네이티브 포트를 담당했던 `dev2-go`는 정리했고, 두 라인을 - **비동기 오류는 경계에서 처리** — 사이드카는 요청 경로로 오류를 던지지 않고 적절한 marker로 저하됩니다. - **Structure SOT** — 현재 유지보수 불변식은 `structure/`에 둡니다. 공개 사용자 워크플로는 - `docs-site/`, 과거 조사/진단 기록은 `docs/`에 둡니다. + `docs-site/`, 유지 관리되는 기술·구현 노트는 `docs/`에 둡니다. - **export 보존** — 다른 모듈이 의존할 수 있습니다. ## 카탈로그에 프로바이더 추가하기 @@ -123,7 +109,7 @@ Go 네이티브 포트를 담당했던 `dev2-go`는 정리했고, 두 라인을 }, ``` -`src/providers/derive.ts`는 이 항목을 `ocx init`, `ocx provider`, 대시보드 preset, API 키 로그인, +`src/providers/derive.ts`는 이 항목을 `ccx init`, `ccx provider`, 대시보드 preset, API 키 로그인, OAuth 설정 seed에 공급합니다. `enrichProviderFromCatalog()`는 모델 메타데이터와 capability 분류를 저장할 프로바이더 설정에 복사합니다. OAuth 프로토콜 구현은 여전히 `src/oauth/`에 있습니다. 레지스트리 메타데이터만 추가해서 OAuth flow가 생기지는 않습니다. @@ -141,4 +127,4 @@ factory라면 `src/index.ts`에서도 export합니다. 변경을 증명하는 가장 좁은 명령부터 실행하세요. 타입은 `bun run typecheck`, 동작은 집중된 `bun test tests/<name>.test.ts` 또는 런타임 probe로 확인한 뒤 영향 범위에 맞는 넓은 gate를 -실행합니다. opencodex는 큰 batch보다 작고 검증 가능한 commit을 선호합니다. +실행합니다. CodexCommander는 큰 batch보다 작고 검증 가능한 commit을 선호합니다. diff --git a/docs-site/src/content/docs/ko/getting-started/for-agents.md b/docs-site/src/content/docs/ko/getting-started/for-agents.md index 4f8f87fb47..2924ca9d7c 100644 --- a/docs-site/src/content/docs/ko/getting-started/for-agents.md +++ b/docs-site/src/content/docs/ko/getting-started/for-agents.md @@ -1,67 +1,70 @@ --- title: 에이전트용 빠른 시작 -description: 사용자의 동의 경계를 넘지 않으면서 에이전트가 주도하는 터미널이나 스크립트에서 opencodex를 설치하고 운용합니다. +description: 사용자의 동의 경계를 넘지 않으면서 에이전트가 주도하는 터미널이나 스크립트에서 CodexCommander를 설치하고 운용합니다. --- 이 페이지는 터미널에서 작업하는 AI 에이전트나 스크립트 사용자를 위한 것입니다. 명령, 종료 상태, 안전한 헤드리스 운영에 집중합니다. 사람이 따라 하는 안내가 필요하면 [Quickstart](/getting-started/quickstart/)를 사용하세요. 대시보드는 대화형 설정에도 계속 사용할 수 있습니다. 자세한 내용은 [Web Dashboard](/guides/web-dashboard/)를 참고하세요. -## opencodex 설정하기 +## CodexCommander 설정하기 -배포된 패키지를 설치하고 `ocx`가 `PATH`에 들어 있는지 확인합니다: +기존 소스 체크아웃을 사용합니다. 레지스트리 패키지는 현재 게시되어 있지 않습니다: ```bash -npm install -g @bitkyc08/opencodex -ocx --version +bun install +bun run build:gui +bun run src/cli/index.ts --version ``` 프록시를 실행하는 방법은 하나를 선택합니다: ```bash # Foreground: blocks this terminal until stopped. -ocx start +bun run src/cli/index.ts start # Background: installs or updates the service, then starts it. -ocx service +bun run src/cli/index.ts service ``` -대화형 터미널에서 `ocx init`를 실행합니다. `ocx start`가 포그라운드를 차지하고 있으면 두 번째 터미널을 사용합니다: +대화형 터미널에서 `ccx init`를 실행합니다. `ccx start`가 포그라운드를 차지하고 있으면 두 번째 터미널을 사용합니다: ```bash -ocx init +bun run src/cli/index.ts init ``` -이 마법사는 `$OPENCODEX_HOME/config.json`를 작성합니다(보통 `~/.opencodex/config.json`). 또한 프록시 주소를 Codex의 `config.toml`에 주입하고, 선택적 Codex 자동 시작 shim을 설치할 수 있습니다. `ocx init`는 프록시를 절대 시작하지 않습니다. 완전히 비대화형으로 설정하려면 아래처럼 마법사를 진행하지 말고 `ocx provider add`로 공급자를 구성하세요. +이후의 `ccx <args>`는 이 체크아웃에서 `bun run src/cli/index.ts <args>`로 실행할 수 있습니다. + +이 마법사는 `$CODEXCOMMANDER_HOME/config.json`를 작성합니다(보통 `~/.codexcommander/config.json`). 또한 프록시 주소를 Codex의 `config.toml`에 주입하고, 선택적 Codex 자동 시작 shim을 설치할 수 있습니다. `ccx init`는 프록시를 절대 시작하지 않습니다. 완전히 비대화형으로 설정하려면 아래처럼 마법사를 진행하지 말고 `ccx provider add`로 공급자를 구성하세요. ## 비대화형 설치 확인하기 스크립트와 에이전트 실행에서는 다음 읽기 전용 점검을 사용합니다: ```bash -ocx status -ocx doctor -ocx health --json +ccx status +ccx doctor +ccx health --json ``` -`ocx status`는 프록시와 서비스 상태를 보고합니다. `ocx doctor`는 로컬 환경, 네트워크, Codex 런타임, 계정 상태 문제를 진단합니다. `ocx health`는 프록시가 건강하면 `0`, 그렇지 않으면 `1`로 종료합니다. `--json`은 구조화된 출력을 반환합니다. +`ccx status`는 프록시와 서비스 상태를 보고합니다. `ccx doctor`는 로컬 환경, 네트워크, Codex 런타임, 계정 상태 문제를 진단합니다. `ccx health`는 프록시가 건강하면 `0`, 그렇지 않으면 `1`로 종료합니다. `--json`은 구조화된 출력을 반환합니다. -`ocx combo set`처럼 관리 API를 사용하는 명령은 실행 중인 라이브 프록시에 접속합니다. 실행 중인 라이브 프록시를 찾을 수 없거나 API에 접근할 수 없으면 CLI는 이를 `503` 실패로 처리하고 0이 아닌 상태로 종료합니다. 다시 시도하기 전에 포그라운드 프록시나 백그라운드 서비스를 시작하세요. 전체 명령과 엔드포인트 범위는 [CLI reference](/reference/cli/)와 [Management API](/reference/management-api/)를 참고하세요. +`ccx combo set`처럼 관리 API를 사용하는 명령은 실행 중인 라이브 프록시에 접속합니다. 실행 중인 라이브 프록시를 찾을 수 없거나 API에 접근할 수 없으면 CLI는 이를 `503` 실패로 처리하고 0이 아닌 상태로 종료합니다. 다시 시도하기 전에 포그라운드 프록시나 백그라운드 서비스를 시작하세요. 전체 명령과 엔드포인트 범위는 [CLI reference](/reference/cli/)와 [Management API](/reference/management-api/)를 참고하세요. ## 대시보드 없이 공급자와 콤보 추가하기 레지스트리의 공급자는 이름으로 추가할 수 있습니다. 예를 들어 다음 명령은 Anthropic API 키 프리셋을 추가하고 기본 공급자로 설정합니다: ```bash -ocx provider add anthropic-apikey \ +ccx provider add anthropic-apikey \ --api-key "$ANTHROPIC_API_KEY" \ --set-default ``` -`ocx provider add`는 로컬 설정을 기록합니다. 라이브 프록시가 이미 실행 중이고 모델을 즉시 Codex와 동기화하려면 `--sync`를 추가하세요. 그렇지 않으면 나중에 `ocx sync`를 실행하면 됩니다. 레지스트리에 없는 커스텀 공급자는 `--adapter`와 `--base-url`이 모두 필요합니다. +`ccx provider add`는 로컬 설정을 기록합니다. 라이브 프록시가 이미 실행 중이고 모델을 즉시 Codex와 동기화하려면 `--sync`를 추가하세요. 그렇지 않으면 나중에 `ccx sync`를 실행하면 됩니다. 레지스트리에 없는 커스텀 공급자는 `--adapter`와 `--base-url`이 모두 필요합니다. 모든 대상 공급자가 설정되고 프록시가 실행되면 failover 콤보를 만듭니다: ```bash -ocx combo set main \ +ccx combo set main \ --targets anthropic/claude-opus-4-8,openai/gpt-5.6-sol \ --strategy failover ``` @@ -70,11 +73,11 @@ ocx combo set main \ ## 원격 및 LAN 바인드 -기본 루프백 바인드에는 API 토큰이 필요하지 않습니다. `0.0.0.0` 같은 비루프백 바인드는 `OPENCODEX_API_AUTH_TOKEN`이 필요하며, 이 토큰이 없으면 프록시가 시작을 거부합니다. `ocx start`를 실행하기 전에, 또는 `ocx service install`을 실행하기 전에 변수를 설정해야 서비스가 이를 전달받습니다: +기본 루프백 바인드에는 API 토큰이 필요하지 않습니다. `0.0.0.0` 같은 비루프백 바인드는 `CODEXCOMMANDER_API_AUTH_TOKEN`이 필요하며, 이 토큰이 없으면 프록시가 시작을 거부합니다. `ccx start`를 실행하기 전에, 또는 `ccx service install`을 실행하기 전에 변수를 설정해야 서비스가 이를 전달받습니다: ```bash -export OPENCODEX_API_AUTH_TOKEN="your-secret-token" -ocx service install +export CODEXCOMMANDER_API_AUTH_TOKEN="your-secret-token" +ccx service install ``` -그다음 클라이언트는 관리 요청과 모델 요청을 인증해야 합니다. 로컬 머신 밖으로 opencodex를 노출하기 전에 원격 액세스 규칙은 [Configuration](/reference/configuration/)에서 확인하세요. +그다음 클라이언트는 관리 요청과 모델 요청을 인증해야 합니다. 로컬 머신 밖으로 CodexCommander를 노출하기 전에 원격 액세스 규칙은 [Configuration](/reference/configuration/)에서 확인하세요. diff --git a/docs-site/src/content/docs/ko/getting-started/how-it-works.mdx b/docs-site/src/content/docs/ko/getting-started/how-it-works.mdx index 8a8e55f15f..f42a5b69ba 100644 --- a/docs-site/src/content/docs/ko/getting-started/how-it-works.mdx +++ b/docs-site/src/content/docs/ko/getting-started/how-it-works.mdx @@ -1,21 +1,21 @@ --- title: 작동 방식 -description: opencodex의 전체 요청 수명 주기 — parse, route, adapt, bridge, stream. +description: CodexCommander의 전체 요청 수명 주기 — parse, route, adapt, bridge, stream. --- import { Steps } from '@astrojs/starlight/components'; -Codex는 OpenAI **Responses API**를 사용합니다. opencodex는 HTTP와 Server-Sent Events로 들어오는 +Codex는 OpenAI **Responses API**를 사용합니다. CodexCommander는 HTTP와 Server-Sent Events로 들어오는 `POST /v1/responses` 요청을 받으며, 같은 경로의 WebSocket upgrade도 선택적으로 지원합니다. 요청은 프로바이더의 wire 포맷으로, 응답은 다시 Responses 이벤트로 바뀌므로 Codex 쪽에서는 OpenAI가 아닌 모델과 통신한다는 사실을 알 필요가 없습니다. ``` - ┌──────────────────────────── opencodex ────────────────────────────┐ + ┌──────────────────────────── CodexCommander ────────────────────────────┐ │ │ Codex ──▶ │ parser ──▶ router ──▶ [vision] ──▶ adapter ──▶ provider │ ──▶ Codex (/v1/ │ │ │ │ │ │ │ (SSE / WS) - responses)│ OcxParsed provider describe buildRequest parseStream │ + responses)│ CodexCommanderParsed provider describe buildRequest parseStream │ │ Request +adapter images + fetch AdapterEvent[] │ │ │ │ │ │ [web-search loop] bridge ─▶ SSE │ @@ -26,7 +26,7 @@ OpenAI가 아닌 모델과 통신한다는 사실을 알 필요가 없습니다. ## Codex 인증 계정 선택 -선택된 프로바이더가 ChatGPT/Codex 패스스루일 때, opencodex는 업스트림으로 전달하기 전에 저장된 +선택된 프로바이더가 ChatGPT/Codex 패스스루일 때, CodexCommander는 업스트림으로 전달하기 전에 저장된 pool 계정을 고를 수 있습니다. 규칙은 의도적으로 둘로 나뉩니다. - **기존 thread id는 같은 계정을 유지합니다.** thread는 시작할 때 선택된 account generation에 @@ -52,7 +52,7 @@ reasoning effort를 알려 줍니다. v2 요청은 Codex가 제공하는 멀티 <Steps> 1. **Parse** — `responses/parser.ts`가 Zod 스키마(`responses/schema.ts`)로 요청을 검증하고 - 이를 내부 `OcxParsedRequest`로 변환합니다: 시스템 프롬프트, 정규화된 메시지 목록 + 이를 내부 `CodexCommanderParsedRequest`로 변환합니다: 시스템 프롬프트, 정규화된 메시지 목록 (텍스트, 이미지, tool call, tool result), tool 정의, 생성 옵션, 그리고 `_webSearch`(호스팅 웹 검색 요청됨)와 `_structuredOutput`(JSON 스키마 / JSON-object `text.format`이 설정됨) 같은 기능 플래그. 이미지는 실제 콘텐츠 파트로 보존되며, @@ -63,14 +63,14 @@ reasoning effort를 알려 줍니다. v2 요청은 Codex가 제공하는 멀티 (`claude-`, `gpt-`, `o1-`/`o3-`/`o4-`, `llama-`/`mixtral-`/`gemma-`) → 프로바이더의 `models[]` → `defaultProvider` 폴백. [모델 라우팅](/ko/guides/model-routing/)을 참고하세요. -3. **Authenticate** — `oauth` 프로바이더의 경우 opencodex는 현재 access 토큰을 bearer 키로 - 해석하고 자격 증명 소유권을 따릅니다. OpenCodex 소유 자격 증명은 자동 갱신되지만, 연결된 +3. **Authenticate** — `oauth` 프로바이더의 경우 CodexCommander는 현재 access 토큰을 bearer 키로 + 해석하고 자격 증명 소유권을 따릅니다. CodexCommander 소유 자격 증명은 자동 갱신되지만, 연결된 Grok/Kimi 네이티브 CLI 세대는 다시 읽어 읽기 전용으로 사용합니다. ChatGPT/Codex pool 계정에서는 `codex/auth-context.ts`가 먼저 계정을 해석하고, 필요한 pool credential이 없으면 passthrough adapter가 계속 진행하지 않습니다. 4. **Vision sidecar(선택)** — 라우팅된 모델이 `provider.noVisionModels`에 나열되어 있고 - 요청에 이미지가 포함된 경우, opencodex는 설정된 ChatGPT vision sidecar로 각 이미지를 설명한 + 요청에 이미지가 포함된 경우, CodexCommander는 설정된 ChatGPT vision sidecar로 각 이미지를 설명한 뒤 텍스트로 치환합니다. 덕분에 텍스트 전용 모델도 해당 이미지에 대해 추론할 수 있습니다. [Sidecar](/ko/guides/sidecars/)를 참고하세요. @@ -79,7 +79,7 @@ reasoning effort를 알려 줍니다. v2 요청은 Codex가 제공하는 멀티 프로바이더 응답은 `AdapterEvent`로 변환하지 않고 그대로 전달합니다. 6. **Web-search sidecar(선택)** — Codex가 호스팅 `web_search`를 활성화했지만 라우팅된 모델이 - OpenAI가 아닌 경우, opencodex는 합성 `web_search` function tool을 노출하고 모델을 작은 + OpenAI가 아닌 경우, CodexCommander는 합성 `web_search` function tool을 노출하고 모델을 작은 에이전트 루프로 실행하면서, 기본값인 `gpt-5.6-luna`를 ChatGPT 로그인으로 호출해 실제 검색을 수행하고 그 결과를 tool result로 다시 주입합니다. @@ -88,7 +88,7 @@ reasoning effort를 알려 줍니다. v2 요청은 Codex가 제공하는 멀티 라우팅 모델에서는 도구 없이 요약을 실행해 Codex가 요구하는 대체 대화 기록 형식을 반환합니다. 8. **Adapt** — 그 외의 경우, 선택된 adapter의 `buildRequest()`가 프로바이더의 네이티브 - 포맷으로 업스트림 HTTP 요청(URL, 헤더, 본문)을 생성하고, opencodex가 이를 `fetch`합니다. + 포맷으로 업스트림 HTTP 요청(URL, 헤더, 본문)을 생성하고, CodexCommander가 이를 `fetch`합니다. 9. **Bridge** — adapter의 `parseStream()`(또는 `parseResponse()`)이 내부 `AdapterEvent`를 생성합니다(텍스트, reasoning, tool-call start/delta/end, done, error). `bridge.ts`는 그 스트림을 @@ -98,9 +98,9 @@ reasoning effort를 알려 줍니다. v2 요청은 Codex가 제공하는 멀티 </Steps> -## 왜 Codex 포크가 아니라 프록시인가? +## 프로토콜 프록시를 사용하는 이유 -Codex는 Responses API를 하드코딩하고 있습니다. opencodex는 프로토콜 경계에서 변환을 수행함으로써 +Codex는 Responses API를 하드코딩하고 있습니다. CodexCommander는 프로토콜 경계에서 변환을 수행함으로써 Codex **CLI, App, SDK**를 변경 없이 그대로 지원하고, Codex 업데이트에도 영향을 받지 않으며, Codex 자체를 건드리지 않고 요청마다 프로바이더를 전환할 수 있게 합니다. 이 변환은 양방향이며 스트리밍에 충실합니다: reasoning 요약, MCP tool 네임스페이스, freeform(`apply_patch`) tool, diff --git a/docs-site/src/content/docs/ko/getting-started/installation.md b/docs-site/src/content/docs/ko/getting-started/installation.md index b70381c3bc..88b0b85cda 100644 --- a/docs-site/src/content/docs/ko/getting-started/installation.md +++ b/docs-site/src/content/docs/ko/getting-started/installation.md @@ -1,9 +1,9 @@ --- title: 설치 -description: opencodex(ocx) 프록시와 사전 요구 사항을 설치하고, 정상 실행되는지 확인합니다. +description: CodexCommander(ccx) 프록시와 사전 요구 사항을 설치하고, 정상 실행되는지 확인합니다. --- -opencodex를 설치하면 같은 실행 파일을 가리키는 `ocx`와 `opencodex` 명령이 함께 제공됩니다. +패키징되거나 로컬로 링크된 빌드에서는 `ccx`와 `codexcommander`라는 두 동등한 명령을 제공합니다. 둘 다 Bun 기반의 작은 로컬 HTTP 서버를 실행합니다. 모델 요청은 라우팅으로 선택된 프로바이더에 전달되며, 필요할 때 vision 및 웹 검색 sidecar가 ChatGPT 로그인을 사용할 수도 있습니다. @@ -11,85 +11,58 @@ opencodex를 설치하면 같은 실행 파일을 가리키는 `ocx`와 `opencod | 요구 사항 | 이유 | | --- | --- | -| **[Node](https://nodejs.org) ≥ 18** | `ocx`는 Bun 런타임에서 실행되지만, 런타임이 `npm install` 시 자동으로 번들되므로 Bun을 직접 설치할 필요가 **없습니다**. | -| **[OpenAI Codex](https://openai.com/codex)**(CLI, App, 또는 SDK) | opencodex가 앞단에 위치하는 클라이언트입니다. opencodex는 `$CODEX_HOME/config.toml`(기본값 `~/.codex/config.toml`)에 기록합니다. | +| **[Bun](https://bun.sh)** | 소스 런타임과 저장소 스크립트는 Bun에서 직접 실행됩니다. | +| **[OpenAI Codex](https://openai.com/codex)**(CLI, App, 또는 SDK) | CodexCommander가 앞단에 위치하는 클라이언트입니다. CodexCommander는 `$CODEX_HOME/config.toml`(기본값 `~/.codex/config.toml`)에 기록합니다. | | 프로바이더 계정 또는 API 키 | Anthropic, xAI, Kimi, Ollama Cloud, OpenRouter, OpenAI API 키, OpenAI 호환 엔드포인트, 또는 ChatGPT 로그인. | -## 설치 +## 소스 체크아웃 실행 ```bash -npm install -g @bitkyc08/opencodex -``` - -:::note[npm이 bun postinstall을 차단했다면?] -최신 npm은 bun의 postinstall 스크립트를 차단할 수 있습니다(`npm warn -install-scripts ... blocked because they are not covered by allowScripts`). -이 경우 번들 Bun 런타임이 준비되지 않으므로 bun 스크립트를 허용해서 -재설치하세요. npm 경고의 축약 명령에는 패키지 이름이 빠져 있어 현재 -디렉터리를 재설치하게 되니, 항상 패키지 이름을 명시해야 합니다: - -```bash -npm install -g --allow-scripts=bun @bitkyc08/opencodex - -# 처음에 sudo로 설치했다면 sudo를 유지하세요: -sudo npm install -g --allow-scripts=bun @bitkyc08/opencodex -``` -::: - -두 명령이 모두 `PATH`에 잡히는지 확인합니다: - -```bash -ocx --version -opencodex --version +bun install +bun run build:gui +bun run src/cli/index.ts start ``` -### 배포 채널 - -안정화 채널인 `latest`에도 ChatGPT, OpenAI API 키, OpenRouter, 실험 단계의 Cursor 경로를 위한 -GPT-5.6 Sol/Terra/Luna 카탈로그 정보가 이미 들어 있습니다. 다만 모델 사용 권한까지 생기는 것은 -아닙니다. 아직 정식 배포되지 않은 opencodex 빌드를 시험할 때만 preview 채널을 사용하세요: +레지스트리 패키지는 현재 게시되어 있지 않습니다. 이 체크아웃에서는 `ccx <args>`를 +`bun run src/cli/index.ts <args>`로 바꿔 실행합니다. 다른 터미널에서 런타임을 확인하세요: ```bash -npm install -g @bitkyc08/opencodex@preview -ocx update --tag preview +bun run src/cli/index.ts --version ``` -## 소스에서 실행 +## 개발 모드 -opencodex 자체를 직접 수정하며 작업하려면: +UI를 편집할 때는 프록시와 대시보드를 별도 프로세스로 실행하세요: ```bash -git clone https://github.com/pavelhov/opencodex.git -cd opencodex -bun install bun run dev:proxy # 개발 모드로 프록시 API 시작 (src/cli/index.ts start) bun run dev:gui # 대시보드 dev 서버 시작 (다른 터미널) ``` -`bun run dev`는 `bun run dev:proxy`의 별칭으로 남아 있습니다. 프록시 API는 `/healthz`, +`bun run dev`는 `bun run dev:proxy`의 별칭입니다. 프록시 API는 `/healthz`, `/v1/responses`, `/api/*`를 노출하며, `GET /`는 `bun run build:gui`가 `gui/dist`를 생성한 뒤에만 패키징된 대시보드를 서빙합니다. 대시보드를 수정할 때는 `bun run dev:gui`로 프론트엔드를 -별도로 실행하세요. +별도로 실행하세요. macOS 컴패니언은 같은 체크아웃에서 `bun run test:macos && bun run build:macos`로 빌드하며, 소스 빌드는 `dist/macos/CodexCommander.app`에 생성됩니다. ## 생성되는 항목 -opencodex 상태 파일은 `$OPENCODEX_HOME`(기본값 `~/.opencodex`) 아래에, Codex 연동 파일은 +CodexCommander 상태 파일은 `$CODEXCOMMANDER_HOME`(기본값 `~/.codexcommander`) 아래에, Codex 연동 파일은 `$CODEX_HOME`(기본값 `~/.codex`) 아래에 저장됩니다. | 경로 | 용도 | | --- | --- | -| `$OPENCODEX_HOME/config.json` | 프로바이더, 기본 프로바이더, 포트, 옵션. | -| `$OPENCODEX_HOME/ocx.pid` | 실행 중인 프록시의 PID(단일 인스턴스 가드). | -| `$OPENCODEX_HOME/runtime-port.json` | 자동으로 고른 대체 포트를 포함한 현재 PID, 호스트명, 포트. | -| `$OPENCODEX_HOME/auth.json` | 저장된 OAuth 자격 증명(`ocx login` 시). | -| `$OPENCODEX_HOME/catalog-backup*.json` | opencodex가 수정하기 전에 만든 Codex 모델 카탈로그 백업. | -| `$CODEX_HOME/config.toml` | 로컬 전용 구성에서는 opencodex가 관리하는 루트 `openai_base_url`을 추가합니다. 로컬이 아닌 주소에 바인딩할 때는 Codex가 API 인증 헤더를 보낼 수 있도록 `model_provider = "opencodex"`와 `[model_providers.opencodex]`를 사용합니다. | -| `$CODEX_HOME/opencodex.config.toml` | 기본 Codex 설정과 함께 생성되는 참고용 fallback 프로필. | -| `$CODEX_HOME/opencodex-catalog.json` | Codex가 사용하는 네이티브 및 라우팅 모델 카탈로그. | +| `$CODEXCOMMANDER_HOME/config.json` | 프로바이더, 기본 프로바이더, 포트, 옵션. | +| `$CODEXCOMMANDER_HOME/codexcommander.pid` | 실행 중인 프록시의 PID(단일 인스턴스 가드). | +| `$CODEXCOMMANDER_HOME/runtime-port.json` | 자동으로 고른 대체 포트를 포함한 현재 PID, 호스트명, 포트. | +| `$CODEXCOMMANDER_HOME/auth.json` | 저장된 OAuth 자격 증명(`ccx login` 시). | +| `$CODEXCOMMANDER_HOME/catalog-backup-<catalog-id>.json` | CodexCommander가 수정하기 전에 만든 Codex 모델 카탈로그 백업. | +| `$CODEX_HOME/config.toml` | 로컬 전용 구성에서는 CodexCommander가 관리하는 루트 `openai_base_url`을 추가합니다. 로컬이 아닌 주소에 바인딩할 때는 Codex가 API 인증 헤더를 보낼 수 있도록 `model_provider = "codexcommander"`와 `[model_providers.codexcommander]`를 사용합니다. | +| `$CODEX_HOME/codexcommander.config.toml` | 기본 Codex 설정과 함께 생성되는 참고용 fallback 프로필. | +| `$CODEX_HOME/codexcommander-catalog.json` | Codex가 사용하는 네이티브 및 라우팅 모델 카탈로그. | :::note -opencodex는 절대 Codex 설정을 삭제하지 않습니다. 모든 주입은 되돌릴 수 있습니다 — `ocx stop`, `ocx restore`, -또는 `ocx eject`는 opencodex가 추가한 줄만 정확히 제거하고 네이티브 Codex를 복원합니다. +CodexCommander는 절대 Codex 설정을 삭제하지 않습니다. 모든 주입은 되돌릴 수 있습니다 — `ccx stop`, `ccx restore`, +또는 `ccx eject`는 CodexCommander가 추가한 줄만 정확히 제거하고 네이티브 Codex를 복원합니다. ::: ## 다음 diff --git a/docs-site/src/content/docs/ko/getting-started/quickstart.md b/docs-site/src/content/docs/ko/getting-started/quickstart.md index fc4c14ae32..9d96b86eec 100644 --- a/docs-site/src/content/docs/ko/getting-started/quickstart.md +++ b/docs-site/src/content/docs/ko/getting-started/quickstart.md @@ -1,6 +1,6 @@ --- title: 빠른 시작 -description: 첫 프로바이더를 설정하고 명령어 세 개로 OpenAI Codex를 opencodex로 라우팅합니다. +description: 첫 프로바이더를 설정하고 명령어 세 개로 OpenAI Codex를 CodexCommander로 라우팅합니다. --- 이 가이드는 새로 설치한 상태에서 OpenAI가 아닌 모델로 Codex를 실행하기까지의 과정을 안내합니다. @@ -8,49 +8,49 @@ description: 첫 프로바이더를 설정하고 명령어 세 개로 OpenAI Cod ## 1. 설정 마법사 실행 ```bash -ocx init +ccx init ``` -`ocx init`은 다음 과정을 안내합니다: +`ccx init`은 다음 과정을 안내합니다: 1. **프로바이더 선택** — 내장 레지스트리 프리셋 76개 중 하나를 고르거나 `custom`을 선택해 base URL과 adapter를 직접 입력합니다. 2. **API 키** — 키를 붙여넣거나 `${ANTHROPIC_API_KEY}` 같은 환경 변수를 참조합니다. 3. **기본 모델** — 키, 로컬, custom 프로바이더에서는 프리셋을 그대로 쓰거나 모델 ID를 직접 입력합니다. 4. **프록시 포트** — 기본값은 `10100`입니다. -5. **Codex에 주입할까요?** — 일반적인 루프백 구성에서는 opencodex가 `$CODEX_HOME/config.toml`의 루트(`~/.codex/config.toml`이 기본값)에 `openai_base_url`을 추가해 Codex의 내장 `openai` 프로바이더가 프록시를 바라보게 합니다. 원격/LAN 바인딩에서는 API 인증 헤더를 포함한 전용 프로바이더 항목을 대신 사용합니다. -6. **자동 시작 shim을 설치할까요?** — 켜 두면 `codex`를 실행할 때 먼저 `ocx ensure`가 실행됩니다. +5. **Codex에 주입할까요?** — 일반적인 루프백 구성에서는 CodexCommander가 `$CODEX_HOME/config.toml`의 루트(`~/.codex/config.toml`이 기본값)에 `openai_base_url`을 추가해 Codex의 내장 `openai` 프로바이더가 프록시를 바라보게 합니다. 원격/LAN 바인딩에서는 API 인증 헤더를 포함한 전용 프로바이더 항목을 대신 사용합니다. +6. **자동 시작 shim을 설치할까요?** — 켜 두면 `codex`를 실행할 때 먼저 `ccx ensure`가 실행됩니다. -결과는 `$OPENCODEX_HOME/config.json`(기본값 `~/.opencodex/config.json`)에 저장됩니다. +결과는 `$CODEXCOMMANDER_HOME/config.json`(기본값 `~/.codexcommander/config.json`)에 저장됩니다. :::note[GPT-5.6 적용 항목] -현재 안정 버전은 ChatGPT 패스스루, OpenAI API 키, OpenRouter, 실험 단계의 Cursor adapter에 GPT-5.6 Sol/Terra/Luna를 기본으로 넣습니다. 이 항목들은 해당 업스트림 계정에 접근 권한이 있을 때만 동작합니다. OpenAI API 키와 OpenRouter 프리셋은 사용 가능한 컨텍스트 창을 372,000토큰으로 제공합니다. Cursor는 자체 adapter 메타데이터를 유지합니다. +현재 소스 트리는 ChatGPT 패스스루, OpenAI API 키, OpenRouter, 실험 단계의 Cursor adapter에 GPT-5.6 Sol/Terra/Luna를 기본으로 넣습니다. 이 항목들은 해당 업스트림 계정에 접근 권한이 있을 때만 동작합니다. OpenAI API 키와 OpenRouter 프리셋은 사용 가능한 컨텍스트 창을 372,000토큰으로 제공합니다. Cursor는 자체 adapter 메타데이터를 유지합니다. ::: ## 2. 프록시 시작 ```bash -ocx start # defaults to port 10100 -ocx start --port 8080 +ccx start # defaults to port 10100 +ccx start --port 8080 ``` -시작하면 opencodex는: +시작하면 CodexCommander는: -- PID를 `~/.opencodex/ocx.pid`에 기록하고 중복 시작을 거부하며, +- PID를 `~/.codexcommander/codexcommander.pid`에 기록하고 중복 시작을 거부하며, - 프로바이더가 지원하는 경우 실시간 모델을 찾아 네이티브와 라우팅 항목을 **Codex 모델 카탈로그에 동기화**하고, - `http://localhost:<port>/v1`에서 수신 대기합니다. -요청한 포트가 이미 사용 중이면 `ocx start`가 빈 포트를 고르고, 그 값을 `runtime-port.json`에 기록한 뒤 Codex가 실시간 리스너를 쓰도록 갱신합니다. +요청한 포트가 이미 사용 중이면 `ccx start`가 빈 포트를 고르고, 그 값을 `runtime-port.json`에 기록한 뒤 Codex가 실시간 리스너를 쓰도록 갱신합니다. 확인: ```bash -ocx status -ocx gui # open the dashboard on the live port +ccx status +ccx gui # open the dashboard on the live port ``` ## 3. Codex 사용 -이제 Codex는 opencodex와 투명하게 연결됩니다: +이제 Codex는 CodexCommander와 투명하게 연결됩니다: ```bash codex "Refactor this function for readability" @@ -65,16 +65,16 @@ codex -m "ollama-cloud/glm-5.2" "Write a SQL migration" ## Sub-agent 모델 선택(선택 사항) -새 구성에는 Codex의 sub-agent 선택기에 네이티브 모델 다섯 개인 `gpt-5.5`, `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna`, `gpt-5.4-mini`가 표시됩니다. `ocx gui`를 열어 네이티브 또는 라우팅 모델을 최대 다섯 개까지 바꾸거나 순서를 다시 정할 수 있습니다. 대시보드에서는 선호하는 sub-agent 모델과 추론 강도도 설정할 수 있습니다. [Sub-agent Surface](/guides/sub-agent-surface/)에서 v1/base/v2를 고르고, guidance, 네이티브 기본값, fallback이 언제 적용되는지 확인합니다. +새 구성에는 Codex의 sub-agent 선택기에 네이티브 모델 다섯 개인 `gpt-5.5`, `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna`, `gpt-5.4-mini`가 표시됩니다. `ccx gui`를 열어 네이티브 또는 라우팅 모델을 최대 다섯 개까지 바꾸거나 순서를 다시 정할 수 있습니다. 대시보드에서는 선호하는 sub-agent 모델과 추론 강도도 설정할 수 있습니다. [Sub-agent Surface](/guides/sub-agent-surface/)에서 v1/base/v2를 고르고, guidance, 네이티브 기본값, fallback이 언제 적용되는지 확인합니다. ## 키를 붙여넣는 대신 로그인하기 -일부 프로바이더는 실제 계정 로그인을 지원합니다. OpenCodex 소유 OAuth 자격 증명은 자동 +일부 프로바이더는 실제 계정 로그인을 지원합니다. CodexCommander 소유 OAuth 자격 증명은 자동 갱신되며, 연결된 Grok/Kimi 네이티브 CLI 세션은 CLI 소유로 유지됩니다: ```bash -ocx login xai # or: anthropic, kimi, kiro, google-antigravity, cursor -ocx logout xai +ccx login xai # or: anthropic, kimi, kiro, google-antigravity, cursor +ccx logout xai ``` OpenAI 자체는 **키가 필요 없습니다** — 기본 프로바이더가 기존 `codex login` 자격 증명을 그대로 전달합니다([Providers](/guides/providers/) 참고). @@ -82,9 +82,9 @@ OpenAI 자체는 **키가 필요 없습니다** — 기본 프로바이더가 ## 중지 및 복원 ```bash -ocx stop # stop the proxy and restore native Codex -ocx restore # restore native Codex without stopping (alias: ocx eject) -ocx restore back # route Codex through the still-running proxy again +ccx stop # stop the proxy and restore native Codex +ccx restore # restore native Codex without stopping (alias: ccx eject) +ccx restore back # route Codex through the still-running proxy again ``` ## 다음 diff --git a/docs-site/src/content/docs/ko/guides/claude-code.md b/docs-site/src/content/docs/ko/guides/claude-code.md index 665c350b02..e2e6b13730 100644 --- a/docs-site/src/content/docs/ko/guides/claude-code.md +++ b/docs-site/src/content/docs/ko/guides/claude-code.md @@ -1,19 +1,19 @@ --- title: Claude Code 사용하기 -description: Claude Code에서 라우팅된 모든 모델을 사용해요. opencodex는 같은 포트에서 Anthropic Messages API와 게이트웨이 모델 검색을 제공해요. +description: Claude Code에서 라우팅된 모든 모델을 사용해요. CodexCommander는 같은 포트에서 Anthropic Messages API와 게이트웨이 모델 검색을 제공해요. --- -opencodex는 `/v1/responses`와 함께 `POST /v1/messages`(및 `count_tokens`)를 제공해요. 따라서 Claude +CodexCommander는 `/v1/responses`와 함께 `POST /v1/messages`(및 `count_tokens`)를 제공해요. 따라서 Claude Code에서 OAuth 로그인, 계정 풀, 키 장애 조치, 사이드카를 포함한 모든 라우팅 제공자를 별도의 인증 작업 없이 사용할 수 있어요. ## 빠른 시작 ```bash -ocx claude +ccx claude ``` -`ocx claude`는 프록시가 실행 중인지 확인한 다음, 환경을 연결해 Claude Code를 실행해요. +`ccx claude`는 프록시가 실행 중인지 확인한 다음, 환경을 연결해 Claude Code를 실행해요. | 변수 | 값 | | --- | --- | @@ -21,18 +21,15 @@ ocx claude | `ANTHROPIC_AUTH_TOKEN` | 프록시에 API 키가 필요할 때만 설정해요. 그 외에는 설정하지 않으므로 claude.ai 로그인(구독 + 커넥터)이 유지돼요 | | `CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY` | `1` (기본 `/model` 선택기의 모델 검색) | | `CLAUDE_CODE_AUTO_COMPACT_WINDOW` | 자동 컨텍스트 압축 임곗값(기본값 `350000`). 자동 컨텍스트가 켜져 있을 때만 주입해요 | -| `ANTHROPIC_MODEL` | `claudeCode.model` (선택 사항) | -| `ANTHROPIC_DEFAULT_HAIKU_MODEL` | `claudeCode.tierModels.haiku ?? claudeCode.smallFastModel` (선택 사항, 기존 `ANTHROPIC_SMALL_FAST_MODEL`도 지원) | -| `ANTHROPIC_DEFAULT_{OPUS,SONNET,FABLE}_MODEL` | `claudeCode.tierModels.*` (선택 사항) | -| `CLAUDE_CODE_ALWAYS_ENABLE_EFFORT` | `alwaysEnableEffort`가 켜져 있으면 `1` (조건부) | -| `CLAUDE_CODE_MAX_CONTEXT_TOKENS` / `DISABLE_COMPACT` | `maxContextTokens`가 설정된 경우 기존 컨텍스트 재정의 값 (조건부) | -직접 내보낸 변수가 항상 우선해요. 추가 인자는 그대로 전달돼요: `ocx claude -p "hello"`. +| `ANTHROPIC_DEFAULT_HAIKU_MODEL` / `ANTHROPIC_SMALL_FAST_MODEL` | 설정된 경우 `claudeCode.smallFastModel` | + +직접 내보낸 변수가 항상 우선해요. 추가 인자는 그대로 전달돼요: `ccx claude -p "hello"`. ## 인증 모드 Claude Code가 게이트웨이와 통신하려면 `ANTHROPIC_AUTH_TOKEN`에 토큰이 필요해요. 그런데 이 변수를 설정하면 claude.ai 로그인과 커넥터가 꺼져요. 둘 중 무엇이 필요한지는 지금 이 컴퓨터에 Claude -로그인이 있느냐에 달려 있고, 그건 opencodex가 직접 확인할 수 있어요. +로그인이 있느냐에 달려 있고, 그건 CodexCommander가 직접 확인할 수 있어요. **Claude → Claude Code**의 **인증 모드**를 기본값인 **자동**으로 두면 실행할 때마다 이렇게 판단해요. @@ -43,29 +40,29 @@ Claude Code가 게이트웨이와 통신하려면 `ANTHROPIC_AUTH_TOKEN`에 토 | 확인 실패(키체인 접근 거부, 파일 손상 등) | 구독으로 간주하고 경고를 출력해요. 읽기에 실패했다고 구독자를 프록시로 옮기지는 않아요 | 이 판단은 저장하지 않고 실행할 때마다 다시 계산해요. 그래서 로그인하거나 로그아웃하면 다음 -`ocx claude`부터 알아서 반영돼요. +`ccx claude`부터 알아서 반영돼요. 고정하고 싶다면 **구독** 또는 **프록시**를 직접 선택하세요. 직접 고른 값은 `claudeCode.authMode`에 저장되고, 이후에 로그인 상태가 바뀌어도 자동 감지가 이 값을 덮어쓰지 않아요. 다시 자동으로 -돌리면 판단을 opencodex에 넘겨요. +돌리면 판단을 CodexCommander에 넘겨요. -macOS의 자동 연결(`claudeCode.systemEnv`)도 같은 방식으로 판단하므로, `ocx` 없이 실행한 `claude`도 +macOS의 자동 연결(`claudeCode.systemEnv`)도 같은 방식으로 판단하므로, `ccx` 없이 실행한 `claude`도 동일하게 동작해요. 다만 이쪽은 프록시가 시작하거나 설정을 저장할 때 갱신되는 스냅숏이고, -`ocx claude`는 실행할 때마다 실시간으로 판단해요. +`ccx claude`는 실행할 때마다 실시간으로 판단해요. ## 시스템 환경 통합(macOS) -`claudeCode.systemEnv`를 `true`로 설정하면(기본값: **꺼짐**) `ocx start`가 `launchctl setenv`를 +`claudeCode.systemEnv`를 `true`로 설정하면(기본값: **꺼짐**) `ccx start`가 `launchctl setenv`를 사용해 `ANTHROPIC_BASE_URL`과 관련 Claude Code 환경 변수를 시스템 전체에 주입해요. 따라서 새 -터미널 창과 탭에서는 `ocx claude` 래퍼 없이 일반 `claude` 명령도 프록시를 거쳐요. 이미 열려 +터미널 창과 탭에서는 `ccx claude` 래퍼 없이 일반 `claude` 명령도 프록시를 거쳐요. 이미 열려 있는 셸에는 적용되지 않으므로 다시 열어야 해요. -`ocx stop`과 프록시 종료는 **주입된 키를 해제해요**. 이전 값을 복원하지는 않고 opencodex가 -주입한 키만 제거해요. 프록시는 `~/.opencodex/claude-env.sh`도 작성하고, `ocx start`는 이 파일을 +`ccx stop`과 프록시 종료는 **주입된 키를 해제해요**. 이전 값을 복원하지는 않고 CodexCommander가 +주입한 키만 제거해요. 프록시는 `~/.codexcommander/claude-env.sh`도 작성하고, `ccx start`는 이 파일을 자동으로 불러오는 `.zshrc` source hook을 설치해요. 설정에서 `claudeCode.systemEnv: false`로 지정하거나 GUI 토글로 끌 수 있어요. 이 기능은 macOS -전용이며, 다른 플랫폼에서는 `ocx claude`를 사용하세요. +전용이며, 다른 플랫폼에서는 `ccx claude`를 사용하세요. ## 네이티브 Claude 패스스루(구독 직접 연결) @@ -75,53 +72,39 @@ macOS의 자동 연결(`claudeCode.systemEnv`)도 같은 방식으로 판단하 네이티브 상태로 유지되고, 같은 세션에서 선택기 별칭을 써서 라우팅 모델도 계속 사용할 수 있어요. **헤더 처리:** hop-by-hop 헤더와 `host`, `content-length`, `accept-encoding`, -`x-opencodex-api-key`, `origin`은 전달 전에 제거해요. 그 밖의 헤더(`anthropic-beta`, +`x-codexcommander-api-key`, `origin`은 전달 전에 제거해요. 그 밖의 헤더(`anthropic-beta`, `anthropic-version` 포함)는 그대로 전달해요. 다음 네 조건을 **모두** 충족하면 패스스루가 작동해요. `nativePassthrough`가 `false`가 아니고, 모델 이름이 `claude` 또는 `anthropic`으로 시작하며, bearer 또는 `x-api-key`가 `sk-ant-`로 -시작하고, 별칭/모델 맵 해석 결과가 변경되지 않은 같은 모델이어야 해요. 그래서 `ocx claude`를 +시작하고, 별칭/모델 맵 해석 결과가 변경되지 않은 같은 모델이어야 해요. 그래서 `ccx claude`를 사용할 때 "claude.ai connectors are disabled" 경고도 더 이상 나타나지 않아요. `claudeCode.nativePassthrough: false`로 끌 수 있고, `claudeCode.anthropicBaseUrl`로 다른 주소를 지정할 수 있어요. ## /model 선택기("From gateway") -각 항목은 `gemini-3-pro (gemini)` 같은 정직한 표시 이름과 함께, 공식 ModelInfo 형태의 모델 -능력 정보(추론 강도 사다리, thinking 타입)를 실어 보냅니다 — Claude Desktop의 서드파티 -게이트웨이 모드가 추론 강도 선택 UI를 열 수 있게 하기 위해서입니다. 실제 Anthropic 모델은 -원래 id를 그대로 유지합니다. 합성된 2026 날짜는 내부 슬롯이며 출시일이 아닙니다. 구버전의 -해시 별칭과 `claude-ocx-<provider>--<model>` 별칭도 계속 해석됩니다. 컨텍스트가 1M인 모델에는 -`…[1m]` 행이 하나 더 생깁니다 — 이걸 고르면 Claude Code가 그 모델의 컨텍스트를 1M로 계산합니다 -(자동 요약 유지, 프록시가 표식을 떼고 라우팅). 선택하면 Claude Code의 -`settings.json` `model` 필드에 저장되고, 인바운드 요청에서 -별칭이 라우팅 모델로 되돌려집니다. 구버전 Claude Code에서는 `ANTHROPIC_MODEL`로 슬롯을 -지정하거나 `/model`에 라우팅 id를 직접 입력하세요 (Claude Code는 문자열을 그대로 통과시킵니다). - Claude Code 2.1.129 이상은 `GET /v1/models?limit=1000`에서 게이트웨이 모델을 찾아 기본 `/model` 선택기의 "From gateway" 항목에 표시해요. 선택기는 `claude` 또는 `anthropic`으로 시작하는 ID만 -받으므로, opencodex는 라우팅 모델을 안정적이고 되돌릴 수 있는 별칭으로 노출해요. +받으므로, CodexCommander는 라우팅 모델을 안정적이고 되돌릴 수 있는 별칭으로 노출해요. | 화면 | 형식 | 예시 | | --- | --- | --- | -| Claude Code CLI | `claude-ocx-<provider>--<model>` (plain) 또는 `claude-ocx2-…` (escaped) | `claude-ocx-native--gpt-5.6-sol` | +| Claude Code CLI | `claude-ccx2-<provider>--<model>` (plain) 또는 `claude-ccx2-…` (escaped) | `claude-ccx2-native--gpt-5.6-sol` | | Claude Desktop 3P | `claude-opus-4-8-<code>` (3자리 base36 해시) | `claude-opus-4-8-ncb` | 프록시는 요청마다 계열을 골라요. `?ids=cli` 또는 `?ids=desktop`이 우선하고, 지정하지 않으면 `claude-code/*` user-agent에는 읽기 쉬운 CLI 형식을, 다른 클라이언트에는 Desktop 해시를 -제공해요. 두 계열은 계속 디코딩할 수 있으므로 어느 형식이든 `settings.json`에 저장한 모델이 -계속 작동해요. +제공해요. 현재 두 계열은 실행 중인 별칭 레지스트리에서 해석돼요. Claude Desktop의 하단 선택기로 이미 실행 중인 3P 대화의 모델이 바뀌지 않는다면, 그 대화에서 -`/model <id>`를 사용하세요. OpenCodex는 선택기 상태를 따로 볼 수 없고 각 요청에 실린 모델 ID를 +`/model <id>`를 사용하세요. CodexCommander는 선택기 상태를 따로 볼 수 없고 각 요청에 실린 모델 ID를 라우팅해요. 적용 결과는 **Logs → requestedModel**에서 확인할 수 있어요. -**별칭 문법 규칙:** provider에는 `/`나 `--`를 넣을 수 없고 `native`와 같아도 안 돼요. `/`와 `~`가 -없는 plain model ID는 v1 접두사 `claude-ocx-…`를 유지해요. `/` 또는 `~`가 있는 model ID는 v2 -접두사 `claude-ocx2-…`로 만들고 이스케이프해요(`/` → `~s`, `~` → `~t`). 예: -`openrouter/anthropic/claude-opus-4-8` → `claude-ocx2-openrouter--anthropic~sclaude-opus-4-8`. -v1 별칭은 리터럴로 디코딩해요(예전 model ID에 들어 있던 두 글자 시퀀스 `~s` / `~t`도 그대로 보존). -v2 별칭은 이스케이프를 펼쳐요. 읽기 쉬운 형식으로 표현할 수 없는 라우트는 해시 별칭으로 대체해요. +**별칭 문법 규칙:** provider에는 `/`나 `--`를 넣을 수 없고 `native`와 같아도 안 돼요. 현재 +`claude-ccx2-…` 인코딩은 `/`를 `~s`, `~`를 `~t`로 이스케이프해요. 예: +`openrouter/anthropic/claude-opus-4-8` → `claude-ccx2-openrouter--anthropic~sclaude-opus-4-8`. +읽기 쉬운 형식으로 표현할 수 없는 라우트는 해시 별칭으로 대체해요. 모델 ID에는 `--`를 넣을 **수 있어요**(해석할 때 첫 번째 `--`만 기준으로 나눠요). `--`가 포함된 네이티브 슬러그는 해시 형식으로 대체해요. @@ -149,11 +132,10 @@ Claude Code는 알 수 없는 모델의 컨텍스트를 200k 토큰으로 계산 2. `CLAUDE_CODE_AUTO_COMPACT_WINDOW`(기본값 `350000`, 범위 `100000`–`1000000`)를 주입해 해당 지점에서 대화를 자동으로 요약해요. -설정 상태는 세 가지예요. +설정 상태는 두 가지예요. - **없음 / `true`:** 사용(기본값) - **`false`:** 사용 안 함. 표식도 붙지 않고 압축 창도 주입하지 않아요 -- **기존 `maxContextTokens` 설정:** 자동 컨텍스트를 자동으로 꺼요 Claude 페이지에서 압축 값을 조절할 수 있어요. **경고:** 모델의 실제 컨텍스트 창보다 크게 올리면 요약을 시작하기 전에 채팅 오류가 발생해요. @@ -164,38 +146,36 @@ Claude 페이지에서 압축 값을 조절할 수 있어요. **경고:** 모델 ### 실제 모델 환경 -`effectiveModelEnv`는 `ocx claude` / 시스템 환경 / 셸 파일이 주입할 슬롯 여섯 개를 계산해요. -`ANTHROPIC_MODEL`, 네 개의 `ANTHROPIC_DEFAULT_{OPUS,SONNET,HAIKU,FABLE}_MODEL`, 기존 -`ANTHROPIC_SMALL_FAST_MODEL`이에요. 실제 Haiku 값은 `tierModels.haiku ?? smallFastModel`이며, -두 Haiku 변수에 모두 들어가요. +`effectiveModelEnv`는 `ccx claude`, 시스템 환경, 셸 파일이 주입할 두 보조 슬롯 +`ANTHROPIC_DEFAULT_HAIKU_MODEL`과 `ANTHROPIC_SMALL_FAST_MODEL`을 계산해요. 둘 다 +`claudeCode.smallFastModel` 값을 사용해요. -`tierModels.haiku`와 `smallFastModel`이 모두 없으면 OpenCodex는 두 보조 모델 변수를 설정하지 않아요. 그러면 Claude Code가 네이티브 보조 모델(현재 Sonnet)을 선택하며, 네이티브 프로바이더 요금이 발생할 수 있어요. +`smallFastModel`이 없으면 CodexCommander는 두 보조 모델 변수를 설정하지 않아요. 그러면 Claude Code가 네이티브 보조 모델을 선택하며, 네이티브 프로바이더 요금이 발생할 수 있어요. ## 로스터 에이전트(injectAgents) -`ocx claude`와 시스템 환경 데몬은 추천 서브에이전트 로스터(Subagents 탭, 최대 5개 모델)와 -`ocx-self`를 `~/.claude/agents/ocx-*.md`에 동기화해요. +`ccx claude`와 시스템 환경 데몬은 추천 서브에이전트 로스터(Subagents 탭, 최대 5개 모델)와 +`ccx-self`를 `~/.claude/agents/ccx-*.md`에 동기화해요. -- **`ocx-self`**는 `/model` 선택기의 기본값을 고정하고, 값이 없으면 `claudeCode.model`을 사용해요. - 둘 다 없으면 만들지 않아요. 모델 상속은 사용하지 않아요. -- 각 에이전트 본문에는 `<!-- ocx-route: <model> -->` 지시문이 들어 있어요. 프록시는 이 지시문으로 +- **`ccx-self`**는 `/model` 선택기의 기본값을 고정해요. 선택기 기본값이 없으면 만들지 않으며 모델 상속도 사용하지 않아요. +- 각 에이전트 본문에는 `<!-- ccx-route: <model> -->` 지시문이 들어 있어요. 프록시는 이 지시문으로 실제 라우트를 고정해요. 따라서 Agent 도구의 `model` 인자는 작동하지 않으며, 자리 표시자로 `"haiku"`를 전달하세요. - frontmatter에는 별칭이 들어가고, 라우팅은 지시문을 따라요. -- `generated-by: opencodex`가 들어 있는 표식 검증된 `ocx-*.md` 파일만 덮어쓰거나 정리해요. +- `generated-by: codexcommander`가 들어 있는 표식 검증된 `ccx-*.md` 파일만 덮어쓰거나 정리해요. 사용자가 만든 에이전트는 건드리지 않아요. - 파일마다 원자적으로 동기화해요(write + rename). - `enabled: false` 또는 `injectAgents: false`를 설정하면 소유권이 확인된 정의를 모두 정리해요. - GUI PUT과 로스터 변경은 즉시 다시 동기화하고, launcher/system-env는 실행할 때 동기화해요. -디스패치 예시: `subagent_type: "ocx-gpt-5-6-sol"`. 1M을 지원하는 대상에는 `[1m]`이 자동으로 +디스패치 예시: `subagent_type: "ccx-gpt-5-6-sol"`. 1M을 지원하는 대상에는 `[1m]`이 자동으로 붙어요. ## 번들 스킬 생략(blockedSkills) Claude Code의 번들 `claude-api` 스킬은 Anthropic 문서 약 840KB(약 136k 토큰)를 주입하며, Claude 모델을 언급하면 자동으로 실행돼요. 라우팅 모델은 이 번들로 학습되지 않았으므로, -opencodex는 기본적으로 **라우팅된** 요청에서 스킬 내용을 짧은 스텁으로 바꿔요. 네이티브 +CodexCommander는 기본적으로 **라우팅된** 요청에서 스킬 내용을 짧은 스텁으로 바꿔요. 네이티브 Anthropic 패스스루는 그대로 유지해요. **두 가지 전달 형식을 처리해요.** @@ -227,7 +207,7 @@ Anthropic 패스스루는 그대로 유지해요. ## 사이드카 매트릭스: 웹 검색과 이미지 이해 -라우팅 모델마다 쓸 수 있는 호스팅 도구와 이미지 지원 범위가 달라요. opencodex는 메인 모델이 +라우팅 모델마다 쓸 수 있는 호스팅 도구와 이미지 지원 범위가 달라요. CodexCommander는 메인 모델이 답하기 전에 부족한 기능을 다음 두 사이드카로 보완해요. - **웹 검색 사이드카**는 실제 호스팅 검색을 실행한 뒤 답변과 출처를 도구 결과로 라우팅 모델에 @@ -353,7 +333,7 @@ role, `tool_use_id` 없는 `tool_result`, id/name 없는 `tool_use`, name 없는 ## 디버그 캡처 -`ocx debug claude on|off|status|reset`, `OCX_CLAUDE_DEBUG=1` 또는 +`ccx debug claude on|off|status|reset`, `CCX_CLAUDE_DEBUG=1` 또는 `PUT /api/debug {"claude": true}`로 입력 캡처를 제어해요. `GET /api/claude/inbound-debug`는 `{enabled, entries}`를 반환해요(최신 항목부터, 20개 순환 버퍼). @@ -369,7 +349,7 @@ role, `tool_use_id` 없는 `tool_result`, id/name 없는 `tool_use`, name 없는 레이블은 모든 언어에서 의도적으로 같아요. 페이지에는 다음 항목이 표시돼요. - 입력 차단 스위치(사용 토글) -- 빠른 시작(`ocx claude`)과 수동 환경 블록 +- 빠른 시작(`ccx claude`)과 수동 환경 블록 - Fast Mode 선택기(Auto / ON / OFF) - 자동 컨텍스트 토글과 압축 임곗값 드롭다운 - 서브에이전트 자동 등록 토글 @@ -384,8 +364,8 @@ ID, 별칭, 포트를 반환해요. `PUT /api/claude-code`는 부분 업데이 **Claude Code에 "Did 0 searches"가 표시됨** — 현재 버전은 완료된 Responses `web_search_call`을 Anthropic의 `server_tool_use`와 `web_search_tool_result` 블록 쌍으로 바꾸고, -`usage.server_tool_use.web_search_requests`도 함께 기록해요. 검색은 됐는데 0회로 표시되는 예전 -버전을 쓰고 있다면 opencodex를 업데이트하세요. +`usage.server_tool_use.web_search_requests`도 함께 기록해요. 검색은 됐는데 0회로 표시된다면 +실행 중인 CodexCommander 프로세스가 현재 체크아웃에서 다시 빌드되었는지 확인하세요. **사이드카가 켜지지 않음** — `backend: "openai"`라면 ChatGPT 로그인과 활성화된 `authMode: "forward"` 프로바이더가 모두 있는지 확인하세요. `backend: "anthropic"`이라면 저장된 @@ -393,27 +373,27 @@ Anthropic OAuth 활성 계정이 `needsReauth` 상태가 아닌지 확인하세 Anthropic 백엔드를 명시하면 의도적으로 실패 후 중단해요. **"claude.ai connectors are disabled"** — 셸에 `ANTHROPIC_API_KEY` 또는 -`ANTHROPIC_AUTH_TOKEN`이 설정되어 있어요. `ocx claude`는 의도적으로 `ANTHROPIC_API_KEY`를 -설정하지 않으므로, 직접 내보냈다면 해제하세요. `ocx claude`를 사용할 때는 +`ANTHROPIC_AUTH_TOKEN`이 설정되어 있어요. `ccx claude`는 의도적으로 `ANTHROPIC_API_KEY`를 +설정하지 않으므로, 직접 내보냈다면 해제하세요. `ccx claude`를 사용할 때는 `ANTHROPIC_BASE_URL`, 검색, 자동 컨텍스트, 설정된 모델 슬롯을 주입하지만 `ANTHROPIC_API_KEY`는 절대 주입하지 않아요. **/model 선택기에 모델이 표시되지 않음** — `CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1`이 -설정되어 있는지 확인하세요(`ocx claude`에서는 자동). `ocx claude`를 실행해 +설정되어 있는지 확인하세요(`ccx claude`에서는 자동). `ccx claude`를 실행해 `~/.claude/cache/gateway-models.json`의 게이트웨이 모델 캐시를 새로 고치세요. `claudeCode.enabled`가 `false`가 아닌지도 확인하세요. **포트 변경 뒤 오래된 환경이 남음** — 프록시 포트가 바뀌었다면 기존 셸의 -`ANTHROPIC_BASE_URL`이 오래된 값일 수 있어요. 새 터미널을 열거나 `ocx claude`를 다시 실행하세요. +`ANTHROPIC_BASE_URL`이 오래된 값일 수 있어요. 새 터미널을 열거나 `ccx claude`를 다시 실행하세요. **대형 모델인데도 컨텍스트가 200k로 제한됨** — 선택기에서 `[1m]` 변형을 고르거나 기본으로 켜져 있는 자동 컨텍스트를 사용하세요. 선택기에 `[1m]` 행이 없다면 모델의 공식 컨텍스트 창이 자동 압축 임곗값보다 작을 수 있어요. **스킬을 불러올 때 토큰 수가 많음** — 번들 `claude-api` 스킬(약 136k 토큰)은 Claude 모델을 -언급하면 자동으로 불러와요. 네이티브 패스스루에서는 정상이며, 라우팅 모델에서는 opencodex가 +언급하면 자동으로 불러와요. 네이티브 패스스루에서는 정상이며, 라우팅 모델에서는 CodexCommander가 기본적으로 스텁으로 바꿔요(`blockedSkills: ["claude-api"]`). -**서브에이전트가 잘못된 모델로 디스패치됨** — 로스터 에이전트(`ocx-*`)는 Agent 도구의 `model` -인자가 아니라 `<!-- ocx-route: ... -->` 지시문을 사용해요. 지시문이 원하는 라우트와 일치하는지 +**서브에이전트가 잘못된 모델로 디스패치됨** — 로스터 에이전트(`ccx-*`)는 Agent 도구의 `model` +인자가 아니라 `<!-- ccx-route: ... -->` 지시문을 사용해요. 지시문이 원하는 라우트와 일치하는지 확인하고, 모델 자리 표시자로 `"haiku"`를 전달하세요. diff --git a/docs-site/src/content/docs/ko/guides/codex-app-models.md b/docs-site/src/content/docs/ko/guides/codex-app-models.md index 779e97687a..d9f0b3634e 100644 --- a/docs-site/src/content/docs/ko/guides/codex-app-models.md +++ b/docs-site/src/content/docs/ko/guides/codex-app-models.md @@ -1,16 +1,16 @@ --- title: Codex App 모델 선택기 -description: 공유 Codex 카탈로그를 통해 opencodex 모델이 Codex App, Codex CLI, Codex TUI에 표시되는 방식. +description: 공유 Codex 카탈로그를 통해 CodexCommander 모델이 Codex App, Codex CLI, Codex TUI에 표시되는 방식. --- -opencodex는 Codex App을 직접 고치지 않습니다. Codex CLI/TUI가 이미 쓰는 Codex 설정과 모델 카탈로그를 +CodexCommander는 Codex App을 직접 고치지 않습니다. Codex CLI/TUI가 이미 쓰는 Codex 설정과 모델 카탈로그를 같은 위치에 씁니다. Codex App도 이 공유 상태를 읽기 때문에, 라우팅된 모델이 일반 Codex 카탈로그 항목처럼 App의 모델 선택기에 나타날 수 있습니다. OpenAI 항목에는 네이티브 Codex 로그인과 네임스페이스가 붙은 `openai-apikey/<model>` API key 경로라는 두 가지 credential 경로가 있습니다. `codexAccountMode`만 Pool과 Direct 사이에서 바꾸는 것은 선택기 id를 바꾸지 않습니다. 하지만 `codexAccountNamespaces`에 대상 계정이 존재하는 selector가 있으면, -opencodex는 매핑된 계정별로 `<selector>/<native-openai-model>` 행을 추가하고 선택기에서 bare native 행을 +CodexCommander는 매핑된 계정별로 `<selector>/<native-openai-model>` 행을 추가하고 선택기에서 bare native 행을 숨깁니다. Selector 이름은 사용자가 정하는 공개 label이며 내장된 계정 역할 의미가 없습니다. `selector`가 붙은 행을 선택하면 매핑된 계정만 사용하고 활성 Pool 계정은 바뀌지 않습니다. 대상 계정을 사용할 수 없으면 다른 계정으로 전환하지 않고 요청이 실패합니다. 자세한 내용은 [명시적 Codex 계정 selector](/reference/configuration/routing/#exact-codex-account-selectors)를 @@ -29,25 +29,17 @@ gpt-5.6-sol # Pool 또는 Direct를 통한 bare Codex openai-apikey/gpt-5.6-sol # API key ``` -새로 설치한 환경과 저장된 모드가 없는 설정은 Pool이 기본값입니다. 현재 설정은 마커 2를 사용하고, -출하된 v1 소스를 `~/.opencodex/config.json.pre-openai-tiers-v2.bak`에 보관합니다. 복원하려면 다음을 -실행합니다: - -```sh -cp ~/.opencodex/config.json.pre-openai-tiers-v2.bak ~/.opencodex/config.json -``` - -이전 v1의 3-provider 설정은 자동으로 옵션을 인식하는 단일 행으로 마이그레이션됩니다. +새로 설치한 환경과 저장된 모드가 없는 설정은 Pool이 기본값입니다. ## 통합 경로 -`ocx init`, `ocx start`, `ocx sync`는 공유 Codex 설정과 카탈로그를 프록시에 연결합니다. 설정 주입, +`ccx init`, `ccx start`, `ccx sync`는 공유 Codex 설정과 카탈로그를 프록시에 연결합니다. 설정 주입, 카탈로그 동기화, shim, WebSocket 폴백, 복원 메커니즘은 [Codex 통합](/guides/codex-integration/)을 참고하세요. ## 라우팅 모델이 표시되는 이유 -Codex의 모델 선택기는 Codex 형식의 카탈로그 항목을 기대합니다. opencodex는 네이티브 Codex 모델 +Codex의 모델 선택기는 Codex 형식의 카탈로그 항목을 기대합니다. CodexCommander는 네이티브 Codex 모델 템플릿을 복제한 뒤 라우팅된 모델의 식별자만 바꿉니다. ```text @@ -57,7 +49,7 @@ visibility = "list" ``` 복제본에는 reasoning level, shell type, API 지원 플래그, base instructions처럼 엄격한 파서가 요구하는 -필드가 그대로 남습니다. 그다음 opencodex는 해당 라우트가 감당할 수 없는 OpenAI service-tier 메타데이터 +필드가 그대로 남습니다. 그다음 CodexCommander는 해당 라우트가 감당할 수 없는 OpenAI service-tier 메타데이터 같은 네이티브 전용 기능을 제거합니다. ## 현재 안정 모델 범위 @@ -130,7 +122,7 @@ service_tier = "fast" fast_mode = true ``` -하지만 모델 카탈로그와 런타임 요청 tier id는 `priority`를 씁니다. opencodex는 이 분리를 그대로 +하지만 모델 카탈로그와 런타임 요청 tier id는 `priority`를 씁니다. CodexCommander는 이 분리를 그대로 유지합니다. 네이티브 OpenAI passthrough 모델은 fast 지원을 유지하고, 라우팅된 프로바이더는 케이퍼빌리티로 게이트되어 프로바이더가 `supportsServiceTier: false`를 선언한 경우에만 `service_tier`가 제거됩니다(레지스트리가 정식 OpenAI를 `true`, DeepSeek과 Volcengine Ark를 `false`로 분류). 미분류 커스텀 게이트웨이는 호출자가 준 값을 그대로 보존하고 주입도 받지 않습니다. 따라서 @@ -142,7 +134,7 @@ Codex는 선택기에 보이는 카탈로그 항목을 `priority` 오름차순 `spawn_agent` model override로 노출합니다. 대시보드의 **Agent Command Center**에서는 bare native id 또는 routed `provider/model` id를 최대 다섯 개 선택하고 저장할 수 있습니다. 이미 설정된 account-qualified `<selector>/<native-openai-model>` id도 보존하며 각 저장 항목이 실제로 노출됐는지 제외됐는지 보고합니다. -opencodex는 선택한 순서대로 낮은 카탈로그 priority를 부여합니다. account selector가 활성화되어 있으면 +CodexCommander는 선택한 순서대로 낮은 카탈로그 priority를 부여합니다. account selector가 활성화되어 있으면 bare native 선택은 selector-qualified 그룹으로 확장됩니다. 다른 모델도 정확한 id로 직접 호출할 수 있습니다. Active Roster는 Dashboard의 **Sub-agent delegation** 선택과 별개입니다. Codex가 먼저 보여 줄 @@ -153,8 +145,8 @@ override를 정할 뿐, 모델을 고르거나 delegation을 시작하지는 않 picker에 오래된 항목이 계속 보이면 카탈로그를 새로 쓰고 대상 Codex 서피스를 다시 시작합니다: ```bash -ocx sync +ccx sync ``` -opencodex는 카탈로그의 visibility, priority, metadata가 바뀔 때마다 `models_cache.json`을 의도적으로 +CodexCommander는 카탈로그의 visibility, priority, metadata가 바뀔 때마다 `models_cache.json`을 의도적으로 오래된 cache wrapper로 다시 씁니다. 다음 Codex 모델 새로고침이 새 카탈로그를 읽도록 하기 위해서입니다. diff --git a/docs-site/src/content/docs/ko/guides/codex-integration.md b/docs-site/src/content/docs/ko/guides/codex-integration.md index 46feaebc32..bb39843837 100644 --- a/docs-site/src/content/docs/ko/guides/codex-integration.md +++ b/docs-site/src/content/docs/ko/guides/codex-integration.md @@ -1,20 +1,20 @@ --- title: Codex 통합 -description: opencodex가 Codex에 자신을 주입하고, 모델 카탈로그를 동기화하고, shim을 설치하고, 깔끔하게 복원하는 방식. +description: CodexCommander가 Codex에 자신을 주입하고, 모델 카탈로그를 동기화하고, shim을 설치하고, 깔끔하게 복원하는 방식. --- -opencodex는 Codex가 읽는 두 가지, 즉 설정(`$CODEX_HOME/config.toml`, 기본값 `~/.codex/config.toml`)과 모델 카탈로그를 편집해서 Codex가 프록시를 경유하게 합니다. 모든 편집은 멱등적이며 되돌릴 수 있습니다. +CodexCommander는 Codex가 읽는 두 가지, 즉 설정(`$CODEX_HOME/config.toml`, 기본값 `~/.codex/config.toml`)과 모델 카탈로그를 편집해서 Codex가 프록시를 경유하게 합니다. 모든 편집은 멱등적이며 되돌릴 수 있습니다. -프록시는 bare `openai` Codex 로그인 경로 하나와 Pool(기본) 및 Direct 계정 모드, 그리고 설정된 API 키용 `openai-apikey/<model>`을 제공합니다. Pool은 메인 계정과 추가된 계정을 포함하고, Direct는 호출자/메인 bearer만 사용합니다. 경로들은 서로 fallback하지 않습니다. shipped v1 config는 marker 2로 이관되며, 수동 복원을 위해 `config.json.pre-openai-tiers-v2.bak`를 보존합니다. +프록시는 bare `openai` Codex 로그인 경로 하나와 Pool(기본) 및 Direct 계정 모드, 그리고 설정된 API 키용 `openai-apikey/<model>`을 제공합니다. Pool은 메인 계정과 추가된 계정을 포함하고, Direct는 호출자/메인 bearer만 사용합니다. 경로들은 서로 fallback하지 않습니다. ## 설정 주입 -`ocx init`, `ocx start`, `ocx sync`는 모두 인젝터를 호출합니다. 기본 loopback 바인드에서는 Codex의 빌트인 `openai` 프로바이더 id를 그대로 유지한 채, 그 프로바이더가 opencodex를 바라보게 합니다. +`ccx init`, `ccx start`, `ccx sync`는 모두 인젝터를 호출합니다. 기본 loopback 바인드에서는 Codex의 빌트인 `openai` 프로바이더 id를 그대로 유지한 채, 그 프로바이더가 CodexCommander를 바라보게 합니다. ```toml # root keys, before the first table -model_catalog_json = "/absolute/path/to/opencodex-catalog.json" -# Auto-injected by opencodex +model_catalog_json = "/absolute/path/to/codexcommander-catalog.json" +# Auto-injected by CodexCommander openai_base_url = "http://127.0.0.1:10100/v1" # fastMode를 설정했을 때만 들어갑니다. 설정하지 않으면 [features] 자체가 생기지 않습니다 @@ -30,17 +30,17 @@ fast_mode = true ### 내장 이미지 생성 (`image_gen`) -Codex의 내장 `image_gen` 도구는 `/v1/responses`를 거치지 않습니다. codex-rs 확장은 채팅과 같은 ChatGPT bearer 인증을 사용해서 `{base_url}/images/generations`를 직접 POST하며, 참조 이미지가 붙어 있으면 `/images/edits`를 POST합니다. 주입된 `base_url`이 opencodex를 가리키므로, 프록시가 이 호출을 OpenAI upstream으로 전달합니다. +Codex의 내장 `image_gen` 도구는 `/v1/responses`를 거치지 않습니다. codex-rs 확장은 채팅과 같은 ChatGPT bearer 인증을 사용해서 `{base_url}/images/generations`를 직접 POST하며, 참조 이미지가 붙어 있으면 `/images/edits`를 POST합니다. 주입된 `base_url`이 CodexCommander를 가리키므로, 프록시가 이 호출을 OpenAI upstream으로 전달합니다. 이것은 [Image Bridge](/guides/image-bridge/)와는 별개입니다. Image Bridge는 **Responses** 턴이 호스티드 `image_generation` 도구를 나열하고, 선택된 모델이 OpenAI가 아닐 때만 활성화됩니다. 독립적인 `/images/generations` 호출은 이 브리지로 들어가지 않습니다. - **모드 인식 forward 후보 하나:** Pool은 적격한 메인/추가 계정을 선택하고, Direct는 호출자 OAuth bearer를 사용합니다. 설정된 모드는 이미지 요청에도 일관되게 적용됩니다. - **OpenAI API-key provider:** forward 후보 중 누구도 인증 실패를 가지지 않을 때만 사용합니다. 고장 나거나 만료된 Pool credential을 별도로 청구되는 API 사용 뒤에 숨기지 않습니다. - **명시적 커스텀 provider:** `images.provider`를 OpenAI Images API를 구현한 커스텀 API-key `openai-responses` provider id로 설정할 수 있습니다. 명시적으로 선택한 provider는 닫힌 상태로 실패하며, 다른 유료 upstream으로 fallback하지 않습니다. registry-managed provider id는 여기서 허용하지 않습니다. 기본 제공 OpenAI tiers를 쓰려면 `images.provider`를 생략하세요. -- **Google Antigravity (CCA) fallback:** OpenAI forward 후보도 keyed provider도 없을 때, `/v1/images/generations`(`/images/edits`는 제외)는 `gemini-3.1-flash-image` 모델을 사용해서 Antigravity **Cloud Code Assist** endpoint로 fallback합니다. OpenAI 인증 해석이 실패할 때(예: 만료되었거나 누락된 ChatGPT credential)에도 이 fallback이 동작하며, OpenAI 후보가 아예 없을 때만 발생하는 것은 아닙니다. 이 기능은 `ocx login google-antigravity`를 필요로 합니다. OAuth token은 오직 고정된 CCA registry host로만 전송되며, config-level `baseUrl` override로는 가지 않습니다. 응답은 Codex가 기대하는 `{created, data:[{b64_json}]}` 형식으로 반환됩니다. +- **Google Antigravity (CCA) fallback:** OpenAI forward 후보도 keyed provider도 없을 때, `/v1/images/generations`(`/images/edits`는 제외)는 `gemini-3.1-flash-image` 모델을 사용해서 Antigravity **Cloud Code Assist** endpoint로 fallback합니다. OpenAI 인증 해석이 실패할 때(예: 만료되었거나 누락된 ChatGPT credential)에도 이 fallback이 동작하며, OpenAI 후보가 아예 없을 때만 발생하는 것은 아닙니다. 이 기능은 `ccx login google-antigravity`를 필요로 합니다. OAuth token은 오직 고정된 CCA registry host로만 전송되며, config-level `baseUrl` override로는 가지 않습니다. 응답은 Codex가 기대하는 `{created, data:[{b64_json}]}` 형식으로 반환됩니다. - **둘 다 없음:** 프록시는 generic 404 대신 명확한 오류를 반환합니다. 라우팅되는 provider(Cursor, Gemini, Kiro 등)는 `image_generation` tool relay를 제공할 수 없습니다. 이 도구를 아예 노출하고 싶지 않다면 Codex에서 `codex features disable image_generation`(`config.toml`의 `[features] image_generation = false`)으로 끄세요. -도구 선언은 여전히 모델의 Responses 요청과 함께 전달됩니다. API-key Responses provider에서는 opencodex가 Codex의 private `image_gen` namespace를 업스트림에서 안전한 `image_gen__<inner-name>` alias(예: `image_gen__imagegen`)로 낮춥니다. 이 사용 가능한 alias가 클라이언트 선언을 대체할 때만 중복된 hosted `image_generation` 선언을 제거합니다. 함수 호출은 Codex가 보기 전에 명시적인 `image_gen` namespace로 다시 매핑되고, 이후 기록이 업스트림으로 replay될 때 다시 인코딩됩니다. 이렇게 하면 namespace를 예약하거나 점이 들어간 함수 이름을 거부하는 공개 호환 upstream에서도 클라이언트 측 이미지 생성을 호출할 수 있습니다. ChatGPT forward 모드는 건드리지 않으며, 네이티브 Responses Lite 형식을 유지합니다. +도구 선언은 여전히 모델의 Responses 요청과 함께 전달됩니다. API-key Responses provider에서는 CodexCommander가 Codex의 private `image_gen` namespace를 업스트림에서 안전한 `image_gen__<inner-name>` alias(예: `image_gen__imagegen`)로 낮춥니다. 이 사용 가능한 alias가 클라이언트 선언을 대체할 때만 중복된 hosted `image_generation` 선언을 제거합니다. 함수 호출은 Codex가 보기 전에 명시적인 `image_gen` namespace로 다시 매핑되고, 이후 기록이 업스트림으로 replay될 때 다시 인코딩됩니다. 이렇게 하면 namespace를 예약하거나 점이 들어간 함수 이름을 거부하는 공개 호환 upstream에서도 클라이언트 측 이미지 생성을 호출할 수 있습니다. ChatGPT forward 모드는 건드리지 않으며, 네이티브 Responses Lite 형식을 유지합니다. OpenAI 호환 커스텀 gateway를 쓰려면 전용 provider를 설정하고 standalone Images 요청에만 선택하세요: @@ -69,21 +69,21 @@ OpenAI 호환 커스텀 gateway를 쓰려면 전용 provider를 설정하고 sta ```toml # root keys -model_provider = "opencodex" -model_catalog_json = "/absolute/path/to/opencodex-catalog.json" +model_provider = "codexcommander" +model_catalog_json = "/absolute/path/to/codexcommander-catalog.json" # appended at the end of the file -# Auto-injected by opencodex -[model_providers.opencodex] -name = "OpenCodex Proxy" +# Auto-injected by CodexCommander +[model_providers.codexcommander] +name = "CodexCommander Proxy" base_url = "http://your-host:10100/v1" wire_api = "responses" requires_openai_auth = true -env_http_headers = { "x-opencodex-api-key" = "OPENCODEX_API_AUTH_TOKEN" } +env_http_headers = { "x-codexcommander-api-key" = "CODEXCOMMANDER_API_AUTH_TOKEN" } # supports_websockets = true # only when config.websockets is true ``` -OpenCodex가 라우팅을 소유할 때는 두 모드 모두 `$CODEX_HOME/opencodex.config.toml`을 참고용/폴백 설정으로 작성합니다. loopback에서는 자동 주입이 사라졌을 때 수동으로 합칠 수 있는 root key가 들어가고, non-loopback에서는 전용 provider 형식이 들어갑니다. 외부 provider 모드는 이 프로필을 건드리지 않습니다. +CodexCommander가 라우팅을 소유할 때는 두 모드 모두 `$CODEX_HOME/codexcommander.config.toml`을 참고용/폴백 설정으로 작성합니다. loopback에서는 자동 주입이 사라졌을 때 수동으로 합칠 수 있는 root key가 들어가고, non-loopback에서는 전용 provider 형식이 들어갑니다. 외부 provider 모드는 이 프로필을 건드리지 않습니다. :::caution `openai_base_url`, `model_provider`, `model_catalog_json` 같은 root key는 첫 번째 `[table]` 헤더보다 **반드시** 앞에 있어야 합니다. 인젝터는 그 위치를 보장하고, 자신이 남긴 오래되었거나 중복된 복사본은 지웁니다. 사용자가 소유한 root `openai_base_url`은 덮어쓰지 않습니다. 그런 값이 있으면 sync는 카탈로그만 갱신하고 라우팅은 주입하지 않았다고 알립니다. @@ -91,30 +91,27 @@ OpenCodex가 라우팅을 소유할 때는 두 모드 모두 `$CODEX_HOME/openco ## 공유 모델 카탈로그 -Codex CLI, TUI, App, SDK는 모두 같은 Codex home을 읽습니다. opencodex는 이 디렉터리를 `CODEX_HOME`에서 해석하고, 없으면 `~/.codex`로 폴백하며 다음 파일을 관리합니다: +Codex CLI, TUI, App, SDK는 모두 같은 Codex home을 읽습니다. CodexCommander는 이 디렉터리를 `CODEX_HOME`에서 해석하고, 없으면 `~/.codex`로 폴백하며 다음 파일을 관리합니다: ```text $CODEX_HOME/config.toml -$CODEX_HOME/opencodex.config.toml -$CODEX_HOME/opencodex-catalog.json +$CODEX_HOME/codexcommander.config.toml +$CODEX_HOME/codexcommander-catalog.json $CODEX_HOME/models_cache.json ``` WSL에서는 `CODEX_HOME`이 비어 있고 Linux `~/.codex/config.toml`도 없을 때 `/mnt/c/Users/*/.codex/config.toml` 아래의 단일 Windows Codex Desktop home도 확인합니다. 후보가 정확히 하나면 그 디렉터리를 사용하므로 WSL app-server mode와 Windows Codex Desktop이 같은 config와 auth 파일을 공유합니다. 이 탐지를 덮으려면 `CODEX_HOME`을 명시하세요. -Windows에서 Orca shell은 `CODEX_HOME`과 `ORCA_CODEX_HOME`을 Orca의 번들 런타임 home으로 설정할 수 있지만, ChatGPT/Codex app은 여전히 `%USERPROFILE%\\.codex`를 읽습니다. `ocx status`와 `ocx doctor`는 이 정확한 불일치를 경고하고, 경로는 가린 채 대상 home을 출력합니다. 해당 Orca shell에서 background service를 설치했다면 먼저 원래 shell에서 uninstall하고, `CODEX_HOME`을 app home으로 설정한 뒤 `ORCA_CODEX_HOME`을 해제하고, sync/restore를 다시 실행한 다음 service를 다시 설치하세요. +Windows에서 Orca shell은 `CODEX_HOME`과 `ORCA_CODEX_HOME`을 Orca의 번들 런타임 home으로 설정할 수 있지만, ChatGPT/Codex app은 여전히 `%USERPROFILE%\\.codex`를 읽습니다. `ccx status`와 `ccx doctor`는 이 정확한 불일치를 경고하고, 경로는 가린 채 대상 home을 출력합니다. 해당 Orca shell에서 background service를 설치했다면 먼저 원래 shell에서 uninstall하고, `CODEX_HOME`을 app home으로 설정한 뒤 `ORCA_CODEX_HOME`을 해제하고, sync/restore를 다시 실행한 다음 service를 다시 설치하세요. -전용 provider 모드의 `requires_openai_auth = true`는 Codex App/TUI의 계정 게이트 화면을 네이티브 Codex와 같은 조건으로 맞춥니다. opencodex는 `/v1/responses`도 WebSocket으로 제공합니다. 전용 provider는 `"websockets": true`일 때만 `supports_websockets = true`를 광고합니다. loopback에서는 Codex의 빌트인 provider가 먼저 WebSocket을 시도할 수 있으며, 비활성화된 proxy는 `426`을 반환해서 Codex가 HTTP/SSE로 fallback합니다. - -## 스레드 식별자와 대화 기록 - -기본 loopback 형식은 새 thread에 네이티브 `openai` provider 태그를 유지하므로 일반적인 resume history는 다시 매핑할 필요가 없습니다. 첫 sync 때는 더 오래된 opencodex 빌드가 태그를 붙인 thread도 `openai`로 이관합니다. non-loopback 전용 provider 모드는 활성 상태일 때만 history를 `opencodex` provider 아래로 미러링하고, 종료할 때는 백업된 메타데이터를 복원합니다. history를 건드리지 않으려면 `syncResumeHistory: false`로 설정하세요. +전용 provider 모드의 `requires_openai_auth = true`는 Codex App/TUI의 계정 게이트 화면을 네이티브 Codex와 같은 조건으로 맞춥니다. CodexCommander는 `/v1/responses`도 WebSocket으로 제공합니다. 전용 provider는 `"websockets": true`일 때만 `supports_websockets = true`를 광고합니다. loopback에서는 Codex의 빌트인 provider가 먼저 WebSocket을 시도할 수 있으며, 비활성화된 proxy는 `426`을 반환해서 Codex가 HTTP/SSE로 fallback합니다. ## 모델 카탈로그 동기화 -Codex는 디스크의 카탈로그(`$CODEX_HOME/opencodex-catalog.json`이 기본값)에 있는 모델을 보여줍니다. 시작 시와 `ocx sync` 시 opencodex는 다음을 수행합니다. +Codex는 디스크의 카탈로그(`$CODEX_HOME/codexcommander-catalog.json`이 기본값)에 있는 모델을 보여줍니다. 시작 시와 `ccx sync` 시 CodexCommander는 다음을 수행합니다. -1. 원본 카탈로그를 `~/.opencodex/catalog-backup.json`에 한 번 **백업**합니다(그래서 featuring도 되돌릴 수 있습니다). +1. 원본 카탈로그를 `~/.codexcommander/catalog-backup-<catalog-id>.json`에 한 번 **백업**합니다 + (그래서 featuring도 되돌릴 수 있습니다). 2. 적격한 provider의 live model catalog를 **가져옵니다**(약 5분 캐시, `modelCacheTtlMs` 기본값 `300000`; 마지막 정상 목록, 그다음 설정된 `models[]`로 fallback). Forward auth에는 model endpoint가 없고, Cursor는 `/models` 대신 `GetUsableModels` RPC를 사용합니다. 3. 라우팅된 모델을 네임스페이스 항목(`provider/model`)으로 **병합**합니다. Codex의 엄격한 parser가 받아들이도록 네이티브 Codex catalog template에서 복제합니다. 4. `config.disabledModels`와 각 provider의 비어 있지 않은 `selectedModels` allowlist를 **필터링**합니다. @@ -131,31 +128,31 @@ Codex는 디스크의 카탈로그(`$CODEX_HOME/opencodex-catalog.json`이 기 CLI에서 표시 이름을 추가할 수 있습니다(proxy가 live 상태면 catalog를 바로 동기화합니다): ```bash -ocx models add deepseek deepseek-v4 --display-name "DeepSeek V4" --context-window 128000 +ccx models add deepseek deepseek-v4 --display-name "DeepSeek V4" --context-window 128000 ``` 원격 Codex client는 management API로 같은 생성된 catalog를 가져올 수 있습니다(다른 `/api/*` 경로와 같은 admission token을 사용합니다): ```bash -dest="${CODEX_HOME:-$HOME/.codex}/opencodex-catalog.json" +dest="${CODEX_HOME:-$HOME/.codex}/codexcommander-catalog.json" tmp="$(mktemp "${dest}.XXXXXX")" -curl -fsS -H "x-opencodex-api-key: $OPENCODEX_ADMIN_AUTH_TOKEN" \ +curl -fsS -H "x-codexcommander-api-key: $CODEXCOMMANDER_ADMIN_AUTH_TOKEN" \ "https://proxy.example.com/api/catalog" > "$tmp" \ && mv "$tmp" "$dest" -ocx sync-cache +ccx sync-cache ``` -응답은 원시 `opencodex-catalog.json` 문서입니다( provider credential 없음). 사용 가능할 때는 `x-opencodex-codex-version` header가 서버 쪽 Codex runtime version을 보고해서 client가 version skew를 알아볼 수 있습니다. +응답은 원시 `codexcommander-catalog.json` 문서입니다( provider credential 없음). 사용 가능할 때는 `x-codexcommander-codex-version` header가 서버 쪽 Codex runtime version을 보고해서 client가 version skew를 알아볼 수 있습니다. 또한 management API(`POST /api/custom-models`, `PUT /api/custom-models/<id>`의 `displayName` string)와 웹 대시보드에서도 설정하거나 수정할 수 있습니다. `/`는 routed-slug separator와 충돌하므로 거부됩니다. -표시 이름은 **표시 전용이며 재생성 사이에서도 안정적**입니다. 모든 `ocx sync`와 catalog refresh는 `config.json`(`customModels` 포함)에서 routed entry를 다시 계산하므로, 설정된 이름이 라우팅 slug로 되돌아가지 않고 다시 적용됩니다. 관리형 service restart도 proxy가 bind된 직후 이 sync를 다시 시도합니다. 예를 들어 offline login 중이라 이 best-effort boot sync가 실패하면, 이전에 저장된 catalog는 유지되고 다음에 성공한 `ocx sync`가 설정된 이름을 다시 적용합니다. 진짜 upstream native name(예: `gpt-5.6-sol` → "GPT-5.6-Sol")은 고정된 upstream snapshot에서 오며, custom display name으로 덮어쓰지 않습니다. +표시 이름은 **표시 전용이며 재생성 사이에서도 안정적**입니다. 모든 `ccx sync`와 catalog refresh는 `config.json`(`customModels` 포함)에서 routed entry를 다시 계산하므로, 설정된 이름이 라우팅 slug로 되돌아가지 않고 다시 적용됩니다. 관리형 service restart도 proxy가 bind된 직후 이 sync를 다시 시도합니다. 예를 들어 offline login 중이라 이 best-effort boot sync가 실패하면, 이전에 저장된 catalog는 유지되고 다음에 성공한 `ccx sync`가 설정된 이름을 다시 적용합니다. 진짜 upstream native name(예: `gpt-5.6-sol` → "GPT-5.6-Sol")은 고정된 upstream snapshot에서 오며, custom display name으로 덮어쓰지 않습니다. ### 외부 provider manager -`config.toml`이 이미 `openai`나 `opencodex`가 아닌 provider를 선택하고 있으면, OpenCodex는 그 파일을 그대로 두고 profile write, catalog/cache refresh, 즉시 및 background Codex history migration을 건너뜁니다. custom provider를 관리하는 도구는 기존 session에 그 provider id를 붙이는 경우가 많고, 활성 id를 바꾸면 그 온전한 session이 Codex의 history view에서 사라질 수 있습니다. 이 보호는 legacy root profile이 선택한 외부 provider에도 동일하게 적용됩니다. +`config.toml`이 이미 `openai`나 `codexcommander`가 아닌 provider를 선택하고 있으면, CodexCommander는 그 파일을 그대로 두고 profile write, catalog/cache refresh, Codex history 동기화를 건너뜁니다. custom provider를 관리하는 도구는 기존 session에 그 provider id를 붙이는 경우가 많고, 활성 id를 바꾸면 그 온전한 session이 Codex의 history view에서 사라질 수 있습니다. 이 보호는 외부 provider가 활성 상태일 때 항상 적용됩니다. -Codex provider configuration의 소유자는 한 도구만 맡게 하세요. 기존 provider manager 뒤에서 OpenCodex를 쓰려면, 그 provider를 `http://127.0.0.1:10100/v1`로 향하게 하고 Responses passthrough를 쓰세요(`wire_api = "responses"` in Codex TOML). Chat Completions translation은 쓰지 않습니다. proxy API auth가 켜져 있으면, 위의 non-loopback provider 형식과 맞추어 `OPENCODEX_API_AUTH_TOKEN`에서 `x-opencodex-api-key`도 함께 전달하세요. OpenCodex가 routing을 직접 주입하게 하려면 먼저 Codex를 built-in `openai` provider로 되돌리고, 사용자가 소유한 root `openai_base_url`을 지운 다음, `ocx start`를 다시 실행하세요. +Codex provider configuration의 소유자는 한 도구만 맡게 하세요. 기존 provider manager 뒤에서 CodexCommander를 쓰려면, 그 provider를 `http://127.0.0.1:10100/v1`로 향하게 하고 Responses passthrough를 쓰세요(`wire_api = "responses"` in Codex TOML). Chat Completions translation은 쓰지 않습니다. proxy API auth가 켜져 있으면, 위의 non-loopback provider 형식과 맞추어 `CODEXCOMMANDER_API_AUTH_TOKEN`에서 `x-codexcommander-api-key`도 함께 전달하세요. CodexCommander가 routing을 직접 주입하게 하려면 먼저 Codex를 built-in `openai` provider로 되돌리고, 사용자가 소유한 root `openai_base_url`을 지운 다음, `ccx start`를 다시 실행하세요. ### 카탈로그 문제 해결 @@ -163,25 +160,25 @@ Codex에서 model이 빠졌거나 catalog 순서/가시성이 이상해 보이 1. provider의 **`selectedModels`** - 비어 있지 않은 allowlist는 해당 id만 Codex에 노출합니다. 비어 있거나 생략하면 발견된 model이 모두 노출됩니다. allowlist에 없는 id는 catalog에 절대 들어가지 않습니다. 2. **`disabledModels`**(top level) - catalog와 `/v1/models`에서 model을 숨기고, bare native GPT slug는 `visibility: "hide"`로 바꿉니다. -3. **`liveModels: false`와 비어 있는 `models`** - live discovery가 꺼져 있고 `models`가 비어 있거나 생략되면, opencodex는 그 provider에 대해 routed model을 하나도 노출하지 않습니다. +3. **`liveModels: false`와 비어 있는 `models`** - live discovery가 꺼져 있고 `models`가 비어 있거나 생략되면, CodexCommander는 그 provider에 대해 routed model을 하나도 노출하지 않습니다. 4. **Cursor `GetUsableModels`** - Cursor adapter는 `/models`가 아니라 protobuf `GetUsableModels` RPC로 model을 찾습니다. 그래서 Cursor 쪽 변경이 다른 provider와 무관하게 어떤 id가 보이는지 바꿀 수 있습니다. -5. **캐시와 `ocx sync`** - live catalog는 약 5분(`modelCacheTtlMs`, 기본값 `300000`) 동안 캐시됩니다. `ocx sync`를 실행하면 새로 가져와서 catalog를 즉시 다시 쓸 수 있습니다. -6. **실행 중인 Codex `app-server`** - 오래 살아 있는 Codex `app-server`(Desktop / CLI background host)가 이전 목록을 메모리에 쥐고 있으면 디스크 catalog를 다시 쓰는 것만으로는 부족합니다. `ocx sync`와 `ocx sync-cache`는 그런 process를 감지하면 경고합니다. `ocx sync --restart-codex`로 다시 시작하거나(아니면 일치하는 `app-server` process를 직접 중지한 뒤), Codex가 다시 만들게 해서 새 목록이 보이게 하세요. +5. **캐시와 `ccx sync`** - live catalog는 약 5분(`modelCacheTtlMs`, 기본값 `300000`) 동안 캐시됩니다. `ccx sync`를 실행하면 새로 가져와서 catalog를 즉시 다시 쓸 수 있습니다. +6. **실행 중인 Codex `app-server`** - 오래 살아 있는 Codex `app-server`(Desktop / CLI background host)가 이전 목록을 메모리에 쥐고 있으면 디스크 catalog를 다시 쓰는 것만으로는 부족합니다. `ccx sync`와 `ccx sync-cache`는 그런 process를 감지하면 경고합니다. `ccx sync --restart-codex`로 다시 시작하거나(아니면 일치하는 `app-server` process를 직접 중지한 뒤), Codex가 다시 만들게 해서 새 목록이 보이게 하세요. :::caution[다른 로컬 writer] -catalog write(`opencodex-catalog.json`, `config.toml`)는 opencodex 내부에서만 원자적입니다. 이것은 두 개의 opencodex 소유 writer가 경합할 때 반쯤만 써진 파일을 막아줄 뿐입니다. 다른 로컬 process, file watcher, sync agent가 opencodex가 쓴 뒤에 catalog visibility나 순서를 다시 쓸 가능성은 막지 못합니다. Codex는 별도의 `models_cache.json`을 유지하고 독립적으로 갱신할 수 있으므로, 이 과정에서 `opencodex-catalog.json`을 다시 쓰지 않고도 보이는 목록이 바뀔 수 있습니다. proxy가 실행 중인데 model이 예상치 않게 바뀌면, 경쟁 writer를 중지하거나 재설정한 뒤 `ocx sync`를 실행하세요. 이것은 외부 writer 위험이지, 확인된 opencodex 결함이 아닙니다. +catalog write(`codexcommander-catalog.json`, `config.toml`)는 CodexCommander 내부에서만 원자적입니다. 이것은 두 개의 CodexCommander 소유 writer가 경합할 때 반쯤만 써진 파일을 막아줄 뿐입니다. 다른 로컬 process, file watcher, sync agent가 CodexCommander가 쓴 뒤에 catalog visibility나 순서를 다시 쓸 가능성은 막지 못합니다. Codex는 별도의 `models_cache.json`을 유지하고 독립적으로 갱신할 수 있으므로, 이 과정에서 `codexcommander-catalog.json`을 다시 쓰지 않고도 보이는 목록이 바뀔 수 있습니다. proxy가 실행 중인데 model이 예상치 않게 바뀌면, 경쟁 writer를 중지하거나 재설정한 뒤 `ccx sync`를 실행하세요. 이것은 외부 writer 위험이지, 확인된 CodexCommander 결함이 아닙니다. ::: ## 프록시 연결 오류 -Codex가 재시도한 뒤 `stream disconnected before completion: error sending request for url (http://127.0.0.1:10100/v1/responses)` 같은 오류로 실패하거나 Claude Code가 비슷한 연결 실패를 보고하면, opencodex proxy가 실행 중이 아닙니다. 설정된 포트에서 아무도 듣지 않으므로 client가 그 raw connection error를 그대로 보여줍니다. proxy를 다시 시작하세요: +Codex가 재시도한 뒤 `stream disconnected before completion: error sending request for url (http://127.0.0.1:10100/v1/responses)` 같은 오류로 실패하거나 Claude Code가 비슷한 연결 실패를 보고하면, CodexCommander proxy가 실행 중이 아닙니다. 설정된 포트에서 아무도 듣지 않으므로 client가 그 raw connection error를 그대로 보여줍니다. proxy를 다시 시작하세요: ```bash -ocx start # foreground -ocx service install # persistent: auto-starts on login and respawns on crash +ccx start # foreground +ccx service install # persistent: auto-starts on login and respawns on crash ``` -`ocx status`는 proxy가 실행 중인지 보여주고, 실행 중이 아닐 때는 같은 restart 힌트를 출력합니다. `ocx doctor`는 restart safety(service/shim coverage)를 보고합니다. +`ccx status`는 proxy가 실행 중인지 보여주고, 실행 중이 아닐 때는 같은 restart 힌트를 출력합니다. `ccx doctor`는 restart safety(service/shim coverage)를 보고합니다. ## 서브에이전트 선택기 @@ -189,16 +186,16 @@ catalog sync는 선택된 서브에이전트 모델을 Codex가 쓸 수 있게 ## Codex 계정 워밍업 -ChatGPT 계정을 Codex account pool에 추가하면, opencodex는 이를 저장하기 전에 Codex Responses backend로 작은 streaming request를 보내 확인합니다. 요청은 실제 Responses item array(`input: [{ type: "message", ... }]`)를 사용하고, `response.completed`를 기다리며, 기본값은 `gpt-5.4-mini`입니다. 그 모델이 HTTP 400을 반환하면 `gpt-5.5`로 다시 시도합니다. 구조화된 upstream error detail은 보여 주되 raw response body는 노출하지 않습니다. background revalidation은 별도 기능이며 기본값은 꺼져 있습니다. Token Guardian이 활성화되고, `chatgpt` refresh policy가 `proactive`이며, `tokenGuardian.codexWarmupEnabled`가 true일 때만 실행됩니다. +ChatGPT 계정을 Codex account pool에 추가하면, CodexCommander는 이를 저장하기 전에 Codex Responses backend로 작은 streaming request를 보내 확인합니다. 요청은 실제 Responses item array(`input: [{ type: "message", ... }]`)를 사용하고, `response.completed`를 기다리며, 기본값은 `gpt-5.4-mini`입니다. 그 모델이 HTTP 400을 반환하면 `gpt-5.5`로 다시 시도합니다. 구조화된 upstream error detail은 보여 주되 raw response body는 노출하지 않습니다. background revalidation은 별도 기능이며 기본값은 꺼져 있습니다. Token Guardian이 활성화되고, `chatgpt` refresh policy가 `proactive`이며, `tokenGuardian.codexWarmupEnabled`가 true일 때만 실행됩니다. ## 네이티브 Codex 복원 -opencodex는 절대 사용자를 가두지 않습니다. **`ocx stop`은 네이티브 Codex로 완전히 되돌리는 단일 명령입니다**. proxy를 중지하고, 설치된 background service가 있으면 그것도 중지한 뒤, 주입된 모든 라인과 라우팅된 catalog 항목을 제거해서 plain `codex`가 opencodex가 처음부터 없었던 것처럼 정확히 동작하게 합니다: +CodexCommander는 절대 사용자를 가두지 않습니다. **`ccx stop`은 네이티브 Codex로 완전히 되돌리는 단일 명령입니다**. proxy를 중지하고, 설치된 background service가 있으면 그것도 중지한 뒤, 주입된 모든 라인과 라우팅된 catalog 항목을 제거해서 plain `codex`가 CodexCommander가 처음부터 없었던 것처럼 정확히 동작하게 합니다: ```bash -ocx stop # stop the proxy + service, restore native Codex -ocx restore # restore without stopping (alias: ocx eject) -ocx restore back # point plain Codex at the running proxy again +ccx stop # stop the proxy + service, restore native Codex +ccx restore # restore without stopping (alias: ccx eject) +ccx restore back # point plain Codex at the running proxy again ``` -opencodex가 managed [background service](/reference/cli/#ocx-service)로 실행될 때는 `OCX_SERVICE=1`을 설정하므로 service-driven restart가 Codex config를 흔들지 **않습니다**. 네이티브 Codex를 복원하는 것은 명시적인 `ocx stop` / `ocx service stop`뿐입니다. +CodexCommander가 managed [background service](/reference/cli/#ccx-service)로 실행될 때는 `CCX_SERVICE=1`을 설정하므로 service-driven restart가 Codex config를 흔들지 **않습니다**. 네이티브 Codex를 복원하는 것은 명시적인 `ccx stop` / `ccx service stop`뿐입니다. diff --git a/docs-site/src/content/docs/ko/guides/combos.md b/docs-site/src/content/docs/ko/guides/combos.md index 9a2b2455e8..18cb29e342 100644 --- a/docs-site/src/content/docs/ko/guides/combos.md +++ b/docs-site/src/content/docs/ko/guides/combos.md @@ -3,7 +3,7 @@ title: "콤보: 페일오버와 로드 밸런싱" description: "하나의 가상 모델을 여러 공급자에 걸쳐 페일오버나 가중 로드 밸런싱으로 라우팅합니다." --- -**콤보**는 정해진 순서로 나열된 실제 공급자/모델 대상 목록 앞에 서는 하나의 가상 모델입니다. 클라이언트는 `combo/<id>`로 요청하고, opencodex는 대상을 하나 선택해 요청을 그 구체적인 `provider/model`로 다시 쓰며, 첫 번째 대상이 재시도 가능한 실패를 내면 다른 대상을 시도할 수 있습니다. +**콤보**는 정해진 순서로 나열된 실제 공급자/모델 대상 목록 앞에 서는 하나의 가상 모델입니다. 클라이언트는 `combo/<id>`로 요청하고, CodexCommander는 대상을 하나 선택해 요청을 그 구체적인 `provider/model`로 다시 쓰며, 첫 번째 대상이 재시도 가능한 실패를 내면 다른 대상을 시도할 수 있습니다. 이 방식은 다음 두 경우에 유용합니다. @@ -17,10 +17,10 @@ description: "하나의 가상 모델을 여러 공급자에 걸쳐 페일오버 이 예시는 Anthropic을 먼저, OpenAI를 나중에 두는 `combo/main`을 만듭니다. 두 공급자는 이미 존재하고 활성화되어 있어야 합니다. ```bash -ocx combo set main --targets anthropic/claude-opus-4-8,openai/gpt-5.6-sol +ccx combo set main --targets anthropic/claude-opus-4-8,openai/gpt-5.6-sol ``` -기본 전략은 페일오버이므로 일반 요청은 `anthropic/claude-opus-4-8`으로 갑니다. 그 시도가 재시도 가능한 실패를 내면 opencodex는 `openai/gpt-5.6-sol`로 넘어갈 수 있습니다. +기본 전략은 페일오버이므로 일반 요청은 `anthropic/claude-opus-4-8`으로 갑니다. 그 시도가 재시도 가능한 실패를 내면 CodexCommander는 `openai/gpt-5.6-sol`로 넘어갈 수 있습니다. 가상 모델은 평소에 모델 ID를 넣는 자리 어디서나 사용할 수 있습니다. @@ -34,7 +34,7 @@ ocx combo set main --targets anthropic/claude-opus-4-8,openai/gpt-5.6-sol 저장된 정의를 확인합니다. ```bash -ocx combo show main +ccx combo show main ``` :::tip @@ -43,7 +43,7 @@ ocx combo show main ## 콤보 이름 동작 -`ocx combo set <id>`의 콤보 ID는 문자나 숫자로 시작해야 합니다. 그 뒤에는 문자, 숫자, `.`, `_`, `-`를 포함할 수 있고, 전체 길이는 64자 이하여야 합니다. 정식 모델 ID는 항상 `combo/<id>`입니다. 예를 들어 ID `main`은 `combo/main`이 됩니다. +`ccx combo set <id>`의 콤보 ID는 문자나 숫자로 시작해야 합니다. 그 뒤에는 문자, 숫자, `.`, `_`, `-`를 포함할 수 있고, 전체 길이는 64자 이하여야 합니다. 정식 모델 ID는 항상 `combo/<id>`입니다. 예를 들어 ID `main`은 `combo/main`이 됩니다. 콤보를 설정하면 `combo/` 네임스페이스는 예약됩니다. 이름이 `combo`인 공급자는 그 자리를 차지할 수 없고, 콤보 ID도 이미 설정된 공급자 이름과 겹칠 수 없습니다. @@ -82,7 +82,7 @@ alias는 클라이언트가 요청하는 공개 이름만 바꿉니다. 콤보 성공 요청 두 번씩 묶는 2:1 콤보를 만듭니다. ```bash -ocx combo set balanced \ +ccx combo set balanced \ --targets anthropic/claude-opus-4-8:2,openai/gpt-5.6-sol:1 \ --strategy round-robin \ --sticky 2 @@ -111,7 +111,7 @@ ocx combo set balanced \ | 클라이언트 취소(499), `origin_rejected`, cyber-policy refusal, context overflow, 또는 invalid request | 멈추고 오류를 반환합니다. 다른 대상을 써도 요청이 유효해지지 않기 때문입니다. | | 그 밖의 분류되지 않은 오류 | 멈추고 오류를 반환합니다. | -홉된 대상은 기본적으로 60초 동안 쿨다운에 들어갑니다. 상위 응답에 유효한 `Retry-After` 값이 있으면 opencodex는 그 값을 대신 사용합니다. 숫자 초와 HTTP-date 값이 모두 허용되며, 모든 쿨다운은 최대 10분으로 제한됩니다. +홉된 대상은 기본적으로 60초 동안 쿨다운에 들어갑니다. 상위 응답에 유효한 `Retry-After` 값이 있으면 CodexCommander는 그 값을 대신 사용합니다. 숫자 초와 HTTP-date 값이 모두 허용되며, 모든 쿨다운은 최대 10분으로 제한됩니다. 현재 요청은 이미 시도한 대상을 다시 시도하지 않습니다. 이후 요청은 그 대상의 쿨다운이 끝날 때까지 건너뜁니다. 적합한 대상이 하나도 남지 않으면 프록시는 HTTP 503과 함께 `error.code = "combo_unavailable"`을 반환합니다. @@ -127,15 +127,15 @@ ocx combo set balanced \ 2. 호출자가 effort를 설정하지 않았습니다. 3. 선택된 대상의 카탈로그가 그 정확한 effort를 광고합니다. -요청에 `reasoning` 객체가 없으면 opencodex가 새로 만듭니다. `reasoning`은 있지만 `effort` 속성이 없으면 다른 필드는 그대로 두고 기본값만 추가합니다. 호출자가 준 effort는 절대 덮어쓰지 않습니다. +요청에 `reasoning` 객체가 없으면 CodexCommander가 새로 만듭니다. `reasoning`은 있지만 `effort` 속성이 없으면 다른 필드는 그대로 두고 기본값만 추가합니다. 호출자가 준 effort는 절대 덮어쓰지 않습니다. -대상 기능을 알 수 없거나 설정한 effort를 포함하지 않으면 opencodex는 기본값을 생략하고 대상의 동작은 그대로 둡니다. 지원 값은 `low`, `medium`, `high`, `xhigh`, `max`, `ultra`입니다. effort를 호출자와 대상에 완전히 맡기려면 이 필드를 생략하거나 `null`로 설정하십시오. +대상 기능을 알 수 없거나 설정한 effort를 포함하지 않으면 CodexCommander는 기본값을 생략하고 대상의 동작은 그대로 둡니다. 지원 값은 `low`, `medium`, `high`, `xhigh`, `max`, `ultra`입니다. effort를 호출자와 대상에 완전히 맡기려면 이 필드를 생략하거나 `null`로 설정하십시오. ## 암호화된 v2 서브에이전트 작업 -Codex v2 서브에이전트에는 중요한 제한이 하나 있습니다([issue #92](https://github.com/lidge-jun/opencodex/issues/92)). 네이티브 부모 프로세스는 새로 생성된 작업자에게 보낼 작업을 네이티브 ChatGPT 백엔드용으로 생성한 암호문으로만 전달할 수 있습니다. 외부 공급자는 그 페이로드를 읽을 수 없습니다. +Codex v2 서브에이전트에는 중요한 제한이 하나 있습니다([issue #92](https://github.com/pavelhov/CodexCommander/issues/92)). 네이티브 부모 프로세스는 새로 생성된 작업자에게 보낼 작업을 네이티브 ChatGPT 백엔드용으로 생성한 암호문으로만 전달할 수 있습니다. 외부 공급자는 그 페이로드를 읽을 수 없습니다. -이런 요청에서 콤보는 재시도 가능한 실패가 나더라도 정식 네이티브 ChatGPT 경로만 적합 대상으로 남깁니다. 콤보에 복호화 가능한 대상이 하나도 없으면 opencodex는 전송 전에 멈추고 HTTP 400을 반환합니다. +이런 요청에서 콤보는 재시도 가능한 실패가 나더라도 정식 네이티브 ChatGPT 경로만 적합 대상으로 남깁니다. 콤보에 복호화 가능한 대상이 하나도 없으면 CodexCommander는 전송 전에 멈추고 HTTP 400을 반환합니다. ```json { @@ -168,13 +168,13 @@ v1/base/v2 모드와 암호화된 작업의 전체 흐름은 [Sub-agent Surface] 주요 명령은 다음과 같습니다. ```bash -ocx combo list -ocx combo show <id> -ocx combo set <id> --targets provider/model[:weight],... -ocx combo remove <id> --yes +ccx combo list +ccx combo show <id> +ccx combo set <id> --targets provider/model[:weight],... +ccx combo remove <id> --yes ``` -`set`은 `--strategy`, `--sticky`, `--effort`, `--alias`, `--rename-from`도 받습니다. `--effort` 또는 `--alias` 값으로 `-`를 주면 해당 필드를 지울 수 있습니다. `create`와 `update`는 `set`의 별칭이고, `delete`는 `remove`의 별칭입니다. 같은 하위 명령은 `ocx route combo` 아래에서도 사용할 수 있습니다. +`set`은 `--strategy`, `--sticky`, `--effort`, `--alias`, `--rename-from`도 받습니다. `--effort` 또는 `--alias` 값으로 `-`를 주면 해당 필드를 지울 수 있습니다. `create`와 `update`는 `set`의 별칭이고, `delete`는 `remove`의 별칭입니다. 같은 하위 명령은 `ccx route combo` 아래에서도 사용할 수 있습니다. ### Management API @@ -217,8 +217,8 @@ ocx combo remove <id> --yes ### `combo/<id>`가 404를 반환하는 이유는 무엇인가요? combo id를 찾을 수 없기 때문입니다. 응답은 HTTP 404와 `invalid_request_error` 유형을 반환합니다. -`ocx combo list`를 실행하고, 철자와 대소문자를 확인하고, 관리 명령이 모델 요청을 받는 것과 동일한 -opencodex 인스턴스에 기록했는지 확인하세요. +`ccx combo list`를 실행하고, 철자와 대소문자를 확인하고, 관리 명령이 모델 요청을 받는 것과 동일한 +CodexCommander 인스턴스에 기록했는지 확인하세요. ### `combo_unavailable`이 발생하는 이유는 무엇인가요? diff --git a/docs-site/src/content/docs/ko/guides/grok-build.md b/docs-site/src/content/docs/ko/guides/grok-build.md index a8fe6e10e3..fde27625f9 100644 --- a/docs-site/src/content/docs/ko/guides/grok-build.md +++ b/docs-site/src/content/docs/ko/guides/grok-build.md @@ -1,69 +1,69 @@ --- title: Grok Build 안내 -description: xAI의 Grok Build CLI에서 opencodex로 라우팅되는 모든 모델을 사용합니다. 프로세스가 실행되는 동안 모델은 `~/.grok/config.toml`에 자동 등록됩니다. +description: xAI의 Grok Build CLI에서 CodexCommander로 라우팅되는 모든 모델을 사용합니다. 프로세스가 실행되는 동안 모델은 `~/.grok/config.toml`에 자동 등록됩니다. --- -opencodex는 로컬 포트에서 OpenAI 호환 `POST /v1/chat/completions`(및 `/v1/responses`)를 제공합니다. Grok Build는 OpenAI 호환 서버를 상대로 사용자 정의 모델을 지원합니다. 이 통합은 opencodex가 노출하는 전체 카탈로그를 Grok Build에 자동 등록합니다. 수동으로 설정 파일을 편집할 필요가 없습니다. +CodexCommander는 로컬 포트에서 OpenAI 호환 `POST /v1/chat/completions`(및 `/v1/responses`)를 제공합니다. Grok Build는 OpenAI 호환 서버를 상대로 사용자 정의 모델을 지원합니다. 이 통합은 CodexCommander가 노출하는 전체 카탈로그를 Grok Build에 자동 등록합니다. 수동으로 설정 파일을 편집할 필요가 없습니다. ## 자동 등록 -`~/.grok`가 있으면 `ocx start`(그리고 `ocx ensure` / `ocx restart`)가 `~/.grok/config.toml`에 관리 블록을 씁니다: +`~/.grok`가 있으면 `ccx start`(그리고 `ccx ensure` / `ccx restart`)가 `~/.grok/config.toml`에 관리 블록을 씁니다: ```toml -# >>> opencodex managed block — do not edit (removed by `ocx stop`) >>> -[model.ocx-gpt-5-6-sol] +# >>> CodexCommander managed block — do not edit (removed by `ccx stop`) >>> +[model.ccx-gpt-5-6-sol] model = "gpt-5.6-sol" base_url = "http://127.0.0.1:10100/v1" api_backend = "chat_completions" -api_key = "opencodex-loopback" -name = "OCX gpt-5.6-sol" -# ... one [model.ocx-*] table per visible model ... -# <<< opencodex managed block <<< +api_key = "codexcommander-loopback" +name = "CodexCommander gpt-5.6-sol" +# ... one [model.ccx-*] table per visible model ... +# <<< CodexCommander managed block <<< ``` -- **추가형:** 펜스 밖에 있는 사용자 설정은 절대 건드리지 않습니다. 기존 파일에 처음 넣기 전에 한 번만 `~/.grok/config.toml.bak-opencodex`에 백업을 남깁니다. -- **멱등적:** `ocx start`를 실행할 때마다(자동 시작이 켜진 상태에서는 `ocx ensure`도) 현재 카탈로그로 펜스 블록을 다시 씁니다. -- **종료 시 제거:** `ocx stop`, `ocx eject`, `ocx uninstall`, 그리고 서비스가 아닌 데몬을 정상 종료할 때는 펜스 블록을 지우고 파일을 바이트 단위까지 원래대로 복원합니다. 서비스 관리자 아래에서는 종료가 `ocx stop`/`ocx uninstall`을 거칩니다(서비스 모드 프로세스는 재생성될 때도 블록을 의도적으로 유지합니다). -- **충돌 안전:** 이미 사용자 정의 `[model.*]` 테이블에 정의된 별칭은 존중합니다(opencodex는 자체 항목에 접미사를 붙입니다). 손상된 펜스(시작 표시는 있는데 끝 표시는 없는 경우)는 자동 변경을 거부하고 수동 복구를 요청합니다. +- **추가형:** 펜스 밖에 있는 사용자 설정은 절대 건드리지 않습니다. 기존 파일에 처음 넣기 전에 한 번만 `~/.grok/config.toml.bak-codexcommander`에 백업을 남깁니다. +- **멱등적:** `ccx start`를 실행할 때마다(자동 시작이 켜진 상태에서는 `ccx ensure`도) 현재 카탈로그로 펜스 블록을 다시 씁니다. +- **종료 시 제거:** `ccx stop`, `ccx eject`, `ccx uninstall`, 그리고 서비스가 아닌 데몬을 정상 종료할 때는 펜스 블록을 지우고 파일을 바이트 단위까지 원래대로 복원합니다. 서비스 관리자 아래에서는 종료가 `ccx stop`/`ccx uninstall`을 거칩니다(서비스 모드 프로세스는 재생성될 때도 블록을 의도적으로 유지합니다). +- **충돌 안전:** 이미 사용자 정의 `[model.*]` 테이블에 정의된 별칭은 존중합니다(CodexCommander는 자체 항목에 접미사를 붙입니다). 손상된 펜스(시작 표시는 있는데 끝 표시는 없는 경우)는 자동 변경을 거부하고 수동 복구를 요청합니다. 그다음 Grok Build에서 모델을 고릅니다: ```bash -grok models # lists ocx-* entries alongside native grok models -grok -m ocx-anthropic-claude-opus-4-8 -p "hello" -# or in the TUI: /model ocx-anthropic-claude-opus-4-8 +grok models # lists ccx-* entries alongside native grok models +grok -m ccx-anthropic-claude-opus-4-8 -p "hello" +# or in the TUI: /model ccx-anthropic-claude-opus-4-8 ``` ## 인증 참고 -Grok Build는 루프백에서도 사용자 정의 모델에 비어 있지 않은 API 키를 요구합니다. 주입되는 항목에는 자리표시자(`opencodex-loopback`)가 들어갑니다. opencodex는 루프백 연결의 admission key를 무시하므로 실제 비밀값은 들어가지 않습니다. +Grok Build는 루프백에서도 사용자 정의 모델에 비어 있지 않은 API 키를 요구합니다. 주입되는 항목에는 자리표시자(`codexcommander-loopback`)가 들어갑니다. CodexCommander는 루프백 연결의 admission key를 무시하므로 실제 비밀값은 들어가지 않습니다. -**자동 등록은 루프백 전용입니다.** opencodex가 비루프백 호스트에 바인드하면, 모든 인터페이스를 노출하는 와일드카드 `0.0.0.0`와 `::`를 포함해 요청은 실제 admission token을 필요로 하고, 관리 블록은 그 값을 안전하게 담을 수 없습니다. 토큰을 그대로 쓰면 비밀값이 `~/.grok/config.toml`에 들어가고, 다음 `ocx start`/`ensure`/`restart` 때 그 자리에 있던 값이 덮어써집니다. 그래서 opencodex는 그런 경우 아무 것도 쓰지 않고(이전에 루프백 바인드가 남긴 블록도 제거합니다), 사용자는 관리 마커 바깥에서 모델을 직접 설정해야 합니다. 이 위치에서는 opencodex가 어떤 일을 해도 그 설정을 덮어쓸 수 없습니다. 정확한 테이블은 [수동 설정](#manual-recipe-without-auto-registration)을 보시고, `base_url`(실제로 `grok`가 도달할 수 있는 호스트)과 `api_key`(사용자의 `OPENCODEX_API_AUTH_TOKEN`)를 함께 설정합니다. +**자동 등록은 루프백 전용입니다.** CodexCommander가 비루프백 호스트에 바인드하면, 모든 인터페이스를 노출하는 와일드카드 `0.0.0.0`와 `::`를 포함해 요청은 실제 admission token을 필요로 하고, 관리 블록은 그 값을 안전하게 담을 수 없습니다. 토큰을 그대로 쓰면 비밀값이 `~/.grok/config.toml`에 들어가고, 다음 `ccx start`/`ensure`/`restart` 때 그 자리에 있던 값이 덮어써집니다. 그래서 CodexCommander는 그런 경우 아무 것도 쓰지 않고(이전에 루프백 바인드가 남긴 블록도 제거합니다), 사용자는 관리 마커 바깥에서 모델을 직접 설정해야 합니다. 이 위치에서는 CodexCommander가 어떤 일을 해도 그 설정을 덮어쓸 수 없습니다. 정확한 테이블은 [수동 설정](#manual-recipe-without-auto-registration)을 보시고, `base_url`(실제로 `grok`가 도달할 수 있는 호스트)과 `api_key`(사용자의 `CODEXCOMMANDER_API_AUTH_TOKEN`)를 함께 설정합니다. 여기서는 `api_key`를 `env_key`로 바꾸지 마십시오. `model_provider`를 설정하지 않은 상태에서 `env_key`가 해결되지 않아도 요청은 멈추지 않습니다. Grok가 사용자의 xAI 세션 토큰으로 넘어가서 항목이 가리키는 `base_url`로 보냅니다. LAN 배포에서는 그 `base_url`이 xAI가 아닌 평문 HTTP 엔드포인트입니다. -주입된 모델별 `api_key`는 이 모델들에 대한 Grok의 자격 증명 체인에서 가장 먼저 사용되므로, opencodex를 대상으로 하는 요청에는 추가 Grok 로그인이 필요하지 않습니다. xAI에 직접 접속하는 네이티브 grok 모델과 모든 하니스 기능에는 평소 쓰던 `grok login` / `XAI_API_KEY` 구성을 그대로 유지합니다. +주입된 모델별 `api_key`는 이 모델들에 대한 Grok의 자격 증명 체인에서 가장 먼저 사용되므로, CodexCommander를 대상으로 하는 요청에는 추가 Grok 로그인이 필요하지 않습니다. xAI에 직접 접속하는 네이티브 grok 모델과 모든 하니스 기능에는 평소 쓰던 `grok login` / `XAI_API_KEY` 구성을 그대로 유지합니다. ## 수동 설정 (자동 등록 없음) -직접 `~/.grok/config.toml`를 관리하거나 opencodex가 비루프백 호스트에 바인드되어 있다면, `# >>> opencodex managed block` 마커 바깥에 모델별 테이블을 직접 필드 형태로 작성합니다: +직접 `~/.grok/config.toml`를 관리하거나 CodexCommander가 비루프백 호스트에 바인드되어 있다면, `# >>> CodexCommander managed block` 마커 바깥에 모델별 테이블을 직접 필드 형태로 작성합니다: ```toml -[model.ocx-opus] +[model.ccx-opus] model = "anthropic/claude-opus-4-8" base_url = "http://127.0.0.1:10100/v1" api_backend = "chat_completions" -api_key = "opencodex-loopback" +api_key = "codexcommander-loopback" ``` 네트워크에서 닿을 수 있는 프록시라면 `base_url`을 `grok`가 실제로 연결할 수 있는 주소로 두고 승인 토큰을 사용합니다: ```toml -[model.ocx-opus] +[model.ccx-opus] model = "anthropic/claude-opus-4-8" base_url = "http://192.168.1.10:10100/v1" # the reachable host, not 127.0.0.1 api_backend = "chat_completions" -api_key = "your-OPENCODEX_API_AUTH_TOKEN" +api_key = "your-CODEXCOMMANDER_API_AUTH_TOKEN" ``` `[model_providers.<id>]` 상속에 엔드포인트를 맡기지 마십시오. Grok Build 0.2.101 기준으로 상속된 `base_url`은 추론 라우팅에 적용되지 않습니다(요청은 기본 xAI 프록시로 넘어가고 401로 실패합니다). 직접 넣은 모델별 필드는 정상적으로 라우팅됩니다. @@ -72,7 +72,7 @@ api_key = "your-OPENCODEX_API_AUTH_TOKEN" ## 알려진 제한 -- **Responses 백엔드와 keep-alive:** 상위 업스트림이 조용한 동안 opencodex는 `/v1/responses` 스트림에 `response.heartbeat` keep-alive를 보냅니다. Grok Build의 Responses 디코더는 알 수 없는 이벤트 타입을 거부하므로, 수동으로 설정한 `api_backend = "responses"` 모델은 느린 업스트림에서 턴 도중 실패할 수 있습니다. 자동 등록된 항목은 `api_backend = "chat_completions"`로 고정되며, 원시 heartbeat 프레임을 노출하지 않습니다. -- **서비스 설치된 `ocx restart`:** opencodex가 서비스 관리자 아래에서 실행될 때 `ocx restart`는 현재 서비스를 멈추고 unmanaged 프로세스로 바꿉니다. 서비스 지속성(auto-restart, start-at-login)은 다음 `ocx service` 설정 전까지 사라지며, 그 unmanaged 프로세스가 죽으면 다음 `ocx start`/`ocx ensure`가 갱신하기 전까지 관리 블록이 죽은 프록시를 가리킬 수 있습니다. -- **설정 읽기 시점:** 가장 예측 가능한 결과를 얻으려면 opencodex를 먼저 시작하고 그다음 `grok`를 실행합니다. Grok Build는 `~/.grok/config.toml`을 감시하다가 `[model]` 테이블이 실제로 바뀔 때 다시 불러옵니다(내용을 기준으로 비교하는 약 1초 디바운스). 그래서 새로 고친 블록은 재시작 없이 열린 세션에도 들어갑니다. Grok가 무엇을 파싱했는지 확인하려면 `grok inspect`를 실행합니다. 이 명령은 로드한 설정 원본을 나열하고 거부한 필드가 있으면 경고합니다. 해석된 모델 목록은 출력하지 않습니다. TOML 오류 하나만으로도 사용자 설정 레이어 전체가 무효가 되므로, opencodex가 파일을 원자적으로 쓰는 이유도 여기에 있습니다. Grok는 절반만 써진 설정을 보지 않습니다. -- **카탈로그 업데이트:** 펜스 블록은 주입 시점의 카탈로그를 반영합니다. 공급자나 모델을 추가한 뒤에는 `ocx ensure`를 실행하거나 프록시를 재시작해 갱신합니다. +- **Responses 백엔드와 keep-alive:** 상위 업스트림이 조용한 동안 CodexCommander는 `/v1/responses` 스트림에 `response.heartbeat` keep-alive를 보냅니다. Grok Build의 Responses 디코더는 알 수 없는 이벤트 타입을 거부하므로, 수동으로 설정한 `api_backend = "responses"` 모델은 느린 업스트림에서 턴 도중 실패할 수 있습니다. 자동 등록된 항목은 `api_backend = "chat_completions"`로 고정되며, 원시 heartbeat 프레임을 노출하지 않습니다. +- **서비스 설치된 `ccx restart`:** CodexCommander가 서비스 관리자 아래에서 실행될 때 `ccx restart`는 현재 서비스를 멈추고 unmanaged 프로세스로 바꿉니다. 서비스 지속성(auto-restart, start-at-login)은 다음 `ccx service` 설정 전까지 사라지며, 그 unmanaged 프로세스가 죽으면 다음 `ccx start`/`ccx ensure`가 갱신하기 전까지 관리 블록이 죽은 프록시를 가리킬 수 있습니다. +- **설정 읽기 시점:** 가장 예측 가능한 결과를 얻으려면 CodexCommander를 먼저 시작하고 그다음 `grok`를 실행합니다. Grok Build는 `~/.grok/config.toml`을 감시하다가 `[model]` 테이블이 실제로 바뀔 때 다시 불러옵니다(내용을 기준으로 비교하는 약 1초 디바운스). 그래서 새로 고친 블록은 재시작 없이 열린 세션에도 들어갑니다. Grok가 무엇을 파싱했는지 확인하려면 `grok inspect`를 실행합니다. 이 명령은 로드한 설정 원본을 나열하고 거부한 필드가 있으면 경고합니다. 해석된 모델 목록은 출력하지 않습니다. TOML 오류 하나만으로도 사용자 설정 레이어 전체가 무효가 되므로, CodexCommander가 파일을 원자적으로 쓰는 이유도 여기에 있습니다. Grok는 절반만 써진 설정을 보지 않습니다. +- **카탈로그 업데이트:** 펜스 블록은 주입 시점의 카탈로그를 반영합니다. 공급자나 모델을 추가한 뒤에는 `ccx ensure`를 실행하거나 프록시를 재시작해 갱신합니다. diff --git a/docs-site/src/content/docs/ko/guides/image-bridge.md b/docs-site/src/content/docs/ko/guides/image-bridge.md index d0610fc7a8..6356ee9fb2 100644 --- a/docs-site/src/content/docs/ko/guides/image-bridge.md +++ b/docs-site/src/content/docs/ko/guides/image-bridge.md @@ -10,7 +10,7 @@ Codex를 Claude, Gemini, Grok 같은 OpenAI가 아닌 모델로 라우팅하면 ## 사전 조건 - 구성에서 `images.bridgeEnabled: true`로 설정해 브리지를 켭니다. 예상치 못한 xAI 요금을 피하려고 기본값은 꺼져 있습니다. 아래 [Configuration](#configuration)을 참고합니다. -- API 키가 있는 `xai` provider 항목이 필요합니다. 브리지는 처리를 레지스트리의 xAI Images endpoint (`https://api.x.ai/v1`)에 고정하며, 이미지 호출에서는 설정된 `baseUrl` override를 무시합니다. OAuth / `ocx login xai`만으로는 브리지가 활성화되지 않습니다. Grok CLI OAuth transport는 채팅용이며 `/images/*`에는 사용되지 않습니다. +- API 키가 있는 `xai` provider 항목이 필요합니다. 브리지는 처리를 레지스트리의 xAI Images endpoint (`https://api.x.ai/v1`)에 고정하며, 이미지 호출에서는 설정된 `baseUrl` override를 무시합니다. OAuth / `ccx login xai`만으로는 브리지가 활성화되지 않습니다. Grok CLI OAuth transport는 채팅용이며 `/images/*`에는 사용되지 않습니다. ```json { @@ -24,7 +24,7 @@ Codex를 Claude, Gemini, Grok 같은 OpenAI가 아닌 모델로 라우팅하면 ## 설정 -Image Bridge 옵션은 `~/.opencodex/config.json`의 `images` 아래에 있습니다. 브리지는 선택적(opt-in) 기능이며, 유료 xAI Grok Imagine 생성을 사용하려면 `bridgeEnabled: true`로 설정해야 합니다. +Image Bridge 옵션은 `~/.codexcommander/config.json`의 `images` 아래에 있습니다. 브리지는 선택적(opt-in) 기능이며, 유료 xAI Grok Imagine 생성을 사용하려면 `bridgeEnabled: true`로 설정해야 합니다. ```json { @@ -47,16 +47,16 @@ Image Bridge 옵션은 `~/.opencodex/config.json`의 `images` 아래에 있습 ## 아티팩트 보존 -생성된 이미지는 `~/.opencodex/artifacts/`에 기록됩니다. 오래 실행되는 세션에서 디스크가 끝없이 늘어나는 것을 막기 위해, 이미지 호출이 완료될 때마다(그 호출의 전체 배치가 디스크에 올라간 뒤) 이 디렉터리를 자동으로 정리합니다. 개수가 설정된 최대값을 넘으면 수정 시각이 가장 오래된 파일부터 삭제합니다. 기본값은 200이며 `images.artifactsKeepCount`로 조정할 수 있습니다. 정리 후에도 남아 있는 경로만 모델에 반환합니다. +생성된 이미지는 `~/.codexcommander/artifacts/`에 기록됩니다. 오래 실행되는 세션에서 디스크가 끝없이 늘어나는 것을 막기 위해, 이미지 호출이 완료될 때마다(그 호출의 전체 배치가 디스크에 올라간 뒤) 이 디렉터리를 자동으로 정리합니다. 개수가 설정된 최대값을 넘으면 수정 시각이 가장 오래된 파일부터 삭제합니다. 기본값은 200이며 `images.artifactsKeepCount`로 조정할 수 있습니다. 정리 후에도 남아 있는 경로만 모델에 반환합니다. ## 동작 방식 Image Bridge는 선택된 모델이 OpenAI가 아닌 상태에서, `/v1/responses`의 `tools` 배열에 hosted `image_generation` 도구가 들어 있는 **Responses** 턴에서만 활성화됩니다. Codex의 내장 `image_gen` 도구는 가로채지 않습니다. 이 도구는 `/v1/images/generations`(또는 `/images/edits`)로 직접 POST하며, 해당 경로는 [Codex Integration](/guides/codex-integration/#built-in-image-generation-image_gen)에서 따로 다룹니다. -1. Responses 요청의 `tools`에 `image_generation`이 들어 있으면, OpenCodex가 요청 사전 처리 과정에서 이를 감지합니다. +1. Responses 요청의 `tools`에 `image_generation`이 들어 있으면, CodexCommander가 요청 사전 처리 과정에서 이를 감지합니다. 2. hosted tool은 라우팅된 모델이 정상적으로 호출할 수 있는 합성된 `function` 도구로 바뀝니다. 이렇게 하면 모델이 실행할 수 없는 opaque hosted tool 대신 호출 가능한 도구를 보게 됩니다. -3. 모델이 그 도구를 호출하면, OpenCodex가 호출을 가로채서 프롬프트를 xAI의 이미지 생성 API로 보냅니다. -4. 생성된 이미지는 `~/.opencodex/artifacts/`에 저장되고, 로컬 파일 경로가 도구 결과로 모델에 반환됩니다. +3. 모델이 그 도구를 호출하면, CodexCommander가 호출을 가로채서 프롬프트를 xAI의 이미지 생성 API로 보냅니다. +4. 생성된 이미지는 `~/.codexcommander/artifacts/`에 저장되고, 로컬 파일 경로가 도구 결과로 모델에 반환됩니다. 5. 모델은 생성된 이미지와 그 위치를 알고 있는 상태로 대화를 이어갑니다. 모델 입장에서는 아무것도 달라지지 않습니다. 도구를 호출했고 결과를 받았을 뿐입니다. 사용자 입장에서는 이미지 생성이 조용히 실패하는 대신, 라우팅된 어떤 provider로도 동작합니다. diff --git a/docs-site/src/content/docs/ko/guides/macos-menu-bar.md b/docs-site/src/content/docs/ko/guides/macos-menu-bar.md index ea85af16db..b8d8561823 100644 --- a/docs-site/src/content/docs/ko/guides/macos-menu-bar.md +++ b/docs-site/src/content/docs/ko/guides/macos-menu-bar.md @@ -1,52 +1,33 @@ --- title: macOS 메뉴 막대 컴패니언 -description: OpenCodex의 네이티브 상태, 에이전트 활동 및 제공자 할당량 컴패니언을 설치하고 사용합니다. +description: CodexCommander의 네이티브 상태, 에이전트 활동 및 제공자 할당량 컴패니언을 설치하고 사용합니다. --- -macOS 컴패니언은 프록시를 대체하거나 웹 대시보드를 중복하지 않으면서 가장 유용한 OpenCodex +macOS 컴패니언은 프록시를 대체하거나 웹 대시보드를 중복하지 않으면서 가장 유용한 CodexCommander 상태를 메뉴 막대에 표시합니다. 네이티브 Swift/AppKit 애플리케이션이며 같은 Mac에서 실행 중인 -OpenCodex 인스턴스와만 통신합니다. +CodexCommander 인스턴스와만 통신합니다. ## 설치 -1. 일치하는 GitHub 릴리스에서 <code>OpenCodex-<version>-macos-universal.zip</code>과 - 해당 <code>.sha256</code> 파일을 다운로드합니다. -2. 아카이브를 확인합니다. - - shasum -a 256 -c OpenCodex-<version>-macos-universal.zip.sha256 - -3. 압축을 풀고 <code>OpenCodex.app</code>을 **응용 프로그램**으로 이동합니다. -4. 앱을 엽니다. 앱에 Bun 런타임, 프록시, 프로덕션 의존성 및 대시보드가 포함되어 있으므로 별도의 npm, - Bun 또는 <code>ocx</code> 설치가 필요하지 않습니다. 아이콘은 메뉴 막대에 나타나며 Dock 아이콘은 추가되지 - 않습니다. 안정적인 위치에서 처음 실행하면 **Launch at Login**이 활성화됩니다. - -번들 런타임은 기존 사용자 상태인 <code>~/.opencodex</code>와 <code>~/.codex</code>를 사용합니다. 자격 증명을 -앱 번들이나 Keychain으로 복사하지 않습니다. 제공자 OAuth 및 API 키 설정은 로컬 대시보드에서 수행합니다. - -릴리스가 Developer ID로 서명되고 공증되기 전까지는 macOS가 다운로드 후 첫 실행을 차단할 수 -있습니다. 앱을 Control-클릭하고 **열기**를 선택한 다음 **열기**를 확인합니다. 로컬에서 만든 -빌드에는 다운로드된 파일의 격리 속성이 없습니다. - -번들 런타임은 읽기 전용입니다. 업데이트는 최신 서명된 <code>OpenCodex.app</code> 번들로 교체해야 하며, -서명된 <code>Contents/Resources</code>에 npm, Bun 또는 소스 업데이트를 실행하지 않습니다. +패키징된 macOS 앱은 현재 게시되어 있지 않습니다. [소스에서 빌드](#소스에서-빌드)의 절차로 기존 체크아웃에서 실행하세요. 개발 앱은 `dist/macos/CodexCommander.app`에 두고 Application Support로 복사하지 마세요. ## 시작 모드 - **Desktop** — 로그인할 때 메뉴 앱을 열고 정확히 하나의 서버에 연결하거나 시작합니다. -- **Headless** — 메뉴 앱 없이 별도로 설치한 `ocx service`만 시작합니다. -- **Off** — 자동으로 시작하지 않으며 앱 또는 `ocx start`로 수동 시작합니다. +- **Headless** — 메뉴 앱 없이 별도로 설치한 `ccx service`만 시작합니다. +- **Off** — 자동으로 시작하지 않으며 앱 또는 `ccx start`로 수동 시작합니다. 시작 행에서 **Launch at Login**을 변경할 수 있습니다. 승인이 필요하면 macOS Login Items 설정을 직접 엽니다. 이 스위치는 백그라운드 서비스를 설치, 중지 또는 제거하지 않습니다. -표시되는 앱과 백그라운드 프록시는 별도로 동작합니다. OpenCodex 패널이 활성화된 상태에서 **Quit Menu Bar**(`⌘Q`)는 컴패니언 UI만 -닫고 라우팅은 계속 유지합니다. **Stop OpenCodex and Quit…**(`⌥⌘Q`)는 명시적인 파괴적 종료로, +표시되는 앱과 백그라운드 프록시는 별도로 동작합니다. CodexCommander 패널이 활성화된 상태에서 **Quit Menu Bar**(`⌘Q`)는 컴패니언 UI만 +닫고 라우팅은 계속 유지합니다. **Stop CodexCommander and Quit…**(`⌥⌘Q`)는 명시적인 파괴적 종료로, 확인 후 프록시와 서비스를 중지하고 네이티브 Codex 라우팅을 복원하며 중지가 확인된 경우에만 컴패니언을 종료합니다. ## 패널에 표시되는 내용 -- **에이전트 활동** — 현재 활성 수와 실시간 모델/제공자 행입니다. OpenCodex가 요청 +- **에이전트 활동** — 현재 활성 수와 실시간 모델/제공자 행입니다. CodexCommander가 요청 메타데이터에서 활성 부모를 입증할 수 있을 때만 생성된 자식이 중첩되며, 그렇지 않으면 독립형 서브에이전트로 표시됩니다. 컴패니언은 대기 중, 검토 중, 속도 제한됨 또는 완료 기록을 만들어내지 않습니다. @@ -58,7 +39,7 @@ OpenCodex 인스턴스와만 통신합니다. - **관리** — 선택한 제공자의 Accounts 또는 API Keys 탭을 엽니다. OAuth, API 키 입력, 재인증, 계정 전환 및 제공자 구성은 대시보드에서 계속 처리합니다. - **Agent catalog update ready** — 실행 중인 Codex 백그라운드 워커가 이전 모델 목록을 계속 보유할 때 - 표시되는 지속적이고 치명적이지 않은 카드입니다. OpenCodex 프록시는 정상적으로 계속 실행됩니다. + 표시되는 지속적이고 치명적이지 않은 카드입니다. CodexCommander 프록시는 정상적으로 계속 실행됩니다. - **Apply agent catalog…** — 가능한 경우 최신 요청 활동을 표시하고 답변이 중단될 수 있음을 경고하는 확인 창을 엽니다. 선택지는 **Apply Now**와 **Later**입니다. - **Stop Proxy…** — 항상 확인을 요청하고 활성 클라이언트 및 서브에이전트 요청을 중단하며, 네이티브 @@ -68,7 +49,7 @@ OpenCodex 인스턴스와만 통신합니다. 신원 검사를 통과할 때까지 앱이 기다립니다. - **Quit Menu Bar** — 컴패니언 UI만 닫으며 프록시, 서비스 또는 클라이언트 라우팅은 중지하지 않습니다. 패널이 활성화된 상태에서 안전한 `⌘Q` 동작입니다. -- **Stop OpenCodex and Quit…** — 중단을 확인한 뒤 백그라운드 프록시와 서비스를 중지하고 네이티브 +- **Stop CodexCommander and Quit…** — 중단을 확인한 뒤 백그라운드 프록시와 서비스를 중지하고 네이티브 Codex 라우팅을 복원합니다. 중지 상태가 확인된 경우에만 종료하며, 실패하면 컴패니언을 열어 둔 채 오류를 표시합니다. 패널이 활성화된 상태에서 단축키는 `⌥⌘Q`입니다. @@ -83,40 +64,40 @@ Grok은 접힌 요약으로 표시됩니다. 구성된 할당량 지원 제공 ## 에이전트 카탈로그 업데이트 -앱을 열면 현재 OpenCodex에 구성된 제공자와 Codex 모델 카탈로그를 자동으로 동기화합니다. 실행 중인 +앱을 열면 현재 CodexCommander에 구성된 제공자와 Codex 모델 카탈로그를 자동으로 동기화합니다. 실행 중인 Codex 워커가 없으면 새 목록은 다음 Codex 작업에서 사용됩니다. 장시간 실행 중인 워커가 이전 목록을 -로드한 경우에도 OpenCodex는 계속 실행되며 패널에는 치명적이지 않은 **Agent catalog update ready** 카드가 +로드한 경우에도 CodexCommander는 계속 실행되며 패널에는 치명적이지 않은 **Agent catalog update ready** 카드가 계속 표시됩니다. 중단 위험을 검토하려면 **Apply agent catalog…**을 선택합니다. 가능한 경우 확인 직전에 활성 요청 수를 가져오지만, 요청이 0개여도 Codex가 유휴 상태라는 증거로 표시하지 않습니다. 작업이 실행되기 전에 새 요청이 시작될 수 있기 때문입니다. **Apply Now**는 다시 동기화한 뒤 현재 사용자가 소유한 정확한 `codex … app-server` 및 `codex-code-mode-host` 일치 프로세스에만 `SIGTERM`을 보내고, 이전 프로세스 ID가 -종료되었는지 잠시 확인합니다. 광범위한 `pkill`을 사용하거나 OpenCodex 프록시를 재시작하거나 메뉴 앱을 +종료되었는지 잠시 확인합니다. 광범위한 `pkill`을 사용하거나 CodexCommander 프록시를 재시작하거나 메뉴 앱을 닫지 않습니다. 다음 작업에서 Codex가 새 백그라운드 호스트를 만들고 최신 목록을 로드합니다. -이 릴리스에는 **Apply when idle**이 없습니다. 답변이 진행 중이면 **Later**를 선택하고 준비가 되었을 때 +현재 컴패니언에는 **Apply when idle**이 없습니다. 답변이 진행 중이면 **Later**를 선택하고 준비가 되었을 때 업데이트를 적용하세요. 카드는 계속 표시됩니다. 고급 CLI 대체 방법은 다음과 같습니다. ```bash -ocx sync --restart-codex +ccx sync --restart-codex ``` ## 인증 및 개인정보 보호 -컴패니언은 별도의 로그인 시스템을 만들지 않으며 macOS Keychain으로 데이터를 마이그레이션하거나 -제공자 자격 증명을 읽지 않습니다. +컴패니언은 별도의 로그인 시스템을 만들지 않고 macOS Keychain을 사용하지 않으며, +Keychain에서 제공자 자격 증명을 읽지도 않습니다. -현재 OpenCodex 버전은 <code>~/.opencodex/admin-api-token</code>(또는 -<code>$OPENCODEX_HOME/admin-api-token</code>)에 독립적인 관리 자격 증명을 생성합니다. 컴패니언은 +현재 CodexCommander 버전은 <code>~/.codexcommander/admin-api-token</code>(또는 +<code>$CODEXCOMMANDER_HOME/admin-api-token</code>)에 독립적인 관리 자격 증명을 생성합니다. 컴패니언은 심볼릭 링크를 따르지 않도록 검증된 파일 디스크립터를 통해 기존 파일을 읽고, 그 값을 프로세스 -메모리에만 유지하며, 신원이 확인된 루프백 OpenCodex 프로세스에만 보냅니다. 토큰을 표시, 기록, +메모리에만 유지하며, 신원이 확인된 루프백 CodexCommander 프로세스에만 보냅니다. 토큰을 표시, 기록, 복사 또는 저장하거나 브라우저 URL에 넣지 않습니다. -제공자 자격 증명은 계속 OpenCodex가 소유합니다. 컴패니언은 ChatGPT, Kimi, Grok, Anthropic 또는 +제공자 자격 증명은 계속 CodexCommander가 소유합니다. 컴패니언은 ChatGPT, Kimi, Grok, Anthropic 또는 기타 제공자 토큰을 읽지 않으며 제공자 로그인 엔드포인트를 직접 호출하지 않습니다. -<code>OPENCODEX_ADMIN_AUTH_TOKEN</code>만으로 구성된 설치는 앱 프로세스가 해당 변수를 상속받을 +<code>CODEXCOMMANDER_ADMIN_AUTH_TOKEN</code>만으로 구성된 설치는 앱 프로세스가 해당 변수를 상속받을 때 작동합니다. Finder에서 실행한 앱은 일반적으로 셸 변수를 상속받지 않습니다. 보호된 토큰 파일이 없으면 컴패니언은 토큰 입력 양식을 표시하는 대신 관리 인증을 사용할 수 없다고 보고합니다. @@ -129,7 +110,7 @@ ID, 제공자/모델 식별자, 타임스탬프 및 집계 수가 포함됩니 ## 폴링 앱은 패널이 열려 있는 동안 가벼운 활동 정보를 자주 새로 고치고, 패널이 닫히면 속도를 늦춥니다. -제공자 할당량은 별도의 느린 주기로 새로 고치며 OpenCodex가 보고한 업스트림 타임스탬프를 +제공자 할당량은 별도의 느린 주기로 새로 고치며 CodexCommander가 보고한 업스트림 타임스탬프를 사용합니다. 반복되는 실패에는 자동으로 백오프가 적용되고 겹치는 새로 고침은 하나로 통합됩니다. @@ -137,39 +118,37 @@ ID, 제공자/모델 식별자, 타임스탬프 및 집계 수가 포함됩니 ## 소스에서 빌드 -macOS 13 이상과 Xcode Command Line Tools가 필요합니다. Intel + Apple silicon 유니버설 릴리스 -빌드에는 전체 Xcode가 필요합니다. +macOS 13 이상과 Xcode Command Line Tools가 필요합니다. Intel + Apple silicon 유니버설 빌드에는 전체 Xcode가 필요합니다. ```bash -git clone https://github.com/pavelhov/opencodex.git -cd opencodex +cd /path/to/CodexCommander bun install bun run test:macos bun run build:macos -open dist/macos/OpenCodex.app +open dist/macos/CodexCommander.app ``` -소스 앱의 위치는 정확히 `dist/macos/OpenCodex.app`입니다. 같은 체크아웃의 Bun과 CLI를 +소스 앱의 위치는 정확히 `dist/macos/CodexCommander.app`입니다. 같은 체크아웃의 Bun과 CLI를 사용하므로 `bun install` 종속성이 필요합니다. 개발 중에는 이 위치에 두고 Application Support로 복사하지 마세요. 더블클릭하면 프록시 시작을 시도하지만 오프라인이거나 시작에 실패해도 앱은 닫히지 않으며 패널과 **Start** 컨트롤을 계속 사용할 수 있습니다. -각 빌드는 정확한 Git 리비전을 번들의 `Info.plist`에 있는 `OpenCodexSourceRevision`에 기록하고 빌드 -마지막에도 출력합니다. 커밋하지 않은 소스에는 `-dirty`가 붙으므로 최종 배포 번들을 만들기 전에 +각 빌드는 정확한 Git 리비전을 번들의 `Info.plist`에 있는 `CodexCommanderSourceRevision`에 기록하고 빌드 +마지막에도 출력합니다. 커밋하지 않은 소스에는 `-dirty`가 붙으므로 최종 번들을 만들기 전에 커밋하세요. ## 문제 해결 -- **프록시를 사용할 수 없음** — <code>ocx start</code>로 시작하거나 - <code>ocx service install</code>로 백그라운드 서비스를 설치합니다. -- **인증을 사용할 수 없음** — <code>ocx doctor</code>를 실행합니다. OpenCodex 상태 디렉터리와 +- **프록시를 사용할 수 없음** — <code>ccx start</code>로 시작하거나 + <code>ccx service install</code>로 백그라운드 서비스를 설치합니다. +- **인증을 사용할 수 없음** — <code>ccx doctor</code>를 실행합니다. CodexCommander 상태 디렉터리와 <code>admin-api-token</code>이 현재 사용자 소유이며 그룹/기타 사용자가 접근할 수 없는지 확인합니다. - **할당량을 사용할 수 없음** — 제공자의 **관리** 대상으로 이동하여 계정을 연결하거나 다시 인증합니다. Grok에 **로그인 새로 고침 필요**가 표시되면 <code>grok</code>에서 로그인을 완료한 뒤 - OpenCodex에서 **새로 고침**하세요. Kimi에서는 <code>kimi</code>를 사용합니다. 일부 제공자는 할당량 + CodexCommander에서 **새로 고침**하세요. Kimi에서는 <code>kimi</code>를 사용합니다. 일부 제공자는 할당량 API를 노출하지 않습니다. -- **재시작 후 복구되지 않음** — **Logs**를 열고 <code>ocx status</code>를 실행합니다. 컴패니언은 +- **재시작 후 복구되지 않음** — **Logs**를 열고 <code>ccx status</code>를 실행합니다. 컴패니언은 대체 수단으로 프로세스를 강제 종료하거나 서비스 상태를 다시 작성하지 않습니다. -- **중지·업데이트·콜드 스타트 후 네이티브 모델만 표시됨** — OpenCodex를 다시 여세요. 시작 시 +- **중지·Codex 업데이트·콜드 스타트 후 네이티브 모델만 표시됨** — CodexCommander를 다시 여세요. 시작 시 카탈로그를 자동으로 동기화하고, 제공자 검색 결과가 일시적으로 비어 있어도 보호된 마지막 정상 카탈로그에서 아직 구성된 라우팅 모델을 복원합니다. **Agent catalog update ready**가 계속 표시되면 **Apply agent catalog…**을 선택하거나 [에이전트 카탈로그 업데이트](#에이전트-카탈로그-업데이트)의 CLI @@ -177,7 +156,7 @@ open dist/macos/OpenCodex.app ## 제거 -**Launch at Login**을 끈 다음 컴패니언을 종료하고 <code>OpenCodex.app</code>을 휴지통으로 +**Launch at Login**을 끈 다음 컴패니언을 종료하고 <code>CodexCommander.app</code>을 휴지통으로 이동합니다. 제공자 자격 증명을 저장하지 않으며 Keychain 항목도 만들지 않습니다. 컴패니언을 -제거해도 OpenCodex 프록시는 중지되거나 제거되지 않습니다. 헤드리스 서비스도 제거하려는 경우에만 -별도로 <code>ocx service uninstall</code>을 실행하십시오. +제거해도 CodexCommander 프록시는 중지되거나 제거되지 않습니다. 헤드리스 서비스도 제거하려는 경우에만 +별도로 <code>ccx service uninstall</code>을 실행하십시오. diff --git a/docs-site/src/content/docs/ko/guides/model-ordering.md b/docs-site/src/content/docs/ko/guides/model-ordering.md index 2fae8c792e..f7d0b68717 100644 --- a/docs-site/src/content/docs/ko/guides/model-ordering.md +++ b/docs-site/src/content/docs/ko/guides/model-ordering.md @@ -1,9 +1,9 @@ --- title: 모델 정렬에 관하여 -description: opencodex가 Codex 모델 선택기와 spawn_agent 모델 override의 순서를 정하는 방식. +description: CodexCommander가 Codex 모델 선택기와 spawn_agent 모델 override의 순서를 정하는 방식. --- -Codex 모델 선택기는 opencodex 설정에 적힌 프로바이더 선언 순서나 모델 배열 순서를 보존하지 +Codex 모델 선택기는 CodexCommander 설정에 적힌 프로바이더 선언 순서나 모델 배열 순서를 보존하지 않습니다. 최종 순서는 카탈로그 priority로 정해지며, 같은 priority를 가진 라우팅 모델에는 결정적인 알파벳순 정렬이 적용됩니다. @@ -13,7 +13,7 @@ Codex의 models-manager는 선택기에 표시되는 카탈로그 항목을 `pri 카탈로그 배열 순서는 버리므로 생성된 JSON 배열에서 항목을 앞으로 옮겨도 선택기에서는 앞으로 이동하지 않습니다. 이 제약은 `src/codex/catalog/sync.ts`에 직접 기록되어 있습니다. -따라서 opencodex는 배열 위치가 아니라 더 낮은 priority를 부여해 featured 위치를 제어합니다. +따라서 CodexCommander는 배열 위치가 아니라 더 낮은 priority를 부여해 featured 위치를 제어합니다. 이 표의 고정값과 아래 예시는 유효한 account selector가 없는 설정을 설명합니다. `N`개의 selector가 있으면 설정 rank `i`의 featured bare native는 priority `i * N + j`인 selector 행으로 확장되며, `j`는 0부터 시작하는 selector 위치입니다. featured routed 행은 `i * N`, exact account-qualified @@ -67,7 +67,7 @@ Codex의 priority 정렬에서도 이 선두 순서가 보존됩니다. 3. 카탈로그 병합 과정에서 featured 블록 아래로 밀린 선택되지 않은 네이티브 모델 `subagentModels`가 없으면 라우팅 모델은 priority `5`를 유지하고, 네이티브 GPT 항목은 정상 priority -(opencodex가 만든 항목은 보통 `9`)를 사용합니다. 라우팅 그룹 내부는 계속 프로바이더/id +(CodexCommander가 만든 항목은 보통 `9`)를 사용합니다. 라우팅 그룹 내부는 계속 프로바이더/id 알파벳순입니다. ## 예시 @@ -110,12 +110,12 @@ account selector가 있으면 bare native 선택이 selector-qualified 그룹으 **Agent Library**에는 다섯 개를 훨씬 넘는 카탈로그 모델이 있을 수 있습니다. 라우트가 사용 가능할 때 항목을 정확한 id로 지정할 수 있으며, 다섯 칸 제한은 `spawn_agent`에 가장 먼저 알려지는 오버라이드에만 적용됩니다. -`ocx agent subagents set`을 사용하거나 opencodex 설정을 편집해 라이브 라이브러리에 없는 정확한 +`ccx agent subagents set`을 사용하거나 CodexCommander 설정을 편집해 라이브 라이브러리에 없는 정확한 `<selector>/<native-openai-model>` 선택지를 추가하세요. 커맨드 센터는 이미 설정된 정확한 selector를 프로바이더가 일시적으로 사용 불가능한 동안에도 보존하고 순서를 바꿀 수 있습니다. account selector가 있으면 bare native 하나가 여러 selector-qualified 행으로 확장될 수 있으므로 설정 항목과 노출 행이 항상 일대일로 대응하지는 않습니다. -현재 `OcxConfig`에는 일반 `modelOrder`, `providerOrder`, priority map 설정이 없습니다. 지원되는 정렬 +현재 `CodexCommanderConfig`에는 일반 `modelOrder`, `providerOrder`, priority map 설정이 없습니다. 지원되는 정렬 필드는 `subagentModels`입니다. `disabledModels`와 각 프로바이더의 `selectedModels`는 노출 필드입니다. 따라서 나머지 선택기 순서를 바꾸려면 설정 수정이 아니라 코드 동작 변경이 필요합니다. diff --git a/docs-site/src/content/docs/ko/guides/model-routing.md b/docs-site/src/content/docs/ko/guides/model-routing.md index 187c40a20e..3d7dfd3486 100644 --- a/docs-site/src/content/docs/ko/guides/model-routing.md +++ b/docs-site/src/content/docs/ko/guides/model-routing.md @@ -1,6 +1,6 @@ --- title: 모델 라우팅 -description: opencodex가 주어진 모델 id를 어느 프로바이더가 처리할지 결정하는 방식. +description: CodexCommander가 주어진 모델 id를 어느 프로바이더가 처리할지 결정하는 방식. --- Codex가 모델을 요청하면 `router.ts`가 이를 정확히 하나의 설정된 프로바이더로 해석합니다. 규칙은 @@ -26,7 +26,7 @@ fallback하지 않습니다. 2. **Combo id 또는 alias** — combo가 하나 이상 설정되어 있는 동안에는 canonical `combo/<id>` 또는 설정된 combo alias가 provider namespace보다 먼저 concrete target을 선택합니다. 설정된 combo가 - 하나도 없으면 이름이 정확히 `combo`인 legacy physical provider는 일반 provider namespace로 + 하나도 없으면 이름이 정확히 `combo`인 physical provider는 일반 provider namespace로 유지됩니다. target selection과 failover 동작은 [Combos](/ko/guides/combos/)를 참고하십시오. 3. **명시적 `provider/model`** — id에 `/`가 포함되어 있고 그 앞부분이 설정된 프로바이더의 이름이면, diff --git a/docs-site/src/content/docs/ko/guides/opencode.md b/docs-site/src/content/docs/ko/guides/opencode.md index 7063610ffb..d08b3db496 100644 --- a/docs-site/src/content/docs/ko/guides/opencode.md +++ b/docs-site/src/content/docs/ko/guides/opencode.md @@ -1,10 +1,10 @@ --- title: opencode -description: opencode에서 라우팅된 어떤 모델이든 사용하세요. opencodex가 런타임 provider 블록을 주입하고, 사용자의 opencode 설정은 그대로 둡니다. +description: opencode에서 라우팅된 어떤 모델이든 사용하세요. CodexCommander가 런타임 provider 블록을 주입하고, 사용자의 opencode 설정은 그대로 둡니다. --- opencode는 환경 변수 대신 병합된 JSON 구성 레이어에서 provider를 읽으므로, -`ANTHROPIC_BASE_URL`처럼 끼워 넣을 자리가 없습니다. `ocx opencode`는 그 간극을 +`ANTHROPIC_BASE_URL`처럼 끼워 넣을 자리가 없습니다. `ccx opencode`는 그 간극을 메웁니다. 프록시가 실행 중인지 확인하고, 표시된 카탈로그에서 provider 블록을 만들고, OpenCode의 인라인 런타임 레이어(`OPENCODE_CONFIG_CONTENT`)를 통해 주입합니다. @@ -12,70 +12,70 @@ opencode는 환경 변수 대신 병합된 JSON 구성 레이어에서 provider ## 빠른 시작 ```bash -ocx opencode +ccx opencode ``` 이 명령은 프록시가 실행 중임을 보장하고, 그 프로세스에는 생성된 -`provider.opencodex` 블록만 주입한 채 opencode를 실행합니다. 추가 인자는 그대로 -전달됩니다: `ocx opencode run "hello"`. +`provider.codexcommander` 블록만 주입한 채 opencode를 실행합니다. 추가 인자는 그대로 +전달됩니다: `ccx opencode run "hello"`. -라우팅된 모델은 선택기에서 `opencodex` 공급자 아래에 나타납니다: +라우팅된 모델은 선택기에서 `codexcommander` 공급자 아래에 나타납니다: ```text -opencodex/kiro/glm-5 -opencodex/gpt-5.6-sol # native slugs stay unprefixed +codexcommander/kiro/glm-5 +codexcommander/gpt-5.6-sol # native slugs stay unprefixed ``` ## 사용자 구성은 절대 수정되지 않습니다 런처는 `~/.config/opencode/opencode.json`, 프로젝트의 `opencode.json` / `opencode.jsonc`, 그리고 그 밖의 어떤 디스크상의 구성 레이어도 복사하거나 다시 -쓰지 않습니다. 전역 또는 프로젝트 구성을 읽어 `provider.opencodex` 재정의가 있는지만 +쓰지 않습니다. 전역 또는 프로젝트 구성을 읽어 `provider.codexcommander` 재정의가 있는지만 확인할 수 있으며, 기존의 공급자, 에이전트, 키 바인딩, MCP 항목, 그리고 상대 경로 `{file:…}` 참조는 계속 원래 파일을 기준으로 해석됩니다. -이번 실행에서만 opencodex는 생성된 `provider.opencodex` 블록을 OpenCode의 인라인 +이번 실행에서만 CodexCommander는 생성된 `provider.codexcommander` 블록을 OpenCode의 인라인 런타임 레이어를 통해 추가합니다. 이 레이어는 전역/사용자 지정/프로젝트 구성 뒤에 병합되며, 자식 프로세스에서는 충돌하는 키만 덮어씁니다. -| 레이어 | `ocx opencode`에서의 동작 | +| 레이어 | `ccx opencode`에서의 동작 | | --- | --- | | 전역 / 사용자 지정 / 프로젝트 구성 | 사용자가 쓴 그대로 디스크에 남습니다 | -| 인라인 런타임 (`OPENCODE_CONFIG_CONTENT`) | 생성된 `provider.opencodex` 블록만 받습니다 | +| 인라인 런타임 (`OPENCODE_CONFIG_CONTENT`) | 생성된 `provider.codexcommander` 블록만 받습니다 | | 상대 `{file:…}` 경로 | 원래 정의된 구성 파일을 기준으로 계속 해석됩니다 | -전역 또는 프로젝트 구성에도 `provider.opencodex`가 정의되어 있으면, 런처는 안내 -메시지를 출력합니다. `ocx opencode`의 런타임 레이어가 이번 실행에서는 그것을 +전역 또는 프로젝트 구성에도 `provider.codexcommander`가 정의되어 있으면, 런처는 안내 +메시지를 출력합니다. `ccx opencode`의 런타임 레이어가 이번 실행에서는 그것을 덮어씁니다. ## 대시보드 영구 연결(선택 사항) -일반 OpenCode, 편집기 통합 또는 Desktop 원클릭 실행에는 OpenCodex 대시보드의 -**Integrations**에서 **Apply connection**을 선택합니다. 이는 `ocx opencode`와 별도의 경로입니다. +일반 OpenCode, 편집기 통합 또는 Desktop 원클릭 실행에는 CodexCommander 대시보드의 +**Integrations**에서 **Apply connection**을 선택합니다. 이는 `ccx opencode`와 별도의 경로입니다. - `XDG_CONFIG_HOME` 아래의 활성 전역 OpenCode 파일(보통 `~/.config/opencode/`) 중 기존 `opencode.jsonc`를 우선하고, 없으면 `opencode.json`을 선택합니다. -- JSONC 편집은 `provider.opencodex`만 바꾸므로 주석, 서식, 다른 provider, agent, MCP와 키는 +- JSONC 편집은 `provider.codexcommander`만 바꾸므로 주석, 서식, 다른 provider, agent, MCP와 키는 보존됩니다. -- 프록시 인증 토큰은 OpenCodex의 보호된 상태에 남고 OpenCode 구성에는 +- 프록시 인증 토큰은 CodexCommander의 보호된 상태에 남고 OpenCode 구성에는 `{file:/absolute/path}` 참조만 들어갑니다. OpenCode 인증 저장소는 읽지 않습니다. - **Always keep OpenCode connected**는 기본적으로 꺼져 있으며, 명시적으로 켠 후에만 프록시 시작 또는 표시된 카탈로그 변경 때 이 관리 블록을 갱신합니다. **Restore**는 journal이 정확한 복원을 안전하다고 판단할 때 원본 바이트를 정확히 복원합니다. 그 외에는 -Dashboard가 사용자의 다른 수정은 보존하고 관리되는 `provider.opencodex`만 되돌립니다. +Dashboard가 사용자의 다른 수정은 보존하고 관리되는 `provider.codexcommander`만 되돌립니다. **Open OpenCode**는 Desktop을 원클릭으로 열며, CLI만 설치한 경우에는 디스크를 수정하지 않는 -`ocx opencode`를 사용하세요. +`ccx opencode`를 사용하세요. ## 블록을 사용자 구성에 넣기 -`ocx opencode`는 provider 블록을 한 번의 실행에만 주입합니다. 위의 대시보드 영구 연결을 적용하지 +`ccx opencode`는 provider 블록을 한 번의 실행에만 주입합니다. 위의 대시보드 영구 연결을 적용하지 않았다면 평범한 `opencode`는 여전히 프록시를 모릅니다. 일반 `opencode`에서, 혹은 런처를 거치지 않는 편집기 -확장에서 라우팅된 모델을 쓰고 싶다면 `ocx export`가 같은 provider 블록을 출력해 +확장에서 라우팅된 모델을 쓰고 싶다면 `ccx export`가 같은 provider 블록을 출력해 주므로 사용자 구성에 병합하면 됩니다: ```bash -ocx export --client opencode +ccx export --client opencode ``` 프록시는 실행 중이어야 합니다. 이 명령은 구성, 표준 대상 위치 @@ -85,32 +85,32 @@ ocx export --client opencode 사용자가 직접 하는 일입니다. :::caution[병합하고, 절대 교체하지 마세요] -기존 구성에 `provider.opencodex` 블록을 병합하세요. 내보낸 파일로 전체를 바꾸면 +기존 구성에 `provider.codexcommander` 블록을 병합하세요. 내보낸 파일로 전체를 바꾸면 기존의 공급자, 에이전트, 키 바인딩, MCP 항목이 모두 사라집니다. -`ocx export --out`이 이미 존재하는 파일을 덮어쓰지 못하게 막는 이유가 바로 이것입니다. +`ccx export --out`이 이미 존재하는 파일을 덮어쓰지 못하게 막는 이유가 바로 이것입니다. 그러니 `--out`은 임시 경로를 가리키게 두고, 블록만 옮겨 담으세요: ```bash -ocx export --client opencode --out ~/opencodex-opencode.json +ccx export --client opencode --out ~/codexcommander-opencode.json ``` ::: 런처의 런타임 블록과 달리, 병합한 블록은 정적인 스냅샷입니다. 카탈로그를 따라가지 -않습니다. provider를 추가하거나 모델 노출을 바꾼 뒤에는 `ocx export`를 다시 +않습니다. provider를 추가하거나 모델 노출을 바꾼 뒤에는 `ccx export`를 다시 실행하세요. 병합한 뒤에는 opencode를 실행하기 전에 인증 키를 export하세요. 단, 프록시가 loopback에 바인딩되어 있으면 필요하지 않습니다: ```bash -export OPENCODEX_OPENCODE_API_KEY=<your key> +export CODEXCOMMANDER_OPENCODE_API_KEY=<your key> ``` ## 인증 키는 디스크에 쓰이지 않습니다 프록시가 API 키를 요구할 때, 인라인 런타임 구성에는 비밀값 대신 opencode의 `{env:…}` 참조가 들어갑니다. 루프백 바인드에서는 그 참조를 `apiKey`로 사용하고, -루프백이 아닌 바인드에서는 `x-opencodex-api-key`로만 보내므로 프록시 인증은 상위 +루프백이 아닌 바인드에서는 `x-codexcommander-api-key`로만 보내므로 프록시 인증은 상위 `Authorization` 헤더와 분리됩니다. 루프백 예시: @@ -118,7 +118,7 @@ export OPENCODEX_OPENCODE_API_KEY=<your key> ```json "options": { "baseURL": "http://127.0.0.1:10100/v1", - "apiKey": "{env:OPENCODEX_OPENCODE_API_KEY}" + "apiKey": "{env:CODEXCOMMANDER_OPENCODE_API_KEY}" } ``` @@ -128,25 +128,25 @@ export OPENCODEX_OPENCODE_API_KEY=<your key> "options": { "baseURL": "http://192.168.1.10:10100/v1", "headers": { - "x-opencodex-api-key": "{env:OPENCODEX_OPENCODE_API_KEY}" + "x-codexcommander-api-key": "{env:CODEXCOMMANDER_OPENCODE_API_KEY}" } } ``` 실제 값은 자식 프로세스 환경으로만 전달됩니다. -`OPENCODEX_API_AUTH_TOKEN`이 가장 우선이고, 그다음 하드닝된 서비스 토큰 파일, +`CODEXCOMMANDER_API_AUTH_TOKEN`이 가장 우선이고, 그다음 하드닝된 서비스 토큰 파일, 그다음에 구성된 API 키가 옵니다. 루프백이 아닌 바인드에는 바로 이 API 키가 필요합니다. 루프백 바인드(`127.0.0.1`, 기본값)는 아무 인증도 하지 않으므로 `{env:…}` 참조는 아무 효과가 없고, 변수를 비워 둬도 됩니다. 이것이 중요해지는 것은 `hostname`이 루프백을 벗어날 때뿐입니다. [원격 접속](/reference/configuration/#remote-access)을 -보세요. 이 인증 키는 opencodex 전용이며, [공급자](/guides/providers/) 아래에 +보세요. 이 인증 키는 CodexCommander 전용이며, [공급자](/guides/providers/) 아래에 설정한 upstream provider 키와는 무관합니다. ## 되돌리기 -일회성 `ocx opencode` 실행은 되돌릴 것이 없습니다. OpenCode 구성 파일을 바꾸지 않기 때문입니다. +일회성 `ccx opencode` 실행은 되돌릴 것이 없습니다. OpenCode 구성 파일을 바꾸지 않기 때문입니다. 대시보드 연결은 **Integrations**의 **Restore**로 되돌립니다. journal이 허용하면 원본 바이트를 정확히 복원하고, 그렇지 않으면 관리되는 provider만 수술식으로 복원합니다. @@ -161,7 +161,7 @@ opencode의 스키마는 `output` 없이 `context`만 있는 `limit` 블록을 window에 맞춰 낮춥니다. 그 수치는 스키마를 만족시키기 위한 값일 뿐이며, 어떤 특정 모델의 실제 최대치를 뜻하지는 않습니다. -`opencodex` provider 블록은 실행할 때마다 다시 생성되므로, 그 안에서 한 모델별 +`codexcommander` provider 블록은 실행할 때마다 다시 생성되므로, 그 안에서 한 모델별 조정은 유지되지 않습니다. 대신 사용자만의 provider 키 아래에 사용자 정의 항목을 두세요. diff --git a/docs-site/src/content/docs/ko/guides/pi.md b/docs-site/src/content/docs/ko/guides/pi.md index 648d71060e..f39f82c8f7 100644 --- a/docs-site/src/content/docs/ko/guides/pi.md +++ b/docs-site/src/content/docs/ko/guides/pi.md @@ -1,10 +1,10 @@ --- title: Pi -description: Pi에서 라우팅된 모델을 그대로 쓸 수 있습니다. `ocx export`가 Pi의 `models.json`에 맞는 커스텀 provider 블록을 내보내고, 실행 중인 프록시에 연결합니다. +description: Pi에서 라우팅된 모델을 그대로 쓸 수 있습니다. `ccx export`가 Pi의 `models.json`에 맞는 커스텀 provider 블록을 내보내고, 실행 중인 프록시에 연결합니다. --- Pi는 provider를 환경 변수 대신 하나의 전역 JSON 파일에서 읽기 때문에, -opencodex가 Pi를 직접 실행하지 않습니다. 대신 `ocx export`가 `opencodex` provider 블록, +CodexCommander가 Pi를 직접 실행하지 않습니다. 대신 `ccx export`가 `codexcommander` provider 블록, 즉 base URL, 모델 목록, 그리고 Pi가 치환하는 환경 변수 참조를 직렬화해서 사용자가 자신의 설정에 병합하도록 합니다. @@ -13,8 +13,8 @@ opencodex가 Pi를 직접 실행하지 않습니다. 대신 `ocx export`가 `ope 프록시를 먼저 띄우고 config를 출력합니다. ```bash -ocx start -ocx export --client pi +ccx start +ccx export --client pi ``` 출력은 JSON으로 시작하고, 이어서 대상 경로, 병합 경고, 환경 변수 export 줄, 그리고 @@ -23,10 +23,10 @@ ocx export --client pi ```json { "providers": { - "opencodex": { + "codexcommander": { "baseUrl": "http://127.0.0.1:10100/v1", "api": "openai-completions", - "apiKey": "$OPENCODEX_API_KEY", + "apiKey": "$CODEXCOMMANDER_API_KEY", "models": [ { "id": "anthropic/claude-opus-5", @@ -55,18 +55,18 @@ Pi의 전역 모델 config는 다음과 같습니다. ``` :::caution[병합하고, 대체하지 마세요] -`ocx export`는 그 파일을 절대 쓰지 않습니다. `providers.opencodex` 블록을 그 안에 +`ccx export`는 그 파일을 절대 쓰지 않습니다. `providers.codexcommander` 블록을 그 안에 병합하세요. 파일을 통째로 바꾸면 이미 설정해 둔 다른 provider가 모두 사라집니다. `--out`은 임시 경로용이며, `--force` 없이 이미 존재하는 파일을 덮어쓰지 못합니다. ```bash -ocx export --client pi --out ~/opencodex-pi-models.json -ocx export --client pi --json > ~/opencodex-pi-models.json # or redirect the byte-exact JSON +ccx export --client pi --out ~/codexcommander-pi-models.json +ccx export --client pi --json > ~/codexcommander-pi-models.json # or redirect the byte-exact JSON ``` ::: 내보낸 블록은 실시간 뷰가 아니라 고정 스냅샷입니다. provider를 추가하거나 모델 -가시성을 바꾼 뒤에는 `ocx export`를 다시 실행하고, 새 블록을 옛 블록 위에 병합하세요. +가시성을 바꾼 뒤에는 `ccx export`를 다시 실행하고, 새 블록을 옛 블록 위에 병합하세요. ## 인증 키 @@ -74,21 +74,21 @@ ocx export --client pi --json > ~/opencodex-pi-models.json # or redirect the b | 키 | 무엇인지 | 어디에 있는지 | | --- | --- | --- | -| Proxy admission key | opencodex의 자체 인증 정보이며, 대시보드의 **API** 탭에서 생성됩니다 | `apiKey`로 `$OPENCODEX_API_KEY`를 참조하며, 값은 환경 변수에 둡니다 | -| Provider key | Anthropic / OpenAI / OpenRouter 키입니다 | opencodex의 자체 config에 있으며, [Providers](/guides/providers/)마다 따로 둡니다 | +| Proxy admission key | CodexCommander의 자체 인증 정보이며, 대시보드의 **API** 탭에서 생성됩니다 | `apiKey`로 `$CODEXCOMMANDER_API_KEY`를 참조하며, 값은 환경 변수에 둡니다 | +| Provider key | Anthropic / OpenAI / OpenRouter 키입니다 | CodexCommander의 자체 config에 있으며, [Providers](/guides/providers/)마다 따로 둡니다 | 내보낸 config에는 비밀값이 아니라 참조만 들어갑니다. Pi는 `$NAME` 형태를 그대로 치환하므로 변수는 다음과 같습니다. ```bash -export OPENCODEX_API_KEY=<your key> +export CODEXCOMMANDER_API_KEY=<your key> ``` 이 이름은 Pi 전용입니다. opencode는 다른 변수를 씁니다 -(`OPENCODEX_OPENCODE_API_KEY`, `{env:…}` 형식) - 자세한 내용은 [opencode 가이드](/guides/opencode/)를 보세요. +(`CODEXCOMMANDER_OPENCODE_API_KEY`, `{env:…}` 형식) - 자세한 내용은 [opencode 가이드](/guides/opencode/)를 보세요. -**루프백 프록시는 키가 전혀 필요 없습니다.** opencodex는 기본적으로 `127.0.0.1`에 -바인드하고 그곳에서는 아무 것도 인증하지 않으므로, `$OPENCODEX_API_KEY` 참조는 +**루프백 프록시는 키가 전혀 필요 없습니다.** CodexCommander는 기본적으로 `127.0.0.1`에 +바인드하고 그곳에서는 아무 것도 인증하지 않으므로, `$CODEXCOMMANDER_API_KEY` 참조는 실제로는 비어 있어도 됩니다. 이 값은 `hostname`이 루프백 바깥으로 설정될 때만 의미가 있으며, 그 경우에는 프록시가 토큰 없이 시작하지 않습니다. 자세한 내용은 [Remote access](/reference/configuration/#remote-access)를 보세요. @@ -97,14 +97,14 @@ export OPENCODEX_API_KEY=<your key> `contextWindow`와 `maxTokens`는 카탈로그가 확정된 context window를 보고할 때만 출력됩니다. 그렇지 않으면 두 필드 모두 해당 모델에서 생략되고, Pi는 자체 기본값을 -적용합니다. `ocx export`는 그 경우가 몇 줄이었는지도 함께 출력합니다. +적용합니다. `ccx export`는 그 경우가 몇 줄이었는지도 함께 출력합니다. `maxTokens`는 스키마를 만족시키기 위한 `32000` 예산이며, context window보다 더 크게 잡히지 않도록 아래로 잘립니다. 즉, 작은 context 모델에 그보다 많은 출력을 주겠다는 의미가 아닙니다. 의도적으로 빠진 필드도 두 개 있습니다. `cost`는 네 개의 가격 필드가 모두 있어야 -하는데, opencodex는 라우팅된 모델의 가격 데이터를 갖고 있지 않습니다. 0을 넣으면 +하는데, CodexCommander는 라우팅된 모델의 가격 데이터를 갖고 있지 않습니다. 0을 넣으면 모든 모델이 무료라고 주장하는 꼴이 됩니다. `reasoning`은 Pi에서는 boolean이지만 카탈로그는 effort 단계 체계를 들고 있으므로, 둘을 1:1로 맞추는 것은 추측입니다. @@ -114,11 +114,11 @@ export OPENCODEX_API_KEY=<your key> 위의 형태는 Pi가 공개한 custom-provider 문서를 따른 것입니다. Pi가 설치된 머신의 실제 `~/.pi/agent/models.json`으로는 아직 검증하지 않았습니다. Pi가 내보낸 블록을 거부하면 문제는 우리 쪽에 있습니다. Pi가 무엇을 보고했는지와 함께 -[issue를 열어주세요](https://github.com/lidge-jun/opencodex/issues). +[issue를 열어주세요](https://github.com/pavelhov/CodexCommander/issues). ::: ## 요구 사항 -실행 중인 opencodex 프록시(`ocx start`)와 설치된 Pi가 필요합니다. `ocx export`는 +실행 중인 CodexCommander 프록시(`ccx start`)와 설치된 Pi가 필요합니다. `ccx export`는 프록시의 management API를 통해 live catalog를 읽으므로, 빈 모델 목록으로는 config를 내보낼 수 없습니다. diff --git a/docs-site/src/content/docs/ko/guides/providers.md b/docs-site/src/content/docs/ko/guides/providers.md index adb66a769c..c92d8eb568 100644 --- a/docs-site/src/content/docs/ko/guides/providers.md +++ b/docs-site/src/content/docs/ko/guides/providers.md @@ -1,10 +1,10 @@ --- title: 프로바이더 -description: opencodex가 LLM 프로바이더를 인증하고 통신하는 모든 방식 — OAuth, API 키, ChatGPT 포워드, 그리고 로컬. +description: CodexCommander가 LLM 프로바이더를 인증하고 통신하는 모든 방식 — OAuth, API 키, ChatGPT 포워드, 그리고 로컬. --- **프로바이더**는 하나의 업스트림 LLM 엔드포인트와 거기에 도달하는 방법을 합친 것입니다: 어댑터, 베이스 URL, 인증 -모드, 그리고 선택적인 모델 목록으로 구성됩니다. 프로바이더는 `~/.opencodex/config.json`의 `providers` 아래에 위치합니다. +모드, 그리고 선택적인 모델 목록으로 구성됩니다. 프로바이더는 `~/.codexcommander/config.json`의 `providers` 아래에 위치합니다. ## OpenAI 계정 모드 @@ -38,10 +38,6 @@ Codex 로그인을 Pool 모드로 사용하면 Providers 개요에는 임의의 판단을 변경하지 않습니다. 개별 계정 상태와 라우팅 제어는 [Codex Auth 계정 풀](/ko/guides/web-dashboard/#codex-auth-and-account-pools)을 참고하세요. -shipped v1 config는 marker 2의 단일 옵션 행으로 자동 이관됩니다. 원본은 -`~/.opencodex/config.json.pre-openai-tiers-v2.bak`에 한 번 보존되며 다음 명령으로 복원합니다: -`cp ~/.opencodex/config.json.pre-openai-tiers-v2.bak ~/.opencodex/config.json`. - ## 인증 모드 프로바이더 설정에서 쓸 수 있는 `authMode`는 세 가지이며, 기본값은 `key`입니다. 빌트인 레지스트리는 @@ -51,7 +47,7 @@ shipped v1 config는 marker 2의 단일 옵션 행으로 자동 이관됩니다. | --- | --- | --- | | `key` | API 키를 전송합니다(`Authorization: Bearer …`, 또는 어댑터에 따라 `x-api-key` / `api-key`). 키는 리터럴이거나 `${ENV_VAR}` 참조일 수 있습니다. | 대부분의 프로바이더. | | `forward` | **수신된 Codex 인증 헤더를** 프로바이더에 그대로 중계합니다 — 키를 저장하지 않습니다. ChatGPT 로그인 패스스루입니다. | OpenAI (`openai-responses` 어댑터). | -| `oauth` | 저장된 OAuth 액세스 토큰을 bearer 키로 사용하고 자격 증명 소유권을 따릅니다. OpenCodex 소유 자격 증명은 만료 전에 갱신되며, 연결된 Grok/Kimi CLI 자격 증명은 읽기 전용으로 채택되어 네이티브 CLI 소유로 유지됩니다. | xAI, Anthropic, Kimi, Kiro, Google Antigravity, Cursor. | +| `oauth` | 저장된 OAuth 액세스 토큰을 bearer 키로 사용하고 자격 증명 소유권을 따릅니다. CodexCommander 소유 자격 증명은 만료 전에 갱신되며, 연결된 Grok/Kimi CLI 자격 증명은 읽기 전용으로 채택되어 네이티브 CLI 소유로 유지됩니다. | xAI, Anthropic, Kimi, Kiro, Google Antigravity, Cursor. | [`retryOn429`](/ko/reference/configuration/)(동일 키 429 재시도)는 API 키 프로바이더 (`authMode: "key"`)에만 적용됩니다. OAuth·forward·로컬 프리셋은 제외됩니다 — 같은 토큰을 @@ -84,40 +80,40 @@ ChatGPT 패스스루 카탈로그에는 GPT-5.6 Sol/Terra/Luna의 네임스페 ## 2. 계정 로그인 (OAuth) OAuth 로그인을 사용하는 프로바이더 프리셋은 일곱 개이며, 여기에 실험적 비공식 디바이스 플로우 -브리지를 쓰는 GitHub Copilot이 추가됩니다. 자격 증명은 `~/.opencodex/auth.json`에 저장됩니다. -OpenCodex 소유 자격 증명은 자동 갱신됩니다. 로그인된 Grok 또는 Kimi CLI 세션을 연결하면 -opencodex는 현재 액세스 세대를 읽기 전용으로 채택하고 갱신 책임은 네이티브 CLI에 남깁니다. +브리지를 쓰는 GitHub Copilot이 추가됩니다. 자격 증명은 `~/.codexcommander/auth.json`에 저장됩니다. +CodexCommander 소유 자격 증명은 자동 갱신됩니다. 로그인된 Grok 또는 Kimi CLI 세션을 연결하면 +CodexCommander는 현재 액세스 세대를 읽기 전용으로 채택하고 갱신 책임은 네이티브 CLI에 남깁니다. 로그인 CLI는 `chatgpt`도 받습니다. 이 명령은 ChatGPT 자격 증명을 발급받고 `forward` 모드 프로바이더 항목을 만듭니다. ```bash -ocx login xai # xAI Grok -ocx login anthropic # Anthropic Claude (Pro/Max) -ocx login kimi # Moonshot Kimi -ocx login kiro # kiro-cli 자격 증명 가져오기(토큰 폴백 지원) -ocx login google-antigravity -ocx login cursor # Cursor 전용 PKCE 로그인 -ocx login command-code # Command Code 브라우저 OAuth (또는 ~/.commandcode/auth.json 가져오기) -ocx login github-copilot # GitHub 디바이스 플로우 → Copilot 토큰 (Copilot Pro/Business) -ocx login chatgpt # 별도 ChatGPT OAuth 로그인 -ocx logout <provider> +ccx login xai # xAI Grok +ccx login anthropic # Anthropic Claude (Pro/Max) +ccx login kimi # Moonshot Kimi +ccx login kiro # kiro-cli 자격 증명 가져오기(토큰 폴백 지원) +ccx login google-antigravity +ccx login cursor # Cursor 전용 PKCE 로그인 +ccx login command-code # Command Code 브라우저 OAuth (또는 ~/.commandcode/auth.json 가져오기) +ccx login github-copilot # GitHub 디바이스 플로우 → Copilot 토큰 (Copilot Pro/Business) +ccx login chatgpt # 별도 ChatGPT OAuth 로그인 +ccx logout <provider> ``` | 프로바이더 | 어댑터 | 베이스 URL | 비고 | | --- | --- | --- | --- | | `xai` | `openai-chat` | `https://api.x.ai/v1` | 실시간 목록을 우선 사용하며, 폴백 기본 모델은 `grok-4.5`입니다. | | `anthropic` | `anthropic` | `https://api.anthropic.com` | Claude 모델; 실시간 모델 목록은 `/v1/models`에서 가져옵니다. | -| `kimi` | `openai-chat` | `https://api.kimi.com/coding/v1` | Kimi K3(`k3`, 1M 컨텍스트), 고정 윈도우 `k3-256k`, 호환 별칭 `k3[1m]`, 레거시 K2.7/K2.6/K2.5 코딩 모델. | -| `kiro` | `kiro` | `https://runtime.us-east-1.kiro.dev` | 최초 로그인은 설치하고 로그인한 `kiro-cli` 세션을 가져옵니다(Unix에서는 `curl -fsSL https://cli.kiro.dev/install | bash`, Windows PowerShell에서는 `irm 'https://cli.kiro.dev/install.ps1' | iex`로 설치한 뒤 `kiro-cli login` 실행). **계정 추가**는 `kiro-cli`에서 로그아웃한 뒤 새 브라우저 로그인을 시작하여 `kiro-cli` 자체의 계정을 전환하고, 계정별 프로필 메타데이터를 저장합니다. 기존 OpenCodex 계정은 유지되며, 취소되거나 실패하면 이전 `kiro-cli` 세션을 복원합니다. | +| `kimi` | `openai-chat` | `https://api.kimi.com/coding/v1` | Kimi K3(`k3`, 1M 컨텍스트), 고정 윈도우 `k3-256k`, 호환 별칭 `k3[1m]`, K2.7/K2.6/K2.5 코딩 모델. | +| `kiro` | `kiro` | `https://runtime.us-east-1.kiro.dev` | 최초 로그인은 설치하고 로그인한 `kiro-cli` 세션을 가져옵니다(Unix에서는 `curl -fsSL https://cli.kiro.dev/install | bash`, Windows PowerShell에서는 `irm 'https://cli.kiro.dev/install.ps1' | iex`로 설치한 뒤 `kiro-cli login` 실행). **계정 추가**는 `kiro-cli`에서 로그아웃한 뒤 새 브라우저 로그인을 시작하여 `kiro-cli` 자체의 계정을 전환하고, 계정별 프로필 메타데이터를 저장합니다. 기존 CodexCommander 계정은 유지되며, 취소되거나 실패하면 이전 `kiro-cli` 세션을 복원합니다. | | `google-antigravity` | `google` | `https://daily-cloudcode-pa.googleapis.com` | Google OAuth를 Cloud Code Assist wire로 사용합니다. CCA가 범용 `/models` 엔드포인트를 제공하지 않으므로 유지 관리되는 6개 모델 정적 카탈로그를 사용합니다. | | `cursor` | `cursor` | `https://api2.cursor.sh` | 실험적 PKCE 로그인, HTTP/2 전송, 계정별 모델 탐색을 지원합니다. | | `github-copilot` | `openai-chat` | `https://api.githubcopilot.com` | 실험적. GitHub 디바이스 플로우 + `copilot_internal` 교환(VS Code OAuth 클라이언트). 활성 Copilot 구독 필요; 공식 서드파티 API가 아닙니다. | -정식 Kimi Coding Plan 프리셋(`kimi` 계정 로그인과 `kimi-code` API key)의 경우, opencodex는 +정식 Kimi Coding Plan 프리셋(`kimi` 계정 로그인과 `kimi-code` API key)의 경우, CodexCommander는 호출자가 제공한 안정적인 `prompt_cache_key`만 Chat Completions 요청으로 전달하며 직접 생성하지 않습니다. Kimi 문서는 Code Plan 캐시 적중률을 높이기 위해 안정적인 세션/작업 key가 필요하다고 명시합니다. key가 없는 요청은 keyless 상태로 유지됩니다. opt-in한 업스트림이 이 필드를 거부해도 -opencodex는 필드를 제거해 재시도하거나 저장된 설정을 변경하지 않습니다. 다른 프로바이더는 +CodexCommander는 필드를 제거해 재시도하거나 저장된 설정을 변경하지 않습니다. 다른 프로바이더는 deny-by-default 상태로 유지됩니다. [웹 대시보드](/ko/guides/web-dashboard/)에서도 OAuth를 시작할 수 있습니다. @@ -127,25 +123,25 @@ deny-by-default 상태로 유지됩니다. 자격 증명에 고정된 계정 id나 이메일이 있는 OAuth 프로바이더는 로그인을 여러 개 보관할 수 있습니다. Providers 페이지에서 계정을 추가하고, 다른 계정을 로그아웃하지 않은 채 활성 계정만 바꿀 수 있습니다. 계정 식별 정보가 없는 Kimi 자격 증명만 활성 슬롯을 교체하며, Kiro 계정은 프로필 ARN을 키로 저장됩니다. -`chatgpt`는 Codex 계정 풀에 별도 저장소가 있어 항상 단일 슬롯만 씁니다. 토큰은 `~/.opencodex/auth.json`에 저장되고, +`chatgpt`는 Codex 계정 풀에 별도 저장소가 있어 항상 단일 슬롯만 씁니다. 토큰은 `~/.codexcommander/auth.json`에 저장되고, `/api/oauth/accounts`는 마스킹된 메타데이터만 반환합니다. ### Kiro 자격 증명 가져오기 -Kiro 로그인에는 Kiro CLI가 필요합니다. Unix에서는 `curl -fsSL https://cli.kiro.dev/install | bash`, Windows PowerShell에서는 `irm 'https://cli.kiro.dev/install.ps1' | iex`로 설치한 뒤 먼저 `kiro-cli login`으로 로그인하세요. `kiro-cli` 세션이 없으면 `ocx login kiro`는 붙여 넣은 액세스 토큰이나 `KIRO_ACCESS_TOKEN` 환경 변수로 폴백합니다. +Kiro 로그인에는 Kiro CLI가 필요합니다. Unix에서는 `curl -fsSL https://cli.kiro.dev/install | bash`, Windows PowerShell에서는 `irm 'https://cli.kiro.dev/install.ps1' | iex`로 설치한 뒤 먼저 `kiro-cli login`으로 로그인하세요. `kiro-cli` 세션이 없으면 `ccx login kiro`는 붙여 넣은 액세스 토큰이나 `KIRO_ACCESS_TOKEN` 환경 변수로 폴백합니다. -일반 `ocx login kiro` 가져오기는 CLI SQLite 데이터베이스를 읽기 전용으로 열며 데이터베이스, WAL, SHM을 수정하지 않습니다. +일반 `ccx login kiro` 가져오기는 CLI SQLite 데이터베이스를 읽기 전용으로 열며 데이터베이스, WAL, SHM을 수정하지 않습니다. - `KIROCLI_DB_PATH`는 비표준 Kiro CLI SQLite 데이터베이스를 선택하며, 지정한 데이터베이스는 이미 존재해야 합니다. - `KIROCLI_TOKEN_KEY`는 모호한 토큰 행이 여러 개일 때 가져올 정확한 `auth_kv` 행의 키를 선택합니다. 선택값이 없으면 추측하지 않고 로그인이 실패합니다. -가져온 자격 증명은 `~/.opencodex/auth.json`에 저장됩니다. **계정 추가** 롤백은 별도 절차로, 이전 스냅샷을 복원할 때 데이터베이스를 교체하고 현재 WAL, SHM, journal 사이드카를 제거합니다. +가져온 자격 증명은 `~/.codexcommander/auth.json`에 저장됩니다. **계정 추가** 롤백은 별도 절차로, 이전 스냅샷을 복원할 때 데이터베이스를 교체하고 현재 WAL, SHM, journal 사이드카를 제거합니다. 롤백은 스냅샷이 있을 때만 가능하므로, 세션 저장소가 존재하지만 캡처할 수 없는 경우(파일을 읽을 수 없음, 스키마 불일치, 토큰 선택 모호), `KIROCLI_DB_PATH` / `KIRO_CLI_DB_FILE`이 실제 CLI 저장소와 다른 가져오기 경로를 가리키는 경우, 또는 기본 CLI 데이터베이스에 인식 가능한 토큰 행이 없는 경우 **계정 추가**는 `kiro-cli` 로그아웃을 거부합니다. 일반 `kiro-cli` 데이터 경로의 손상된 데이터베이스를 수리하거나 제거하고, 가져오기 전용 선택자가 설정돼 있으면 해제한 뒤 다시 시도하세요. 기존 `kiro-cli` 세션이 아예 없는 환경에서는 영향이 없습니다. ## 3. API 키 카탈로그 -opencodex에는 빌트인 프리셋이 76개 들어 있습니다. 키 방식 64개, OAuth 8개, 로컬 3개, +CodexCommander에는 빌트인 프리셋이 76개 들어 있습니다. 키 방식 64개, OAuth 8개, 로컬 3개, 기본 ChatGPT 포워드 프리셋 1개입니다. 대시보드의 **Add provider** 선택기는 키 발급 페이지를 열고, 입력한 키를 검증한 뒤 저장합니다(검증은 프로바이더별로 다릅니다). 주요 항목은 다음과 같습니다: @@ -153,9 +149,9 @@ opencodex에는 빌트인 프리셋이 76개 들어 있습니다. 키 방식 64 [Chat Completions 엔드포인트](https://docs.cline.bot/api/chat-completions)에 연결합니다. 운영 주체는 [Cline 약관](https://cline.bot/tos)에 명시된 Cline Bot Inc.입니다. `cline-pass/cline-pass/kimi-k3` 같은 라우팅 ID는 정상입니다. -앞의 `cline-pass`는 opencodex 프로바이더이고, 뒤의 `cline-pass/kimi-k3`는 upstream에 보내는 +앞의 `cline-pass`는 CodexCommander 프로바이더이고, 뒤의 `cline-pass/kimi-k3`는 upstream에 보내는 전체 모델 slug입니다. ClinePass 사용량은 계정의 5시간 롤링·주간·월간 한도를 함께 사용합니다. -현재 opencodex는 실측된 `low` reasoning 단계만 광고하며, 더 높은 요청은 공식 지원 범위가 +현재 CodexCommander는 실측된 `low` reasoning 단계만 광고하며, 더 높은 요청은 공식 지원 범위가 게시되거나 검증될 때까지 `low`로 제한합니다. **Cline**은 동일한 API 키·엔드포인트를 종량제로 사용하며 100개 이상의 모델에 접근합니다 @@ -215,14 +211,14 @@ Volcengine Agent Plan은 `openai-responses` 어댑터로 네이티브 Responses `opencode-go`는 `https://opencode.ai/zen/go/v1`의 OpenCode Go 구독 제공자이며 OpenCode Desktop/CLI와는 별개입니다. [OpenCode 콘솔](https://opencode.ai/console)에서 키를 만든 뒤 대시보드 **Providers**에서 **OpenCode Go**를 추가하거나 그 키로 `opencode-go` 프리셋을 구성하세요. -OpenCodex는 OpenCode 인증 저장소를 읽거나 이 키를 Keychain으로 마이그레이션하지 않습니다. +CodexCommander는 OpenCode 인증 저장소를 읽지 않으며 이 키를 Keychain에 저장하지 않습니다. 공개 모델 카탈로그는 키가 작동한다는 증거가 아닙니다. 저장된 키는 활성 키로 첫 추론에 성공한 뒤에만 **검증됨**이 됩니다. 공개 한도는 참조값인 **$12 / 5시간**, **$30 / 7일**, **$60 / 30일**입니다. 해당 기간의 로컬 관측값은 실시간 남은 할당량이나 청구가 아닌 사용량 추정치입니다. 권위 있는 제한 이벤트는 업스트림이 구체적으로 보고한 경우에만 표시합니다. -내장 프리셋은 API 키 방식이므로 Add Provider에서 계정 로그인 대신 **Paid**로 분류되며, OpenCodex는 +내장 프리셋은 API 키 방식이므로 Add Provider에서 계정 로그인 대신 **Paid**로 분류되며, CodexCommander는 OpenCode Go OAuth 흐름을 제공하지 않습니다. Client Apps의 **OpenCode** 클라이언트 및 키가 필요 없는 **OpenCode Free** 프로바이더와도 별개입니다. Add Provider 검색은 Accounts, Free, Paid를 함께 검색하므로 어느 탭에서든 `opencode`를 입력하면 일치하는 프리셋과 구분이 표시됩니다. @@ -257,7 +253,7 @@ Nscale service token은 [Nscale Console](https://console.nscale.com)에서 만 **Command Code 검색:** 프리셋은 Command Code의 `/provider/v1/models` 목록을 고정된 Provider API 호스트에서 읽고, 슬래시가 포함된 네이티브 모델 ID를 보존하며 live discovery를 256 KiB와 raw 행 -256개로 제한합니다. `ocx login command-code`는 브라우저 OAuth 로그인을 지원하며(기존 Command Code +256개로 제한합니다. `ccx login command-code`는 브라우저 OAuth 로그인을 지원하며(기존 Command Code CLI 사용자는 `~/.commandcode/auth.json`의 로컬 CLI 자격 증명을 가져올 수 있음), 모델 카탈로그는 계정 단위이며 로그인 후 인증된 discovery 엔드포인트에서 가져옵니다. 채팅 요청은 설정된 bearer 키를 사용합니다. 키는 [Command Code Studio](https://commandcode.ai/studio/)에서 생성합니다. @@ -296,7 +292,7 @@ Project ID가 포함된 URL과 dedicated deployment는 custom provider로 설정 `openai-chat`, `authMode: "key"`, 공식 `https://api.a6api.com` 또는 `https://api.a6api.com/v1` 주소를 사용하는 사용자 지정 프로바이더는 대시보드와 -`ocx account refresh <provider>`에서 A6API 크레딧 사용량을 표시합니다. 프로바이더 이름은 자유롭게 정할 수 +`ccx account refresh <provider>`에서 A6API 크레딧 사용량을 표시합니다. 프로바이더 이름은 자유롭게 정할 수 있습니다. 계정의 hard credit limit을 기준으로 토큰 단위를 USD로 환산해 사용률과 남은 크레딧을 표시하며, 토큰 만료는 충전을 뜻하지 않으므로 쿼터 리셋으로 표시하지 않습니다. 활성 키만 공식 호스트로 전송하고 리디렉션을 거부하며, 음수이거나 서로 일치하지 않는 결제 합계에는 보고서를 만들지 않습니다. @@ -318,13 +314,13 @@ Project ID가 포함된 URL과 dedicated deployment는 custom provider로 설정 ### 터미널에서 계정 전환하기 -대시보드를 열지 않고도 `ocx account list`, `ocx account current`, `ocx account use`로 같은 Codex, +대시보드를 열지 않고도 `ccx account list`, `ccx account current`, `ccx account use`로 같은 Codex, OAuth, API-key pool을 확인하고 전환할 수 있습니다. 전체 명령, JSON 출력, 새 세션 적용 방식은 -[CLI 레퍼런스](/ko/reference/cli/#ocx-account-subcommand)를 참고하세요. +[CLI 레퍼런스](/ko/reference/cli/#ccx-account-subcommand)를 참고하세요. ### GPT-5.6 프리뷰 경로 -실시간 모델 카탈로그 갱신이 늦어도 `ocx sync`에서 모델이 사라지지 않도록 GPT-5.6 +실시간 모델 카탈로그 갱신이 늦어도 `ccx sync`에서 모델이 사라지지 않도록 GPT-5.6 Sol/Terra/Luna를 폴백 목록에 넣어 둡니다. | Codex 경로 | 미리 등록된 모델 id | Codex에 표시되는 컨텍스트 | @@ -340,12 +336,12 @@ Sol/Terra/Luna를 폴백 목록에 넣어 둡니다. 기준으로 현재 계정에서 쓸 수 있는 모델만 남깁니다. :::note[게이트웨이 및 구독 프록시] -프로바이더 지원 여부는 "에이전트" 제품인지가 아니라 opencodex에 맞는 wire 어댑터가 있는지로 +프로바이더 지원 여부는 "에이전트" 제품인지가 아니라 CodexCommander에 맞는 wire 어댑터가 있는지로 결정됩니다. 현재 어댑터 id는 `openai-chat`, `openai-responses`, `anthropic`, `google`(AI Studio, -Vertex, Antigravity/Cloud Code Assist 모드), `azure` / `azure-openai`, `kiro`, `cursor`입니다. +Vertex, Antigravity/Cloud Code Assist 모드), `azure-openai`, `kiro`, `cursor`입니다. Amazon Bedrock 네이티브 API처럼 이 구현 중 어느 것과도 맞지 않는 독자 프로토콜은 직접 지원하지 않습니다. **GitHub Copilot**과 **GitLab Duo**는 자신의 범용 OpenAI 호환 엔드포인트에 매핑된 멀티 모델 -게이트웨이입니다. Copilot은 `ocx login github-copilot`으로 GitHub 디바이스 플로우 OAuth 로그인을 +게이트웨이입니다. Copilot은 `ccx login github-copilot`으로 GitHub 디바이스 플로우 OAuth 로그인을 지원합니다(비공식 브리지 — VS Code 공개 클라이언트 id로 로그인 후 단기 Copilot API 토큰으로 교환하며, 활성 Copilot 구독이 필요하고 GitHub 정책 변경으로 막힐 수 있음). GitLab Duo는 Bearer **구독 토큰**(일반 API 키가 아님)으로 인증합니다. **Cloudflare AI @@ -353,23 +349,23 @@ Gateway**는 URL에 계정 + 게이트웨이 id를 채워야 합니다. Copilot은 혼합 wire 카탈로그를 제공합니다. GPT-5 계열 모델(`gpt-5.3-codex`, `gpt-5.4`, `gpt-5.4-mini`, `gpt-5.5`, `gpt-5.6-luna`, `gpt-5.6-sol`, `gpt-5.6-terra`)은 에이전트 -트래픽에 대해 `/chat/completions`를 거부하므로 opencodex는 이 모델들을 내장 기본값으로 +트래픽에 대해 `/chat/completions`를 거부하므로 CodexCommander는 이 모델들을 내장 기본값으로 Responses API를 통해 라우팅하고, 다른 Copilot 모델은 모두 chat completions를 유지합니다. 우선순위는 하드 wire 핀 → 명시적 [`modelAdapters`](/ko/reference/configuration/providers/) 항목 → 레지스트리 기본값 → 프로바이더 전체 adapter 순입니다. 내장 기본값이 없는 모델(예: `gpt-5.4-nano`)을 Responses로 전환하려면 `"modelAdapters": { "gpt-5.4-nano": "openai-responses" }`를 설정하세요. -Cursor는 별도의 실험적 어댑터로 추적합니다. `adapter: "cursor"`는 `ocx init`과 dashboard Add +Cursor는 별도의 실험적 어댑터로 추적합니다. `adapter: "cursor"`는 `ccx init`과 dashboard Add Provider picker에 실험적 local config 항목으로 표시되며, Cursor의 static fallback model catalog -metadata를 저장합니다. Cursor access token이 설정되면 opencodex는 Cursor live HTTP/2 transport를 +metadata를 저장합니다. Cursor access token이 설정되면 CodexCommander는 Cursor live HTTP/2 transport를 사용합니다. 번들 폴백 목록에는 1M 컨텍스트의 `gpt-5.6-sol` / `terra` / `luna`, 500K 컨텍스트의 `grok-4.5` / `grok-4.5-fast`, 262K 컨텍스트의 `kimi-k3`가 들어 있으며, 실시간 탐색 결과에 따라 현재 계정에 표시할 모델을 결정합니다. Cursor는 Kimi K3를 effort 접미사가 붙은 wire id로만 제공하므로 `cursor/kimi-k3`는 `low` / `high` / `max` 래더를 노출하고 기본값은 모델 문서의 API 기본값과 같은 `max`입니다. Cursor 서버가 직접 보내는 native read/write/delete/ls/grep/shell/fetch 실행은 Codex 승인 및 sandbox 경로를 우회하므로 기본적으로 비활성화되어 있습니다. 신뢰한 로컬 실험에서만 -`~/.opencodex/config.json`의 `providers.cursor`에 `unsafeAllowNativeLocalExec: true`를 설정하세요. +`~/.codexcommander/config.json`의 `providers.cursor`에 `nativeLocalExec: "on"`을 설정하세요. 대시보드에서는 **Providers → Cursor → Edit JSON**에서 설정할 수 있습니다. 전체 예시는 [설정 레퍼런스](/ko/reference/configuration/#cursor-provider-adapter-cursor)를 참고하세요. MCP, 화면 녹화, computer-use는 executor hook으로 열려 있으며, 로컬 @@ -381,7 +377,7 @@ model discovery는 이 실험적 어댑터에서 활성화되어 있으며, Curs ### Ollama Cloud Ollama Cloud는 호스팅형(로컬이 아님) Ollama로, `https://ollama.com/v1`에서 OpenAI 호환이며 키는 -[ollama.com/settings/keys](https://ollama.com/settings/keys)에서 발급받습니다. opencodex는 클라우드 +[ollama.com/settings/keys](https://ollama.com/settings/keys)에서 발급받습니다. CodexCommander는 클라우드 라인업을 비전 기능에 따라 분류하여 [비전 사이드카](/ko/guides/sidecars/)가 텍스트 전용 모델에만 작동하도록 합니다. 텍스트 전용 모델(예: `glm-5.2`, `deepseek-v4-pro`, `gpt-oss`, `qwen3-coder`, `minimax-m2.x`, `nemotron-3-*`)은 `noVisionModels`에 나열되며, 비전 네이티브 모델(예: @@ -390,7 +386,7 @@ Ollama의 `:size` 태그에 관대하므로 `gpt-oss`는 `gpt-oss:120b`와 `gpt- ## 4. 로컬 프로바이더 -opencodex를 로컬 OpenAI 호환 서버로 향하게 하세요 — 보통은 빈 키와 함께 사용합니다: +CodexCommander를 로컬 OpenAI 호환 서버로 향하게 하세요 — 보통은 빈 키와 함께 사용합니다: | 프로바이더 | 베이스 URL | | --- | --- | @@ -401,6 +397,6 @@ opencodex를 로컬 OpenAI 호환 서버로 향하게 하세요 — 보통은 ## 모든 OpenAI 호환 엔드포인트 프로바이더가 Chat Completions를 사용한다면 `openai-chat` 어댑터가 이를 처리합니다 — 대시보드에서 -**Custom**을 선택하거나 `ocx init`에서 `custom`을 선택한 뒤 베이스 URL을 입력하세요. 모든 프로바이더 필드 +**Custom**을 선택하거나 `ccx init`에서 `custom`을 선택한 뒤 베이스 URL을 입력하세요. 모든 프로바이더 필드 (`headers`, `noReasoningModels`, `noVisionModels`, `models`, …)는 [설정 레퍼런스](/ko/reference/configuration/)를 참고하세요. diff --git a/docs-site/src/content/docs/ko/guides/sidecars.md b/docs-site/src/content/docs/ko/guides/sidecars.md index 1ea7596bda..bbf8fb126d 100644 --- a/docs-site/src/content/docs/ko/guides/sidecars.md +++ b/docs-site/src/content/docs/ko/guides/sidecars.md @@ -3,7 +3,7 @@ title: "사이드카: 웹 검색 및 비전" description: 네이티브 ChatGPT 사이드카를 통해 라우팅 모델에 실제 웹 검색을, 텍스트 전용 모델에 이미지 이해 기능을 제공합니다. --- -라우팅 모델마다 호스팅 **웹 검색**이나 네이티브 **이미지 입력** 지원 범위가 다릅니다. opencodex는 +라우팅 모델마다 호스팅 **웹 검색**이나 네이티브 **이미지 입력** 지원 범위가 다릅니다. CodexCommander는 ChatGPT 로그인(`forward`) 프로바이더나 저장된 Anthropic OAuth 프로바이더를 사용하는 두 사이드카로 부족한 기능을 보완합니다. 사이드카 오류는 턴 전체를 실패시키지 않고 길이가 제한된 도구 결과나 이미지 안내문으로 바뀝니다. @@ -17,7 +17,7 @@ OAuth 프로바이더가 있을 때 `anthropic`, 없을 때 `openai`를 사용 ## 웹 검색 사이드카 -Codex가 패스스루가 아닌 라우팅 모델에 호스팅 `web_search`를 요청하면 opencodex는 다음 순서로 +Codex가 패스스루가 아닌 라우팅 모델에 호스팅 `web_search`를 요청하면 CodexCommander는 다음 순서로 처리합니다. 1. 호스팅 `web_search` 도구를 **제거하고** 라우팅 모델에는 합성 `web_search(query)` 함수 도구를 @@ -30,7 +30,7 @@ Codex가 패스스루가 아닌 라우팅 모델에 호스팅 `web_search`를 **반복**합니다. 한도에 닿으면 검색 도구를 제거하고 최종 답변을 강제합니다. `apply_patch`나 shell 같은 실제 클라이언트 도구가 나오면 턴을 끝내 해당 호출이 Codex에 전달되게 합니다. -라우팅 모델의 모든 반복은 업스트림에 `stream: true`를 요청하지만, opencodex는 검색 여부나 최종 +라우팅 모델의 모든 반복은 업스트림에 `stream: true`를 요청하지만, CodexCommander는 검색 여부나 최종 답변을 결정하기 전에 의미 있는 event를 내부에서 전부 버퍼링합니다. 첫 번째 반복의 최종 header/status와 429 key rotation만 미리 가져옵니다. 따라서 합성 검색 호출과 중간 출력은 클라이언트에 모델 출력으로 노출되지 않습니다. @@ -69,10 +69,10 @@ stall은 전체 생성 timeout이 아닙니다. SSE가 시작되기 전 실패 ## 비전 사이드카 -라우팅 모델이 해당 프로바이더의 `noVisionModels`에 있고 요청에 이미지가 들어오면, opencodex는 +라우팅 모델이 해당 프로바이더의 `noVisionModels`에 있고 요청에 이미지가 들어오면, CodexCommander는 메인 호출 **전에** 각 이미지를 설명한 텍스트로 바꿉니다. Dashboard와 관리 API의 현재 기본 선택값은 -`gpt-5.6-luna`이며, 시작할 때 명시적으로 저장된 기존 `gpt-5.4-mini` 값도 Luna로 마이그레이션합니다. -다만 `visionSidecar.model` 필드 자체가 없으면 비전 실행 경로는 코드 폴백인 `gpt-5.4-mini`를 씁니다. +`gpt-5.6-luna`입니다. `visionSidecar.model` 필드 자체가 없으면 비전 실행 경로는 코드 폴백인 +`gpt-5.4-mini`를 씁니다. - 이미지는 사용자, developer, 도구 결과 메시지에서 올 수 있습니다. Codex의 `view_image` 결과도 포함됩니다. diff --git a/docs-site/src/content/docs/ko/guides/sub-agent-surface.md b/docs-site/src/content/docs/ko/guides/sub-agent-surface.md index ee921476d0..cf2a879b07 100644 --- a/docs-site/src/content/docs/ko/guides/sub-agent-surface.md +++ b/docs-site/src/content/docs/ko/guides/sub-agent-surface.md @@ -5,7 +5,7 @@ description: Codex가 모든 모델에서 서브에이전트를 생성하고 관 ## 서브에이전트란 -서브에이전트는 메인 에이전트가 집중된 작업을 맡기기 위해 생성할 수 있는 별도의 Codex 작업자입니다. 자체 컨텍스트와 도구를 가지므로 서로 독립적인 작업을 병렬로 진행할 수 있습니다. opencodex는 어떤 Codex 협업 서피스가 이 작업자들을 노출할지, Codex가 서브에이전트에 어떤 모델을 제공할지, 실패한 모델이 어떻게 대체 경로로 넘어갈지를 제어합니다. 다만 메인 에이전트가 언제 위임해야 하는지는 결정하지 않습니다. +서브에이전트는 메인 에이전트가 집중된 작업을 맡기기 위해 생성할 수 있는 별도의 Codex 작업자입니다. 자체 컨텍스트와 도구를 가지므로 서로 독립적인 작업을 병렬로 진행할 수 있습니다. CodexCommander는 어떤 Codex 협업 서피스가 이 작업자들을 노출할지, Codex가 서브에이전트에 어떤 모델을 제공할지, 실패한 모델이 어떻게 대체 경로로 넘어갈지를 제어합니다. 다만 메인 에이전트가 언제 위임해야 하는지는 결정하지 않습니다. ## 모드 @@ -29,7 +29,7 @@ description: Codex가 모든 모델에서 서브에이전트를 생성하고 관 - **base**는 업스트림 핀을 복원합니다. 핀이 없는 항목은 기본 `multi_agent_v2` 기능 플래그를 따릅니다. - **v2**는 모든 모델에 `multi_agent_version = "v2"`를 설정합니다. -opencodex는 이 값을 Codex가 읽는 실시간 `/v1/models` 카탈로그와 디스크에 동기화된 카탈로그 모두에 마지막 단계로 적용합니다. 그래서 모드를 바꾸면 새로 만들어지는 App, CLI, TUI 세션에 일관되게 반영됩니다. +CodexCommander는 이 값을 Codex가 읽는 실시간 `/v1/models` 카탈로그와 디스크에 동기화된 카탈로그 모두에 마지막 단계로 적용합니다. 그래서 모드를 바꾸면 새로 만들어지는 App, CLI, TUI 세션에 일관되게 반영됩니다. v2 로스터의 경우 적합성은 세 가지 상태로 나뉩니다. `"v2"`로 표시된 항목, 명시적으로 `null`로 설정된 항목, 또는 `multi_agent_version` 필드가 없는 항목은 사용 가능합니다. 진짜 `"v1"` 핀은 해당 모델이 다른 협업 서피스에 속한다고 명시하므로 제외됩니다. @@ -37,11 +37,11 @@ v2 로스터의 경우 적합성은 세 가지 상태로 나뉩니다. `"v2"`로 대시보드의 **서브에이전트 위임** 설정은 다음 세 가지 값을 제어합니다. -- `injectionModel`은 opencodex 가이드에서 선호하는 작업자 모델입니다. +- `injectionModel`은 CodexCommander 가이드에서 선호하는 작업자 모델입니다. - `injectionEffort`는 해당 모델에 요청할 선택적 `reasoning_effort`입니다. - `injectionPrompt`는 내장 v2 가이드 문구를 바꿉니다. -`multiAgentGuidanceEnabled`는 기본적으로 켜져 있으며, opencodex가 작성한 가이드에 대한 전역 스위치입니다. 이 값을 끄면 v2 지정 블록과 v1의 능동적 안내 문구가 모두 사라집니다. +`multiAgentGuidanceEnabled`는 기본적으로 켜져 있으며, CodexCommander가 작성한 가이드에 대한 전역 스위치입니다. 이 값을 끄면 v2 지정 블록과 v1의 능동적 안내 문구가 모두 사라집니다. 이 값들은 메인 에이전트에 대한 지시이며, 프록시 쪽 스폰 라우터가 아닙니다. v2에서는 전체 히스토리 fork가 부모 모델을 상속하고 모델 또는 추론 강도 오버라이드를 거부합니다. 그래서 가이드는 `model` 또는 `reasoning_effort`를 넘길 때 `fork_turns: "none"`(또는 `"3"` 같은 양수 부분 turn 수)을 사용하고, 작업 메시지를 자체 완결형으로 만들라고 안내합니다. @@ -54,31 +54,31 @@ v2 로스터의 경우 적합성은 세 가지 상태로 나뉩니다. `"v2"`로 | `{{roster}}` | 해석된 선택기 표시 가능, 서피스 호환 로스터 | | `{{fallback}}` | 설정된 전역 폴백 가이드 | -내장 v2 가이드는 700자 예산을 가집니다. 이 한도를 넘기면 opencodex는 핵심 스폰 지시를 자르는 대신 로스터를 먼저 제거합니다. 내장 가이드는 선호 모델, 적합한 로스터 또는 폴백 체인이 해석될 때만 발화합니다. 사용자 정의 프롬프트는 `injectionModel`만 설정되어 있어도 발화하며, 선택자가 없는 값을 하나로 해석할 수 없으면 `{{model}}`은 빈 문자열로 치환됩니다. +내장 v2 가이드는 700자 예산을 가집니다. 이 한도를 넘기면 CodexCommander는 핵심 스폰 지시를 자르는 대신 로스터를 먼저 제거합니다. 내장 가이드는 선호 모델, 적합한 로스터 또는 폴백 체인이 해석될 때만 발화합니다. 사용자 정의 프롬프트는 `injectionModel`만 설정되어 있어도 발화하며, 선택자가 없는 값을 하나로 해석할 수 없으면 `{{model}}`은 빈 문자열로 치환됩니다. -v1에서는 opencodex가 `max` 또는 `ultra` 추론 강도에서만 업스트림 스타일의 능동 위임 가이드만 주입합니다. v1에는 선호 모델, 로스터, 폴백 목록, 사용자 정의 프롬프트를 추가하지 않습니다. +v1에서는 CodexCommander가 `max` 또는 `ultra` 추론 강도에서만 업스트림 스타일의 능동 위임 가이드만 주입합니다. v1에는 선호 모델, 로스터, 폴백 목록, 사용자 정의 프롬프트를 추가하지 않습니다. -기본값이 꺼진 `syncCodexSubagentDefaults` 옵션은 가이드와 별개입니다. opencodex가 활성 Codex 라우팅을 소유하는 경우, 동기화나 재시작 시 선택한 값을 Codex TOML의 표식이 붙은 `[agents] default_subagent_model` 및 `default_subagent_reasoning_effort` 항목으로 쓸 수 있습니다. opencodex는 자신이 붙인 표식이 있는 필드만 갱신하거나 제거합니다. 대상 필드 중 하나라도 사용자 소유라면 부분 쓰기는 하지 않고 쌍을 그대로 둡니다. 애매한 TOML은 쓰기 없이 거부합니다. 외부 프로바이더 관리자와 사용자 소유 루트 라우팅도 여전히 최종 권한을 가집니다. +기본값이 꺼진 `syncCodexSubagentDefaults` 옵션은 가이드와 별개입니다. CodexCommander가 활성 Codex 라우팅을 소유하는 경우, 동기화나 재시작 시 선택한 값을 Codex TOML의 표식이 붙은 `[agents] default_subagent_model` 및 `default_subagent_reasoning_effort` 항목으로 쓸 수 있습니다. CodexCommander는 자신이 붙인 표식이 있는 필드만 갱신하거나 제거합니다. 대상 필드 중 하나라도 사용자 소유라면 부분 쓰기는 하지 않고 쌍을 그대로 둡니다. 애매한 TOML은 쓰기 없이 거부합니다. 외부 프로바이더 관리자와 사용자 소유 루트 라우팅도 여전히 최종 권한을 가집니다. ## Fallback 체인 -스폰된 작업자에 대해 opencodex는 다음 우선순위를 적용합니다. +스폰된 작업자에 대해 CodexCommander는 다음 우선순위를 적용합니다. 1. 요청한 기본 모델 2. 역할의 `$CODEX_HOME/agents/*.toml` 정의에 있는 `model_fallback` 목록 -3. opencodex 설정의 전역 `subagentModelFallback` 목록 +3. CodexCommander 설정의 전역 `subagentModelFallback` 목록 -중복 모델 id는 첫 번째 출현을 유지한 채 제거합니다. 선택 과정에서 opencodex는 비활성화된 후보, 라우팅 불가 후보, 비활성화된 프로바이더가 받쳐주는 후보, unhealthy로 표시된 후보, cooldown 중인 후보, 사용할 수 있는 pooled Codex 계정이 없는 후보, 또는 설정된 quota 임계치를 넘는 후보를 건너뜁니다. 가용성 프로브는 기본값 60초인 `subagentModelFallbackPollMs` 동안 캐시됩니다. +중복 모델 id는 첫 번째 출현을 유지한 채 제거합니다. 선택 과정에서 CodexCommander는 비활성화된 후보, 라우팅 불가 후보, 비활성화된 프로바이더가 받쳐주는 후보, unhealthy로 표시된 후보, cooldown 중인 후보, 사용할 수 있는 pooled Codex 계정이 없는 후보, 또는 설정된 quota 임계치를 넘는 후보를 건너뜁니다. 가용성 프로브는 기본값 60초인 `subagentModelFallbackPollMs` 동안 캐시됩니다. 폴백이 호환되지 않는 암호화 작업을 읽을 수 있게 만들어 주지는 않습니다. 자식 작업이 ChatGPT용으로 암호화되어 있으면, 체인 앞쪽에 외부 모델이 있더라도 선택은 정규 네이티브 ChatGPT 대상만 허용됩니다. ## 암호화된 v2 작업 전달 -Codex는 v2 네이티브→라우팅 자식 작업을 백엔드 암호화된 `encrypted_content`로만 보낼 수 있습니다. 이 페이로드는 네이티브 ChatGPT 백엔드가 읽을 수 있지만 외부 프로바이더는 읽을 수 없습니다. 이것이 알려진 [#92 제한](https://github.com/lidge-jun/opencodex/issues/92)입니다. +Codex는 v2 네이티브→라우팅 자식 작업을 백엔드 암호화된 `encrypted_content`로만 보낼 수 있습니다. 이 페이로드는 네이티브 ChatGPT 백엔드가 읽을 수 있지만 외부 프로바이더는 읽을 수 없습니다. 이것이 알려진 [#92 제한](https://github.com/pavelhov/CodexCommander/issues/92)입니다. -이는 기본값인 `multiAgentV2MessageDelivery: "encrypted"`의 동작입니다. 실험적인 `"plaintext"`를 선택하면 OpenCodex는 완전하게 인식된 V2 스키마만 비예약 네임스페이스로 변환하고 Codex 응답에서 다시 `collaboration`으로 복원합니다. 따라서 Sol 같은 네이티브 부모가 V2 수명주기를 유지한 채 Kimi, Grok, DeepSeek에 위임할 수 있습니다. 단, 네이티브 자식에게 보내는 메시지를 포함해 해당 부모의 모든 V2 메시지가 평문이 됩니다. 저장 후 새 세션을 시작해야 하며, 알 수 없거나 부분적인 스키마는 변환하지 않고 안전하게 실패합니다. +이는 기본값인 `multiAgentV2MessageDelivery: "encrypted"`의 동작입니다. 실험적인 `"plaintext"`를 선택하면 CodexCommander는 완전하게 인식된 V2 스키마만 비예약 네임스페이스로 변환하고 Codex 응답에서 다시 `collaboration`으로 복원합니다. 따라서 Sol 같은 네이티브 부모가 V2 수명주기를 유지한 채 Kimi, Grok, DeepSeek에 위임할 수 있습니다. 단, 네이티브 자식에게 보내는 메시지를 포함해 해당 부모의 모든 V2 메시지가 평문이 됩니다. 저장 후 새 세션을 시작해야 하며, 알 수 없거나 부분적인 스키마는 변환하지 않고 안전하게 실패합니다. -opencodex는 읽을 수 없거나 빈 작업을 그대로 넘기지 않고 안전하게 실패합니다. +CodexCommander는 읽을 수 없거나 빈 작업을 그대로 넘기지 않고 안전하게 실패합니다. - 비네이티브 직접 라우팅은 HTTP 400과 `error.code = "unreadable_encrypted_agent_task"`를 반환하며, 암호문을 에코하지 않습니다. - 콤보는 해당 작업에 대해 재시도를 포함해 정규 네이티브 ChatGPT 대상만 고려합니다. 사용할 수 있는 대상이 없으면 같은 400 오류를 반환합니다. @@ -101,27 +101,27 @@ opencodex는 읽을 수 없거나 빈 작업을 그대로 넘기지 않고 안 ### CLI -서피스 협업 설정과 네이티브 기능 설정에는 `ocx v2`를 사용합니다. +서피스 협업 설정과 네이티브 기능 설정에는 `ccx v2`를 사용합니다. ```bash -ocx v2 status -ocx v2 mode v1 -ocx v2 mode default -ocx v2 mode v2 -ocx v2 threads 8 +ccx v2 status +ccx v2 mode v1 +ccx v2 mode default +ccx v2 mode v2 +ccx v2 threads 8 ``` -위임, 로스터, 추론 상한, 폴백 설정에는 `ocx agent`를 사용합니다. +위임, 로스터, 추론 상한, 폴백 설정에는 `ccx agent`를 사용합니다. ```bash -ocx agent status -ocx agent injection set --model anthropic/claude-sonnet-5 --effort xhigh -ocx agent subagents set gpt-5.6-sol,anthropic/claude-sonnet-5 -ocx agent fallback set gpt-5.4-mini,xai/grok-4.5 --poll-ms 60000 -ocx agent effort set --subagent max +ccx agent status +ccx agent injection set --model anthropic/claude-sonnet-5 --effort xhigh +ccx agent subagents set gpt-5.6-sol,anthropic/claude-sonnet-5 +ccx agent fallback set gpt-5.4-mini,xai/grok-4.5 --poll-ms 60000 +ccx agent effort set --subagent max ``` -널 값이 가능한 `ocx agent injection` 값을 지우려면 `-`를 넘기거나, 로스터나 폴백 목록에는 해당 `clear` 액션을 사용하세요. 모든 명령 패밀리는 [CLI reference](/reference/cli/)를 참고하세요. +널 값이 가능한 `ccx agent injection` 값을 지우려면 `-`를 넘기거나, 로스터나 폴백 목록에는 해당 `clear` 액션을 사용하세요. 모든 명령 패밀리는 [CLI reference](/reference/cli/)를 참고하세요. ### API @@ -163,11 +163,11 @@ curl -X PUT http://localhost:10100/api/injection-model \ ### 모드를 바꾸면 실행 중인 세션에도 반영되나요? -아닙니다. 모드를 바꾼 뒤에는 새 Codex 세션을 시작하세요. 오래 실행 중인 App 호스트에 오래된 카탈로그 상태가 남아 있으면 `ocx sync`를 실행한 뒤 해당 Codex 서피스를 다시 시작하세요. +아닙니다. 모드를 바꾼 뒤에는 새 Codex 세션을 시작하세요. 오래 실행 중인 App 호스트에 오래된 카탈로그 상태가 남아 있으면 `ccx sync`를 실행한 뒤 해당 Codex 서피스를 다시 시작하세요. ### 추론 강도 -`injectionEffort`는 위임된 작업자 가이드와, 명시적으로 활성화한 경우 네이티브 Codex 서브에이전트 기본값에만 영향을 줍니다. 부모 세션의 추론 강도는 바꾸지 않습니다. `ultra`는 Codex가 `max`로 변환하는 클라이언트 노출 상위 단계이며, opencodex는 그 값을 선택한 프로바이더에 맞게 매핑하거나 클램프합니다. +`injectionEffort`는 위임된 작업자 가이드와, 명시적으로 활성화한 경우 네이티브 Codex 서브에이전트 기본값에만 영향을 줍니다. 부모 세션의 추론 강도는 바꾸지 않습니다. `ultra`는 Codex가 `max`로 변환하는 클라이언트 노출 상위 단계이며, CodexCommander는 그 값을 선택한 프로바이더에 맞게 매핑하거나 클램프합니다. ### 컨텍스트 상한 diff --git a/docs-site/src/content/docs/ko/guides/video-bridge.md b/docs-site/src/content/docs/ko/guides/video-bridge.md index 325837848b..3e90a6d75d 100644 --- a/docs-site/src/content/docs/ko/guides/video-bridge.md +++ b/docs-site/src/content/docs/ko/guides/video-bridge.md @@ -5,13 +5,13 @@ description: 비OpenAI 모델을 통해 Grok Imagine Video로 영상을 생성 ## 개요 -Video Bridge는 opencodex가 라우팅한 OpenAI가 아닌 모델로 xAI의 Grok Imagine Video 생성을 사용할 수 있게 합니다. 활성화하면 대화에 합성 `video_gen` 도구가 주입됩니다. 모델은 이를 일반 함수 도구처럼 호출하고, opencodex는 이 호출을 가로채 xAI에 영상 생성 작업을 제출한 뒤 완료될 때까지 폴링하고 결과를 내려받습니다. +Video Bridge는 CodexCommander가 라우팅한 OpenAI가 아닌 모델로 xAI의 Grok Imagine Video 생성을 사용할 수 있게 합니다. 활성화하면 대화에 합성 `video_gen` 도구가 주입됩니다. 모델은 이를 일반 함수 도구처럼 호출하고, CodexCommander는 이 호출을 가로채 xAI에 영상 생성 작업을 제출한 뒤 완료될 때까지 폴링하고 결과를 내려받습니다. ## 사전 조건 -- API 키가 있는 `xai` provider entry (`ocx login xai`만으로는 충분하지 않습니다. 비디오 브리지는 OAuth가 아니라 키 인증이 필요합니다) +- API 키가 있는 `xai` provider entry (`ccx login xai`만으로는 충분하지 않습니다. 비디오 브리지는 OAuth가 아니라 키 인증이 필요합니다) - 라우팅 대상 provider로 비OpenAI 모델 사용 예시: Anthropic Claude, Google Gemini -- 비OpenAI provider를 거치도록 opencodex 설정 +- 비OpenAI provider를 거치도록 CodexCommander 설정 > **⚠ Provider key required:** 비디오 브리지는 `xai` provider가 > API key auth를 사용할 때만 활성화됩니다. 설정에 다음을 추가하십시오: @@ -24,7 +24,7 @@ Video Bridge는 opencodex가 라우팅한 OpenAI가 아닌 모델로 xAI의 Grok > } > ``` > -> `ocx login xai`(OAuth)로 연결했다면 provider는 계속 `authMode: "oauth"` +> `ccx login xai`(OAuth)로 연결했다면 provider는 계속 `authMode: "oauth"` > 상태이며, 브리지는 아무 경고 없이 활성화되지 않습니다. 환경 변수로 `XAI_API_KEY`를 > 설정하거나, 위처럼 키를 직접 넣으십시오. @@ -53,9 +53,9 @@ Video Bridge는 opencodex가 라우팅한 OpenAI가 아닌 모델로 xAI의 Grok ## 동작 방식 -1. opencodex는 `videoBridgeEnabled: true`가 켜진 비OpenAI 라우팅 모델을 감지합니다. +1. CodexCommander는 `videoBridgeEnabled: true`가 켜진 비OpenAI 라우팅 모델을 감지합니다. 2. 합성 `video_gen` 함수 도구가 대화에 주입됩니다. -3. 모델이 `video_gen`을 호출하면, opencodex는 xAI의 `/videos/generations`로 작업을 제출합니다. +3. 모델이 `video_gen`을 호출하면, CodexCommander는 xAI의 `/videos/generations`로 작업을 제출합니다. 4. 브리지는 5-15초마다 작업 상태를 폴링하고, 스트림을 살리기 위해 heartbeat 메시지를 보냅니다. 5. 비디오가 준비되면 artifacts 디렉터리로 내려받습니다. 6. 로컬 파일 경로가 도구 결과로 모델에 반환됩니다. diff --git a/docs-site/src/content/docs/ko/guides/web-dashboard.md b/docs-site/src/content/docs/ko/guides/web-dashboard.md index edc3da2792..142a992f23 100644 --- a/docs-site/src/content/docs/ko/guides/web-dashboard.md +++ b/docs-site/src/content/docs/ko/guides/web-dashboard.md @@ -1,29 +1,29 @@ --- title: 웹 대시보드 -description: 프록시 상태, 프로바이더, 모델, 위임 안내, 인증 풀, 사용량, 로그를 관리하는 opencodex GUI. +description: 프록시 상태, 프로바이더, 모델, 위임 안내, 인증 풀, 사용량, 로그를 관리하는 CodexCommander GUI. --- -opencodex는 프록시가 제공하는 로컬 웹 대시보드(`gui/` 아래의 Vite/React 앱)를 포함합니다. +CodexCommander는 프록시가 제공하는 로컬 웹 대시보드(`gui/` 아래의 Vite/React 앱)를 포함합니다. 프로바이더, Codex/ChatGPT 계정, 카탈로그 모델, 사이드카, 서브에이전트 설정, 요청 트래픽을 가장 빠르게 관리할 수 있는 화면입니다. ## 열기 ```bash -ocx gui +ccx gui ``` 브라우저에서 `http://localhost:<port>`를 엽니다. 프록시가 꺼져 있으면 먼저 자동으로 시작합니다. 개발 중에는 실행 중인 프록시와 GUI 개발 서버를 따로 띄울 수 있습니다. ```bash -ocx start +ccx start bun run dev:gui ``` ## 로그인 -`localhost`나 `127.0.0.1` 같은 loopback 주소에서 연 대시보드는 짧게 유지되는 GUI 세션을 자동으로 받으므로 보통 토큰을 입력할 필요가 없습니다. loopback이 아닌 호스트로 공개한 대시보드에는 `OPENCODEX_ADMIN_AUTH_TOKEN` 또는 자동 생성되는 `~/.opencodex/admin-api-token` 파일의 관리자 토큰이 필요합니다. +`localhost`나 `127.0.0.1` 같은 loopback 주소에서 연 대시보드는 짧게 유지되는 GUI 세션을 자동으로 받으므로 보통 토큰을 입력할 필요가 없습니다. loopback이 아닌 호스트로 공개한 대시보드에는 `CODEXCOMMANDER_ADMIN_AUTH_TOKEN` 또는 자동 생성되는 `~/.codexcommander/admin-api-token` 파일의 관리자 토큰이 필요합니다. 원격 대시보드는 표준 비밀번호 폼을 표시하므로 브라우저 비밀번호 관리자가 토큰 저장과 자동 완성을 제안할 수 있습니다. 대시보드 자체는 토큰을 메모리에만 보관하며 `localStorage`나 `sessionStorage`에 쓰지 않습니다. 저장 여부는 전적으로 브라우저 또는 비밀번호 관리자가 결정합니다. @@ -32,19 +32,19 @@ bun run dev:gui | 영역 | 기능 | | --- | --- | | **Dashboard 요약** | Multi-agent 모드, 온라인 상태, 버전, 가동 시간, 프로바이더 수, 최근 30일 토큰 합계, 활성 프로바이더와 사용 가능한 네이티브/라우팅 모델을 보여줍니다. | -| **Sub-agent delegation** | OpenCodex 위임 가이드와 선택적인 Codex 네이티브 서브에이전트 기본값이 함께 사용할 네이티브/라우팅 모델과 선택적 reasoning 강도를 고릅니다. 스폰별 라우터는 아닙니다. 아래 설명을 확인하세요. | +| **Sub-agent delegation** | CodexCommander 위임 가이드와 선택적인 Codex 네이티브 서브에이전트 기본값이 함께 사용할 네이티브/라우팅 모델과 선택적 reasoning 강도를 고릅니다. 스폰별 라우터는 아닙니다. 아래 설명을 확인하세요. | | **사이드카** | 웹 검색 모델과 강도, 이미지 설명 모델을 선택합니다. 다음 요청부터 적용됩니다. | -| **Maintenance** | Codex 모델 카탈로그를 다시 동기화하고, 프로젝트 로컬 설정의 우회 경고를 확인하고, latest/preview 업데이트를 조회하거나 선택적 프록시 재시작과 함께 설치합니다. | +| **Maintenance** | Codex 모델 카탈로그를 다시 동기화하고 프로젝트 로컬 설정의 우회 경고를 확인합니다. | | **시작 안전성** | 주입된 Codex 라우팅이 재부팅 후에도 유지되는지 서비스와 launcher shim 상태, 정확한 복구 명령과 함께 표시합니다. | | **Windows 트레이** | 로그인할 때 사용자 전용 트레이를 시작하고 프록시 시작·중지·재시작·대시보드·상태를 클릭으로 제어합니다. 트레이는 재시작 서비스가 아닙니다. | -| **Codex 자동 시작** | 이미 설치된 Codex launcher shim이 `ocx ensure`를 실행하도록 허용합니다. 이 토글은 shim이나 백그라운드 서비스를 설치하지 않습니다. | +| **Codex 자동 시작** | 이미 설치된 Codex launcher shim이 `ccx ensure`를 실행하도록 허용합니다. 이 토글은 shim이나 백그라운드 서비스를 설치하지 않습니다. | | **Providers** | 프로바이더를 추가, 편집, 기본으로 설정(활성만), 활성화/비활성화, 제거하고, 지원되는 OAuth 계정 풀과 API key 풀을 관리합니다. 현재 기본 프로바이더를 제거하면 남아 있는 첫 번째 활성 프로바이더로 전환됩니다(있는 경우); 없으면 삭제가 거부되고 현재 기본이 유지됩니다. Claude(Anthropic) OAuth 풀에서는 로그인한 계정마다 자체 5시간·주간 한도 막대가 표시되며(사용량은 자격 증명 단위), 조회 실패 시 마지막 값을 유지하고 일시 불가 상태로 표시합니다. | | **Add provider** | 레지스트리 기반 프리셋에서 계정 로그인, API key 서비스, 로컬 서버, custom endpoint를 검색합니다. 검색어는 Accounts, Free, Paid를 함께 찾고 탭은 둘러보기에 사용됩니다. | | **Codex Auth** | ChatGPT/Codex 풀 계정을 추가하고, 다음 세션 계정을 선택하고, 5시간 / 주간 / 30일 할당량을 갱신하며, 할당량 자동 전환을 켜거나 끄고 1~100% 임계값과 일시적 실패 failover를 설정합니다. | | **Subagents** | **Agent Command Center**에서 `spawn_agent`에 노출할 다섯 모델을 선택하고 순서를 정하며, 현재 카탈로그를 검색하고 프로토콜·V2 전달·안내·폴백·스레드 제한의 Run Policy를 설정합니다. 저장됐지만 노출되지 않은 항목은 명시적으로 보고됩니다. | | **Models** | 네이티브 GPT와 라우팅 모델을 켜고 끄고, 프로바이더 allowlist와 컨텍스트 상한을 설정하며, **Classic v1**, **Follow Codex defaults**, **Concurrent v2**를 선택하고 v2 thread 수를 설정합니다. Current behavior 카드는 컨텍스트를 **Uncapped**, **Limited**, **Mixed limits**로 표시합니다. 각 라우팅 프로바이더에는 **자동 검색 켜짐** 또는 **정적 카탈로그만** 상태와 해당 프로바이더 설정 링크가 표시됩니다. | | **Client Apps** | 설정된 로컬 클라이언트와 연결 가능한 클라이언트를 확인하고, 지원되는 관리 설정을 적용하거나 제거하며 백업을 검토합니다. Codex, Claude Code/Desktop, Grok Build, OpenCode와 파일 관리 클라이언트를 프로바이더와 구분해 한곳에서 찾을 수 있습니다. | -| **API Access** | 다른 앱이 OpenCodex 프록시에 인증할 키를 발급하고 관리합니다. 업스트림 프로바이더 자격 증명은 Providers에 남습니다. | +| **API Access** | 다른 앱이 CodexCommander 프록시에 인증할 키를 발급하고 관리합니다. 업스트림 프로바이더 자격 증명은 Providers에 남습니다. | | **Logs** | 토큰, 요청한 강도와 (사용 가능한 경우) 실제 전송 강도, 실제 모델, 프로바이더, 상태, 요청 id, 소요 시간, 오류 상세가 포함된 최근 요청을 자동 갱신합니다. 어댑터가 reasoning 매개변수를 전송한 경우 상세 보기에 정확한 wire field도 표시됩니다. 클라이언트가 보낸 불투명 대화/세션 id로 필터하면 현재 로드된 Logs 링의 토큰·추정 정가 합계를 볼 수 있습니다. | | **Usage / Debug** | 토큰 사용량의 측정 범위와 추이를 보거나, 선택적 프로바이더 전송/사용량 추출 진단을 켭니다. | | **Storage** | CODEX_HOME 디스크 사용량(세션, 보관, DB, 첨부)을 읽기 전용으로 표시합니다. 선택적 보관 정리: 가장 오래된 N%를 미리본 뒤 기본으로 `CODEX_HOME/.trash`에 격리하거나, 명시 체크 후 영구 삭제합니다. **자동 정리 정책**은 opt-in이며 **기본 OFF**(`storageCleanupPolicy.enabled`)입니다. Storage 페이지에서 임계값/목표/일정/모드를 설정하거나 **지금 실행**하세요. Storage 페이지에서 격리 항목을 복원할 수 있습니다(JSONL + 스레드). 활성 세션은 읽기 전용입니다. Codex가 최신/활성 `state_*.sqlite`를 잠그면 정리와 복원을 거절합니다. | @@ -52,7 +52,7 @@ bun run dev:gui ### 섹션으로 바로 가기 -레이아웃은 하나뿐이라 전환할 설정이 없습니다. 대신 Dashboard의 섹션마다 주소가 있습니다. `#dashboard`는 Overview, `#dashboard/providers`와 `#dashboard/models`는 나머지 두 섹션입니다. 새로고침하거나 북마크해도, 뒤로 가도 보던 섹션이 그대로 유지됩니다. **Logs**도 `#logs`와 `#logs/debug`로 똑같이 동작합니다. 예전 `#providers/workspace` 북마크는 `#providers`로 넘어갑니다. +레이아웃은 하나뿐이라 전환할 설정이 없습니다. 대신 Dashboard의 섹션마다 주소가 있습니다. `#dashboard`는 Overview, `#dashboard/providers`와 `#dashboard/models`는 나머지 두 섹션입니다. 새로고침하거나 북마크해도, 뒤로 가도 보던 섹션이 그대로 유지됩니다. **Logs**도 `#logs`와 `#logs/debug`로 똑같이 동작합니다. **Logs**와 **Usage**의 비용 값은 보고된 토큰으로 계산한 API 정가 환산치입니다. 결제 영수증이나 실제 청구 증거가 아니며, 구독 사용량 또는 프로바이더 크레딧이 대신 적용될 수 있습니다. @@ -66,18 +66,18 @@ bun run dev:gui ## 위임 선택기와 스폰 라우팅의 차이 Dashboard의 **Sub-agent delegation** 선택기는 `injectionModel`과 선택적인 `injectionEffort`를 -저장합니다. 선택한 값은 OpenCodex가 작성하는 위임 가이드에 사용되고, 이 가이드는 +저장합니다. 선택한 값은 CodexCommander가 작성하는 위임 가이드에 사용되고, 이 가이드는 `multiAgentGuidanceEnabled`가 별도로 제어합니다. 모델을 지우면 저장된 강도도 지워지고 네이티브 기본값 동기화도 꺼집니다. -**Codex 네이티브 서브에이전트 기본값으로 사용**을 켜면 OpenCodex가 활성 Codex 라우팅을 관리하는 +**Codex 네이티브 서브에이전트 기본값으로 사용**을 켜면 CodexCommander가 활성 Codex 라우팅을 관리하는 경우 다음 sync 또는 restart에서 선택한 모델과 강도를 네이티브 `[agents]` 기본값으로 적용합니다. 외부 사용자 관리 provider 설정은 변경하지 않습니다. 이 기본값은 새로 생성되는 Codex task에만 적용되고, 이 옵션 자체가 위임을 일으키지는 않습니다. 기존 사용자 소유 `[agents]` 기본값은 덮어쓰지 않고 보존하므로 요청한 기본값과 실제 Codex 기본값이 다를 수 있습니다. :::caution -두 토글은 서로 독립적입니다. OpenCodex 위임 가이드를 꺼도 네이티브 기본값 동기화는 꺼지지 않고, +두 토글은 서로 독립적입니다. CodexCommander 위임 가이드를 꺼도 네이티브 기본값 동기화는 꺼지지 않고, 네이티브 기본값 동기화를 켜도 위임 가이드를 켜거나 위임을 발생시키지 않습니다. 어느 쪽도 프록시가 스폰마다 모델을 바꾸는 라우터가 아닙니다. v1/base/v2의 정확한 동작은 [서브에이전트 서피스](/ko/guides/sub-agent-surface/)를 참고하세요. @@ -101,7 +101,7 @@ Dashboard의 **Sub-agent delegation** 선택기는 `injectionModel`과 선택적 순서가 높은 계정부터 쓰이며, 그 위의 계정이 모두 소진되거나 사용할 수 없게 된 뒤에야 낮은 순서로 내려갑니다. 순서를 바꾸면 **다음 미바인딩 요청** 부터 적용되며, 이미 계정에 바인딩된 thread를 옮기지 않습니다. Codex Desktop(메인) 계정도 똑같이 정렬되므로 **가장 마지막**으로 두어 예비로 남길 수 - 있습니다. `ocx account priority`로 프리셋 밖의 값을 지정해도 카드에서 그대로 보이고 선택할 수 + 있습니다. `ccx account priority`로 프리셋 밖의 값을 지정해도 카드에서 그대로 보이고 선택할 수 있습니다. - Thread affinity가 요청마다 계정이 흔들리는 일을 막습니다. 할당량 자동 전환이 켜져 있으면 오래 실행되는 thread도 주기적으로 다시 평가합니다. 관련 사용량이 임계값 이상이고 사용량이 확실히 더 낮은 @@ -109,7 +109,7 @@ Dashboard의 **Sub-agent delegation** 선택기는 `injectionModel`과 선택적 - 새 세션은 사용량이 가장 낮은 정상 계정을 고를 수 있습니다. 유료 플랜은 알려진 5시간, 주간, 30일 창 중 가장 높은 사용률로 점수를 매기고, Go/Free 플랜은 30일 창만 사용합니다. - WHAM이 `limit_window_seconds`를 제공하면 Codex Auth는 28일 이상인 primary window를 주간이 아닌 - 30일 창으로 분류합니다. 기간이 없는 기존 응답은 이전과 동일하게 주간 창으로 해석합니다. + 30일 창으로 분류합니다. 기간 정보가 없는 응답은 주간 창으로 해석합니다. - **Refresh quotas**는 계정 사용량을 즉시 다시 읽어 라우팅과 화면의 계정 카드가 같은 값을 보게 합니다. - 풀 요청 로그에는 이메일 대신 `p3fa91c` 같은 불투명한 라벨을 사용합니다. @@ -127,7 +127,6 @@ GUI는 프록시의 JSON 관리 API를 사용하는 얇은 클라이언트입니 | `GET /api/startup-health` | 비밀값 없이 라우팅, 서비스, shim, 재부팅 안전성 진단을 읽습니다. | | `GET` / `POST /api/windows-tray` | Windows 트레이 설치 및 표시 상태를 읽거나 `install`, `start`, `stop`, `uninstall` 작업을 수행합니다. | | `POST /api/sync` | 공유 모델 카탈로그를 다시 만들고 Codex 모델 캐시를 오래된 상태로 표시합니다. | -| `GET /api/update/check` · `POST /api/update/run` · `GET /api/update/status` | 자체 업데이트 작업을 확인, 실행, 추적합니다. | | `GET` / `PUT /api/sidecar-settings` | 검색/비전 사이드카 모델 설정을 읽거나 바꿉니다. | | `GET` / `PUT /api/injection-model` | 위임 가이드의 모델/강도, 가이드 토글, Codex 네이티브 서브에이전트 기본값 동기화 토글을 읽거나 바꿉니다. | | `GET` / `PUT /api/v2` | 서피스 모드, Codex 기능 플래그, v2 thread 상한을 읽거나 바꿉니다. | diff --git a/docs-site/src/content/docs/ko/index.mdx b/docs-site/src/content/docs/ko/index.mdx index f1182e8c0d..655e263c5f 100644 --- a/docs-site/src/content/docs/ko/index.mdx +++ b/docs-site/src/content/docs/ko/index.mdx @@ -1,10 +1,10 @@ --- -title: "opencodex — Codex를 어떤 LLM 위에서든" +title: "CodexCommander — Codex를 어떤 LLM 위에서든" description: OpenAI Codex & Claude Code를 위한 범용 프로바이더 프록시 — Codex CLI, App, SDK와 Claude Code에서 어떤 LLM이든 사용하세요. template: splash head: - tag: title - content: "opencodex — Codex를 어떤 LLM 위에서든" + content: "CodexCommander — Codex를 어떤 LLM 위에서든" - tag: meta attrs: property: og:locale diff --git a/docs-site/src/content/docs/ko/reference/adapters.md b/docs-site/src/content/docs/ko/reference/adapters.md index bddf944b70..cfb2710e09 100644 --- a/docs-site/src/content/docs/ko/reference/adapters.md +++ b/docs-site/src/content/docs/ko/reference/adapters.md @@ -3,7 +3,7 @@ title: 어댑터 description: 7가지 프로바이더 어댑터의 대상, 요청 구성 방식, 고유 동작. --- -**어댑터**는 opencodex의 내부 요청/응답 모델과 프로바이더 wire 형식 사이를 변환합니다. 모든 +**어댑터**는 CodexCommander의 내부 요청/응답 모델과 프로바이더 wire 형식 사이를 변환합니다. 모든 어댑터는 `ProviderAdapter` 인터페이스(`src/adapters/base.ts`)를 구현합니다. ```ts @@ -17,7 +17,7 @@ interface ProviderAdapter { } ``` -`buildRequest`는 `OcxParsedRequest`를 업스트림 HTTP 요청으로 내리고, `parseStream` / +`buildRequest`는 `CodexCommanderParsedRequest`를 업스트림 HTTP 요청으로 내리고, `parseStream` / `parseResponse`는 프로바이더 응답을 내부 `AdapterEvent`로 올립니다. `fetchResponse`가 있으면 어댑터가 재시도와 타임아웃을 직접 맡습니다. `runTurn`은 한 번의 HTTP fetch와 뒤이은 응답 스트림으로 표현할 수 없는 전송 방식을 지원합니다. 이후 @@ -58,7 +58,7 @@ interface ProviderAdapter { 같은 키로 동일 요청을 대기 후 재전송합니다. 커스텀 `runTurn` 전송은 HTTP 재시도 루프에 포함되지 않습니다. -- `forward` URL → `{baseUrl}/responses`. `key` provider는 기본적으로 기존 `{baseUrl}/v1/responses` 구성을 사용합니다. +- `forward` URL → `{baseUrl}/responses`. `key` provider의 기본 URL은 `{baseUrl}/v1/responses`입니다. - `key` provider는 검증된 상대 `responsesPath`를 설정할 수 있습니다. adapter는 `baseUrl` 끝의 `/` 하나를 제거하고 `{trimmedBaseUrl}{responsesPath}`로 전송합니다. Ark Agent Plan은 `baseUrl: "https://ark.cn-beijing.volces.com/api/plan/v3"`와 `responsesPath: "/responses"`를 사용합니다. - `forward` 모드에서는 안전한 헤더 허용 목록(`FORWARD_HEADERS`)만 중계합니다. authorization, ChatGPT account id, OpenAI beta/originator/session 헤더가 대상입니다. 이 ChatGPT 로그인 경로는 @@ -139,10 +139,10 @@ commentary로 유지하고 비공개 완료 툴을 한 번 검증합니다. - `cursor/grok-4.5-fast`는 선택 가능한 모델로 유지하되, Cursor에는 정식 `grok-4.5` 모델을 보내고 별도의 `effort`, `fast=true` 값은 `requested_model.parameters`에 담습니다. - Cursor 네이티브 로컬 파일시스템/shell/network 실행은 기본적으로 거부합니다. 명시적인 - `mcpServers`와 `desktopExecutor` 통합은 각각 별도 opt-in입니다. `unsafeAllowNativeLocalExec`은 + `mcpServers`와 `desktopExecutor` 통합은 각각 별도 opt-in입니다. `nativeLocalExec: "on"`은 더 넓은 내장 executor를 켜며 Codex 승인/샌드박스 규칙을 우회합니다. -## `azure-openai` (별칭: `azure`) +## `azure-openai` **대상:** **Azure OpenAI**. `openai-responses`를 감싸므로 마찬가지로 `passthrough: true`입니다. **인증:** `api-key` 헤더의 `key`(Bearer 아님). diff --git a/docs-site/src/content/docs/ko/reference/architecture.md b/docs-site/src/content/docs/ko/reference/architecture.md index 0166f48292..f8df483744 100644 --- a/docs-site/src/content/docs/ko/reference/architecture.md +++ b/docs-site/src/content/docs/ko/reference/architecture.md @@ -1,9 +1,9 @@ --- title: 아키텍처 -description: opencodex 내부 구조 — 모듈 맵, AdapterEvent 브리지, 요청 파서, 그리고 캐싱. +description: CodexCommander 내부 구조 — 모듈 맵, AdapterEvent 브리지, 요청 파서, 그리고 캐싱. --- -opencodex는 단일 Bun 프로세스입니다. 요청은 OpenAI Responses로 들어와 내부 모델로 정규화되고, +CodexCommander는 단일 Bun 프로세스입니다. 요청은 OpenAI Responses로 들어와 내부 모델로 정규화되고, 라우팅된 뒤, 어댑터를 통해 프로바이더로 전송되고, 다시 Responses SSE로 브리징됩니다. 엔드투엔드 플로우는 [동작 원리](/ko/getting-started/how-it-works/)를 참조하세요. @@ -11,7 +11,7 @@ opencodex는 단일 Bun 프로세스입니다. 요청은 OpenAI Responses로 들 ``` src/ -├── cli/ # ocx command dispatch, init, status, provider commands +├── cli/ # ccx command dispatch, init, status, provider commands ├── server/ # Bun.serve, /v1/* proxy, /api/* management API, WS bridge ├── codex/ # Codex config injection, catalog sync, auth/account integration ├── providers/ # provider metadata, API-key pool, quota and labels @@ -21,12 +21,12 @@ src/ ├── lib/ # runtime, process, retry, privacy, token estimate helpers ├── web-search/ # web-search sidecar (synthetic tool, loop, executor, parser) ├── vision/ # vision sidecar (describe + plan) -├── config.ts # ~/.opencodex/config.json, defaults, PID, env resolution +├── config.ts # ~/.codexcommander/config.json, defaults, PID, env resolution ├── router.ts # model id → provider + adapter ├── bridge.ts # AdapterEvent stream → Responses SSE / JSON ├── reasoning-effort.ts # reasoning-effort translation, clamping, and catalog levels ├── responses/ -│ ├── parser.ts # Responses request → OcxParsedRequest +│ ├── parser.ts # Responses request → CodexCommanderParsedRequest │ ├── schema.ts # Zod validation │ └── compaction.ts # remote compaction prompts, envelopes, compact history ├── service.ts # launchd / systemd / Task Scheduler background service @@ -34,13 +34,12 @@ src/ └── index.ts # public entry ``` -기존의 대형 진입 파일 세 개는 이제 호환성 facade입니다. `codex/catalog.ts`는 7개의 -`codex/catalog/*.ts` 모듈을, `server/management-api.ts`는 9개의 `server/management/*.ts` -모듈을, `server/responses.ts`는 5개의 `server/responses/*.ts` 모듈을 연결합니다. +`codex/catalog.ts`는 7개의 `codex/catalog/*.ts` 모듈을, `server/management-api.ts`는 9개의 +`server/management/*.ts` 모듈을, `server/responses.ts`는 5개의 `server/responses/*.ts` 모듈을 연결합니다. ## 요청 처리 흐름 -HTTP 경계는 `server/index.ts`가 맡고, Responses 데이터 플레인은 `server/responses.ts` facade와 +HTTP 경계는 `server/index.ts`가 맡고, Responses 데이터 플레인은 `server/responses.ts`와 `server/responses/*.ts` 모듈로 넘깁니다. 1. `server/index.ts`에서 CORS와 API 인증을 확인하고, 종료 대기 중이면 새 요청을 거부한 뒤 요청 수명 @@ -67,9 +66,9 @@ HTTP 경계는 `server/index.ts`가 맡고, Responses 데이터 플레인은 `se ## 파서 `responses/parser.ts`는 들어오는 요청을 `responses/schema.ts`(Zod)로 검증한 다음 -`OcxParsedRequest`를 구성합니다: +`CodexCommanderParsedRequest`를 구성합니다: -- **Messages** — `input` 항목은 정규화된 `OcxMessage[]`가 됩니다: user / developer / assistant / +- **Messages** — `input` 항목은 정규화된 `CodexCommanderMessage[]`가 됩니다: user / developer / assistant / toolResult. `reasoning` 항목은 thinking 블록이 되고, `function_call`, `custom_tool_call`, `tool_search_call` 항목은 툴 호출이 되며, 그에 대응하는 `*_output`은 툴 결과가 됩니다. - **Tools** — function 툴은 그대로 통과합니다. **네임스페이스가 있는 (MCP) 툴은 평탄화되어** @@ -113,7 +112,7 @@ Responses 항목 타입으로 구분됩니다 — 따라서 MCP 네임스페이 ## 전송과 compaction `server/index.ts`는 기본적으로 `/v1/responses`를 HTTP/SSE로 제공합니다. `websockets`가 `false`인 -상태에서 Codex가 Responses WebSocket 업그레이드를 시도하면 opencodex는 `426 upgrade_required`를 +상태에서 Codex가 Responses WebSocket 업그레이드를 시도하면 CodexCommander는 `426 upgrade_required`를 반환하고, Codex는 해당 세션에서 HTTP로 폴백합니다. `"websockets": true`가 설정되면 같은 엔드포인트가 업그레이드를 받아들이고 WebSocket 브리지를 사용합니다. @@ -126,7 +125,7 @@ Codex 컨텍스트 compaction은 라우팅된 모델에서도 동작합니다. ` - `codex/model-cache.ts`는 실시간 `/models` 결과를 프로바이더별로 메모리에 TTL 캐싱하며(기본 5분, Codex 자체 캐시와 일치), fetch가 실패하면 stale-fallback을 제공합니다. -- `codex/catalog.ts` facade가 내보내는 `codex/catalog/sync.ts`는 라우팅된 모델을 네임스페이스 +- `codex/catalog.ts`가 내보내는 `codex/catalog/sync.ts`는 라우팅된 모델을 네임스페이스 항목으로 Codex의 카탈로그에 병합하고, 추천 [서브에이전트 모델](/ko/guides/codex-integration/#the-subagent-picker)을 먼저 랭크하며, `disabledModels`를 필터링하고, 일회성 백업으로부터 원본 카탈로그를 완전히 복원할 수 있습니다. @@ -145,7 +144,7 @@ Codex 카탈로그는 Codex가 수용하는 레이블(`low` / `medium` / `high` ## 코어 타입 -내부 모델은 `types.ts`에 있습니다: `OcxParsedRequest`, `OcxContext`, `OcxMessage` 유니온, -`OcxContentPart`(text / image), `OcxToolCall`, `OcxTool`, `AdapterEvent`, 그리고 설정 타입 -(`OcxConfig`, `OcxProviderConfig`). 두 가지 헬퍼가 널리 사용됩니다: `namespacedToolName()`과 +내부 모델은 `types.ts`에 있습니다: `CodexCommanderParsedRequest`, `CodexCommanderContext`, `CodexCommanderMessage` 유니온, +`CodexCommanderContentPart`(text / image), `CodexCommanderToolCall`, `CodexCommanderTool`, `AdapterEvent`, 그리고 설정 타입 +(`CodexCommanderConfig`, `CodexCommanderProviderConfig`). 두 가지 헬퍼가 널리 사용됩니다: `namespacedToolName()`과 `modelInList()`(`noVisionModels` / `noReasoningModels`에 대한 관대한 `:size` 태그 매칭). diff --git a/docs-site/src/content/docs/ko/reference/cli.md b/docs-site/src/content/docs/ko/reference/cli.md index d98118d618..5ab5d316c8 100644 --- a/docs-site/src/content/docs/ko/reference/cli.md +++ b/docs-site/src/content/docs/ko/reference/cli.md @@ -1,15 +1,15 @@ --- title: CLI 레퍼런스 -description: 명령 분기, 종료 코드, 그리고 모든 ocx 명령군으로 연결되는 링크. +description: 명령 분기, 종료 코드, 그리고 모든 ccx 명령군으로 연결되는 링크. --- -opencodex CLI는 `ocx`입니다. 첫 번째 명령 이름으로 분기하며, `setup`/`init`, `restore`/`eject`, `models`/`model` 같은 별칭은 같은 동작으로 이어집니다. 알 수 없는 명령과 잘못된 명령 형태는 오류입니다. +CodexCommander CLI는 `ccx`입니다. 첫 번째 명령 이름으로 분기하며, `setup`/`init`, `restore`/`eject`, `models`/`model` 같은 별칭은 같은 동작으로 이어집니다. 알 수 없는 명령과 잘못된 명령 형태는 오류입니다. -`ocx help`(`ocx --help` / `ocx -h`도 가능)는 최상위 사용법을 보여 줍니다. 도움말 표에 등록된 명령은 `ocx help <command>`, `ocx <command> --help`, `ocx <command> -h`로 볼 수 있습니다. 도움말과 버전 명령은 읽기 전용이며 Codex나 opencodex 상태를 시작, 중지, 설치, 제거하거나 다시 쓰지 않습니다. +`ccx help`(`ccx --help` / `ccx -h`도 가능)는 최상위 사용법을 보여 줍니다. 도움말 표에 등록된 명령은 `ccx help <command>`, `ccx <command> --help`, `ccx <command> -h`로 볼 수 있습니다. 도움말과 버전 명령은 읽기 전용이며 Codex나 CodexCommander 상태를 시작, 중지, 설치, 제거하거나 다시 쓰지 않습니다. ## 명령군 -- [라이프사이클](/reference/cli/lifecycle/) — 설정, 프록시와 서비스 라이프사이클, 상태 확인, 진단, 카탈로그 동기화, 대시보드, 업데이트. +- [라이프사이클](/reference/cli/lifecycle/) — 설정, 프록시와 서비스 라이프사이클, 상태 확인, 진단, 카탈로그 동기화, 대시보드. - [프로바이더, 계정, 모델](/reference/cli/providers-accounts/) — 프로바이더 설정, 인증, 자격 증명 풀, quota, 사용자 지정 모델, 표시 여부, 선택된 모델, 컨텍스트 상한. - [에이전트, 라우팅, 통합](/reference/cli/agents/) — 다중 에이전트 제어, 조합, 관측성, admission key, 클라이언트 통합, 런타임 설정, 검증된 설정. @@ -17,16 +17,14 @@ opencodex CLI는 `ocx`입니다. 첫 번째 명령 이름으로 분기하며, `s 관리 명령은 기록된 런타임 포트와 신원 검사를 사용해 살아 있는 프록시의 management API와 왕복 통신하며, 두 번째 설정 경로를 따로 두지 않습니다. 멈췄거나 닿을 수 없는 프록시는 HTTP 503으로 표시되며 CLI는 0이 아닌 종료 코드를 반환합니다. 명시적으로 오프라인 설정 작업으로 문서화된 명령은 라이브 프록시 없이 설정 파일을 검증하고 수정할 수 있습니다. -뜻이 분명하면 `list`나 `status`가 기본입니다. 구조화된 스냅샷은 `--json`을, 스트리밍 요청 로그 피드는 `ocx observe logs --follow --jsonl`을 사용합니다. 테마, 언어, 내비게이션처럼 순수하게 시각적인 브라우저 상태에는 CLI 대응이 없습니다. Cloudflare Tunnel 설정은 이 명령 집합 밖입니다. +뜻이 분명하면 `list`나 `status`가 기본입니다. 구조화된 스냅샷은 `--json`을, 스트리밍 요청 로그 피드는 `ccx observe logs --follow --jsonl`을 사용합니다. 테마, 언어, 내비게이션처럼 순수하게 시각적인 브라우저 상태에는 CLI 대응이 없습니다. Cloudflare Tunnel 설정은 이 명령 집합 밖입니다. ## 종료 코드와 확인 -성공한 명령은 종료 코드 0을 반환합니다. 잘못된 사용법, 알 수 없는 명령이나 리소스, 실패한 API 작업, 필요한 서비스가 없음은 0이 아닌 종료 코드를 반환합니다. `ocx health`는 프록시가 건강할 때만 0을, 그렇지 않으면 1을 반환하므로 서비스 probe로 쓸 수 있습니다. 스크립트는 사람이 읽는 출력 대신 종료 코드를 확인해야 합니다. +성공한 명령은 종료 코드 0을 반환합니다. 잘못된 사용법, 알 수 없는 명령이나 리소스, 실패한 API 작업, 필요한 서비스가 없음은 0이 아닌 종료 코드를 반환합니다. `ccx health`는 프록시가 건강할 때만 0을, 그렇지 않으면 1을 반환하므로 서비스 probe로 쓸 수 있습니다. 스크립트는 사람이 읽는 출력 대신 종료 코드를 확인해야 합니다. -제거, 가져오기, 크레딧 소모, 업데이트처럼 확인을 알리는 파괴적 작업은 비대화형 사용 시 `--yes`가 필요합니다. 이 플래그는 명시적인 동의이며, 생략했다고 해서 동작이 조용히 확인되면 안 됩니다. +제거, 가져오기, 크레딧 소모처럼 확인을 알리는 파괴적 작업은 비대화형 사용 시 `--yes`가 필요합니다. 이 플래그는 명시적인 동의이며, 생략했다고 해서 동작이 조용히 확인되면 안 됩니다. -## 버전과 내부 디스패치 대상 +## 버전 -`ocx --version`, `ocx -v`, `ocx version`은 스크립트가 읽기 좋은 한 줄짜리 버전을 출력하고 종료합니다. - -일반 도움말에는 두 개의 디스패치 대상이 의도적으로 빠져 있습니다. `__refresh-version [preview]`는 분리된 프로세스에서 업데이트 알림 캐시를 새로 고치고, `__gui-update-worker <job-id> [latest|preview] [restart]`는 대시보드 업데이트 작업을 실행합니다. 이들은 구현 세부 사항일 뿐이며 안정적인 사용자 명령이 아닙니다. 대시보드는 worker PID를 기록하고, worker가 죽은 활성 작업은 복구하며, PID가 없는 오래된 활성 기록은 10분 뒤 오래된 것으로 취급하고, 살아 있는 worker를 동시 업데이트로부터 보호합니다. +`ccx --version`, `ccx -v`, `ccx version`은 스크립트가 읽기 좋은 한 줄짜리 버전을 출력하고 종료합니다. diff --git a/docs-site/src/content/docs/ko/reference/cli/agents.md b/docs-site/src/content/docs/ko/reference/cli/agents.md index 7632d49549..25a2366aa4 100644 --- a/docs-site/src/content/docs/ko/reference/cli/agents.md +++ b/docs-site/src/content/docs/ko/reference/cli/agents.md @@ -3,20 +3,20 @@ title: CLI 에이전트, 라우팅, 통합 description: 멀티 에이전트, 콤보, 관측성, 접근, 통합, 시스템, 구성 명령입니다. --- -이 명령들은 에이전트 정책과 라우팅을 제어하고, 실행 중인 프록시를 검사하며, 지원되는 클라이언트를 opencodex에 연결합니다. +이 명령들은 에이전트 정책과 라우팅을 제어하고, 실행 중인 프록시를 검사하며, 지원되는 클라이언트를 CodexCommander에 연결합니다. ## 에이전트 정책 -### `ocx agent <status|injection|effort|subagents|fallback|sidecar> ...` +### `ccx agent <status|injection|effort|subagents|fallback|sidecar> ...` 헤드리스 멀티 에이전트 목록, effort 상한, 프롬프트 주입, fallback, sidecar 설정을 관리합니다. 현재 정책은 `status`로 확인합니다. surface mode, delegation, effort, fallback 동작이 어떻게 맞물리는지는 [Sub-agent surfaces](/guides/sub-agent-surface/)를 보십시오. ```bash -ocx agent subagents set ark/model-a,openai/gpt-5.5 +ccx agent subagents set ark/model-a,openai/gpt-5.5 ``` -### `ocx v2 <status|on|off|mode <v1|default|v2>|threads <n>>` +### `ccx v2 <status|on|off|mode <v1|default|v2>|threads <n>>` Codex `multi_agent_v2` 기능 플래그와 세 상태 멀티 에이전트 surface mode를 관리합니다. @@ -31,109 +31,109 @@ Codex `multi_agent_v2` 기능 플래그와 세 상태 멀티 에이전트 surfac | `threads <n>` | 활성 v1/v2 thread 한도를 1 이상의 정수로 설정합니다. | ```bash -ocx v2 status -ocx v2 mode v1 -ocx v2 mode default -ocx v2 on -ocx v2 threads 16 +ccx v2 status +ccx v2 mode v1 +ccx v2 mode default +ccx v2 on +ccx v2 threads 16 ``` -`mode` 하위 명령은 `multiAgentMode`를 opencodex config에 쓰고 Codex catalog를 다시 동기화합니다. +`mode` 하위 명령은 `multiAgentMode`를 CodexCommander config에 쓰고 Codex catalog를 다시 동기화합니다. mode와 flag 전환은 현재 숫자 thread 한도를 유효한 v1/v2 Codex key 사이로 옮깁니다. 전환이 실패하면 원래의 `config.toml`이 복원됩니다. 변경은 새 Codex 세션에만 적용되고, 실행 중인 세션은 고정된 surface를 유지합니다. ## 콤보 라우팅 -### `ocx combo <list|show|set|remove> ...` · `ocx route combo ...` +### `ccx combo <list|show|set|remove> ...` · `ccx route combo ...` -콤보 failover와 round-robin 가상 모델을 관리합니다. `ocx route combo`는 계층형 별칭이며, +콤보 failover와 round-robin 가상 모델을 관리합니다. `ccx route combo`는 계층형 별칭이며, 현재 지원되는 라우팅 리소스는 combo입니다. 대상은 `provider/model[:weight],provider/model[:weight]` 형식을 사용합니다. ```bash -ocx combo list -ocx route combo set reliable --targets ark/model-a:2,openai/gpt-5.5 +ccx combo list +ccx route combo set reliable --targets ark/model-a:2,openai/gpt-5.5 ``` 라우팅 동작과 설정 안내는 [Combos](/guides/combos/)를 보십시오. ## 관측성과 디버그 -### `ocx observe <logs|usage|storage|memory|debug|claude-inbound|injection> ...` +### `ccx observe <logs|usage|storage|memory|debug|claude-inbound|injection> ...` 프록시 요청, 사용량, 저장소, 메모리, 디버그 데이터를 확인합니다. 직접 별칭은 다음과 같습니다: | 별칭 | 대응 리소스 | | --- | --- | -| `ocx logs [filters] [--follow] [--json|--jsonl]` | `ocx observe logs` | -| `ocx usage [--range <7d|30d|all>] [--surface <all|codex|claude|grok>] [--json]` | `ocx observe usage` | -| `ocx storage [--json]` | `ocx observe storage` | -| `ocx memory [--json]` | `ocx observe memory` | +| `ccx logs [filters] [--follow] [--json|--jsonl]` | `ccx observe logs` | +| `ccx usage [--range <7d|30d|all>] [--surface <all|codex|claude|grok>] [--json]` | `ccx observe usage` | +| `ccx storage [--json]` | `ccx observe storage` | +| `ccx memory [--json]` | `ccx observe memory` | ```bash -ocx observe usage --range 30d --json +ccx observe usage --range 30d --json ``` -### `ocx debug <provider|usage|injection|claude> <on|off|status|reset|logs [-f]>` +### `ccx debug <provider|usage|injection|claude> <on|off|status|reset|logs [-f]>` 실행 중인 프록시의 관리 API를 통해 런타임 디버그 override를 읽거나 변경합니다. ```bash -ocx debug provider on|off|status|reset -ocx debug provider logs [-f|--follow] -ocx debug usage on|off|status|reset -ocx debug usage logs [-f|--follow] +ccx debug provider on|off|status|reset +ccx debug provider logs [-f|--follow] +ccx debug usage on|off|status|reset +ccx debug usage logs [-f|--follow] ``` -scope를 지정하지 않으면 `ocx debug`는 사용량을 출력하고, 프록시가 중지된 상태라면 다음 시작 시의 환경 기본값도 함께 보여줍니다. provider 디버그의 기본값은 `OCX_DEBUG=1`에서 오며(`OCX_DEBUG_FRAMES=1`도 예전 방식으로 동작합니다), usage 디버그의 기본값은 `OPENCODEX_USAGE_DEBUG=1`에서 옵니다. +scope를 지정하지 않으면 `ccx debug`는 사용량을 출력하고, 프록시가 중지된 상태라면 다음 시작 시의 환경 기본값도 함께 보여줍니다. provider 디버그의 기본값은 `CCX_DEBUG=1`에서 오며, usage 디버그의 기본값은 `CODEXCOMMANDER_USAGE_DEBUG=1`에서 옵니다. ## API 접근 -### `ocx access <key|endpoints|models|test> ...` +### `ccx access <key|endpoints|models|test> ...` -OpenCodex admission API key를 관리하고 외부 endpoint와 model을 검사합니다. `ocx api-key -<list|create|remove> ...`는 `ocx access key`의 별칭입니다. +CodexCommander admission API key를 관리하고 외부 endpoint와 model을 검사합니다. `ccx api-key +<list|create|remove> ...`는 `ccx access key`의 별칭입니다. ```bash -ocx access key create deployment +ccx access key create deployment ``` ## 클라이언트 통합 -### `ocx integration <claude|grok> ...` +### `ccx integration <claude|grok> ...` 지원되는 Claude 및 Grok 통합을 관리합니다. 아래의 직접 명령군이 클라이언트별 제어를 제공합니다. -### `ocx claude [claude args...]` +### `ccx claude [claude args...]` 프록시가 실행 중인지 확인한 뒤, `ANTHROPIC_BASE_URL`, -`ANTHROPIC_AUTH_TOKEN`, `CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1`, 그리고 `config.claudeCode`의 모델 슬롯을 사용해 Claude Code를 실행합니다. 라우팅된 model은 Claude Code 2.1.129 이상에서 안정적인 slot alias를 통해 기본 `/model` 선택기에 나타납니다. 더 오래된 버전에서는 `ANTHROPIC_MODEL` 또는 `/model <id>`로 선택합니다. 사용자가 내보낸 `ANTHROPIC_*` 변수는 항상 우선합니다. +`ANTHROPIC_AUTH_TOKEN`, `CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1`, 그리고 `config.claudeCode`의 현재 인증/헬퍼 설정을 사용해 Claude Code를 실행합니다. 라우팅된 model은 Claude Code 2.1.129 이상에서 안정적인 alias를 통해 기본 `/model` 선택기에 나타납니다. 더 오래된 버전에서는 `ANTHROPIC_MODEL` 또는 `/model <id>`로 선택합니다. 사용자가 내보낸 `ANTHROPIC_*` 변수는 항상 우선합니다. Claude Desktop 프로필 명령은 다음과 같습니다: ```text -ocx claude desktop [apply] Save and apply the four-family profile -ocx claude desktop show [--json] Show routes, families, and defaults -ocx claude desktop move <route> <family> [--default] -ocx claude desktop default <family> <route|none> -ocx claude desktop export <path|-> Export versioned JSON (`-` = stdout) -ocx claude desktop import <path> [--apply] Validate and import JSON +ccx claude desktop apply Save and apply the four-family profile +ccx claude desktop show [--json] Show routes, families, and defaults +ccx claude desktop move <route> <family> [--default] +ccx claude desktop default <family> <route|none> +ccx claude desktop export <path|-> Export versioned JSON (`-` = stdout) +ccx claude desktop import <path> [--apply] Validate and import JSON ``` -family는 `opus`, `fable`, `sonnet`, `haiku`이며, 새 route는 `opus`에서 시작합니다. `none`은 해당 family가 비어 있을 때만 유효합니다. 레거시 apply 플래그인 `--static`, `--hybrid`, `--discovery-only`도 계속 지원합니다. Claude Code 설정은 `ocx claude config <status|set> ...`를 사용하십시오. +family는 `opus`, `fable`, `sonnet`, `haiku`이며, 새 route는 `opus`에서 시작합니다. `none`은 해당 family가 비어 있을 때만 유효합니다. Claude Code 설정은 `ccx claude config <status|set> ...`를 사용하십시오. -### `ocx opencode [opencode args...]` +### `ccx opencode [opencode args...]` -프록시가 실행 중인지 확인한 뒤, OpenCode의 인라인 런타임 계층(`OPENCODE_CONFIG_CONTENT`)에 생성된 `provider.opencodex` 블록을 넣어 opencode를 실행합니다. 기존 인라인 config는 유지되고, 이번 실행에서는 `provider.opencodex`만 교체됩니다. 전역 또는 프로젝트 `opencode.json` 파일은 기존 override가 있는지 경고하기 위해 읽을 수 있지만, 디스크상의 파일은 절대 수정하지 않습니다. 라우팅된 model은 `opencodex/<provider>/<model>`로 나타납니다. 이 런처는 이후 plain `opencode` 실행을 바꾸지 않으며, `provider.opencodex`를 영속화하는 경로는 별도의 opt-in 대시보드 통합뿐입니다. +프록시가 실행 중인지 확인한 뒤, OpenCode의 인라인 런타임 계층(`OPENCODE_CONFIG_CONTENT`)에 생성된 `provider.codexcommander` 블록을 넣어 opencode를 실행합니다. 기존 인라인 config는 유지되고, 이번 실행에서는 `provider.codexcommander`만 교체됩니다. 전역 또는 프로젝트 `opencode.json` 파일은 기존 override가 있는지 경고하기 위해 읽을 수 있지만, 디스크상의 파일은 절대 수정하지 않습니다. 라우팅된 model은 `codexcommander/<provider>/<model>`로 나타납니다. 이 런처는 이후 plain `opencode` 실행을 바꾸지 않으며, `provider.codexcommander`를 영속화하는 경로는 별도의 opt-in 대시보드 통합뿐입니다. -### `ocx grok <status|exclude|include|set|clear|apply> ...` +### `ccx grok <status|exclude|include|set|clear|apply> ...` Grok Build model fence를 관리하고 적용합니다. ## 클라이언트 설정 내보내기 -### `ocx export --client <opencode|pi>` +### `ccx export --client <opencode|pi>` -실행 중인 프록시에 연결된 client config를 출력합니다. opencode와 [Pi](/guides/pi/)는 environment variable이 아니라 각자의 JSON config에서 provider를 읽으므로, 이 명령은 `opencodex` provider block, 즉 base URL, model list, 그리고 client의 env reference를 직렬화해서 해당 파일에 병합할 수 있게 해줍니다. +실행 중인 프록시에 연결된 client config를 출력합니다. opencode와 [Pi](/guides/pi/)는 environment variable이 아니라 각자의 JSON config에서 provider를 읽으므로, 이 명령은 `codexcommander` provider block, 즉 base URL, model list, 그리고 client의 env reference를 직렬화해서 해당 파일에 병합할 수 있게 해줍니다. 프록시는 실행 중이어야 합니다. 이 명령은 실제 포트를 확인하고, `/api/models`를 읽고, 현재 Codex가 볼 수 있는 model만 내보냅니다. @@ -145,22 +145,22 @@ Grok Build model fence를 관리하고 적용합니다. | `--force` | `--out`이 기존 파일을 덮어쓰도록 허용합니다. | ```bash -ocx export --client opencode # config plus destination, merge warning, and counts -ocx export --client pi --json > pi-models.json # byte-exact JSON for a pipe or a diff -ocx export --client opencode --out ~/opencodex-opencode.json +ccx export --client opencode # config plus destination, merge warning, and counts +ccx export --client pi --json > pi-models.json # byte-exact JSON for a pipe or a diff +ccx export --client opencode --out ~/codexcommander-opencode.json ``` `--json`이 없으면 JSON이 먼저 나오고, 그다음 표준 대상 경로, merge 경고, env export 줄, 그리고 context limit을 생략한 row 수를 포함한 model count가 이어집니다(이 경우 client는 자체 기본값을 적용합니다). | 클라이언트 | 표준 대상 경로 | 다운로드 파일명 | 환경 변수 | | --- | --- | --- | --- | -| `opencode` | `~/.config/opencode/opencode.json` (`XDG_CONFIG_HOME`이 설정되어 있으면 우선합니다) | `opencode.json` | `OPENCODEX_OPENCODE_API_KEY` | -| `pi` | `~/.pi/agent/models.json` | `pi-models.json` | `OPENCODEX_API_KEY` | +| `opencode` | `~/.config/opencode/opencode.json` (`XDG_CONFIG_HOME`이 설정되어 있으면 우선합니다) | `opencode.json` | `CODEXCOMMANDER_OPENCODE_API_KEY` | +| `pi` | `~/.pi/agent/models.json` | `pi-models.json` | `CODEXCOMMANDER_API_KEY` | -두 환경 변수 이름은 서로 다르며, 각 client는 자기 것만 보간합니다. opencode는 `{env:OPENCODEX_OPENCODE_API_KEY}`를 읽고, Pi는 `$OPENCODEX_API_KEY`를 읽습니다. +두 환경 변수 이름은 서로 다르며, 각 client는 자기 것만 보간합니다. opencode는 `{env:CODEXCOMMANDER_OPENCODE_API_KEY}`를 읽고, Pi는 `$CODEXCOMMANDER_API_KEY`를 읽습니다. :::caution[Merge, never replace] -`ocx export`는 실제 client config를 절대 쓰지 않습니다. 대상 경로는 손으로 병합하라고 출력되며, `--out`은 `--force` 없이 기존 파일을 덮어쓰지 않습니다. config를 바꾸어 덮어쓰면 이미 들어 있던 다른 provider, agent, MCP entry가 사라지기 때문입니다. +`ccx export`는 실제 client config를 절대 쓰지 않습니다. 대상 경로는 손으로 병합하라고 출력되며, `--out`은 `--force` 없이 기존 파일을 덮어쓰지 않습니다. config를 바꾸어 덮어쓰면 이미 들어 있던 다른 provider, agent, MCP entry가 사라지기 때문입니다. ::: 어떤 key도 직렬화되지 않습니다. config에는 client의 env reference만 들어가므로 secret은 환경 변수에 남습니다. loopback proxy(`127.0.0.1`, 기본값)는 admission key가 전혀 필요하지 않습니다. reference는 단지 사용되지 않을 뿐입니다. proxy가 loopback을 넘어 바인딩할 때만 변수를 설정하십시오. admission key가 어떻게 발급되는지는 [Remote access](/reference/configuration/#remote-access)를 보십시오. upstream provider 자체의 key는 완전히 별개의 것으로, 각 [Providers](/guides/providers/)에 맞게 설정합니다. @@ -169,14 +169,14 @@ ocx export --client opencode --out ~/opencodex-opencode.json ## 런타임과 설정 -### `ocx system <status|settings|startup|diagnostics|sync|update> ...` +### `ccx system <status|settings|startup|diagnostics|sync> ...` -헤드리스 런타임 설정, 시작, 동기화, 진단, 업데이트를 관리합니다. +헤드리스 런타임 설정, 시작, 동기화, 진단을 관리합니다. ```bash -ocx system settings --stream-mode eager-relay +ccx system settings --stream-mode eager-relay ``` -### `ocx config <show|get|set|unset|validate|export|import> ...` +### `ccx config <show|get|set|unset|validate|export|import> ...` -검증된 OpenCodex configuration을 검사하고 안전하게 수정합니다. `show`와 `get`은 비밀 값을 가립니다. import는 쓰기 전에 검증하며 `--yes`가 필요합니다. +검증된 CodexCommander configuration을 검사하고 안전하게 수정합니다. `show`와 `get`은 비밀 값을 가립니다. import는 쓰기 전에 검증하며 `--yes`가 필요합니다. diff --git a/docs-site/src/content/docs/ko/reference/cli/lifecycle.md b/docs-site/src/content/docs/ko/reference/cli/lifecycle.md index 83586d5332..8da01bcba5 100644 --- a/docs-site/src/content/docs/ko/reference/cli/lifecycle.md +++ b/docs-site/src/content/docs/ko/reference/cli/lifecycle.md @@ -1,50 +1,50 @@ --- title: CLI 수명 주기 -description: 설정, 시작, 중지, 서비스, 진단, 동기화, 업데이트 명령입니다. +description: 설정, 시작, 중지, 서비스, 진단, 동기화 명령입니다. --- -이 명령들은 로컬 opencodex 프록시와 Codex 연동을 설치, 실행, 점검, 복구, 업데이트합니다. +이 명령들은 로컬 CodexCommander 프록시와 Codex 연동을 설치, 실행, 점검, 복구합니다. ## 설정 -### `ocx init` · `ocx setup` +### `ccx init` · `ccx setup` 대화형 설정 마법사입니다 (`setup`은 `init`의 별칭입니다). 공급자(프리셋 또는 사용자 지정), -API 키(리터럴 또는 `${ENV}`), 기본 모델, 프록시 포트를 묻고 `~/.opencodex/config.json`에 저장합니다. +API 키(리터럴 또는 `${ENV}`), 기본 모델, 프록시 포트를 묻고 `~/.codexcommander/config.json`에 저장합니다. 원하면 프록시를 `$CODEX_HOME/config.toml`(기본값 `~/.codex/config.toml`)에 주입하고, Codex 자동 시작 shim도 설치합니다. ## 프록시 수명 주기 -### `ocx start [--port <port>]` +### `ccx start [--port <port>]` -프록시 서버를 시작합니다(권장 포트는 `10100`). 해당 포트가 이미 사용 중이면 opencodex가 다른 +프록시 서버를 시작합니다(권장 포트는 `10100`). 해당 포트가 이미 사용 중이면 CodexCommander가 다른 사용 가능한 포트를 골라 기록합니다. PID와 런타임 포트 상태를 기록하고, 두 번째 활성 인스턴스는 시작하지 않습니다. 시작할 때는 각 공급자의 모델을 Codex 카탈로그로 동기화합니다. 종료할 때는 기본 Codex를 -복원합니다. 단, 관리형 서비스로 실행한 경우(`OCX_SERVICE=1`)는 예외입니다. +복원합니다. 단, 관리형 서비스로 실행한 경우(`CCX_SERVICE=1`)는 예외입니다. ```bash -ocx start -ocx start --port 8080 +ccx start +ccx start --port 8080 ``` -### `ocx stop` +### `ccx stop` 실행 중인 프록시를 PID 기준으로 중지하고, PID 파일을 삭제한 뒤 기본 Codex를 복원합니다. 관리형 -백그라운드 서비스가 설치되어 있으면 `ocx stop`이 먼저 그 서비스를 중지하므로 프록시가 다시 +백그라운드 서비스가 설치되어 있으면 `ccx stop`이 먼저 그 서비스를 중지하므로 프록시가 다시 올라올 수 없습니다. 같은 동작은 웹 대시보드의 **Stop** 버튼(`POST /api/stop`)에서도 사용할 수 있습니다. -### `ocx restart` +### `ccx restart` `stop` 다음에 `ensure`를 실행합니다. 즉, 프록시/서비스를 중지하고 기본 Codex를 복원한 뒤, 프록시를 백그라운드에서 다시 시작하고 살아 있는 포트를 Codex에 다시 동기화합니다. -### `ocx ensure` +### `ccx ensure` 백그라운드 프록시가 실행 중인지 멱등적으로 보장한 다음, 살아 있는 모델 카탈로그를 동기화합니다. `codexAutoStart`가 `false`이면 자동 시작이 비활성화되었다고 출력하고 아무것도 하지 않습니다. -### `ocx restore [back]` · `ocx eject [back]` +### `ccx restore [back]` · `ccx eject [back]` 프록시를 중지하지 않고 기본 Codex를 **복원**합니다. 주입된 설정 줄과 라우팅된 카탈로그 항목을 제거하므로 일반 `codex`가 다시 네이티브로 동작합니다. `eject`는 `restore`의 별칭입니다. @@ -53,25 +53,20 @@ ocx start --port 8080 연결하되, 프록시 수명 주기는 바꾸지 않습니다. ```bash -ocx restore back -ocx eject back +ccx restore back +ccx eject back ``` -### `ocx recover-history --legacy-openai` - -역방향 복구 지원이 생기기 전, 초기 개발 빌드에서 Codex App 기록을 재매핑하던 오래된 빌드를 위한 -명시적 복구 명령입니다. 기록 데이터베이스가 잠겨 있으면 먼저 Codex를 종료해 주세요. - -### `ocx uninstall` · `ocx remove` +### `ccx uninstall` · `ccx remove` 서비스와 프록시를 중지하고, 서비스와 Codex shim을 제거한 뒤, 기본 Codex를 복원합니다. 그 다음 -복원 단계가 모두 성공했을 때만 opencodex 로컬 설정을 제거합니다. `remove`는 `uninstall`의 +복원 단계가 모두 성공했을 때만 CodexCommander 로컬 설정을 제거합니다. `remove`는 `uninstall`의 별칭입니다. 설정 정리에는 새 설치로 만들어진 소유권 메타데이터가 필요하며, 오래된 디렉터리나 공유 디렉터리는 그대로 남깁니다. ## 상태 및 헬스 -### `ocx status [--json]` +### `ccx status [--json]` 읽기 전용 진단 요약을 출력합니다. 프록시 PID, `/healthz` 도달 가능 여부, 대시보드 URL, 설정 경로, 기본 공급자, Codex 자동 시작 설정, 서비스 상태, shim 상태, 그리고 마스킹된 @@ -85,8 +80,8 @@ ocx eject back 이메일은 절대 출력하지 않습니다. `--json` 계약에는 이 헬스 블록이 아직 포함되지 않습니다. ```bash -ocx status -ocx status --json +ccx status +ccx status --json ``` 축약 예시 형태는 다음과 같습니다. @@ -107,8 +102,8 @@ ocx status --json "url": "http://localhost:10100/" }, "paths": { - "config": "/Users/example/.opencodex/config.json", - "pid": "/Users/example/.opencodex/ocx.pid", + "config": "/Users/example/.codexcommander/config.json", + "pid": "/Users/example/.codexcommander/codexcommander.pid", "runtime": "/path/to/bun" }, "runtime": { @@ -124,7 +119,7 @@ ocx status --json "codexAutostart": true, "defaultProvider": "openai", "service": { - "summary": "not installed (logs: /Users/example/.opencodex/service.log)" + "summary": "not installed (logs: /Users/example/.codexcommander/service.log)" }, "codexShim": { "summary": "Codex autostart shim: not installed" @@ -137,62 +132,62 @@ ocx status --json 기존 필드는 안정적으로 유지되어야 합니다. 이 스키마는 API 키, OAuth 토큰, Authorization 헤더, 요청 내용, 이메일, 계정 식별자를 의도적으로 제외합니다. -### `ocx health [--json]` +### `ccx health [--json]` 실행 중인 프록시의 신원 확인을 수행합니다. 일반 출력은 PID/포트를 보고하고, `--json`은 `{ok, pid, port}`를 내보냅니다. 이 명령은 정상일 때만 종료 코드 0을, 그렇지 않으면 1을 반환하므로 서비스 프로브에 적합합니다. -### `ocx ready [--json] [--wait [--timeout <seconds>]]` +### `ccx ready [--json] [--wait [--timeout <seconds>]]` 인증이 필요 없는 `GET /readyz` 엔드포인트로 동기화 후 준비 상태를 확인합니다. 준비되면 `200`, `pending` 또는 종단 상태인 `failed`이면 `Retry-After: 1`과 함께 `503`을 반환합니다. HTTP의 정제된 -식별 필드는 `{service, version, uptime, pid, port, status}`입니다. `/readyz`가 없는 이전 프록시는 -`unreachable`로 fail-closed하며, `/healthz`는 준비 상태가 아닌 별도의 liveness 확인입니다. 기본값은 한 번의 +식별 필드는 `{service, version, uptime, pid, port, status}`입니다. `/healthz`는 준비 상태가 아닌 별도의 +liveness 확인입니다. 기본값은 한 번의 probe이며, `--wait`는 준비 또는 timeout까지 polling하지만 종단 `failed`를 확인하면 즉시 종료합니다. 기본 timeout은 45초이며, `--timeout <seconds>`는 `--wait`와 함께 써야 하고 양의 정수인 1~300초 범위를 받습니다. CLI JSON은 `{ready, status, pid, port}`를 출력하며 `status`는 `ready`, `pending`, `failed`, `unreachable` 중 하나입니다. 종료 코드는 ready가 0, not-ready/pending/failed/timeout/unreachable이 1, 잘못된 인수가 64입니다. -### `ocx doctor` +### `ccx doctor` 읽기 전용 환경 및 연결 진단을 실행합니다. 상태 경로와 파일시스템 유형, WSL 이중 설치, 프록시 -환경/설정, ChatGPT 도달 가능성, Codex 플러그인 및 프로젝트 설정 경고, 보류 중인 기록 마이그레이션이 -포함됩니다. Codex 앱 홈 대상 지정 섹션은 좁은 범위의 Windows Orca 런타임 홈 불일치도 감지하고, -해당할 때 서비스 마이그레이션을 설명합니다. 이 진단에 표시되는 경로는 OS 사용자 이름을 마스킹합니다. +환경/설정, ChatGPT 도달 가능성, Codex 플러그인 및 프로젝트 설정 경고가 포함됩니다. Codex 앱 홈 +대상 지정 섹션은 좁은 범위의 Windows Orca 런타임 홈 불일치도 감지하고, 해당할 때 수동 제거, +환경 설정, 재설치 단계를 표시합니다. 이 진단에 표시되는 경로는 OS 사용자 이름을 마스킹합니다. doctor는 복구 힌트를 보여 주지만 직접 적용하지는 않습니다. -**OAuth 안정성** 섹션은 자격 증명 저장소에 쓰기 가능한지, `OPENCODEX_HOME` 아래에 refresh +**OAuth 안정성** 섹션은 자격 증명 저장소에 쓰기 가능한지, `CODEXCOMMANDER_HOME` 아래에 refresh single-flight/lock 파일을 만들 수 있는지, 건강하지 않은 OAuth 또는 Codex pool 계정(마스킹된 ID)과 복구용 `Action:`, 그리고 Codex 전달 경로가 공식 클라이언트 메타데이터를 꾸며 내지 않는다는 정적 OK를 보고합니다. doctor는 자격 증명을 변경하거나 복구를 적용하지 않습니다. ## 카탈로그 동기화 -### `ocx sync [--restart-codex]` +### `ccx sync [--restart-codex]` 설정된 모든 공급자에서 라이브 모델 목록을 가져와 병합된 카탈로그를 Codex에 다시 주입합니다. 공급자를 추가한 뒤나 사용 가능한 모델을 새로 고칠 때 실행합니다. -오래 실행 중인 Codex `app-server` 프로세스가 아직 살아 있으면, `opencodex-catalog.json` / +오래 실행 중인 Codex `app-server` 프로세스가 아직 살아 있으면, `codexcommander-catalog.json` / `models_cache.json`가 업데이트되었더라도 이전 인메모리 모델 목록을 계속 서비스할 수 있다고 경고합니다. `--restart-codex`를 붙이면 현재 사용자가 소유한 `codex … app-server`와 `codex-code-mode-host` 프로세스 중 일치하는 것에만 `SIGTERM`을 보냅니다(활성 작업이 중단될 수 있습니다). 광범위한 `pkill -f codex` 매칭은 의도적으로 피합니다. -### `ocx sync-cache [--restart-codex]` +### `ccx sync-cache [--restart-codex]` -Codex의 로컬 모델 선택기 캐시를 무효화하여, 활성 opencodex 카탈로그에서 다시 빌드되게 합니다. -`ocx sync`와 같은 오래된 `app-server` 경고와 선택적 `--restart-codex` 동작이 적용됩니다. +Codex의 로컬 모델 선택기 캐시를 무효화하여, 활성 CodexCommander 카탈로그에서 다시 빌드되게 합니다. +`ccx sync`와 같은 오래된 `app-server` 경고와 선택적 `--restart-codex` 동작이 적용됩니다. ## 백그라운드 서비스 -### `ocx service [install|repair|start|stop|status|uninstall|remove]` +### `ccx service [install|repair|start|stop|status|uninstall|remove]` -로그인 관리형 백그라운드 서비스로 opencodex를 실행합니다(macOS **launchd**, Linux **systemd** 사용자 +로그인 관리형 백그라운드 서비스로 CodexCommander를 실행합니다(macOS **launchd**, Linux **systemd** 사용자 유닛, Windows **Task Scheduler**). 로그인 시 자동 시작하고 충돌 시 자동 재시작합니다. 서비스 실행은 -`OCX_SERVICE=1`을 설정하므로 재시작해도 Codex 설정이 흔들리지 않습니다. +`CCX_SERVICE=1`을 설정하므로 재시작해도 Codex 설정이 흔들리지 않습니다. | 하위 명령 | 동작 | | --- | --- | @@ -206,35 +201,35 @@ Codex의 로컬 모델 선택기 캐시를 무효화하여, 활성 opencodex 카 | `remove` | `uninstall`의 별칭입니다. | ```bash -ocx service -ocx service install -ocx service repair -ocx service status -ocx service uninstall +ccx service +ccx service install +ccx service repair +ccx service status +ccx service uninstall ``` -Windows에서는 `ocx service status`가 Task Scheduler 등록 상태를 ID가 검증된 OpenCodex 프록시 +Windows에서는 `ccx service status`가 Task Scheduler 등록 상태를 ID가 검증된 CodexCommander 프록시 도달 가능성과 별도로 보고합니다. 로컬라이즈된 `schtasks` 표는 출력하지 않으므로, 요약은 Windows 코드 페이지에서도 읽기 쉽습니다. Windows에서 Task Scheduler 항목을 만들려면 권한 상승이 필요합니다. 인식되는 로컬라이즈된 접근 거부 텍스트는 기존 안내 경로를 유지합니다. 그 텍스트를 읽을 수 없으면, 대체 경로는 소유된 -명령 형태 `/create /tn opencodex-proxy /xml <non-empty-path> /f`, 상태 1, 그리고 상승하지 +명령 형태 `/create /tn codexcommander-proxy /xml <non-empty-path> /f`, 상태 1, 그리고 상승하지 않은 토큰의 확인이 필요합니다. 그러면 대시보드의 Startup Safety 작업이 UAC를 자동으로 요청할 수 있습니다. 그 대체 경로로도 토큰 상태를 판별할 수 없으면 원래 스케줄러 오류를 유지합니다. 외부 작업이나 외부 연산은 자동 권한 상승 표시를 절대 내지 못합니다. 대시보드 UAC 프롬프트를 승인하거나 -상승된 PowerShell 창에서 `ocx service install`을 다시 실행해 주세요. +상승된 PowerShell 창에서 `ccx service install`을 다시 실행해 주세요. -### `ocx codex-shim <install|status|uninstall|remove>` +### `ccx codex-shim <install|status|uninstall|remove>` PATH 위의 스크립트 기반 `codex` 런처를 가벼운 자동 시작 스크립트로 감쌉니다. 정확한 실행 파일 호출을 깨지 않도록 실제 `codex.exe` 대상은 손대지 않습니다. -완료된 외부 Codex 업데이트가 설치된 shim을 덮어쓰면, 다음 일반 `ocx` 명령이 안정적인 새 런처를 +완료된 외부 Codex 업데이트가 설치된 shim을 덮어쓰면, 다음 일반 `ccx` 명령이 안정적인 새 런처를 백업하고 명령을 처리하기 전에 shim을 복원합니다. 아직 변경 중인 런처는 건드리지 않고 나중에 다시 시도합니다. -복구 실패는 요청한 명령을 실패시키지 않고 경고만 표시합니다. 수동 대체 수단은 `ocx codex-shim install` +복구 실패는 요청한 명령을 실패시키지 않고 경고만 표시합니다. 수동 대체 수단은 `ccx codex-shim install` 입니다. `codexShimAutoRestore`를 `false`로 설정하거나, 프로세스 수준에서 제외하려면 -`OPENCODEX_CODEX_SHIM_AUTO_RESTORE=0`을 설정합니다. +`CODEXCOMMANDER_CODEX_SHIM_AUTO_RESTORE=0`을 설정합니다. | 하위 명령 | 동작 | | --- | --- | @@ -244,17 +239,17 @@ PATH 위의 스크립트 기반 `codex` 런처를 가벼운 자동 시작 스크 | `status` | shim 상태(설치됨, 오래됨, 누락)를 보고합니다. | ```bash -ocx codex-shim install -ocx codex-shim status -ocx codex-shim uninstall +ccx codex-shim install +ccx codex-shim status +ccx codex-shim uninstall ``` :::tip[서비스와 shim] -항상 켜져 있는 백그라운드 프록시에는 `ocx service`를 사용합니다(권장). 데몬 없이 가볍게 필요할 -때만 시작하려면 `ocx codex-shim`을 사용합니다. 이 경우 프록시는 `codex`를 실행할 때만 시작됩니다. +항상 켜져 있는 백그라운드 프록시에는 `ccx service`를 사용합니다(권장). 데몬 없이 가볍게 필요할 +때만 시작하려면 `ccx codex-shim`을 사용합니다. 이 경우 프록시는 `codex`를 실행할 때만 시작됩니다. ::: -### `ocx tray <install|start|stop|status|uninstall|remove> [--json] [--no-start]` +### `ccx tray <install|start|stop|status|uninstall|remove> [--json] [--no-start]` Windows 상태 트레이 아이콘을 설치하고 제어합니다. Windows 로그인 시 시작되며, 프록시를 원클릭으로 제어할 수 있습니다. `start`와 `stop`은 아이콘만 제어합니다. 프록시 제어는 메뉴를 사용하세요. @@ -262,25 +257,7 @@ Windows 상태 트레이 아이콘을 설치하고 제어합니다. Windows 로 ## 대시보드 -### `ocx gui` +### `ccx gui` 프록시가 실행 중이 아니면 자동으로 시작하면서 [웹 대시보드](/guides/web-dashboard/)를 `http://localhost:<port>`에서 엽니다. - -## 업데이트 - -### `ocx update [--tag latest|preview]` - -npm에서 opencodex를 자체 업데이트합니다. 안정판 설치는 `@latest`를 사용하고, 미리보기 설치는 -`--tag latest|preview`를 주지 않으면 `@preview`를 유지합니다. 소스 체크아웃을 감지하면 대신 -`git pull && bun install`을 실행하라고 안내하고, 해당 태그에서 이미 최신 버전이면 아무 동작도 하지 -않습니다. 실행 중인 프록시가 있으면 파일을 교체하기 전에 중지합니다. 설치된 서비스는 자동으로 다시 -빌드해 시작하며, 포그라운드 설치에서는 다음 단계로 `ocx start`를 출력합니다. - -```bash -ocx update -ocx update --tag preview -``` - -새 버전은 [Release workflow](https://github.com/lidge-jun/opencodex/actions/workflows/release.yml)가 -npm에 게시하면 사용할 수 있게 됩니다. diff --git a/docs-site/src/content/docs/ko/reference/cli/providers-accounts.md b/docs-site/src/content/docs/ko/reference/cli/providers-accounts.md index 9fb0de3878..90df40219c 100644 --- a/docs-site/src/content/docs/ko/reference/cli/providers-accounts.md +++ b/docs-site/src/content/docs/ko/reference/cli/providers-accounts.md @@ -7,7 +7,7 @@ description: 제공자 설정, 자격 증명, 할당량, 모델 카탈로그 명 ## 제공자 -### `ocx provider <subcommand>` +### `ccx provider <subcommand>` 비대화형 제공자 관리입니다. 레지스트리 항목은 이름으로 시드되며, 사용자 지정 이름을 쓰려면 `--adapter`와 `--base-url`을 둘 다 지정해야 합니다. @@ -26,13 +26,13 @@ description: 제공자 설정, 자격 증명, 할당량, 모델 카탈로그 명 | `account-mode` | `pool`, `direct`, `--json` | Codex 계정 라우팅을 풀 기반으로 할지 직접 연결로 할지 선택합니다. | ```bash -ocx provider list --json -ocx provider test ark -ocx provider add anthropic --api-key sk-ant-... --set-default --sync -ocx provider add local-dev --adapter openai-chat --base-url http://localhost:11434/v1 -ocx provider show anthropic --json -ocx models --provider anthropic --json -ocx models live --provider ark --json +ccx provider list --json +ccx provider test ark +ccx provider add anthropic --api-key sk-ant-... --set-default --sync +ccx provider add local-dev --adapter openai-chat --base-url http://localhost:11434/v1 +ccx provider show anthropic --json +ccx models --provider anthropic --json +ccx models live --provider ark --json ``` :::caution[커스텀 헤더는 자격증명 통로가 아닙니다] @@ -54,29 +54,29 @@ ocx models live --provider ark --json ## 인증 -### `ocx login <provider>` +### `ccx login <provider>` -제공자에 등록된 로그인 흐름을 시작합니다. 제공자에 따라 OAuth 로그인은 브라우저를 열거나 로그인된 네이티브 CLI 세션을 가져오거나 연결합니다. `~/.opencodex/`에 저장된 OpenCodex 소유 자격 증명은 자동 갱신됩니다. 연결된 Grok/Kimi CLI 액세스 세대는 읽기 전용으로 채택되며 갱신 책임은 네이티브 CLI에 남습니다. API 키 로그인 제공자는 키 대시보드를 열고, 키 입력을 요청한 뒤, 가능한 경우 검증하고, 그 결과 나온 제공자 설정을 저장합니다. 이름이 없거나 알 수 없으면 현재 허용되는 OAuth 및 API 키 제공자 id를 출력합니다. +제공자에 등록된 로그인 흐름을 시작합니다. 제공자에 따라 OAuth 로그인은 브라우저를 열거나 로그인된 네이티브 CLI 세션을 가져오거나 연결합니다. `~/.codexcommander/`에 저장된 CodexCommander 소유 자격 증명은 자동 갱신됩니다. 연결된 Grok/Kimi CLI 액세스 세대는 읽기 전용으로 채택되며 갱신 책임은 네이티브 CLI에 남습니다. API 키 로그인 제공자는 키 대시보드를 열고, 키 입력을 요청한 뒤, 가능한 경우 검증하고, 그 결과 나온 제공자 설정을 저장합니다. 이름이 없거나 알 수 없으면 현재 허용되는 OAuth 및 API 키 제공자 id를 출력합니다. -`ocx status` / `ocx doctor`가 재인증 필요 또는 터미널 새로고침 실패를 보고한 뒤에는 같은 명령으로 **재인증**하면 됩니다(대시보드의 Reauthenticate를 써도 됩니다). Codex 풀 계정은 공개 `ocx login` 제공자가 아닙니다. 대신 대시보드의 Codex 계정 풀(Reauthenticate)이나 헤드리스 `ocx account reauth` 흐름으로 재인증해야 합니다. +`ccx status` / `ccx doctor`가 재인증 필요 또는 터미널 새로고침 실패를 보고한 뒤에는 같은 명령으로 **재인증**하면 됩니다(대시보드의 Reauthenticate를 써도 됩니다). Codex 풀 계정은 공개 `ccx login` 제공자가 아닙니다. 대신 대시보드의 Codex 계정 풀(Reauthenticate)이나 헤드리스 `ccx account reauth` 흐름으로 재인증해야 합니다. ```bash -ocx login xai -ocx login anthropic +ccx login xai +ccx login anthropic ``` -### `ocx logout <provider>` +### `ccx logout <provider>` 제공자에 저장된 OAuth 자격 증명을 제거합니다. ## 계정과 키 풀 -### `ocx account <subcommand>` +### `ccx account <subcommand>` 실행 중인 프록시를 통해 제공자 계정과 API 키 풀을 나열하고 전환합니다. 제공되는 도움말 표면은 다음과 같습니다: ```text -Usage: ocx account <list|current|use|refresh|auto-switch|priority|login|reauth|code|cancel|remove|add-key|reset-credits> ... +Usage: ccx account <list|current|use|refresh|auto-switch|priority|login|reauth|code|cancel|remove|add-key|reset-credits> ... list [provider] Codex account pool, OAuth accounts and API keys (identifiers shown masked as the API returns them). current <provider> Show the active account or key. @@ -111,7 +111,7 @@ Codex pool selection applies to the next request after clearing existing affinit } ``` -### `ocx account list [provider] [--json] [--all]` +### `ccx account list [provider] [--json] [--all]` 제공자를 지정하지 않으면 Codex 풀, OAuth 계정, 설정된 API 키 풀을 나열합니다. `--all`이 없으면 비어 있는 제공자는 건너뜁니다. 제공자를 지정하면 해당 자격 증명 계열만 나열합니다. 사람이 보는 출력은 `PROVIDER TYPE ID PLAN/LABEL PRIORITY STATUS` 형식을 사용하며, 수동으로 선택한 Codex 행에는 `selected`가 표시됩니다. 저장된 Kiro 계정이 있으면 출력에 Kiro에는 로그인 슬롯이 하나뿐이고 다시 로그인하면 현재 계정을 바꾼다는 점이 표시됩니다. 빈 결과도 성공입니다. `--json`은 다음을 반환합니다: @@ -119,7 +119,7 @@ Codex pool selection applies to the next request after clearing existing affinit { accounts: AccountRow[], notes: string[] } ``` -### `ocx account current <provider> [--json]` +### `ccx account current <provider> [--json]` 활성 계정이나 키를 보여줍니다. 수동 고정이 없는 Codex 풀은 우선순위를 고려한 자동 선택을 보고합니다. 가장 우선순위가 높은 적격 tier를 고르고, 그 tier 안에서 할당량 라우팅 기준으로 가장 적게 사용한 항목을 선택합니다. 활성 자격 증명이 없는 다른 계열은 그 상태를 보고하고도 종료 코드 0으로 끝납니다. `--json`은 다음을 반환합니다: @@ -127,10 +127,10 @@ Codex pool selection applies to the next request after clearing existing affinit { provider, type, activeId: string | null, autoSwitchThreshold?: number, account: AccountRow | null } ``` -### `ocx account use <provider> <account-or-key-id|main> [--json]` +### `ccx account use <provider> <account-or-key-id|main> [--json]` 기존 Codex 계정, OAuth 계정 또는 API key를 선택합니다. `openai`에서 `main`은 Codex App 로그인을 -선택합니다. Codex Pool 선택은 프로세스 로컬 affinity를 지우고 기존에 보이던 작업을 포함한 다음 요청부터 적용됩니다. 프록시 재시작이나 affinity eviction 뒤에도 작업이 바인딩 없는 상태가 될 수 있지만, 진행 중인 요청은 이미 확보한 계정을 유지합니다. 이 선택은 Pool 라우팅만 제어하며 Direct mode는 호출자 소유/native main credential을 계속 사용합니다. 사용량 기반 선제 전환, 401/403 재인증, 429/retry-after cooldown, 제외, 출력 전 429/402 실패 복구는 나중에 다른 적격 Pool 계정을 선택할 수 있습니다. 이러한 복구 경로는 사용량 기반 전환이 꺼져 있어도 동작합니다. 계정이 바뀌어도 OpenCodex는 대화 문맥을 재생하지만 프로바이더 측 prompt cache는 다시 예열해야 할 수 있습니다. +선택합니다. Codex Pool 선택은 프로세스 로컬 affinity를 지우고 기존에 보이던 작업을 포함한 다음 요청부터 적용됩니다. 프록시 재시작이나 affinity eviction 뒤에도 작업이 바인딩 없는 상태가 될 수 있지만, 진행 중인 요청은 이미 확보한 계정을 유지합니다. 이 선택은 Pool 라우팅만 제어하며 Direct mode는 호출자 소유/native main credential을 계속 사용합니다. 사용량 기반 선제 전환, 401/403 재인증, 429/retry-after cooldown, 제외, 출력 전 429/402 실패 복구는 나중에 다른 적격 Pool 계정을 선택할 수 있습니다. 이러한 복구 경로는 사용량 기반 전환이 꺼져 있어도 동작합니다. 계정이 바뀌어도 CodexCommander는 대화 문맥을 재생하지만 프로바이더 측 prompt cache는 다시 예열해야 할 수 있습니다. 알 수 없는 프로바이더나 id는 종료 코드 1입니다. `--json`은 다음을 반환합니다. **401/403**이 발생하면 해당 계정의 프로세스 로컬 affinity를 해제하고 재인증을 요구합니다. **429**에서는 `Retry-After`를 준수해 계정 cooldown을 시작하고 affinity를 해제한 뒤, @@ -141,13 +141,13 @@ Codex pool selection applies to the next request after clearing existing affinit { ok: true, provider, type, activeId } ``` -### `ocx account refresh <provider> [--json]` +### `ccx account refresh <provider> [--json]` -Codex 풀에는 `ocx account refresh openai [--json]`를 사용합니다. 계정 할당량을 강제로 새로 고치고 사용 가능 주간/월간 비율과 재설정 시간을 출력합니다. 할당량 데이터가 없으면 0%가 아니라 알 수 없음으로 보고합니다. JSON 봉투는 `{ accounts: AccountRow[] }`이며, Codex 행마다 `quota`가 붙습니다. +Codex 풀에는 `ccx account refresh openai [--json]`를 사용합니다. 계정 할당량을 강제로 새로 고치고 사용 가능 주간/월간 비율과 재설정 시간을 출력합니다. 할당량 데이터가 없으면 0%가 아니라 알 수 없음으로 보고합니다. JSON 봉투는 `{ accounts: AccountRow[] }`이며, Codex 행마다 `quota`가 붙습니다. OAuth 및 API 키 제공자에는 제공자의 할당량 보고 엔드포인트를 강제로 새로 고칩니다. 토큰 재로그인이나 단순한 계정 목록 재읽기가 아닙니다. `--json`은 `{ provider, report: ProviderQuotaReport | null }`를 반환합니다. 지원되는 할당량 보고가 없는 제공자는 `no quota report available for <provider>`를 출력하고 종료 코드 0으로 끝납니다. 알 수 없는 제공자와 관리 API 실패는 종료 코드 1로 끝납니다. 상위 할당량 확인이 실패하거나 시간 초과되면 대시보드의 할당량 막대와 맞추어 null 또는 오래된 보고로만 떨어집니다(종료 코드 0). -### `ocx account auto-switch <provider> <on|off|status|threshold <0-100>> [--json]` +### `ccx account auto-switch <provider> <on|off|status|threshold <0-100>> [--json]` `openai` Codex 계정 풀만 제어합니다. `on`은 80%, `off`는 0%를 설정하고, `status`는 현재 값을 읽으며, `threshold <n>`은 0부터 100까지의 정수를 받습니다. 다른 제공자와 잘못된 값은 종료 코드 1로 끝납니다. `--json`은 다음을 반환합니다: @@ -155,12 +155,12 @@ OAuth 및 API 키 제공자에는 제공자의 할당량 보고 엔드포인트 { provider, autoSwitchThreshold: number, enabled: boolean } ``` -### `ocx account priority <provider> <account-id|main> [<-100..100|first|earlier|normal|later|last|reset>] [--json]` +### `ccx account priority <provider> <account-id|main> [<-100..100|first|earlier|normal|later|last|reset>] [--json]` Codex pool 계정 하나의 선택 순서를 읽거나 설정합니다. **값이 클수록 먼저** 쓰이고 기본값은 `0`, 범위는 `-100`부터 `100`까지입니다. 순서를 갖는 것은 `openai` Codex pool뿐이므로 다른 프로바이더는 종료 코드 1입니다. `main`은 Codex Desktop 로그인을 가리키며 다른 pool 계정과 똑같이 정렬됩니다. -`ocx account priority openai main last`로 예비 계정으로 남겨 둘 수 있습니다. +`ccx account priority openai main last`로 예비 계정으로 남겨 둘 수 있습니다. 프리셋 단어는 작은 정수의 다른 이름입니다. `first`는 `+2`, `earlier`는 `+1`, `normal`은 `0`, `later`는 `-1`, `last`는 `-2`입니다. `reset`은 기본값으로 되돌리고 저장된 항목을 지웁니다. **값을 @@ -177,11 +177,11 @@ Codex pool 계정 하나의 선택 순서를 읽거나 설정합니다. **값이 ``` -### `ocx account login|reauth|code|cancel ...` +### `ccx account login|reauth|code|cancel ...` -헤드리스 셸에서 브라우저 기반 또는 수동 코드 계정 인증을 실행합니다. 제공자별 명령 형태는 `ocx account --help`를 보십시오. +헤드리스 셸에서 브라우저 기반 또는 수동 코드 계정 인증을 실행합니다. 제공자별 명령 형태는 `ccx account --help`를 보십시오. -### `ocx account remove <provider> <id|main> --yes [--json]` +### `ccx account remove <provider> <id|main> --yes [--json]` 이 보호된 비대화형 삭제는 `--yes`를 요구합니다. 삭제하기 전에 id가 존재하는지 확인하며, 없는 id는 DELETE를 보내지 않고 종료 코드 1로 끝납니다. Codex App의 main 로그인은 제거할 수 없으므로 `remove openai main --yes`는 거부됩니다. 삭제 후에는 해당 계열을 다시 읽습니다. 고정된 Codex 계정을 제거하면 고정이 풀리고 자동 선택으로 돌아갑니다. OAuth는 남아 있는 첫 번째 계정으로 승격하거나 없다고 보고합니다. API 키 풀은 남아 있는 첫 번째 키로 승격하거나 없다고 보고합니다. `--json`의 성공 및 실패 형식은 다음과 같습니다: @@ -190,32 +190,32 @@ Codex pool 계정 하나의 선택 순서를 읽거나 설정합니다. **값이 { error: string } // stderr, exit 1 ``` -### `ocx account add-key <provider> [--label <label>] [--json]` +### `ccx account add-key <provider> [--label <label>] [--json]` API 키 제공자에 키를 추가하고 활성화합니다. 키는 비TTY 파이프/리디렉션 stdin에서만 읽습니다. 대화형 TTY 입력, 빈 입력, OAuth/Codex 제공자, API 실패는 종료 코드 1로 끝납니다. 라벨 안에 들어 있더라도 키는 절대 출력되지 않습니다. 비밀 관리자나 here-string을 쓰는 편이 좋습니다: ```bash -ocx account add-key openrouter --label personal <<< "$OPENROUTER_API_KEY" -security find-generic-password -w openrouter | ocx account add-key openrouter --json +ccx account add-key openrouter --label personal <<< "$OPENROUTER_API_KEY" +security find-generic-password -w openrouter | ccx account add-key openrouter --json ``` `--json`은 `{ ok: true, id: string | null, label?: string }`를 반환하며 키를 절대 포함하지 않습니다. -### `ocx account reset-credits <id|main> [--consume --yes]` +### `ccx account reset-credits <id|main> [--consume --yes]` 계정의 Codex reset credits를 확인합니다. credit을 소비하는 동작은 파괴적이므로 `--consume`와 `--yes`를 둘 다 요구합니다. -### `ocx account main <subcommand>` +### `ccx account main <subcommand>` -OpenCodex 계정 풀 라우팅을 변경하지 않고 이름이 지정된 네이티브 Codex 기본 로그인 프로필을 관리합니다. +CodexCommander 계정 풀 라우팅을 변경하지 않고 이름이 지정된 네이티브 Codex 기본 로그인 프로필을 관리합니다. ```text -ocx account main doctor [--json] -ocx account main list [--json] -ocx account main register <label> [--json] -ocx account main add <label> -ocx account main switch <profile-id-or-label> --yes [--json] -ocx account main recover [--rollback --yes] [--json] +ccx account main doctor [--json] +ccx account main list [--json] +ccx account main register <label> [--json] +ccx account main add <label> +ccx account main switch <profile-id-or-label> --yes [--json] +ccx account main recover [--rollback --yes] [--json] ``` 각 변경 명령은 실행 중인 프록시가 반환한 정규화된 유효 `CODEX_HOME`을 표시합니다. 이 경로는 @@ -224,21 +224,19 @@ ocx account main recover [--rollback --yes] [--json] 버전 1은 파일 기반 Codex 인증을 지원하고 저장된 프로필을 AES-256-GCM으로 암호화하며 암호화 키를 운영 체제 자격 증명 저장소에 보관합니다. `add`는 생성된 자격 증명을 가져오기 전에 공식 Codex 로그인을 스테이징합니다. 프로필을 전환하기 전에 Codex를 종료하십시오. 전환에 성공하면 로컬 작업과 기록은 보존되지만 계속하기 전에 Codex를 다시 시작해야 합니다. `doctor`로 프로필 상태를 확인하고 `recover`로 중단된 전환을 완료하거나 롤백할 수 있습니다. `switch`에는 프로필 ID 또는 라벨을 지정할 수 있습니다. -v1 복구 매트릭스는 트랜잭션 파일이 rename으로 게시된 뒤 OpenCodex 프로세스가 종료되는 경우를 다룹니다. 운영 체제 또는 커널 충돌이나 갑작스러운 전원 손실에 대한 내구성은 보장하지 않습니다. `atomicWriteFileAsync()`는 파일이나 부모 디렉터리에 `fsync`를 수행하지 않습니다. +v1 복구 매트릭스는 트랜잭션 파일이 rename으로 게시된 뒤 CodexCommander 프로세스가 종료되는 경우를 다룹니다. 운영 체제 또는 커널 충돌이나 갑작스러운 전원 손실에 대한 내구성은 보장하지 않습니다. `atomicWriteFileAsync()`는 파일이나 부모 디렉터리에 `fsync`를 수행하지 않습니다. -암호화된 볼트, 전환 저널, 복구 마커 및 저널 격리 파일은 정규 `<real CODEX_HOME>/.opencodex-native-main-profiles` 디렉터리에 저장됩니다. 따라서 해당 Codex 홈을 공유하는 모든 OpenCodex 인스턴스는 동일한 단일 소유자와 단일 복구 상태를 관찰합니다. 평문 로그인 스테이징은 각 `<OPENCODEX_HOME>/native-main-profile-staging` 디렉터리 아래에 서로 분리된 채 유지됩니다. +암호화된 볼트, 전환 저널, 복구 마커 및 저널 격리 파일은 정규 `<real CODEX_HOME>/.codexcommander-native-main-profiles` 디렉터리에 저장됩니다. 따라서 해당 Codex 홈을 공유하는 모든 CodexCommander 인스턴스는 동일한 단일 소유자와 단일 복구 상태를 관찰합니다. 평문 로그인 스테이징은 각 `<CODEXCOMMANDER_HOME>/native-main-profile-staging` 디렉터리 아래에 서로 분리된 채 유지됩니다. -native-main 트래픽이나 저널 복구를 허용하기 전에 수명 주기 소유자가 자격 증명에 대한 배타적 점유권을 획득하고, 이름이 정확히 `auth.json.ocx.<pid>.<sequence>.tmp`인 충돌 잔여 파일만 제거합니다. 각 후보는 변경되지 않은 정규 `CODEX_HOME` 아래에서 하드 링크 수가 1인 일반 파일로 유지되어야 하며, 내용을 잘라내고 flush한 다음 unlink합니다. 링크나 재분석 지점(reparse point)으로의 바꿔치기, 파일 식별 정보 변경 또는 그 밖의 모호성이 있으면 native-main 트래픽은 계속 차단되며, 이름이 비슷할 뿐 정확히 일치하지 않는 파일은 자동으로 제거하지 않습니다. 이는 정상적으로 협력하는 OpenCodex 프로세스의 충돌을 방어하지만, 이미 같은 운영 체제 사용자로 실행 중인 악의적 프로세스까지 방어하지는 않습니다. 해당 사용자와 `CODEX_HOME`이 있는 파일 시스템은 계속 신뢰 대상으로 간주되며, 내용을 잘라내더라도 copy-on-write 저장소, 스냅샷 또는 SSD 잔류 데이터에서 물리적으로 지워진다고 보장할 수 없습니다. - -프리뷰 빌드는 `<OPENCODEX_HOME>/native-main-profiles`를 사용했습니다. 이 레이아웃은 절대로 자동으로 가져오지 않습니다. `doctor`가 레거시 프로필 상태를 보고하면 동일한 `CODEX_HOME`을 공유하는 모든 OpenCodex 프록시를 중지하십시오. 그런 다음 해당하는 `*.vault.json`, `*.journal.json`, 복구 마커 및 참조된 journal-quarantine 파일을 백업하고, 소유자 전용 권한을 유지한 채 모두 함께 정규 디렉터리로 옮기십시오. 또는 이전 프리뷰 파일 세트를 제거하고 `ocx account main register`를 다시 실행하십시오. 동일한 `CODEX_HOME`을 공유하는 프록시가 하나라도 실행 중인 동안에는 여러 이전 루트 중 하나를 선택하거나 두 레이아웃을 동시에 사용하지 마십시오. Windows에서는 이전의 대소문자를 구분하지 않는 홈 식별자를 키로 사용한 프리뷰 상태를 옮기지 말고 재설정해야 합니다. 암호화된 AAD와 운영 체제 키링 식별자는 의도적으로 재사용하지 않기 때문입니다. +native-main 트래픽이나 저널 복구를 허용하기 전에 수명 주기 소유자가 자격 증명에 대한 배타적 점유권을 획득하고, 이름이 정확히 `auth.json.ccx.<pid>.<sequence>.tmp`인 충돌 잔여 파일만 제거합니다. 각 후보는 변경되지 않은 정규 `CODEX_HOME` 아래에서 하드 링크 수가 1인 일반 파일로 유지되어야 하며, 내용을 잘라내고 flush한 다음 unlink합니다. 링크나 재분석 지점(reparse point)으로의 바꿔치기, 파일 식별 정보 변경 또는 그 밖의 모호성이 있으면 native-main 트래픽은 계속 차단되며, 이름이 비슷할 뿐 정확히 일치하지 않는 파일은 자동으로 제거하지 않습니다. 이는 정상적으로 협력하는 CodexCommander 프로세스의 충돌을 방어하지만, 이미 같은 운영 체제 사용자로 실행 중인 악의적 프로세스까지 방어하지는 않습니다. 해당 사용자와 `CODEX_HOME`이 있는 파일 시스템은 계속 신뢰 대상으로 간주되며, 내용을 잘라내더라도 copy-on-write 저장소, 스냅샷 또는 SSD 잔류 데이터에서 물리적으로 지워진다고 보장할 수 없습니다. ## 모델 -### `ocx models [subcommand]` · `ocx model <subcommand>` +### `ccx models [subcommand]` · `ccx model <subcommand>` -`ocx model`은 `ocx models`의 별칭입니다. 하위 명령이 없으면 설정된 제공자에 사전 등록된 모델을 나열합니다. `--provider`는 설정된 제공자 하나를 필터링하고 `--json`은 모델 메타데이터를 반환합니다. `live`는 실행 중인 카탈로그를 읽습니다. `add`, `edit`, `remove`, `list-custom`은 수동 카탈로그 항목을 관리합니다. `enable`, `disable`, `provider`는 가시성을 제어합니다. `selected`는 제공자 허용 목록을 제어합니다. `context`는 제공자 컨텍스트 한도를 제어합니다. `shadow`는 백그라운드 shadow-call 가로채기를 관리합니다. +`ccx model`은 `ccx models`의 별칭입니다. 하위 명령이 없으면 설정된 제공자에 사전 등록된 모델을 나열합니다. `--provider`는 설정된 제공자 하나를 필터링하고 `--json`은 모델 메타데이터를 반환합니다. `live`는 실행 중인 카탈로그를 읽습니다. `add`, `edit`, `remove`, `list-custom`은 수동 카탈로그 항목을 관리합니다. `enable`, `disable`, `provider`는 가시성을 제어합니다. `selected`는 제공자 허용 목록을 제어합니다. `context`는 제공자 컨텍스트 한도를 제어합니다. `shadow`는 백그라운드 shadow-call 가로채기를 관리합니다. -대시보드가 제공하는 모델별 작업은 모두 여기에서도 사용할 수 있으므로, 헤드리스 설치에서는 카탈로그를 관리할 때 GUI가 필요하지 않습니다. `add`, `remove`, `list-custom`은 구성 파일을 대상으로 하며 카탈로그 동기화를 통해 실행 중인 프록시에 적용됩니다. 나머지는 실시간 관리 API와 통신하며 프록시가 실행 중이어야 합니다(`ocx start` 또는 설치된 서비스). +대시보드가 제공하는 모델별 작업은 모두 여기에서도 사용할 수 있으므로, 헤드리스 설치에서는 카탈로그를 관리할 때 GUI가 필요하지 않습니다. `add`, `remove`, `list-custom`은 구성 파일을 대상으로 하며 카탈로그 동기화를 통해 실행 중인 프록시에 적용됩니다. 나머지는 실시간 관리 API와 통신하며 프록시가 실행 중이어야 합니다(`ccx start` 또는 설치된 서비스). | 하위 명령 | 지원 플래그 | 동작 | | --- | --- | --- | @@ -253,18 +251,18 @@ native-main 트래픽이나 저널 복구를 허용하기 전에 수명 주기 | `provider <name> <on\|off>` | `--json` | 한 제공자의 모든 모델을 한 번의 쓰기로 활성화하거나 비활성화합니다. | | `selected <provider>` | `--set <id,id...>`, `--clear`, `--json` | 제공자 모델 허용 목록을 읽거나 교체합니다. `--clear`는 허용 목록을 제거해 모든 모델을 제공하도록 합니다. | | `context <status\|value <tokens>\|provider <name> <on\|off>\|all <on\|off>>` | `--json` | 전역 또는 제공자별로 컨텍스트 창 한도를 읽거나 설정합니다. | -| `shadow <status\|set> [model\|-]` | `--enabled <on\|off>`, `--json` | Codex의 백그라운드 헬퍼 호출에 사용할 대체 모델을 읽거나 설정합니다. `-`는 모델을 지웁니다. `status`는 프록시가 가로채는 헬퍼 슬러그인 `sourceModels`도 보고합니다(기본값: `gpt-5.6-luna`; 0.144.x 이하 클라이언트가 사용한 `gpt-5.4-mini`는 명시적인 `sourceModels` 재정의로 복원할 수 있습니다). | +| `shadow <status\|set> [model\|-]` | `--enabled <on\|off>`, `--json` | Codex의 백그라운드 헬퍼 호출에 사용할 대체 모델을 읽거나 설정합니다. `-`는 모델을 지웁니다. `status`는 프록시가 가로채는 헬퍼 슬러그인 `sourceModels`도 보고합니다(기본값: `gpt-5.6-luna`; 명시적 재정의는 현재의 커스텀 헬퍼 ID에만 사용합니다). | ```bash -ocx models live --json # what Codex can actually see right now -ocx models disable anthropic/claude-haiku-4 # hide one routed model -ocx models enable gpt-5.6-sol # no slash, so it is treated as native -ocx models provider zenmux off # hide a noisy provider wholesale -ocx models selected anthropic --set claude-opus-5,claude-fable-5 -ocx models selected anthropic --clear # drop the allowlist again -ocx models add deepseek deepseek-v4 --display-name 'DeepSeek V4' --context-window 128000 --modalities text,image -ocx models list-custom --json # read the custom-id for edit/remove -ocx models remove deepseek/deepseek-v4 --yes +ccx models live --json # what Codex can actually see right now +ccx models disable anthropic/claude-haiku-4 # hide one routed model +ccx models enable gpt-5.6-sol # no slash, so it is treated as native +ccx models provider zenmux off # hide a noisy provider wholesale +ccx models selected anthropic --set claude-opus-5,claude-fable-5 +ccx models selected anthropic --clear # drop the allowlist again +ccx models add deepseek deepseek-v4 --display-name 'DeepSeek V4' --context-window 128000 --modalities text,image +ccx models list-custom --json # read the custom-id for edit/remove +ccx models remove deepseek/deepseek-v4 --yes ``` 슬래시가 있는 모델 선택기는 라우팅됩니다(`anthropic/claude-opus-5`). 슬래시가 없는 id는 native OpenAI 모델로 취급되므로, 라우팅된 것처럼 보일 수 있는 id에 대해 그 읽기를 강제하려면 `--native`가 필요합니다. diff --git a/docs-site/src/content/docs/ko/reference/configuration.md b/docs-site/src/content/docs/ko/reference/configuration.md index 4f80b5136a..dedda1b6d8 100644 --- a/docs-site/src/content/docs/ko/reference/configuration.md +++ b/docs-site/src/content/docs/ko/reference/configuration.md @@ -1,19 +1,19 @@ --- title: 설정 레퍼런스 -description: opencodex가 설정을 저장하는 위치, 편집 방식, 각 설정 도메인으로 가는 링크를 안내합니다. +description: CodexCommander가 설정을 저장하는 위치, 편집 방식, 각 설정 도메인으로 가는 링크를 안내합니다. --- -opencodex는 지속 설정을 `$OPENCODEX_HOME/config.json`에 저장합니다. 보통은 -`~/.opencodex/config.json`이며, Windows에서는 기본값이 -`%USERPROFILE%\.opencodex\config.json`입니다. +CodexCommander는 지속 설정을 `$CODEXCOMMANDER_HOME/config.json`에 저장합니다. 보통은 +`~/.codexcommander/config.json`이며, Windows에서는 기본값이 +`%USERPROFILE%\.codexcommander\config.json`입니다. ## 설정을 편집하는 방법 작업에 맞는 편집 경로를 선택하세요. - **대시보드:** 안내형 UI에서 프로바이더, 모델, 에이전트, 접근, 저장소 설정을 조정합니다. -- **CLI:** `ocx init`은 초기 파일을 만들고, `ocx provider`, `ocx models`, `ocx combo`, - `ocx agent`, `ocx config` 같은 명령은 각 명령이 맡은 설정을 갱신하거나 조회합니다. +- **CLI:** `ccx init`은 초기 파일을 만들고, `ccx provider`, `ccx models`, `ccx combo`, + `ccx agent`, `ccx config` 같은 명령은 각 명령이 맡은 설정을 갱신하거나 조회합니다. - **파일:** 전용 UI나 CLI 명령이 없는 필드는 `config.json`을 직접 편집합니다. 파일은 유효한 JSON이어야 합니다. @@ -23,14 +23,14 @@ opencodex는 지속 설정을 `$OPENCODEX_HOME/config.json`에 저장합니다. 경로가 명시된 `claudeCode`와 리스너 바인딩 필드의 외부 수정분을 병합하지만, 그 보호가 모든 하위 트리를 덮지는 않습니다. -파일을 파싱할 수 없으면 opencodex는 `config.json.invalid-<timestamp>`로 백업하고, 콘솔에 경고를 +파일을 파싱할 수 없으면 CodexCommander는 `config.json.invalid-<timestamp>`로 백업하고, 콘솔에 경고를 남긴 뒤 기본값으로 시작합니다. 파일이 없어도 새로 설치한 경우의 기본값을 그대로 사용하며, 그것은 단일 `openai` forward 프로바이더입니다. ## 우선순위와 기본값 `config.json`의 유효한 값은 내장 기본값보다 우선합니다. 선택 사항으로 비어 있는 필드는 각 도메인 페이지에 -문서화된 기본값을 사용합니다. `OPENCODEX_HOME`은 기본 설정 디렉터리보다 우선합니다. +문서화된 기본값을 사용합니다. `CODEXCOMMANDER_HOME`은 기본 설정 디렉터리보다 우선합니다. `apiKey: "${PROVIDER_API_KEY}"`처럼 환경 참조를 허용하는 필드는 요청 시점에 해당 변수를 풉니다. 외부로 나가는 프록시 연결에서는 이미 설정된 `HTTP_PROXY` 또는 `HTTPS_PROXY`가 최상위 `proxy` 필드보다 우선합니다. @@ -57,8 +57,8 @@ OAuth와 forward-provider 토큰은 `config.json`이 아니라 별도의 자격 account id와 이메일도 공개하지 않는 편이 좋으니, 가능하면 공개 selector alias를 사용하세요. :::note[원자적 쓰기] -opencodex는 관리형 `config.toml`과 `opencodex-catalog.json` 파일을 임시 파일로 쓴 뒤 rename하는 +CodexCommander는 관리형 `config.toml`과 `codexcommander-catalog.json` 파일을 임시 파일로 쓴 뒤 rename하는 방식(`atomicWriteFile`)으로 저장합니다. -이렇게 하면 `ocx stop`과 프록시 종료 handler처럼 동시에 실행되는 writer가 Codex를 되돌릴 때도 +이렇게 하면 `ccx stop`과 프록시 종료 handler처럼 동시에 실행되는 writer가 Codex를 되돌릴 때도 부분 파일이 생기지 않습니다. ::: diff --git a/docs-site/src/content/docs/ko/reference/configuration/agents.md b/docs-site/src/content/docs/ko/reference/configuration/agents.md index ec340296b1..9284fe8541 100644 --- a/docs-site/src/content/docs/ko/reference/configuration/agents.md +++ b/docs-site/src/content/docs/ko/reference/configuration/agents.md @@ -3,7 +3,7 @@ title: 에이전트 설정 description: 멀티 에이전트 표면, 위임 안내, 선호 모델, 대체 체인, 기본값 동기화, 노력 상한을 다룹니다. --- -에이전트 설정은 어떤 Codex 협업 표면을 노출할지와, opencodex가 위임 작업을 어떻게 안내하고, 라우팅하고, 제한할지를 제어합니다. +에이전트 설정은 어떤 Codex 협업 표면을 노출할지와, CodexCommander가 위임 작업을 어떻게 안내하고, 라우팅하고, 제한할지를 제어합니다. ## 에이전트 필드 @@ -11,18 +11,18 @@ description: 멀티 에이전트 표면, 위임 안내, 선호 모델, 대체 | --- | --- | --- | --- | | `multiAgentMode?` | `"v1" \| "default" \| "v2"` | `"default"` | `v1`은 카탈로그의 모든 모델에 v1을 표시하고, `v2`는 모든 모델에 v2를 표시합니다. `default`는 상위 고정값(Sol/Terra는 v2, Luna는 v1)을 복원하고, 그 외에는 네이티브 `multi_agent_v2` 플래그를 따릅니다. 새 세션에 적용됩니다. | | `multiAgentV2MessageDelivery?` | `"encrypted" \| "plaintext"` | `"encrypted"` | V2 부모 메시지 전달 정책입니다. `encrypted`는 ChatGPT의 예약된 암호화 계약을 유지합니다. 실험적인 `plaintext`는 이후 V2 부모 요청을 다중 프로바이더 호환 모드로 전환하며, 해당 부모의 모든 위임 메시지를 평문으로 만듭니다. 라우팅된 부모의 메시지 호출에도 Codex 평문 마커를 추가합니다. 변경 후 새 세션을 시작하세요. | -| `subagentModels?` | `string[]` | `gpt-5.5`, `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna`, `gpt-5.4-mini` | 최대 다섯 개의 bare native id, account-qualified `<selector>/<native-openai-model>` id 또는 routed `provider/model` id를 서브에이전트 선택기에 우선 노출합니다. 대시보드는 account-qualified 선택을 포함한 기존 exact selector를 보존하고, 저장된 항목 중 실제로 노출되거나 제외된 항목을 보고합니다. 현재 카탈로그에 없는 선택은 `ocx agent subagents set`을 사용하거나 설정을 직접 편집하세요. 명시적인 빈 목록도 그대로 보존됩니다. | +| `subagentModels?` | `string[]` | `gpt-5.5`, `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna`, `gpt-5.4-mini` | 최대 다섯 개의 bare native id, account-qualified `<selector>/<native-openai-model>` id 또는 routed `provider/model` id를 서브에이전트 선택기에 우선 노출합니다. 대시보드는 account-qualified 선택을 포함한 기존 exact selector를 보존하고, 저장된 항목 중 실제로 노출되거나 제외된 항목을 보고합니다. 현재 카탈로그에 없는 선택은 `ccx agent subagents set`을 사용하거나 설정을 직접 편집하세요. 명시적인 빈 목록도 그대로 보존됩니다. | | `injectionModel?` | `string` | — | 프록시가 작성한 v2 위임 안내에서 사용하는 선호 네이티브 또는 라우팅된 서브에이전트 모델입니다. | | `injectionEffort?` | `string` | — | 선호 노력(`low`부터 `ultra`까지)입니다. `injectionModel`이 있을 때만 의미가 있습니다. | | `injectionPrompt?` | `string` | — | 내장 v2 안내 본문을 대체합니다. `{{model}}`, `{{effort}}`, `{{roster}}`, `{{fallback}}`를 지원합니다. `injectionModel`만 설정되어 있어도 사용자 정의 프롬프트가 발동합니다. | -| `multiAgentGuidanceEnabled?` | `boolean` | `true` | opencodex가 작성하는 v1/v2 개발자 안내만 제어합니다. 네이티브 에이전트 기본값, 도구, 라우팅, 로스터, 노력 상한은 바꾸지 않습니다. | +| `multiAgentGuidanceEnabled` | `boolean` | `true` | CodexCommander가 작성하는 v1/v2 개발자 안내만 제어합니다. 네이티브 에이전트 기본값, 도구, 라우팅, 로스터, 노력 상한은 바꾸지 않습니다. | | `syncCodexSubagentDefaults?` | `boolean` | `false` | 동기화 또는 재시작 시 `injectionModel`과 선택적 `injectionEffort`를 Codex의 네이티브 기본값으로 기록하도록 선택합니다. `injectionModel`이 필요합니다. | | `subagentModelFallback?` | `string[]` | `[]` | 생성된 하위 턴에 적용되는 전역 대체 모델 우선순위 목록입니다. | | `subagentModelFallbackPollMs?` | `number` | `60000` | 사용 가능성 검사 캐시 간격입니다. 1000 ms 미만의 값은 기본값으로 돌아갑니다. | | `effortCap?` | `string` | — | 자격을 갖춘 v2 메인 턴과 표시된 생성 하위 턴에 대한 하드 상한입니다. `low`부터 `ultra`까지 허용합니다. | | `subagentEffortCap?` | `string` | — | 생성된 하위 턴에만 적용되는 추가 상한입니다. 두 상한이 모두 적용되면 더 낮은 값이 이깁니다. | -이 표면은 대시보드나 `ocx v2 status|on|off|mode <v1|default|v2>|threads <n>`로 관리합니다. 모드 변경은 새 세션에 적용됩니다. `maxConcurrentThreadsPerSession`은 `config.json` 키가 아니라 `PUT /api/v2` 필드입니다. `ocx v2 threads <n>`는 v2가 활성화된 뒤 Codex의 `$CODEX_HOME/config.toml` 안 `[features.multi_agent_v2]` 아래에 `max_concurrent_threads_per_session`을 기록합니다. +이 표면은 대시보드나 `ccx v2 status|on|off|mode <v1|default|v2>|threads <n>`로 관리합니다. 모드 변경은 새 세션에 적용됩니다. `maxConcurrentThreadsPerSession`은 `config.json` 키가 아니라 `PUT /api/v2` 필드입니다. `ccx v2 threads <n>`는 v2가 활성화된 뒤 Codex의 `$CODEX_HOME/config.toml` 안 `[features.multi_agent_v2]` 아래에 `max_concurrent_threads_per_session`을 기록합니다. 관리 API는 `GET`/`PUT /api/v2`, `/api/injection-model`, `/api/effort-caps`, `/api/subagent-models`, `/api/subagent-model-fallback`를 제공합니다. injection-model 업데이트는 부분 업데이트입니다. 사용자 지정 프롬프트는 이 API의 `prompt` 필드입니다. @@ -48,7 +48,7 @@ V1 안내는 `max` 또는 `ultra`에서만 선제 텍스트로 제공됩니다. 2. `$CODEX_HOME/agents/*.toml`의 역할 수준 `model_fallback` 3. 전역 `subagentModelFallback` 항목 -opencodex는 비활성, 라우팅 불가, 비정상, 쿨다운 중, 또는 할당량 임계값에 걸린 후보를 건너뜁니다. 사용 가능성 스냅샷은 `subagentModelFallbackPollMs` 동안 캐시됩니다. 암호화된 하위 작업은 체인을 정규 네이티브 ChatGPT 대상으로만 제한할 수 있습니다. 어떤 대상도 암호화된 페이로드를 읽을 수 없으면, 읽을 수 없는 암호문을 다른 곳으로 라우팅하는 대신 요청이 실패합니다. +CodexCommander는 비활성, 라우팅 불가, 비정상, 쿨다운 중, 또는 할당량 임계값에 걸린 후보를 건너뜁니다. 사용 가능성 스냅샷은 `subagentModelFallbackPollMs` 동안 캐시됩니다. 암호화된 하위 작업은 체인을 정규 네이티브 ChatGPT 대상으로만 제한할 수 있습니다. 어떤 대상도 암호화된 페이로드를 읽을 수 없으면, 읽을 수 없는 암호문을 다른 곳으로 라우팅하는 대신 요청이 실패합니다. ```json { @@ -68,6 +68,6 @@ opencodex는 비활성, 라우팅 불가, 비정상, 쿨다운 중, 또는 할 상한은 v2 협업 기능에만 적용됩니다. 메인 턴은 도구가 v2를 노출할 때 적격이 되고, 하위 턴은 leaf 도구가 더 이상 협업을 노출하지 않더라도 `x-codex-turn-metadata` 안에 codex-rs의 정확한 `x-openai-subagent: collab_spawn` 또는 `"subagent_kind": "thread_spawn"` 표시가 있으면 적격이 됩니다. V1 메인 턴, `multiAgentMode: "v1"`, compaction, review, memory-consolidation 턴은 상한을 적용받지 않습니다. -상한은 노력만 낮춥니다. 모델이 광고한 단계 중 상한 이하에서 가장 높은 단계로 맞춥니다. 모델에 노력 제어가 없거나 맞는 지원 단계가 없으면, opencodex는 노력을 제거하고 제공자 기본값을 적용합니다. `max`와 `ultra`는 허용되며, 대시보드는 `low`부터 `xhigh`까지 제공합니다. +상한은 노력만 낮춥니다. 모델이 광고한 단계 중 상한 이하에서 가장 높은 단계로 맞춥니다. 모델에 노력 제어가 없거나 맞는 지원 단계가 없으면, CodexCommander는 노력을 제거하고 제공자 기본값을 적용합니다. `max`와 `ultra`는 허용되며, 대시보드는 `low`부터 `xhigh`까지 제공합니다. v1, default, v2 동작에 대한 초보자용 설명은 [Sub-agent surfaces](/guides/sub-agent-surface/)를 참고하세요. diff --git a/docs-site/src/content/docs/ko/reference/configuration/providers.md b/docs-site/src/content/docs/ko/reference/configuration/providers.md index ec6dbcf509..b7fa87dba1 100644 --- a/docs-site/src/content/docs/ko/reference/configuration/providers.md +++ b/docs-site/src/content/docs/ko/reference/configuration/providers.md @@ -3,14 +3,13 @@ title: 공급자 설정 description: 공급자 항목, 인증, 엔드포인트, 모델 카탈로그, 할당량, 컨텍스트 상한, 공급자별 옵션. --- -공급자는 opencodex에 모델의 위치, 사용하는 와이어 어댑터, 요청 인증 방식을 알려줍니다. +공급자는 CodexCommander에 모델의 위치, 사용하는 와이어 어댑터, 요청 인증 방식을 알려줍니다. ## 공급자 관련 최상위 필드 | 필드 | 타입 | 기본값 | 의미 | | --- | --- | --- | --- | -| `providers` | `Record<string, OcxProviderConfig>` | — | 공급자 이름을 공급자 설정에 매핑합니다. | -| `openaiProviderTierVersion?` | `2` | 마이그레이션으로 설정됨 | 옵션을 인식하는 단일 OpenAI 투영이 완료되었음을 표시합니다. | +| `providers` | `Record<string, CodexCommanderProviderConfig>` | — | 공급자 이름을 공급자 설정에 매핑합니다. | | `disabledModels?` | `string[]` | — | Codex catalog와 `/v1/models`에서는 숨기지만 직접 proxy 호출은 차단하지 않습니다. routed id는 목록에서 제거됩니다. account-qualified native id는 해당 selector row만 숨기고, bare native GPT id는 bare row와 그 model의 모든 account-selector row를 숨깁니다. Models 페이지에는 bare native 행과 routed 행만 표시됩니다. selector-qualified 행 하나만 숨기려면 이 설정 필드에 직접 추가하세요. | | `providerContextCaps?` | `Record<string, number>` | `{}` | 공급자별 Codex 표시 컨텍스트 상한입니다. 상한은 이미 알려진 컨텍스트 윈도만 낮춥니다. | | `contextCapValue?` | `number` | `350000` | 대시보드의 컨텍스트 상한 컨트롤이 사용하는 값입니다. 이 값을 바꾸면 활성화된 모든 `providerContextCaps` 항목이 함께 갱신됩니다. | @@ -18,16 +17,16 @@ description: 공급자 항목, 인증, 엔드포인트, 모델 카탈로그, 할 | `pausedCodexAccountIds?` | `string[]` | `[]` | 일시 중지된 `__main__` 계정을 포함해, 재개될 때까지 Pool 선택에서 제외되는 계정입니다. | | `codexAccountNamespaces?` | `Record<string, string>` | — | 임의의 공개 model selector를 저장된 Codex 계정 target에 연결하는 선택적 map입니다. target이 존재하는 각 selector는 Codex picker에 별도의 `<selector>/<native-openai-model>` row를 추가하며, 각 row는 해당 계정만 사용합니다. selector가 하나라도 활성화되면 bare native row는 picker에서 숨겨지지만, 명시적으로 비활성화하지 않는 한 해당 id는 계속 routing 가능하고 raw `/v1/models`에 표시됩니다. | | `activeCodexAccountId?` | `string` | — | 다음 요청에 수동으로 선택한 Pool 계정입니다. 선택하면 thread 결속이 해제되며, 진행 중인 요청은 캡처한 자격 증명을 유지합니다. | -| `codexAccountPriorities?` | `Record<string,number>` | — | Codex pool의 계정별 선택 순서. 계정 ID → `-100`부터 `100`까지의 정수이며 **값이 클수록 먼저** 쓰이고, 항목이 없으면 `0`입니다. 이는 eligibility 경계가 아니라 순서 경계입니다. 선택은 이미 적격한 계정들을 quota 여유가 남은 최상위 tier로 좁히고, 그 tier 안에서 `accountPoolStrategy`가 계정을 고릅니다. tier를 건너뛰는 경우는 그 구성원 전부가 `autoSwitchThreshold` 초과, cooldown, soft-avoid, 일시 중지 또는 재인증 대기일 때뿐이며, usage를 알 수 없다고 해서 tier가 소진되지는 않습니다. 순서는 부적격 계정을 선택 가능하게 만들지 않고, 이미 계정에 묶인 thread를 다시 bind하지도 않습니다. 메인 `__main__` 계정도 동일한 조건으로 참여하므로 Codex Desktop 로그인을 마지막에 쓰도록 둘 수 있습니다. 항목이 하나도 없으면 동작은 이전과 같습니다. map이 잘못된 경우 경고를 출력하고 순서 지정을 끕니다(config 복구는 하지 않습니다). `ocx account priority`와 Codex Auth 페이지에서 관리합니다. | +| `codexAccountPriorities?` | `Record<string,number>` | — | Codex pool의 계정별 선택 순서. 계정 ID → `-100`부터 `100`까지의 정수이며 **값이 클수록 먼저** 쓰이고, 항목이 없으면 `0`입니다. 이는 eligibility 경계가 아니라 순서 경계입니다. 선택은 이미 적격한 계정들을 quota 여유가 남은 최상위 tier로 좁히고, 그 tier 안에서 `accountPoolStrategy`가 계정을 고릅니다. tier를 건너뛰는 경우는 그 구성원 전부가 `autoSwitchThreshold` 초과, cooldown, soft-avoid, 일시 중지 또는 재인증 대기일 때뿐이며, usage를 알 수 없다고 해서 tier가 소진되지는 않습니다. 순서는 부적격 계정을 선택 가능하게 만들지 않고, 이미 계정에 묶인 thread를 다시 bind하지도 않습니다. 메인 `__main__` 계정도 동일한 조건으로 참여하므로 Codex Desktop 로그인을 마지막에 쓰도록 둘 수 있습니다. 항목이 하나도 없으면 모든 계정의 우선순위가 `0`입니다. map이 잘못된 경우 경고를 출력하고 순서 지정을 끕니다(config 복구는 하지 않습니다). `ccx account priority`와 Codex Auth 페이지에서 관리합니다. | | `autoSwitchThreshold?` | `number` | `80` | 사용량 기반 선제 전환 임계값입니다. `quota`는 바인딩된 작업과 바인딩 없는 작업의 다음 요청을 모두 재평가할 수 있고, `fill-first`는 바인딩 없는 작업 배정의 소진 기준으로만 사용하며, 기본 `round-robin` 선택은 이 값을 사용하지 않습니다. 알려진 5시간, 주간, 30일 quota window 중 가장 높은 점수를 씁니다. `0`은 사용량 기반 전환만 끄며 바인딩 없는 작업 배정이나 실패 복구는 끄지 않습니다. | | `accountPoolStrategy?` | `"quota" \| "round-robin" \| "fill-first"` | `"quota"` | 새 작업/바인딩 없는 Codex 요청의 계정 배정 전략입니다. `(parent thread id, quota scope)`의 live affinity가 없으면 바인딩 없는 요청이며, 프록시 재시작이나 affinity 초기화 뒤에는 기존에 보이던 작업도 바인딩이 없어질 수 있습니다. `quota`는 활성 계정이 없을 때 알려진 usage가 가장 낮은 적격 계정을 선택하고, 적격 활성 계정이 `autoSwitchThreshold` 미만이면 유지합니다. 임계값 도달 뒤에는 바인딩 없는 요청이나 바인딩된 작업의 다음 요청을 usage가 더 낮은 적격 계정으로 옮길 수 있습니다. `round-robin`은 바인딩 없는 요청을 균등 분배하고, `fill-first`는 cooldown, 사용 불가 또는 drain threshold까지 활성 계정에 배정합니다. | | `accountPoolStickyLimit?` | `number` | `1` | 한 round-robin 선택이 다음으로 넘어가기 전에 유지하는 새 작업/바인딩 없는 작업 배정 수입니다. 카운터는 업스트림 성공 뒤가 아니라 작업을 바인딩할 때 증가합니다. 범위 1–100이며 `accountPoolStrategy`가 `round-robin`일 때만 적용됩니다. | | `upstreamFailoverThreshold?` | `number` | `3` | 연속된 일시적 실패가 이 횟수에 도달하면 이후 새 세션은 failover됩니다. `0`으로 두면 비활성화됩니다. 입증된 연결 전 DNS/TCP 도달 불가 실패는 provider-host 범위로 기록되며 계정 상태, 쿨다운, 스레드/세션 선호도, 활성 계정 선택 또는 Pool 라우팅에 영향을 주지 않고 이 임계값에도 집계되지 않습니다. | | `modelCacheTtlMs?` | `number` | `300000` | 공급자별 `/models` 캐시의 최신성 창입니다. | | `cacheRetention?` | `"none" \| "short" \| "long"` | `"short"` | Anthropic 프롬프트 캐시 정책입니다. 비활성, 5분짜리 임시, 1시간짜리 확장 중 하나입니다. | -| `tokenGuardian?` | `OcxTokenGuardianConfig` | 꺼짐 | 선택적 선제 OAuth 갱신과 Codex 계정 워밍업 정책입니다. | +| `tokenGuardian?` | `CodexCommanderTokenGuardianConfig` | 꺼짐 | 선택적 선제 OAuth 갱신과 Codex 계정 워밍업 정책입니다. | -selector 이름은 사용자가 정하는 공개 label이며, opencodex는 여기에 계정 역할 의미를 부여하지 않습니다. +selector 이름은 사용자가 정하는 공개 label이며, CodexCommander는 여기에 계정 역할 의미를 부여하지 않습니다. `codexAccountNamespaces` 키는 길이가 1~64자이고 시작과 끝은 ASCII 영숫자여야 하며, 내부에는 영숫자, `.`, `_`, `-`를 사용할 수 있습니다. 예약된 JavaScript object 이름은 거부됩니다. 값은 유효한 pool account id(내부 `__main__` 제외)이거나 Codex Desktop 계정을 나타내는 `"@main"`입니다. @@ -41,17 +40,15 @@ target도 selector로 재사용할 수 없습니다. raw account id와 email은 `openai`와 `openai-apikey`는 고정 예약 id입니다. `openai.codexAccountMode`의 기본값은 `"pool"`이며, 메인 계정과 추가된 계정 전체에서 선택합니다. `"direct"`는 현재 호출자/메인 로그인만 사용합니다. API는 설정된 API 키 또는 키 풀만 사용합니다. 모델 이름만 쓰거나 `openai-apikey/<model>`을 사용하십시오. 다른 라우트의 자격 증명으로는 대체하지 않습니다. API GPT-5.6 행에는 1,050,000 컨텍스트 / 922,000 최대 입력 메타데이터가 들어가며, Pro 가상 id는 기본 와이어 모델로 다시 쓰면서 `reasoning.mode: "pro"`를 적용합니다. -`openaiProviderTierVersion: 2`는 현재의 단일 공급자 투영을 표시합니다. 출시된 v1 설정을 마이그레이션하기 전에 opencodex는 `config.json.pre-openai-tiers-v2.bak`를 만들고, 기존에 다른 백업이 있더라도 덮어쓰지 않으며, 알려진 레거시 네임스페이스 지정 선택 id를 bare id로 다시 씁니다. - -## 공급자 항목 (`OcxProviderConfig`) +## 공급자 항목 (`CodexCommanderProviderConfig`) | 필드 | 타입 | 의미 | | --- | --- | --- | -| `adapter` | `string` | `openai-chat`, `openai-responses`, `anthropic`, `google`, `kiro`, `cursor`, `azure-openai` 중 하나이며, `azure`는 별칭입니다. | +| `adapter` | `string` | `openai-chat`, `openai-responses`, `anthropic`, `google`, `kiro`, `cursor`, `azure-openai` 중 하나입니다. | | `baseUrl` | `string` | 상위 API 기본 URL입니다. 대부분의 내장 고정 엔드포인트는 불일치를 무시합니다. 충돌 안전 키 프리셋은 같은 이름의 이전 사용자 지정 목적지를 보존합니다. | | `responsesPath?` | `string` | 키 인증 `openai-responses` 요청의 상대 리소스 경로입니다. 반드시 `/`로 시작해야 하며 스킴, query, fragment를 포함하면 안 됩니다. | | `supportsServiceTier?` | `boolean` | `service_tier` 케이퍼빌리티 3상태입니다. `true`: fast 모드가 주입할 수 있고 호출자 값도 보존합니다. `false`: 필드를 제거하고 절대 주입하지 않습니다(미지원으로 문서화된 업스트림에는 볼 수 없습니다). 미설정: 미분류 — 호출자가 준 값은 그대로 보존하고 fast 모드는 주입하지 않습니다. 레지스트리는 정식 OpenAI(`true`), DeepSeek, Volcengine Ark(`false`)를 분류하며, 실제로 티어를 지원하는 커스텀 게이트웨이에만 명시적으로 설정하세요. | -| `preserveResponsesReasoningContent?` | `boolean` | 리플레이되는 Responses reasoning 항목의 평문 reasoning 내용을 지우지 않고 유지합니다(지우는 것은 ChatGPT 백엔드 규칙입니다). DeepSeek처럼 reasoning 리플레이를 허용하는 업스트림에 켜세요. 프록시가 만든 `ocxr1` 봉투는 항상 제거됩니다. | +| `preserveResponsesReasoningContent?` | `boolean` | 리플레이되는 Responses reasoning 항목의 평문 reasoning 내용을 지우지 않고 유지합니다(지우는 것은 ChatGPT 백엔드 규칙입니다). DeepSeek처럼 reasoning 리플레이를 허용하는 업스트림에 켜세요. 프록시가 만든 `ccxr1` 봉투는 항상 제거됩니다. | | `disabled?` | `boolean` | 공급자를 디스크에는 남기되, 라우팅과 모델/카탈로그 목록에서는 제외합니다. | | `apiKey?` | `string` | API 키 또는 요청 시점에 해석되는 `${ENV_VAR}` / `$ENV_VAR` 참조입니다. | | `apiKeyTransport?` | `"x-api-key" \| "bearer"` | Anthropic 키 헤더 형식입니다. 기본값은 네이티브 `x-api-key`이며, 키 인증 `anthropic` 공급자에만 유효합니다. | @@ -103,16 +100,15 @@ target도 selector로 재사용할 수 없습니다. raw account id와 email은 | `location?` | `string` | Vertex 위치입니다. 환경 변수 폴백은 `GOOGLE_CLOUD_LOCATION`입니다. | | `mcpServers?` | `Record<string, CursorMcpServerConfig>` | Cursor 전용입니다. stdio 또는 Streamable HTTP MCP 서버입니다. | | `desktopExecutor?` | `DesktopExecutorConfig` | Cursor 전용입니다. 외부 computer-use 및 record-screen 명령입니다. | -| `unsafeAllowNativeLocalExec?` | `boolean` | Cursor 레거시 불리언입니다. 더 새로운 필드가 설정되지 않았을 때만 `nativeLocalExec: "on"`과 같습니다. | -| `nativeLocalExec?` | `"off" \| "codex-sandbox" \| "on"` | Cursor 로컬 실행 정책입니다. 기본값은 `off`입니다. `codex-sandbox`는 현재 `off`처럼 실패를 닫습니다. | +| `nativeLocalExec?` | `"off" \| "on"` | Cursor 로컬 실행 정책입니다. 기본값은 `off`입니다. | -API 키 공급자는 리터럴 키나 환경 참조를 둘 수 있습니다. OAuth 공급자는 `ocx login`으로 채워지는 자격 증명 저장소를 사용합니다. 구독 기반 Claude Code 실행 동작은 [`claudeCode.authMode`](/reference/configuration/server/#claude-code)에서 설정합니다. +API 키 공급자는 리터럴 키나 환경 참조를 둘 수 있습니다. OAuth 공급자는 `ccx login`으로 채워지는 자격 증명 저장소를 사용합니다. 구독 기반 Claude Code 실행 동작은 [`claudeCode.authMode`](/reference/configuration/server/#claude-code)에서 설정합니다. ## 공급자 진단용 외부 요청 안전성 -대시보드 연결 테스트와 라이브 모델 발견은 범위가 제한된 GET 전용 전송을 사용합니다. 아웃바운드 프록시가 없으면 opencodex는 호스트 이름을 한 번만 확인하고, 검증된 주소로만 연결합니다. HTTPS는 원래 Host, SNI, 인증서 검증을 유지하며, 공급자 설정으로 인증서 검사를 끌 수는 없습니다. +대시보드 연결 테스트와 라이브 모델 발견은 범위가 제한된 GET 전용 전송을 사용합니다. 아웃바운드 프록시가 없으면 CodexCommander는 호스트 이름을 한 번만 확인하고, 검증된 주소로만 연결합니다. HTTPS는 원래 Host, SNI, 인증서 검증을 유지하며, 공급자 설정으로 인증서 검사를 끌 수는 없습니다. -`HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`가 적용되면 이 작업들은 Bun의 네이티브 fetch를 그대로 사용합니다. URL과 리터럴 주소 검사는 계속 실행되지만, 최종 경로, DNS 응답, 피어는 프록시가 고르므로 opencodex는 그 피어를 고정하거나 검증할 수 없습니다. 이는 명시적인 보안 한계입니다. +`HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`가 적용되면 이 작업들은 Bun의 네이티브 fetch를 그대로 사용합니다. URL과 리터럴 주소 검사는 계속 실행되지만, 최종 경로, DNS 응답, 피어는 프록시가 고르므로 CodexCommander는 그 피어를 고정하거나 검증할 수 없습니다. 이는 명시적인 보안 한계입니다. 사설/로컬 목적지는 `allowPrivateNetwork: true`가 필요하며, 아웃바운드 프록시가 활성화된 경우에는 일치하는 `NO_PROXY` 항목도 필요합니다. loopback은 자동으로 추가됩니다. CIDR 항목은 해석하지 않으므로 각 LAN 호스트는 따로 적어야 합니다. matcher는 정확한 호스트, 도메인 접미사, 선택적 포트, 괄호로 감싼 IPv6, `*`를 지원합니다. 예를 들면 `192.168.1.50`은 따로 적어야 합니다. 메타데이터와 link-local 목적지는 계속 차단됩니다. 진단 요청은 리디렉션을 거부하고, 자격 증명이 제거된 대상만 보고합니다. 일반적인 공급자 요청의 리디렉션 검토는 이 진단 가드와 별도로 유지됩니다. @@ -159,14 +155,14 @@ affinity 초기화 뒤의 기존 작업도 포함될 수 있습니다. 출력 활성화되면 429 레코드가 `Retry-After` 또는 기본 backoff에서 제한된 쿨다운을 기록하고, 요청 안에서 회전할 수 있습니다. 결속은 프로세스 로컬이며 크기가 제한됩니다. 자격 증명 401/403은 해당 계정이 재인증이 필요함을 표시합니다. 적격한 계정이 모두 쿨다운 중이면, 클라이언트는 인증 오류가 아니라 알려진 경우 `Retry-After`가 포함된 429를 받습니다. :::caution[실험적 기능] -Anthropic 계정 정책 위험을 이해하지 못한다면 이 기능은 꺼두십시오. 확신이 없으면 수동 `ocx account use anthropic <id>` 전환을 우선하십시오. +Anthropic 계정 정책 위험을 이해하지 못한다면 이 기능은 꺼두십시오. 확신이 없으면 수동 `ccx account use anthropic <id>` 전환을 우선하십시오. ::: ### 관리되는 레코드 구조 `apiKeys[]` 항목에는 `id`, `name`, 생성된 `key`, ISO 형식 `createdAt` 문자열이 들어갑니다. `codexAccounts[]` 항목에는 `id`, `email`, `isMain`이 필요하고, 선택적으로 `plan`, `chatgptAccountId`, 개인정보를 해치지 않는 `logLabel`을 둘 수 있습니다. 이런 레코드는 보통 대시보드가 관리합니다. -### `tokenGuardian` (`OcxTokenGuardianConfig`) +### `tokenGuardian` (`CodexCommanderTokenGuardianConfig`) | 필드 | 타입 | 기본값 | 의미 | | --- | --- | --- | --- | @@ -192,7 +188,7 @@ Anthropic 계정 정책 위험을 이해하지 못한다면 이 기능은 꺼두 어댑터는 나중에 해석된 URL을 조정할 수 있습니다. 예를 들어 Kiro는 가져온 자격 증명의 API 지역을 따라 정식 `runtime.{region}.kiro.dev`를 사용합니다. [Adapters](/reference/adapters/)를 보십시오. -라우팅이 `baseUrl`을 버리면 opencodex는 레지스트리 엔드포인트와 설정된 origin만 기록합니다. 설정된 path 자체에 자격 증명이 들어 있을 수도 있습니다. 쓰지 않는 URL은 지우거나, 의도한 지역과 맞는 공급자 항목을 고르십시오. `alibaba-token-plan`은 베이징에 고정되어 있고, `alibaba-token-plan-intl`은 국제 엔드포인트를 담당합니다. +라우팅이 `baseUrl`을 버리면 CodexCommander는 레지스트리 엔드포인트와 설정된 origin만 기록합니다. 설정된 path 자체에 자격 증명이 들어 있을 수도 있습니다. 쓰지 않는 URL은 지우거나, 의도한 지역과 맞는 공급자 항목을 고르십시오. `alibaba-token-plan`은 베이징에 고정되어 있고, `alibaba-token-plan-intl`은 국제 엔드포인트를 담당합니다. 깨진 `openai-responses` 게이트웨이는 공급자 객체에서 복구해야 합니다. @@ -217,7 +213,7 @@ Anthropic 계정 정책 위험을 이해하지 못한다면 이 기능은 꺼두 ## Cursor 공급자 (`adapter: "cursor"`) -Cursor 브리지는 실험적입니다. `ocx login cursor`를 실행한 뒤 `providers.cursor`를 추가하거나 수정하십시오. Cursor Router의 최적화 단계는 선택기가 Cursor 전용 모델 매개변수를 렌더링하지 못하므로 별도의 Codex id로 노출됩니다. +Cursor 브리지는 실험적입니다. `ccx login cursor`를 실행한 뒤 `providers.cursor`를 추가하거나 수정하십시오. Cursor Router의 최적화 단계는 선택기가 Cursor 전용 모델 매개변수를 렌더링하지 못하므로 별도의 Codex id로 노출됩니다. | Codex 모델 | Cursor Router 모드 | | --- | --- | @@ -232,8 +228,6 @@ Cursor 서버 주도 로컬 도구는 기본값으로 비활성화됩니다. Cod - `"off"`(기본값)는 Cursor 네이티브 `read`, `write`, `delete`, `ls`, `grep`, `shell`, `fetch` 실행을 거부합니다. - `"on"`은 신뢰된 로컬 실행을 허용하고, Codex 승인/샌드박스 의미를 우회합니다. -- `"codex-sandbox"`는 호환성을 위해 남아 있지만 `"off"`처럼 실패를 닫습니다. 요청 문구는 신뢰할 수 있는 샌드박스 증명이 아닙니다. - ```json { "providers": { @@ -248,7 +242,7 @@ Cursor 서버 주도 로컬 도구는 기본값으로 비활성화됩니다. Cod } ``` -필드는 최상위가 아니라 `providers.cursor`에 설정하십시오. 대시보드에서는 **Providers → Cursor → Edit JSON**을 사용해 저장한 뒤 다시 시작합니다. 레거시 `unsafeAllowNativeLocalExec: true`는 `nativeLocalExec`이 설정되지 않았을 때만 `nativeLocalExec: "on"`과 같습니다. MCP, 화면 녹화, computer use는 `mcpServers`와 `desktopExecutor`가 따로 제어합니다. +필드는 최상위가 아니라 `providers.cursor`에 설정하십시오. 대시보드에서는 **Providers → Cursor → Edit JSON**을 사용해 저장한 뒤 다시 시작합니다. MCP, 화면 녹화, computer use는 `mcpServers`와 `desktopExecutor`가 따로 제어합니다. 각 `mcpServers.<name>`는 `command`(stdio) 또는 `url`(Streamable HTTP) 중 하나를 받습니다. stdio는 `args`, `env`, `cwd`도 받습니다. HTTP는 `headers`를 받습니다. 둘 다 `enabled`(기본값 true)와 `toolPrefix`를 지원합니다. `desktopExecutor`는 `computerUseCommand`, `recordScreenCommand`, `cwd`, `env`, `timeoutMs`(기본값 `30000`)를 받습니다. 명령은 `sh -c`를 거치며 stdin에서 JSON 요청 하나를 읽고, stdout에 JSON 결과 하나를 써야 합니다. @@ -284,7 +278,7 @@ OpenRouter는 하나의 모델을 여러 추론 공급자로 제공할 수 있 } ``` -모델 키는 외부 opencodex 공급자 접두사 없이, 정확한 네이티브 OpenRouter id여야 합니다. `openrouter/anthropic-claude-sonnet-5`를 선택하면 모델 규칙을 적용하기 전에 네이티브 `anthropic/claude-sonnet-5`로 되돌아갑니다. +모델 키는 외부 CodexCommander 공급자 접두사 없이, 정확한 네이티브 OpenRouter id여야 합니다. `openrouter/anthropic-claude-sonnet-5`를 선택하면 모델 규칙을 적용하기 전에 네이티브 `anthropic/claude-sonnet-5`로 되돌아갑니다. ## 정적 모델 허용 목록 diff --git a/docs-site/src/content/docs/ko/reference/configuration/routing.md b/docs-site/src/content/docs/ko/reference/configuration/routing.md index 4615b63620..266d418612 100644 --- a/docs-site/src/content/docs/ko/reference/configuration/routing.md +++ b/docs-site/src/content/docs/ko/reference/configuration/routing.md @@ -10,11 +10,11 @@ description: 기본 provider 선택, model 해석 순서, combo 별칭, 대상 | Field | Type | Default | Meaning | | --- | --- | --- | --- | | `defaultProvider` | `string` | `"openai"` | 앞선 모델 규칙이 하나도 맞지 않을 때 쓰는 최종 provider입니다. 활성화되어 있고 설정된 provider 이름이어야 합니다. | -| `combos?` | `Record<string, OcxComboConfig>` | `{}` | 순서가 정해진 provider/model 대상들로 구성한 가상 `combo/<id>` 모델입니다. | +| `combos?` | `Record<string, CodexCommanderComboConfig>` | `{}` | 순서가 정해진 provider/model 대상들로 구성한 가상 `combo/<id>` 모델입니다. | ## 모델 해석 순서 -opencodex는 요청된 model을 다음 순서로 해석합니다: +CodexCommander는 요청된 model을 다음 순서로 해석합니다: 1. 설정된 `<account-selector>/<native-openai-model>` 네임스페이스입니다. 매핑된 저장 Codex 계정으로만 routing하며, exact target이 잘못되었거나 사용할 수 없으면 fail closed합니다. 2. 정규화된 `combo/<id>` 또는 설정된 combo 별칭입니다. 정규화된 id가 별칭보다 먼저 적용됩니다. @@ -76,7 +76,7 @@ selector는 표시되지 않습니다. selector 검증, 충돌 규칙, privacy g ### 카탈로그 적격성 -combo는 목록에 오를 수 없더라도 계속 직접 라우팅할 수 있습니다. `ocx sync`, `/v1/models`, 그리고 Codex picker는 다음 조건을 모두 만족할 때만 이를 나열합니다: +combo는 목록에 오를 수 없더라도 계속 직접 라우팅할 수 있습니다. `ccx sync`, `/v1/models`, 그리고 Codex picker는 다음 조건을 모두 만족할 때만 이를 나열합니다: - live metadata, registry hint, 또는 provider의 `modelContextWindows` / `contextWindow`에서 얻은 양수 `contextWindow` - 비어 있지 않은 `inputModalities` 교집합. 생략된 member value는 `["text"]`로 취급합니다. @@ -87,7 +87,7 @@ context metadata가 없는 bare relay id이거나 modalities가 서로 겹치지 명시적으로 요청된 `policy/<id>`(또는 설정된 별칭)가 고정된 후보 허용 목록에서 하드 능력 요구사항과 결정적·설명 가능한 점수로 선택합니다. 기존 모델 ID가 암시적으로 프로필을 통과하지 않습니다. `candidates`(명시적 허용 목록), 선택적 `alias`, `require`(`minContextWindow`, `minQuotaHeadroom`, `tools`, `imageInput`, `structuredOutput`, `localOnly`, `remoteAllowed`, `encryptedCodexTasks`, `reasoningEffort`, `serviceTier`), `optimize`(latency/health/cost/quota 가중치), `limits.maxEstimatedCostUsd`, `unknownEvidence`(allow/penalize/exclude)를 지원합니다. 알 수 없음은 0이나 무료가 되지 않습니다. -CLI: `ocx route policy list`, `ocx route policy show <id>`, `ocx route policy dry-run <id> --model-context <tokens> --tools`, `ocx route policy evaluate <id>`. +CLI: `ccx route policy list`, `ccx route policy show <id>`, `ccx route policy dry-run <id> --model-context <tokens> --tools`, `ccx route policy evaluate <id>`. 콤보는 명시적인 순서·가중치 대상 라우팅 및 장애 조치입니다. 정책 프로필은 후보 간 증거 기반 선택입니다. @@ -100,8 +100,8 @@ CLI: `ocx route policy list`, `ocx route policy show <id>`, `ocx route policy dr 반환되는 히스토리와 라우트 결정 페이로드는 마스킹된 요청 메타데이터만 노출합니다(예: 불투명한 `apiKeyId` 라벨). 자격 증명, 원본 프롬프트 본문, 공급자 시크릿은 포함하지 않습니다. -CLI: `ocx logs explain <request-id>`, `ocx logs rebuild-index`, `ocx logs index-status`. +CLI: `ccx logs explain <request-id>`, `ccx logs rebuild-index`, `ccx logs index-status`. -## 마이그레이션 +## 기존 데이터 -`routingProfiles`는 선택적 추가 설정입니다. 기존 설정 파일과 이전 `usage.jsonl` 행은 그대로 읽힙니다. 인덱스는 일회용이며 삭제 시 다음 쿼리에서 `usage.jsonl`로 자동 재구축됩니다. 자동 튜닝은 없습니다. +`routingProfiles`는 선택적 추가 설정입니다. 기존 설정 파일과 `routeDecision`이 없는 `usage.jsonl` 행도 읽힙니다. 인덱스는 일회용이며 삭제 시 다음 쿼리에서 `usage.jsonl`로 자동 재구축됩니다. 자동 튜닝은 없습니다. diff --git a/docs-site/src/content/docs/ko/reference/configuration/server.md b/docs-site/src/content/docs/ko/reference/configuration/server.md index 3ac1fba3d7..e22a82a03a 100644 --- a/docs-site/src/content/docs/ko/reference/configuration/server.md +++ b/docs-site/src/content/docs/ko/reference/configuration/server.md @@ -10,42 +10,39 @@ description: 리스너, 원격 접근, admission 키, 타임아웃, 저장소, | 필드 | 형식 | 기본값 | 의미 | | --- | --- | --- | --- | | `port` | `number` | `10100` | 프록시 수신 포트입니다. | -| `hostname?` | `string` | `"127.0.0.1"` | 바인드 주소입니다. 루프백이 아닌 바인드에는 `OPENCODEX_API_AUTH_TOKEN`이 필요합니다. | +| `hostname?` | `string` | `"127.0.0.1"` | 바인드 주소입니다. 루프백이 아닌 바인드에는 `CODEXCOMMANDER_API_AUTH_TOKEN`이 필요합니다. | | `proxy?` | `string` | — | 송신용 HTTP(S) 프록시 URL 또는 `${ENV_VAR}`입니다. 해당 변수가 비어 있을 때만 `HTTP_PROXY` / `HTTPS_PROXY`에 적용되며, 루프백은 `NO_PROXY`에 그대로 남습니다. | | `stallTimeoutSec?` | `number` | `300` | 업스트림 데이터가 없을 때 `response.incomplete`가 되기까지의 초 수입니다. 최소 1입니다. | | `connectTimeoutMs?` | `number` | `200000` | 시도별 DNS/TCP/TLS/최종 헤더 기한입니다. 본문 생성 전에 끝납니다. | | `shutdownTimeoutMs?` | `number` | `5000` | 진행 중인 turn을 중단하기 전에 허용하는 정상 종료 드레인 기한입니다. | | `websockets?` | `boolean` | `false` | Responses WebSocket 경로에 `supports_websockets`를 광고합니다. `false`이면 HTTP/SSE를 유지합니다. | | `corsAllowOrigins?` | `string[]` | `[]` | CORS에서 추가로 허용할 정확한 origin입니다. 루프백 origin은 항상 허용됩니다. `chrome-extension://<extension-id>` 같은 authority 기반 브라우저 확장 origin을 지원하며, `*`는 와일드카드가 아닙니다. Firefox와 Safari는 확장 UUID를 (설치/브라우저 실행 때마다) 새로 만드므로 origin이 바뀌면 항목을 갱신하세요. | -| `apiKeys?` | `OcxApiKey[]` | `[]` | 비루프백 바인드에서 관리 API와 데이터 플레인 인증이 허용하는 생성된 `ocx_…` 자격 증명입니다. 대시보드에서 관리합니다. | +| `apiKeys?` | `CodexCommanderApiKey[]` | `[]` | 비루프백 바인드의 데이터 플레인 인증에서 허용하는 생성된 `ccx_data_…` 자격 증명입니다. 대시보드에서 관리하며 `/api/*` 인증에는 사용할 수 없습니다. | | `storageCleanupPolicy?` | `StorageCleanupPolicy` | disabled | 선택적으로 활성화하는 보관 세션 정리 정책입니다. 절대 암묵적으로 활성화되지 않습니다. | | `appOwnedMemoryBudgetMb?` | `number` | `256` | 제거 가능한 앱 소유 로그, 캐시, blob, continuation payload에 대한 MiB 단위 상한입니다. 범위는 64–4096이며 RSS 상한은 아닙니다. | -| `codexAutoStart?` | `boolean` | `true` | Codex shim이 Codex를 실행하기 전에 `ocx ensure`를 돌리도록 허용합니다. `false`이면 ensure는 아무 작업도 하지 않습니다. | -| `codexShimAutoRestore?` | `boolean` | `true` | 완료된 외부 Codex 업데이트가 설치된 shim을 교체한 뒤 복원합니다. 환경 변수로 끌 수 있습니다: `OPENCODEX_CODEX_SHIM_AUTO_RESTORE=0`. | -| `syncResumeHistory?` | `boolean` | `true` | 되돌릴 수 있는 Codex App history 호환성입니다. 원래 메타데이터는 `ocx stop` / `ocx restore`가 백업하고 복원합니다. | -| `shadowCallIntercept?` | `{ enabled?: boolean; model?: string; sourceModels?: string[] }` | off | 인식된 Codex 보조/섀도 호출을 선택한 모델로 낮은 노력 수준에서 다시 보냅니다. 기본 source prefix는 `gpt-5.6-luna`입니다. 0.144.x 이하의 이전 클라이언트는 `gpt-5.4-mini`를 사용했으며 `sourceModels`로 복원할 수 있습니다. | -| `webSearchSidecar?` | `OcxWebSearchSidecarConfig` | on when usable | 웹 검색 사이드카 옵션입니다. | -| `visionSidecar?` | `OcxVisionSidecarConfig` | on when usable | 이미지 설명 사이드카 옵션입니다. | -| `images?` | `OcxImagesConfig` | automatic OpenAI selection | Codex `image_gen`용 독립형 Images 릴레이 옵션입니다. | - -오래된 개발 빌드가 백업 지원이 생기기 전에 resume-history 메타데이터를 바꿨다면, native-provider 복구를 강제로 수행하려면 `ocx recover-history --legacy-openai`를 실행합니다. +| `codexAutoStart?` | `boolean` | `true` | Codex shim이 Codex를 실행하기 전에 `ccx ensure`를 돌리도록 허용합니다. `false`이면 ensure는 아무 작업도 하지 않습니다. | +| `codexShimAutoRestore?` | `boolean` | `true` | 완료된 외부 Codex 업데이트가 설치된 shim을 교체한 뒤 복원합니다. 환경 변수로 끌 수 있습니다: `CODEXCOMMANDER_CODEX_SHIM_AUTO_RESTORE=0`. | +| `shadowCallIntercept?` | `{ enabled?: boolean; model?: string; sourceModels?: string[] }` | off | 인식된 Codex 보조/섀도 호출을 선택한 모델로 낮은 노력 수준에서 다시 보냅니다. 기본 source prefix는 `gpt-5.6-luna`이며, `sourceModels`는 현재 커스텀 소스를 명시적으로 지정하는 재정의입니다. | +| `webSearchSidecar?` | `CodexCommanderWebSearchSidecarConfig` | on when usable | 웹 검색 사이드카 옵션입니다. | +| `visionSidecar?` | `CodexCommanderVisionSidecarConfig` | on when usable | 이미지 설명 사이드카 옵션입니다. | +| `images?` | `CodexCommanderImagesConfig` | automatic OpenAI selection | Codex `image_gen`용 독립형 Images 릴레이 옵션입니다. | ## Remote access 기본 `127.0.0.1` 바인드는 루프백 전용입니다. `0.0.0.0` 같은 루프백이 아닌 주소는 `/api/*`와 데이터 플레인 모두에서 토큰 인증이 필요합니다. 시작하기 전에 토큰을 내보냅니다: ```bash -export OPENCODEX_API_AUTH_TOKEN="your-secret-token" -ocx start +export CODEXCOMMANDER_API_AUTH_TOKEN="your-secret-token" +ccx start ``` -이 변수가 없으면 프록시는 원격 바인드를 거부합니다. 백그라운드 서비스라면 `ocx service install` 전에 내보내서 launchd, systemd, 또는 Task Scheduler가 이를 받도록 합니다. 클라이언트는 다음을 보내야 합니다: +이 변수가 없으면 프록시는 원격 바인드를 거부합니다. 백그라운드 서비스라면 `ccx service install` 전에 내보내서 launchd, systemd, 또는 Task Scheduler가 이를 받도록 합니다. 클라이언트는 다음을 보내야 합니다: ```text -x-opencodex-api-key: your-secret-token +x-codexcommander-api-key: your-secret-token ``` -| 엔드포인트 | `Authorization: Bearer` | `x-opencodex-api-key` | `x-api-key` | +| 엔드포인트 | `Authorization: Bearer` | `x-codexcommander-api-key` | `x-api-key` | | --- | --- | --- | --- | | `/v1/responses` | 허용되지 않음 | **필수** | 허용되지 않음 | | `/v1/chat/completions` | 허용되지 않음 | **필수** | 허용되지 않음 | @@ -66,7 +63,7 @@ Responses와 Chat Completions는 `Authorization`을 향후 Codex Direct 패스 ssh -L 20100:localhost:10100 you@remote ``` -로컬 포트는 무엇이든 사용할 수 있습니다. Host가 `localhost`, `127.0.0.1`, 또는 `::1`로 해석되는 요청은 포트와 무관하게 루프백으로 유지되므로 `http://localhost:20100/v1`이 동작합니다. 클라이언트에 그 base URL을 설정하십시오. `ocx`는 관리되는 클라이언트 config에 기본 로컬 `127.0.0.1` 주소만 기록합니다. +로컬 포트는 무엇이든 사용할 수 있습니다. Host가 `localhost`, `127.0.0.1`, 또는 `::1`로 해석되는 요청은 포트와 무관하게 루프백으로 유지되므로 `http://localhost:20100/v1`이 동작합니다. 클라이언트에 그 base URL을 설정하십시오. `ccx`는 관리되는 클라이언트 config에 기본 로컬 `127.0.0.1` 주소만 기록합니다. provider OAuth 콜백은 고정된 원격 포트에서 수신합니다. 원격 머신에서 로그인하거나 그 포트도 함께 포워딩합니다: @@ -84,21 +81,20 @@ ssh -L 20100:localhost:10100 -L 1455:localhost:1455 you@remote ## Claude Code (`claudeCode`) -이 설정은 `/v1/messages`, `ocx claude` 실행기, 그리고 Claude 대시보드 페이지를 제어합니다. +이 설정은 `/v1/messages`, `ccx claude` 실행기, 그리고 Claude 대시보드 페이지를 제어합니다. | 키 | 형식 | 기본값 | 설명 | | --- | --- | --- | --- | | `claudeCode.bodyStallSec?` | `number` | `90` | 읽기가 대기 중일 때의 native-passthrough 본문 비활성 시간 한도입니다. 전체 지속 시간이 아니라는 점에 유의합니다. 최소 1이며, 정확히 `0`이면 비활성화됩니다. | | `claudeCode.bodyMaxBytes?` | `number` | `67108864` | 스트리밍 및 버퍼링된 응답에 대한 누적 native-passthrough 본문 상한입니다. 정확히 `0`이면 비활성화됩니다. | | `claudeCode.authMode?` | `"proxy" \| "subscription"` | auto | 실행 시 `ANTHROPIC_AUTH_TOKEN`을 어떻게 다룰지입니다. 자동은 매 실행마다 인증을 감지하며, 명시 값은 절대 덮어쓰지 않습니다. | -| `claudeCode.authModeMigratedAt?` | `string` | unset | 내부적인 일회성 업그레이드 마커입니다. 수동으로 설정하지 마십시오. | -| `claudeCode.subagentEffort?` | `"low" \| "medium" \| "high" \| "xhigh" \| "max"` | inherit | 생성된 `~/.claude/agents/ocx-*.md`에 쓰이는 노력 수준입니다. Codex 지침과 프록시 상한과는 별개입니다. 다시 생성하려면 `ocx claude`로 재시작합니다. | +| `claudeCode.subagentEffort?` | `"low" \| "medium" \| "high" \| "xhigh" \| "max"` | inherit | 생성된 `~/.claude/agents/ccx-*.md`에 쓰이는 노력 수준입니다. Codex 지침과 프록시 상한과는 별개입니다. 다시 생성하려면 `ccx claude`로 재시작합니다. | 자동 인증은 저장된 Claude 인증이 있으면 subscription을, 없으면 proxy를 선택합니다. 감지가 불명확할 때는 경고와 함께 subscription을 선택합니다. [Claude Code 인증 모드](/guides/claude-code/#auth-mode)를 보십시오. ## Shadow calls -Codex는 제목과 커밋 메시지 같은 작업에 작은 보조 모델을 사용합니다. 인식된 source-model prefix를 다른 구성된 모델로 돌리려면 `shadowCallIntercept`를 활성화합니다. 대체 호출은 낮은 노력 수준으로 실행됩니다. 클라이언트가 다른 helper id를 사용할 때만 `sourceModels`를 설정합니다. +Codex는 제목과 커밋 메시지 같은 작업에 작은 보조 모델을 사용합니다. 인식된 source-model prefix를 다른 구성된 모델로 돌리려면 `shadowCallIntercept`를 활성화합니다. 대체 호출은 낮은 노력 수준으로 실행됩니다. `sourceModels`는 현재 커스텀 소스를 명시적으로 지정할 때만 설정합니다. `x-codex-turn-metadata`에서 인식된 유지관리 요청만 대상이며, 일반 턴과 메타데이터가 없거나 잘못되었거나 인식되지 않은 요청은 가로채지 않습니다. ```json { @@ -112,7 +108,7 @@ Codex는 제목과 커밋 메시지 같은 작업에 작은 보조 모델을 사 ## Sidecars -### `images` (`OcxImagesConfig`) +### `images` (`CodexCommanderImagesConfig`) | 필드 | 형식 | 기본값 | 의미 | | --- | --- | --- | --- | @@ -121,13 +117,13 @@ Codex는 제목과 커밋 메시지 같은 작업에 작은 보조 모델을 사 명시적으로 선택하면 provider가 없거나, 비활성화되어 있거나, 호환되지 않거나, 사용할 수 있는 키가 없을 때는 닫힌 상태로 실패하며, 다른 유료 업스트림으로 절대 폴백하지 않습니다. 이 엔드포인트는 Codex가 기대하는 OpenAI Images API 경로와 응답 형식을 구현해야 합니다. -### `webSearchSidecar` (`OcxWebSearchSidecarConfig`) +### `webSearchSidecar` (`CodexCommanderWebSearchSidecarConfig`) | 필드 | 형식 | 기본값 | 의미 | | --- | --- | --- | --- | | `enabled?` | `boolean` | on when usable | 주 스위치입니다. | | `backend?` | `"openai" \| "anthropic"` | auto | 명시값이 우선입니다. 그 외에는 사용 가능한 저장된 Anthropic OAuth가 있으면 `anthropic`을, 아니면 `openai`를 선택합니다. | -| `model?` | `string` | backend-dependent | OpenAI는 `gpt-5.6-luna`, Anthropic은 `claude-sonnet-5`입니다. 레거시로 명시된 `gpt-5.4-mini`는 시작 시 마이그레이션됩니다. | +| `model?` | `string` | backend-dependent | OpenAI는 `gpt-5.6-luna`, Anthropic은 `claude-sonnet-5`입니다. | | `reasoning?` | `string` | `low` | 사이드카 노력 수준입니다. `minimal`은 web search와 함께 거부됩니다. | | `maxSearchesPerTurn?` | `number` | `3` | 메인 모델 턴당 허용되는 실제 검색 수입니다. | | `routedModelStallTimeoutMs?` | `number` | `200000` | 설정 파일 전용 routed-model 원시 본문 비활성 기한입니다. 정수 1–2147483647이며, 비어 있지 않은 모든 청크가 이를 다시 시작합니다. | @@ -137,7 +133,7 @@ OpenAI 백엔드는 ChatGPT 로그인과 활성화된 ChatGPT `forward` provider 검색에는 네 가지 시계가 작동합니다: 기본 `stallTimeoutSec`, `connectTimeoutMs`, routed-model 비활성 시간, 그리고 hosted-search 제한 시간입니다. 실제 bridge watchdog은 이들 중 최댓값에 30초를 더한 값입니다. Routed stall은 비활성 가드이지, 전체 생성 기한이 아닙니다. -### `visionSidecar` (`OcxVisionSidecarConfig`) +### `visionSidecar` (`CodexCommanderVisionSidecarConfig`) | 필드 | 형식 | 기본값 | 의미 | | --- | --- | --- | --- | @@ -149,4 +145,4 @@ OpenAI 백엔드는 ChatGPT 로그인과 활성화된 ChatGPT `forward` provider Vision은 provider의 `noVisionModels`에 속한 모델로 보낸 이미지에만 활성화됩니다. OpenAI는 검색과 같은 로그인/forward 요건을 갖고 있으며, 명시적으로 선택한 Anthropic은 사용할 수 있는 자격 증명이 없으면 닫힌 상태로 실패합니다. 성공한 `data:` 설명은 backend, model, detail, image bytes, 그리고 정규화된 메시지 컨텍스트를 키로 하는 bounded cache를 사용합니다. 히트와 같은 턴의 중복은 한도를 소모하지 않습니다. 원격 `https:` 이미지와 실패했거나 비어 있는 설명은 캐시하지 않습니다. -Anthropic OAuth 사이드카는 opencodex의 기존 Claude Code OAuth fingerprint를 재사용합니다. 의도한 계정과 워크로드로 소크 테스트를 수행합니다. +Anthropic OAuth 사이드카는 CodexCommander의 기존 Claude Code OAuth fingerprint를 재사용합니다. 의도한 계정과 워크로드로 소크 테스트를 수행합니다. diff --git a/docs-site/src/content/docs/ko/reference/management-api.md b/docs-site/src/content/docs/ko/reference/management-api.md index 8ebf01300b..c9d6ba0c08 100644 --- a/docs-site/src/content/docs/ko/reference/management-api.md +++ b/docs-site/src/content/docs/ko/reference/management-api.md @@ -1,25 +1,25 @@ --- title: 관리 API -description: opencodex 제어 평면의 인증, 오류, 엔드포인트 참고 문서입니다. +description: CodexCommander 제어 평면의 인증, 오류, 엔드포인트 참고 문서입니다. --- -Management API는 opencodex의 제어 평면입니다. `http://localhost:10100`의 대시보드는 이 API의 한 클라이언트이며, 헤드리스 `ocx` provider, model, combo, account, settings, diagnostics, lifecycle 명령도 모두 클라이언트입니다. 이 API는 프록시가 실행 중일 때만 사용할 수 있습니다. +Management API는 CodexCommander의 제어 평면입니다. `http://localhost:10100`의 대시보드는 이 API의 한 클라이언트이며, 헤드리스 `ccx` provider, model, combo, account, settings, diagnostics, lifecycle 명령도 모두 클라이언트입니다. 이 API는 프록시가 실행 중일 때만 사용할 수 있습니다. 대화형 클라이언트가 필요하면 [Web Dashboard](/guides/web-dashboard/)를 사용하고, 자동화를 만들 때는 이 참고 문서를 사용하십시오. 영속 값은 결국 [Configuration](/reference/configuration/)을 따릅니다. ## 인증 모델 -Management API에는 데이터 평면 API 키와는 독립된 자체 관리자 자격 증명이 있습니다. 시작 시 opencodex는 다음 순서로 이를 확인합니다. +Management API에는 데이터 평면 API 키와는 독립된 자체 관리자 자격 증명이 있습니다. 시작 시 CodexCommander는 다음 순서로 이를 확인합니다. -1. 설정되어 있으면 `OPENCODEX_ADMIN_AUTH_TOKEN` -2. 강화된 비밀 파일에 저장된 생성된 `ocx_admin_*` 토큰 +1. 설정되어 있으면 `CODEXCOMMANDER_ADMIN_AUTH_TOKEN` +2. 강화된 비밀 파일에 저장된 생성된 `ccx_admin_*` 토큰 파일 기반 토큰은 해당 디렉터리와 파일 권한 또는 ACL이 강화된 뒤에만 허용됩니다. 이를 보장할 수 없으면 관리 인증은 실패를 닫는 방식으로 처리되며, 환경 토큰이 제공되거나 파일 상태가 복구될 때까지 API는 503을 반환합니다. 관리자 토큰은 다음 두 형식 중 하나로 보내면 됩니다. ```http -X-OpenCodex-API-Key: <admin-token> +X-CodexCommander-API-Key: <admin-token> ``` ```http @@ -32,7 +32,7 @@ Authorization: Bearer <admin-token> ### 루프백 대시보드 세션 -루프백 바인드에서는 대시보드 초기화가 수명이 짧은 `ocx_session_*` 자격 증명을 받을 수 있습니다. 각 세션은 5분 동안 유지되며 정확한 대시보드 origin에 묶입니다. 안전한 요청은 그 origin과 일치해야 합니다. 안전하지 않은 메서드에는 브라우저 `Origin`과 세션의 CSRF 토큰도 필요합니다. +루프백 바인드에서는 대시보드 초기화가 수명이 짧은 `ccx_session_*` 자격 증명을 받을 수 있습니다. 각 세션은 5분 동안 유지되며 정확한 대시보드 origin에 묶입니다. 안전한 요청은 그 origin과 일치해야 합니다. 안전하지 않은 메서드에는 브라우저 `Origin`과 세션의 CSRF 토큰도 필요합니다. 세션 발급은 원격 바인드와 같이 데이터 평면 인증이 필요한 경우에는 항상 비활성화됩니다. 원격 운영자는 원시 관리자 토큰으로 인증해야 하며, 루프백 방식의 GUI 세션은 발급되지 않습니다. @@ -42,7 +42,7 @@ Authorization: Bearer <admin-token> | 상태 | 유형 또는 코드 | 의미 | | --- | --- | --- | -| 401 | `opencodex admin token required` | 관리자 토큰 또는 GUI 세션이 없거나, 잘못되었거나, 만료되었거나, origin이 일치하지 않거나, CSRF 증거가 없습니다 | +| 401 | `codexcommander admin token required` | 관리자 토큰 또는 GUI 세션이 없거나, 잘못되었거나, 만료되었거나, origin이 일치하지 않거나, CSRF 증거가 없습니다 | | 403 | `cross-origin request blocked` | 요청 origin이 management allowlist 밖에 있습니다 | | 404 | `not_found` | method와 path에 맞는 management route가 없습니다 | | 413 | `request body too large` | POST, PUT, PATCH 본문이 management 2 MiB 제한을 초과했습니다 | @@ -65,7 +65,7 @@ Authorization: Bearer <admin-token> | `PUT /api/grok/selection` | 제외할 Grok 모델을 영속화합니다 | 400 잘못되었거나 너무 큰 선택 | | `POST /api/grok/apply` | 관리형 동기화를 통해 영속화된 Grok 구성을 적용합니다 | 409 `grok_apply_busy`; 400/500 적용 실패 | | `GET, PUT /api/claude-desktop` | Claude Desktop 라우팅/네이티브 프로필을 읽거나 저장합니다 | 400 잘못되었거나 사용할 수 없는 할당 | -| `POST /api/claude-desktop/apply` | 저장된 프로필을 Claude Desktop의 관리형 구성에 기록합니다 | 400/500 기록 실패 | +| `POST /api/claude-desktop/apply` | 저장된 프로필을 Claude Desktop의 관리형 구성에 기록합니다. JSON 객체와 명시적 `mode`(`static`, `hybrid`, `discovery`)가 필요합니다 | 400 본문/mode 오류, 500 기록 실패 | | `GET /api/claude-desktop/status` | 저장된 프로필과 적용된 프로필, Desktop 상태를 확인합니다 | 400 상태 읽기 실패 | | `GET, PUT /api/claude-code` | Claude Code gateway, auth-mode, model-map, context, agent, sidecar 설정을 읽거나 갱신합니다 | 400 잘못된 필드 또는 형태 | @@ -93,9 +93,6 @@ Authorization: Bearer <admin-token> | `GET, POST /api/windows-tray` | Windows tray 상태를 읽거나 설치, 시작, 중지, 제거합니다 | 400 지원되지 않는 플랫폼/작업; 500 작업 실패 | | `GET /api/diagnostics/project-config` | 캐시된 프로젝트 구성 경고를 읽습니다 | — | | `POST /api/sync` | 현재 모델 카탈로그를 Codex에 동기화하고 `catalogQuality`, `rehydrated`, Codex app-server `catalogState`, 필요한 재시작 힌트를 반환합니다 | 409 쓰기 권한 거부, 500 동기화 실패 | -| `GET /api/update/check` | `latest` 또는 `preview` 업데이트 채널을 확인합니다 | 400 잘못된 태그 | -| `POST /api/update/run` | 선택적으로 restart를 뒤따르게 할 수 있는 업데이트 작업을 시작합니다 | 400 잘못된 본문; 작업별 충돌/오류 상태 | -| `GET /api/update/status` | id로 업데이트 작업을 조회합니다 | 404 알 수 없는 작업 | | `GET, PUT /api/sidecar-settings` | web-search 및 vision sidecar 모델/backend 설정을 읽거나 업데이트합니다 | 400 잘못된 형태, backend, 또는 한도 | | `GET, PUT /api/shadow-call-settings` | shadow-call interception 설정을 읽거나 업데이트합니다 | 400 잘못된 형태 또는 값 | @@ -175,12 +172,6 @@ Authorization: Bearer <admin-token> `provider_has_dependent_combos`는 안전 장치입니다. provider를 삭제하기 전에 종속된 combo를 제거하거나 수정하십시오. -### 사이드바 - -| Method and path | 목적 | 주요 오류 | -| --- | --- | --- | -| `GET /api/update/badge` | 저렴한 sidebar update-badge 상태를 읽습니다 | — | - ### 시스템 수명 주기 | Method and path | 목적 | 주요 오류 | @@ -200,7 +191,7 @@ Authorization: Bearer <admin-token> | `PUT /api/codex-auth/accounts/pause` | 계정 하나를 일시 중지하거나 재개합니다 | 400 잘못된 account/state; 404 누락된 account | | `PUT /api/codex-auth/accounts/pause-exhausted` | quota가 소진된 account를 일시 중지합니다 | mutation-lock 실패는 503이 됩니다 | | `POST /api/codex-auth/accounts/clear-cooldown` | account 하나 또는 모든 account의 runtime cooldown을 지웁니다 | 400 잘못된 id | -| `GET, PUT /api/codex-auth/active` | 활성 account를 읽거나 선택합니다 | 400 잘못되었거나 누락된 account; 409 paused/legacy-row 충돌 | +| `GET, PUT /api/codex-auth/active` | 활성 account를 읽거나 선택합니다 | 400 잘못되었거나 누락된 account; 409 일시 중지된 account | | `PUT /api/codex-auth/auto-switch` | 자동 account 전환을 위한 quota threshold를 설정합니다 | 400 잘못된 threshold | | `PUT, PATCH /api/codex-auth/pool-strategy` | Codex account-pool 선택 전략을 업데이트합니다 | 400 잘못된 전략/구성 | | `PUT /api/codex-auth/failover` | account failover threshold를 설정합니다 | 400 잘못된 threshold | @@ -216,4 +207,4 @@ Authorization: Bearer <admin-token> ## 클라이언트 선택 -일반적인 관리 작업에는 [Web Dashboard](/guides/web-dashboard/)가 가장 안전한 안내형 워크플로를 제공합니다. 헤드리스 호스트와 자동화에는 대응하는 `ocx` 명령을 사용하십시오. 이 명령들은 동일한 실시간 API를 호출하며, 프록시에 접근할 수 없거나 작업이 실패하면 0이 아닌 결과를 반환합니다. 직접 HTTP는 위의 정확한 엔드포인트 계약이 필요한 통합에 가장 유용합니다. +일반적인 관리 작업에는 [Web Dashboard](/guides/web-dashboard/)가 가장 안전한 안내형 워크플로를 제공합니다. 헤드리스 호스트와 자동화에는 대응하는 `ccx` 명령을 사용하십시오. 이 명령들은 동일한 실시간 API를 호출하며, 프록시에 접근할 수 없거나 작업이 실패하면 0이 아닌 결과를 반환합니다. 직접 HTTP는 위의 정확한 엔드포인트 계약이 필요한 통합에 가장 유용합니다. diff --git a/docs-site/src/content/docs/ko/reference/proxy-formats.md b/docs-site/src/content/docs/ko/reference/proxy-formats.md index de1f19bdac..deb0964b1e 100644 --- a/docs-site/src/content/docs/ko/reference/proxy-formats.md +++ b/docs-site/src/content/docs/ko/reference/proxy-formats.md @@ -3,7 +3,7 @@ title: 프록시 API 형식 description: Responses, Chat Completions, Anthropic Messages, 모델 카탈로그, WebSocket, realtime, compaction 표면에 대한 와이어 레벨 참고 문서입니다. --- -opencodex는 하나의 로컬 프록시를 여러 클라이언트 방언으로 제공합니다. Codex 클라이언트는 +CodexCommander는 하나의 로컬 프록시를 여러 클라이언트 방언으로 제공합니다. Codex 클라이언트는 Responses API를 말할 수 있고, OpenAI 호환 앱은 Chat Completions를 말할 수 있으며, Claude Code는 각 업스트림 공급자가 모든 형식을 구현하지 않아도 Anthropic Messages를 말할 수 있습니다. @@ -33,7 +33,7 @@ Responses 표현이 이 연결의 중심입니다. 네이티브 호환 경로는 ## `POST /v1/responses` -이것이 opencodex의 기본 데이터 평면 형식입니다. 요청 본문은 비어 있지 않은 `model`을 가진 JSON 객체여야 +이것이 CodexCommander의 기본 데이터 평면 형식입니다. 요청 본문은 비어 있지 않은 `model`을 가진 JSON 객체여야 합니다. `input`은 문자열이거나 Responses 항목 배열일 수 있습니다. ### 허용되는 요청 필드 @@ -178,7 +178,7 @@ Responses로 변환되어 일반적으로 라우팅된 뒤, Anthropic JSON 또 ## `POST /v1/live`와 Realtime sideband `POST /v1/live`는 ChatGPT/Codex App Frameless call-creation 표면을 받습니다. -`POST /v1/realtime/calls`는 OpenAI Realtime call-creation 표면을 받습니다. opencodex는 적절한 OpenAI 계열 +`POST /v1/realtime/calls`는 OpenAI Realtime call-creation 표면을 받습니다. CodexCommander는 적절한 OpenAI 계열 경로를 선택하고, 업스트림 인증 모드에 맞게 call-creation 요청을 정규화한 뒤, 제한된 응답을 릴레이합니다. call creation 이후 클라이언트는 다음의 지원되는 모든 inbound 형식 중 하나로 sideband WebSocket에 참여할 수 @@ -198,7 +198,7 @@ Compaction은 긴 Responses 대화를 줄여야 하는 클라이언트를 위해 | 경로 유형 | 동작 | | --- | --- | | 정식 ChatGPT 또는 공식 OpenAI 경로 | 확인된 계정과 모델 인증을 사용해 요청을 네이티브 `/responses/compact` endpoint로 전달합니다 | -| 다른 라우팅된 모델 | `compaction_trigger`가 있는 내부 비스트리밍 no-tools compaction 턴을 실행합니다. `encrypted_content`가 `ocx1:` envelope인 synthetic `compaction` 항목이 정확히 하나 있어야 하며, 그 요약을 v1 replacement history로 디코딩합니다 | +| 다른 라우팅된 모델 | `compaction_trigger`가 있는 내부 비스트리밍 no-tools compaction 턴을 실행합니다. `encrypted_content`가 `ccx1:` envelope인 synthetic `compaction` 항목이 정확히 하나 있어야 하며, 그 요약을 v1 replacement history로 디코딩합니다 | 네이티브 compact 응답은 선언된 `Content-Length`가 이미 한도를 넘는 응답을 포함해 최대 32 MiB로 버퍼링됩니다. compact 전용 실패는 다음과 같습니다. @@ -210,12 +210,12 @@ compact 전용 실패는 다음과 같습니다. | 499 | `client_cancelled` | 전달 또는 버퍼링 중에 client가 취소했습니다 | | 502 | `compact_response_too_large` | 네이티브 compact 출력이 32 MiB를 초과했습니다 | | 502 | `upstream_error` | 연결, 읽기, 또는 synthetic compaction 턴 실패 | -| 502 | `invalid_response_error` | synthetic 턴이 유효하고 비어 있지 않은 `ocx1:` compaction 항목을 정확히 하나 만들지 못했습니다 | +| 502 | `invalid_response_error` | synthetic 턴이 유효하고 비어 있지 않은 `ccx1:` compaction 항목을 정확히 하나 만들지 못했습니다 | ## 인증 매트릭스 loopback 전용 bind에서는 data-plane admission에 설정된 key가 필요하지 않습니다. remote bind에서는 아래 -매트릭스를 사용하십시오. “Dedicated”는 `X-OpenCodex-API-Key`를 뜻하고, 다른 열은 `Authorization: Bearer ...` +매트릭스를 사용하십시오. “Dedicated”는 `X-CodexCommander-API-Key`를 뜻하고, 다른 열은 `Authorization: Bearer ...` 와 `x-api-key`를 뜻합니다. | 표면 | Dedicated | Bearer | `x-api-key` | @@ -254,13 +254,13 @@ OpenAI 스타일 `origin_rejected` body가 아니라 403 `permission_error`입 ## 암호화된 콘텐츠 위생 프록시는 실제 백엔드 암호문을 불투명한 데이터로 취급합니다. 구조적으로 유효한 암호문은 바이트 단위로 -그대로 보존됩니다. opencodex는 이를 복호화하거나, 내용을 번역하거나, 다른 프로바이더용으로 다시 +그대로 보존됩니다. CodexCommander는 이를 복호화하거나, 내용을 번역하거나, 다른 프로바이더용으로 다시 암호화하지 않습니다. -일부 에이전트 hook은 과거에 평문 제어 텍스트를 `encrypted_content` 슬롯에 넣었습니다. 호환성을 위해 -프록시는 구조적으로 유효한 Fernet 구간은 그대로 유지하면서 해당 평문을 텍스트 파트로 분리합니다. +일부 에이전트 hook은 평문 제어 텍스트를 `encrypted_content` 슬롯에 넣습니다. 프록시는 구조적으로 +유효한 Fernet 구간은 그대로 유지하면서 해당 평문을 텍스트 파트로 분리합니다. 이 복구 과정에서 `agent_message`의 암호화된 파트가 모두 사라지면 일반 user message가 됩니다. 현재 v2 작업이 실제로 암호화된 상태이고 선택된 라우팅 대상이 네이티브 ChatGPT 암호문을 읽을 수 없다면, -opencodex는 읽을 수 없는 바이트를 프로바이더에 보내는 대신 `unreadable_encrypted_agent_task`로 +CodexCommander는 읽을 수 없는 바이트를 프로바이더에 보내는 대신 `unreadable_encrypted_agent_task`로 실패합니다. worker task와 관련된 클라이언트 동작은 [서브에이전트 표면](/guides/sub-agent-surface/)을 참조하세요. diff --git a/docs-site/src/content/docs/ko/troubleshooting/windows-memory.md b/docs-site/src/content/docs/ko/troubleshooting/windows-memory.md index d68a67d493..2e1c5855ee 100644 --- a/docs-site/src/content/docs/ko/troubleshooting/windows-memory.md +++ b/docs-site/src/content/docs/ko/troubleshooting/windows-memory.md @@ -1,13 +1,13 @@ --- title: Windows 메모리 증가 -description: Bun 프로세스가 Windows에서 수 GiB 수준까지 RAM을 늘릴 수 있는 이유, opencodex가 현재 무엇을 하고 있는지, 그리고 상위 Bun 수정이 배포되기 전까지 사용할 수 있는 선택지를 설명합니다. +description: Bun 프로세스가 Windows에서 수 GiB 수준까지 RAM을 늘릴 수 있는 이유, CodexCommander가 현재 무엇을 하고 있는지, 그리고 상위 Bun 수정이 배포되기 전까지 사용할 수 있는 선택지를 설명합니다. --- -일부 Windows 사용자는 opencodex 뒤에서 동작하는 `bun` 프로세스가 긴 스트리밍 세션 동안 RSS 기준으로 수 GiB까지 커지는 현상을 봅니다(이슈 [#314](https://github.com/lidge-jun/opencodex/issues/314)로 보고됨). 이 페이지에서는 실제로 무슨 일이 일어나는지, 그리고 지금 무엇을 할 수 있는지 솔직하게 설명합니다. +일부 Windows 사용자는 CodexCommander 뒤에서 동작하는 `bun` 프로세스가 긴 스트리밍 세션 동안 RSS 기준으로 수 GiB까지 커지는 현상을 봅니다(이슈 [#314](https://github.com/pavelhov/CodexCommander/issues/314)로 보고됨). 이 페이지에서는 실제로 무슨 일이 일어나는지, 그리고 지금 무엇을 할 수 있는지 솔직하게 설명합니다. ## 근본 원인: 상위 Bun 런타임 문제 -opencodex는 Bun 런타임(현재 **1.3.14**)을 포함합니다. 이 메모리 증가는 프록시의 JavaScript 수준 누수가 아니라 알려진 상위 Bun 이슈들 때문에 발생합니다. +CodexCommander는 Bun 런타임(현재 **1.3.14**)을 포함합니다. 이 메모리 증가는 프록시의 JavaScript 수준 누수가 아니라 알려진 상위 Bun 이슈들 때문에 발생합니다. | Bun 이슈 | 상태(확인 시점 2026-07-23) | |---|---| @@ -15,16 +15,16 @@ opencodex는 Bun 런타임(현재 **1.3.14**)을 포함합니다. 이 메모리 | [#32111](https://github.com/oven-sh/bun/issues/32111) — 클라이언트가 async-pull 스트림을 중단할 때 발생하는 충돌 | 수정 PR [#32120](https://github.com/oven-sh/bun/pull/32120)이 2026-06-21에 머지됨. 1.3.14에는 들어 있다고 가정하지 않습니다. 참고로 이 충돌은 **Windows 전용이 아닙니다**. macOS/Linux에서도 재현되었습니다. | | [PR #31654](https://github.com/oven-sh/bun/pull/31654) — `node:net` 소켓 핸들 누수 | 여전히 상위 저장소에서 **열려 있습니다** | -Windows에서는 opencodex가 #32111 충돌을 피하기 위해 스트리밍 응답을 보수적인 코드 경로로 유지해야 하며, 그 경로가 바로 backpressure 문제에 가장 취약합니다. 느리거나 멈춘 클라이언트는 런타임이 상위 데이터를 네이티브 메모리에 버퍼링하게 만들 수 있고, JavaScript는 그 양을 제한할 수 없습니다. +Windows에서는 CodexCommander가 #32111 충돌을 피하기 위해 스트리밍 응답을 보수적인 코드 경로로 유지해야 하며, 그 경로가 바로 backpressure 문제에 가장 취약합니다. 느리거나 멈춘 클라이언트는 런타임이 상위 데이터를 네이티브 메모리에 버퍼링하게 만들 수 있고, JavaScript는 그 양을 제한할 수 없습니다. -## opencodex가 지금 하는 일 +## CodexCommander가 지금 하는 일 완화와 가시성만 제공합니다. **해결책은 아닙니다**. 번들된 1.3.14 런타임에서는 누수 자체가 여전히 상위 문제입니다. - **메모리 감시기** - 프록시는 1분마다 자체 메모리를 샘플링하고, 관측된 메모리가 4 GiB를 넘으면 속도 제한이 걸린 경고를 기록합니다. 관측된 메모리는 RSS, `external`, `arrayBuffers`의 합이 아니라 그중 가장 큰 값입니다. Windows의 working-set/RSS 카운터가 커밋된 external 잔존량을 낮게 잡을 수 있기 때문입니다. -- **`ocx doctor`** - "Memory / runtime" 섹션에서 *서비스* 프로세스의 Bun 버전, RSS, external/ArrayBuffers 카운터, JS 힙 문맥, 스트림 모드 결정을 보여줍니다. 번들된 Bun 1.3.14 런타임에서는 `heapUsed` / `jscHeap`만으로 누수를 판별할 수 없습니다. 애플리케이션 수준 누수로 단정하기 전에 관측된 메모리, `responseState`, 반복 샘플을 함께 보아야 합니다. -- **`GET /api/system/memory`** - 대시보드나 스크립트에서 쓸 수 있도록 같은 데이터를 인증된 관리 API로 제공합니다. RSS/heap/external 카운터와 함께, 프록시의 메모리 내 `previous_response_id` 이어받기 저장소에 대한 스칼라 `responseState` 블록(항목 수, 직렬화된 총/최대 바이트, 가장 오래된 항목의 경과 시간)을 보고합니다. 이를 통해 증가 원인을 더 잘 구분할 수 있습니다. 관측된 메모리가 함께 증가하면서 `responseState.totalBytes`도 늘면 대화 보존(long `store:false` 체인이 매 턴 다시 확장되는 경우)을 가리키고, 관측된 메모리는 늘지만 `responseState`는 평평하면 그 저장소와는 무관한 원인을 가리킵니다. 값은 스칼라만 포함하며 요청 본문, 토큰, 경로, 계정 식별자는 포함하지 않습니다. 또한 읽기 동작은 부작용이 없습니다. 절대 prune하거나 evict하지 않습니다. 대시보드의 **Memory observability** 카드는 같은 필드를 렌더링하고, 확인을 거쳐야 하는 **Drain & restart** 동작도 제공합니다. 현재 활성 턴 수를 보여주고, 기존 503 + `Retry-After` 드레인과 같은 방식으로 최대 60초 동안 활성 턴을 기다린 뒤, 남아 있는 턴을 강제로 중단하고 Codex 주입을 해제하지 않은 채 라이브 포트의 `ocx start`(또는 실패했을 때만 동작하는 서비스 슈퍼바이저 재기동)를 통해 프록시를 재시작합니다. 이는 `POST /api/stop`의 짧은 드레인보다 더 길고, 더 많은 정보를 반영한 재순환입니다. -- **가드된 대체 스트림 경로** - tee + JavaScript rewrite 체인을 없애는 bounded single-reader relay입니다. Windows rewrite 트래픽에는 이미 사용되며, 일반 Windows 트래픽은 계속 런타임 게이트를 따릅니다. macOS에서는 opt-in plaintext V2 collaboration이 실제로 client rewrite를 활성화하고 검증된 bundled Bun 1.3.14를 실행할 때만 `auto`가 동기식 `pull()` relay를 선택합니다. 이는 [#1127](https://github.com/lidge-jun/opencodex/issues/1127)의 terminal delivery hang을 해결하는 좁은 경로이며, Bun 1.3.14에 일반 #32111 수정이 포함되었다고 주장하지 않습니다. 다른 macOS rewrite는 명시적 opt-in으로 남습니다. memory endpoint는 in-flight, cancel, abort, error, queue watermark 스칼라 counter만 제공하며 body나 request identity는 포함하지 않습니다. +- **`ccx doctor`** - "Memory / runtime" 섹션에서 *서비스* 프로세스의 Bun 버전, RSS, external/ArrayBuffers 카운터, JS 힙 문맥, 스트림 모드 결정을 보여줍니다. 번들된 Bun 1.3.14 런타임에서는 `heapUsed` / `jscHeap`만으로 누수를 판별할 수 없습니다. 애플리케이션 수준 누수로 단정하기 전에 관측된 메모리, `responseState`, 반복 샘플을 함께 보아야 합니다. +- **`GET /api/system/memory`** - 대시보드나 스크립트에서 쓸 수 있도록 같은 데이터를 인증된 관리 API로 제공합니다. RSS/heap/external 카운터와 함께, 프록시의 메모리 내 `previous_response_id` 이어받기 저장소에 대한 스칼라 `responseState` 블록(항목 수, 직렬화된 총/최대 바이트, 가장 오래된 항목의 경과 시간)을 보고합니다. 이를 통해 증가 원인을 더 잘 구분할 수 있습니다. 관측된 메모리가 함께 증가하면서 `responseState.totalBytes`도 늘면 대화 보존(long `store:false` 체인이 매 턴 다시 확장되는 경우)을 가리키고, 관측된 메모리는 늘지만 `responseState`는 평평하면 그 저장소와는 무관한 원인을 가리킵니다. 값은 스칼라만 포함하며 요청 본문, 토큰, 경로, 계정 식별자는 포함하지 않습니다. 또한 읽기 동작은 부작용이 없습니다. 절대 prune하거나 evict하지 않습니다. 대시보드의 **Memory observability** 카드는 같은 필드를 렌더링하고, 확인을 거쳐야 하는 **Drain & restart** 동작도 제공합니다. 현재 활성 턴 수를 보여주고, 기존 503 + `Retry-After` 드레인과 같은 방식으로 최대 60초 동안 활성 턴을 기다린 뒤, 남아 있는 턴을 강제로 중단하고 Codex 주입을 해제하지 않은 채 라이브 포트의 `ccx start`(또는 실패했을 때만 동작하는 서비스 슈퍼바이저 재기동)를 통해 프록시를 재시작합니다. 이는 `POST /api/stop`의 짧은 드레인보다 더 길고, 더 많은 정보를 반영한 재순환입니다. +- **가드된 대체 스트림 경로** - tee + JavaScript rewrite 체인을 없애는 bounded single-reader relay입니다. Windows rewrite 트래픽에는 이미 사용되며, 일반 Windows 트래픽은 계속 런타임 게이트를 따릅니다. macOS에서는 opt-in plaintext V2 collaboration이 실제로 client rewrite를 활성화하고 검증된 bundled Bun 1.3.14를 실행할 때만 `auto`가 동기식 `pull()` relay를 선택합니다. 이는 [#1127](https://github.com/pavelhov/CodexCommander/issues/1127)의 terminal delivery hang을 해결하는 좁은 경로이며, Bun 1.3.14에 일반 #32111 수정이 포함되었다고 주장하지 않습니다. 다른 macOS rewrite는 명시적 opt-in으로 남습니다. memory endpoint는 in-flight, cancel, abort, error, queue watermark 스칼라 counter만 제공하며 body나 request identity는 포함하지 않습니다. 이 변경들로 실제 RSS가 얼마나 좋아지는지는 **Windows 사용자의 검증을 기다리고 있습니다**. 아직 이 누수가 해결되었다고 말하지는 않습니다. @@ -32,10 +32,10 @@ Windows에서는 opencodex가 #32111 충돌을 피하기 위해 스트리밍 응 ## 선택지 -1. **번들된 런타임 업데이트를 기다립니다.** Bun 릴리스가 수정 사항을 실제로 포함함이 확인되면 opencodex가 번들 런타임을 올리고, Windows의 no-rewrite stream path가 자동으로 켜집니다. 위의 macOS plaintext-V2 `auto` 예외는 이와 별도로 특정 Bun 버전에 고정됩니다. +1. **번들된 런타임 업데이트를 기다립니다.** Bun 릴리스가 수정 사항을 실제로 포함함이 확인되면 CodexCommander가 번들 런타임을 올리고, Windows의 no-rewrite stream path가 자동으로 켜집니다. 위의 macOS plaintext-V2 `auto` 예외는 이와 별도로 특정 Bun 버전에 고정됩니다. -2. **`OPENCODEX_BUN_PATH`로 신뢰하는 Bun 런타임을 사용합니다.** 이 경로는 검증되지 않은 영역입니다. opencodex를 아직 테스트하지 않은 런타임에서 실행하는 것이므로, 위험은 사용자에게 있습니다. 서비스 설치에서 특히 중요한 점은 이 override가 서비스 시작 시가 아니라 **서비스 아티팩트를 생성할 때** 읽힌다는 것입니다. 환경 변수를 설정한 뒤, 같은 셸에서 `ocx service repair`를 다시 실행해야 경로가 영구적인 서비스 정의에 반영됩니다. 환경 변수만 설정하면 이미 설치된 서비스에는 아무 영향이 없습니다. +2. **`CCX_BUN_PATH`로 신뢰하는 Bun 런타임을 사용합니다.** 이 경로는 검증되지 않은 영역입니다. CodexCommander를 아직 테스트하지 않은 런타임에서 실행하는 것이므로, 위험은 사용자에게 있습니다. 서비스 설치에서 특히 중요한 점은 이 override가 서비스 시작 시가 아니라 **서비스 아티팩트를 생성할 때** 읽힌다는 것입니다. 환경 변수를 설정한 뒤, 같은 셸에서 `ccx service repair`를 다시 실행해야 경로가 영구적인 서비스 정의에 반영됩니다. 환경 변수만 설정하면 이미 설치된 서비스에는 아무 영향이 없습니다. -3. **`streamMode: "eager-relay"`로 bounded relay를 opt-in합니다.** 방법은 두 가지입니다. `config.json`을 수정해 `"streamMode": "eager-relay"`를 추가하거나, 관리 API에 `PUT /api/settings`와 `{"streamMode":"eager-relay"}`를 보내 새 턴에 재시작 없이 적용합니다. **충돌 위험 경고:** Bun 1.3.14의 일반 async-pull stream은 여전히 #32111의 영향을 받으므로, 검증되지 않은 형태에 eager relay를 강제하면 어떤 OS에서든 프로세스가 충돌할 수 있습니다. 서비스 관리자가 다시 시작하겠지만 진행 중인 요청은 실패합니다. `"legacy-tee"`는 tee를 고정하고 macOS plaintext-V2 auto 예외도 끕니다. Windows의 `"auto"`(기본값)는 런타임 게이트를 따릅니다. macOS의 `"auto"`는 검증된 plaintext-V2 collaboration rewrite만 예외로 하고 tee를 유지하며, 명시적 `"eager-relay"`는 다른 적격 SSE 턴을 opt-in합니다. +3. **`streamMode: "eager-relay"`로 bounded relay를 opt-in합니다.** 방법은 두 가지입니다. `config.json`을 수정해 `"streamMode": "eager-relay"`를 추가하거나, 관리 API에 `PUT /api/settings`와 `{"streamMode":"eager-relay"}`를 보내 새 턴에 재시작 없이 적용합니다. **충돌 위험 경고:** Bun 1.3.14의 일반 async-pull stream은 여전히 #32111의 영향을 받으므로, 검증되지 않은 형태에 eager relay를 강제하면 어떤 OS에서든 프로세스가 충돌할 수 있습니다. 서비스 관리자가 다시 시작하겠지만 진행 중인 요청은 실패합니다. `"safe-tee"`는 tee를 고정하고 macOS plaintext-V2 auto 예외도 끕니다. Windows의 `"auto"`(기본값)는 런타임 게이트를 따릅니다. macOS의 `"auto"`는 검증된 plaintext-V2 collaboration rewrite만 예외로 하고 tee를 유지하며, 명시적 `"eager-relay"`는 다른 적격 SSE 턴을 opt-in합니다. -이 중 어떤 방법이든 실제 Windows 워크로드에 적용해 보셨다면, 변경 전후의 `ocx doctor` 메모리 섹션을 [#314](https://github.com/lidge-jun/opencodex/issues/314)에 남겨 주세요. 이것이 바로 이 완화책이 기다리고 있는 검증입니다. +이 중 어떤 방법이든 실제 Windows 워크로드에 적용해 보셨다면, 변경 전후의 `ccx doctor` 메모리 섹션을 [#314](https://github.com/pavelhov/CodexCommander/issues/314)에 남겨 주세요. 이것이 바로 이 완화책이 기다리고 있는 검증입니다. diff --git a/docs-site/src/content/docs/reference/adapters.md b/docs-site/src/content/docs/reference/adapters.md index de5b781368..85e35a6a56 100644 --- a/docs-site/src/content/docs/reference/adapters.md +++ b/docs-site/src/content/docs/reference/adapters.md @@ -3,7 +3,7 @@ title: Adapters description: The seven provider adapters — what each targets, how it builds requests, and its quirks. --- -An **adapter** translates between opencodex's internal request/response model and one provider wire +An **adapter** translates between CodexCommander's internal request/response model and one provider wire format. Every adapter implements the `ProviderAdapter` interface (`src/adapters/base.ts`): ```ts @@ -17,7 +17,7 @@ interface ProviderAdapter { } ``` -`buildRequest` lowers an `OcxParsedRequest` into an upstream HTTP request; `parseStream` / +`buildRequest` lowers an `CodexCommanderParsedRequest` into an upstream HTTP request; `parseStream` / `parseResponse` lift the provider's reply back into internal `AdapterEvent`s. `fetchResponse` lets an adapter own retries/timeouts, while `runTurn` supports transports that cannot be represented as one HTTP fetch followed by one response stream. [`bridge.ts`](/reference/architecture/#the-bridge) @@ -51,7 +51,7 @@ provider — xAI, Kimi, DeepSeek, GLM, Groq, OpenRouter, Ollama (local & cloud), K3 presets enable this mode and advertise summary support, so the app can display genuine Kimi reasoning deltas as soon as Kimi sends them. It is presentation-only: it neither changes effort nor invents percentage, ETA, or heartbeat text. A client request that hides reasoning still wins; - opencodex emits no visible reasoning deltas and keeps the existing replay envelope. + CodexCommander emits no visible reasoning deltas and keeps the existing replay envelope. ## `openai-responses` @@ -64,7 +64,7 @@ waits and replays the identical request on the same key before any other handlin the translated `openai-chat` / Anthropic request path. Custom `runTurn` transports are not part of the HTTP retry loop. -- `forward` URL → `{baseUrl}/responses`. A `key` provider defaults to the legacy `{baseUrl}/v1/responses` construction. +- `forward` URL → `{baseUrl}/responses`. A `key` provider defaults to `{baseUrl}/v1/responses`. - A `key` provider may set a validated relative `responsesPath`; the adapter removes one trailing slash from `baseUrl` and sends `{trimmedBaseUrl}{responsesPath}`. For Ark Agent Plan, use `baseUrl: "https://ark.cn-beijing.volces.com/api/plan/v3"` with `responsesPath: "/responses"`. - In `forward` mode only a safe header allowlist is relayed (`FORWARD_HEADERS`): authorization, ChatGPT account id, and the OpenAI beta/originator/session headers. This is the ChatGPT-login path @@ -102,9 +102,9 @@ of the HTTP retry loop. (`gemini-3.1-flash-image`, `gemini-2.0-flash-preview-image-generation`, or `gemini-3-pro-image-preview`), the adapter sends `responseModalities: ["TEXT", "IMAGE"]`. Standalone media-generation IDs such as `gemini-3-pro-image` are not included. Returned - `inlineData` parts are materialized under the configured OpenCodex `artifacts/` directory and + `inlineData` parts are materialized under the configured CodexCommander `artifacts/` directory and surfaced as markdown image links to the authenticated opaque route - `/v1/opencodex/artifacts/<id>` (not `file:` URIs or host filesystem paths). Each image is capped + `/v1/codexcommander/artifacts/<id>` (not `file:` URIs or host filesystem paths). Each image is capped at 50 MB and each response at 100 MB of decoded data; malformed base64 payloads are rejected. Artifacts are pruned automatically when the count exceeds 200 files. @@ -143,7 +143,7 @@ output. Filtering and guardrail stops surface as filtered incomplete output, and that arrives without an actual tool call is reported as a contradiction rather than treated as progress. -When an ordinary client tool exists, opencodex adds a private +When an ordinary client tool exists, CodexCommander adds a private `codex_kiro_final_answer` tool to the upstream request; progress text streams as commentary and cannot terminate the turn. The adapter consumes the private call, emits its answer as final text, and never exposes the private tool to Codex or Claude Code. Because the stop reason only arrives at @@ -169,7 +169,7 @@ important than cosmetic de-duplication. Tool-free requests retain normal text co the request field differently. A selected `low`, `medium`, `high`, `xhigh`, or `max` value is sent as `additionalModelRequestFields.reasoning.effort` for `gpt-5.6-sol` and as `additionalModelRequestFields.output_config.effort` for `claude-opus-5`. Other Kiro models currently -use emulated reasoning: opencodex converts the selected level into bounded thinking instructions in +use emulated reasoning: CodexCommander converts the selected level into bounded thinking instructions in the user content because their native effort field has not been verified. Do not interpret an advertised effort control on those models as proof of upstream-native reasoning support. @@ -186,15 +186,14 @@ advertised effort control on those models as proof of upstream-native reasoning run request is committed to the wire. - Exposes Cursor Router as `cursor/auto` plus explicit `cursor/auto-cost`, `cursor/auto-balance`, and `cursor/auto-intelligence` entries. Explicit levels are encoded in - `requested_model.parameters` while the legacy `cursor/auto` entry retains the account/team default. + `requested_model.parameters` while the base `cursor/auto` entry retains the account/team default. - Keeps `cursor/grok-4.5-fast` as a selectable model while sending Cursor's canonical `grok-4.5` model with separate `effort` and `fast=true` parameters. - Cursor-native local filesystem/shell/network execution is denied by default. Explicit `mcpServers` and `desktopExecutor` integrations have separate opt-ins; `nativeLocalExec: "on"` enables the - broader built-in executor and bypasses Codex approval/sandbox semantics, and legacy - `unsafeAllowNativeLocalExec: true` remains equivalent only when `nativeLocalExec` is unset. + broader built-in executor and bypasses Codex approval/sandbox semantics. -## `azure-openai` (alias: `azure`) +## `azure-openai` **Targets:** **Azure OpenAI**. Wraps `openai-responses` (so also `passthrough: true`). **Auth:** `key` via the `api-key` header (not Bearer). diff --git a/docs-site/src/content/docs/reference/architecture.md b/docs-site/src/content/docs/reference/architecture.md index c33c6047f3..219936f782 100644 --- a/docs-site/src/content/docs/reference/architecture.md +++ b/docs-site/src/content/docs/reference/architecture.md @@ -1,9 +1,9 @@ --- title: Architecture -description: opencodex internals — module map, the AdapterEvent bridge, the request parser, and caching. +description: CodexCommander internals — module map, the AdapterEvent bridge, the request parser, and caching. --- -opencodex is a single Bun process. A request enters as OpenAI Responses, is normalized to an internal +CodexCommander is a single Bun process. A request enters as OpenAI Responses, is normalized to an internal model, routed, sent to a provider via an adapter, and bridged back to Responses SSE. See [How It Works](/getting-started/how-it-works/) for the end-to-end flow. @@ -11,7 +11,7 @@ model, routed, sent to a provider via an adapter, and bridged back to Responses ``` src/ -├── cli/ # ocx command dispatch, init, status, provider commands +├── cli/ # ccx command dispatch, init, status, provider commands ├── server/ # Bun.serve, /v1/* proxy, /api/* management API, WS bridge ├── codex/ # Codex config injection, catalog sync, auth/account integration ├── providers/ # provider metadata, API-key pool, quota and labels @@ -21,12 +21,12 @@ src/ ├── lib/ # runtime, process, retry, privacy, token estimate helpers ├── web-search/ # web-search sidecar (synthetic tool, loop, executor, parser) ├── vision/ # vision sidecar (describe + plan) -├── config.ts # ~/.opencodex/config.json, defaults, PID, env resolution +├── config.ts # ~/.codexcommander/config.json, defaults, PID, env resolution ├── router.ts # model id → provider + adapter ├── bridge.ts # AdapterEvent stream → Responses SSE / JSON ├── reasoning-effort.ts # reasoning-effort translation, clamping, and catalog levels ├── responses/ -│ ├── parser.ts # Responses request → OcxParsedRequest +│ ├── parser.ts # Responses request → CodexCommanderParsedRequest │ ├── schema.ts # Zod validation │ └── compaction.ts # remote compaction prompts, envelopes, compact history ├── service.ts # launchd / systemd / Task Scheduler background service @@ -34,7 +34,7 @@ src/ └── index.ts # public entry ``` -Three formerly large entry files now preserve compatibility as facades: `codex/catalog.ts` exports +Three entry files are thin module facades: `codex/catalog.ts` exports the seven focused `codex/catalog/*.ts` modules, `server/management-api.ts` dispatches to the nine `server/management/*.ts` modules, and `server/responses.ts` exports the five `server/responses/*.ts` modules. @@ -70,9 +70,9 @@ the `server/responses.ts` facade and its `server/responses/*.ts` modules: ## The parser `responses/parser.ts` validates the incoming request with `responses/schema.ts` (Zod), then builds an -`OcxParsedRequest`: +`CodexCommanderParsedRequest`: -- **Messages** — `input` items become a normalized `OcxMessage[]`: user / developer / assistant / +- **Messages** — `input` items become a normalized `CodexCommanderMessage[]`: user / developer / assistant / toolResult. `reasoning` items become thinking blocks; `function_call`, `custom_tool_call`, and `tool_search_call` items become tool calls; their `*_output` counterparts become tool results. - **Tools** — function tools pass through; **namespaced (MCP) tools are flattened** to @@ -120,24 +120,24 @@ single non-streaming response object from the same events. provider CRUD and key pools, model selection/context caps/v2 controls, catalog sync, diagnostics and debug logs, usage and quotas, sidecar settings, updates, generated client API keys, OAuth login/status/ logout and account selection, Codex account management, and graceful stop. `server/auth-cors.ts` -requires `OPENCODEX_API_AUTH_TOKEN` for both `/api/*` and `/v1/*` when the proxy binds beyond +requires `CODEXCOMMANDER_API_AUTH_TOKEN` for both `/api/*` and `/v1/*` when the proxy binds beyond loopback; configured `corsAllowOrigins` entries extend the local-origin allowlist. OAuth implementations live in `oauth/`; access tokens are loaded or refreshed immediately before a routed call, while `oauth/token-guardian.ts` can proactively refresh only providers whose policy allows it. Refresh is coordinated with in-process single-flight, a per-account file lock, and generation CAS so concurrent writers cannot clobber a newer credential. A shared health projection -(`oauth/health.ts`) feeds `ocx status`, `ocx doctor`, the management API, and the dashboard. +(`oauth/health.ts`) feeds `ccx status`, `ccx doctor`, the management API, and the dashboard. Codex/ChatGPT pool credentials and process-local thread affinity live under `codex/` and are kept out of management responses; affinity clears on `401` / `403` / `429` (not pinned through rate limits) -and is not persisted across restarts. Request usage is normalized to `OcxUsage`, surfaced in +and is not persisted across restarts. Request usage is normalized to `CodexCommanderUsage`, surfaced in Responses terminal events, and aggregated by `usage/` for the dashboard and optional JSONL diagnostics. ## Transport and compaction `server/index.ts` serves HTTP/SSE on `/v1/responses` by default. If Codex attempts a Responses -WebSocket upgrade while `websockets` is `false`, opencodex returns `426 upgrade_required`; Codex then +WebSocket upgrade while `websockets` is `false`, CodexCommander returns `426 upgrade_required`; Codex then falls back to HTTP for that session. When `"websockets": true` is set, the same endpoint accepts the upgrade and uses the WebSocket bridge. @@ -168,7 +168,7 @@ upstream providers may support only a smaller subset or require a real alias. Th ## Core types -The internal model lives in `types.ts`: `OcxParsedRequest`, `OcxContext`, the `OcxMessage` union, -`OcxContentPart` (text / image), `OcxToolCall`, `OcxTool`, `AdapterEvent`, and the config types -(`OcxConfig`, `OcxProviderConfig`). Two helpers are widely used: `namespacedToolName()` and +The internal model lives in `types.ts`: `CodexCommanderParsedRequest`, `CodexCommanderContext`, the `CodexCommanderMessage` union, +`CodexCommanderContentPart` (text / image), `CodexCommanderToolCall`, `CodexCommanderTool`, `AdapterEvent`, and the config types +(`CodexCommanderConfig`, `CodexCommanderProviderConfig`). Two helpers are widely used: `namespacedToolName()` and `modelInList()` (tolerant `:size`-tag matching for `noVisionModels` / `noReasoningModels`). diff --git a/docs-site/src/content/docs/reference/cli.md b/docs-site/src/content/docs/reference/cli.md index c01f0b303e..6bc0335791 100644 --- a/docs-site/src/content/docs/reference/cli.md +++ b/docs-site/src/content/docs/reference/cli.md @@ -1,21 +1,21 @@ --- title: CLI Reference -description: Command dispatch, exit codes, and links to every ocx command family. +description: Command dispatch, exit codes, and links to every ccx command family. --- -The opencodex CLI is `ocx`. It dispatches on the first command name, with documented aliases such +The CodexCommander CLI is `ccx`. It dispatches on the first command name, with documented aliases such as `setup`/`init`, `restore`/`eject`, and `models`/`model` reaching the same operation. Unknown commands and invalid command shapes are errors. -Run `ocx help` (or `ocx --help` / `ocx -h`) for top-level usage. Run `ocx help <command>`, -`ocx <command> --help`, or `ocx <command> -h` for a command registered in the help table. Help and +Run `ccx help` (or `ccx --help` / `ccx -h`) for top-level usage. Run `ccx help <command>`, +`ccx <command> --help`, or `ccx <command> -h` for a command registered in the help table. Help and version commands are read-only: they do not start, stop, install, uninstall, or rewrite Codex or -opencodex state. +CodexCommander state. ## Command families - [Lifecycle](/reference/cli/lifecycle/) — setup, proxy and service lifecycle, health, diagnostics, - catalog sync, the dashboard, and updates. + catalog sync, and the dashboard. - [Providers, accounts, and models](/reference/cli/providers-accounts/) — provider configuration, authentication, credential pools, quota, custom models, visibility, selected models, and context caps. @@ -31,28 +31,21 @@ offline configuration operations can instead validate and edit the config file w proxy. List or status is the default where unambiguous. Use `--json` for structured snapshots and -`ocx observe logs --follow --jsonl` for a streaming request-log feed. Theme, language, navigation, +`ccx observe logs --follow --jsonl` for a streaming request-log feed. Theme, language, navigation, and other purely visual browser state have no CLI equivalent; Cloudflare Tunnel setup is outside this command set. ## Exit codes and confirmation Successful commands exit 0. Invalid usage, unknown commands or resources, failed API operations, -and unavailable required services exit nonzero. `ocx health` specifically exits 0 only when the +and unavailable required services exit nonzero. `ccx health` specifically exits 0 only when the proxy is healthy and 1 otherwise, so it can be used as a service probe. Scripts should test the exit code instead of scraping human-readable output. -Destructive removal, import, credit-consumption, and update operations that advertise confirmation +Destructive removal, import, and credit-consumption operations that advertise confirmation require `--yes` in non-interactive use. The flag is an explicit opt-in; omitting it must not silently confirm the action. -## Version and internal dispatch targets +## Version -`ocx --version`, `ocx -v`, and `ocx version` print one script-friendly version line and exit. - -Two dispatch targets are intentionally omitted from normal help: `__refresh-version [preview]` -refreshes the update-notification cache in a detached process, and -`__gui-update-worker <job-id> [latest|preview] [restart]` runs a dashboard update job. They are -implementation details, not stable user-facing commands. The dashboard records the worker PID, -recovers an active job whose worker died, treats older PID-less active records as stale after ten -minutes, and protects a live worker from concurrent updates. +`ccx --version`, `ccx -v`, and `ccx version` print one script-friendly version line and exit. diff --git a/docs-site/src/content/docs/reference/cli/agents.md b/docs-site/src/content/docs/reference/cli/agents.md index f7c194c8a3..3def38f4ca 100644 --- a/docs-site/src/content/docs/reference/cli/agents.md +++ b/docs-site/src/content/docs/reference/cli/agents.md @@ -3,21 +3,21 @@ title: CLI Agents, Routing, and Integrations description: Multi-agent, combo, observability, access, integration, system, and config commands. --- -These commands control agent policy and routing, inspect the live proxy, and connect supported clients to opencodex. +These commands control agent policy and routing, inspect the live proxy, and connect supported clients to CodexCommander. ## Agent policy -### `ocx agent <status|injection|effort|subagents|fallback|sidecar> ...` +### `ccx agent <status|injection|effort|subagents|fallback|sidecar> ...` Manage the headless multi-agent roster, effort caps, prompt injection, fallback, and sidecar settings. Use `status` for the current policy. See [Sub-agent surfaces](/guides/sub-agent-surface/) for how surface modes, delegation, effort, and fallback behavior fit together. ```bash -ocx agent subagents set ark/model-a,openai/gpt-5.5 +ccx agent subagents set ark/model-a,openai/gpt-5.5 ``` -### `ocx v2 <status|on|off|mode <v1|default|v2>|threads <n>>` +### `ccx v2 <status|on|off|mode <v1|default|v2>|threads <n>>` Manage the Codex `multi_agent_v2` feature flag and the three-state multi-agent surface mode. @@ -32,126 +32,125 @@ Manage the Codex `multi_agent_v2` feature flag and the three-state multi-agent s | `threads <n>` | Set the active v1/v2 thread limit to an integer of at least 1. | ```bash -ocx v2 status -ocx v2 mode v1 -ocx v2 mode default -ocx v2 on -ocx v2 threads 16 +ccx v2 status +ccx v2 mode v1 +ccx v2 mode default +ccx v2 on +ccx v2 threads 16 ``` -The `mode` subcommand writes `multiAgentMode` to the opencodex config and resyncs the Codex catalog. +The `mode` subcommand writes `multiAgentMode` to the CodexCommander config and resyncs the Codex catalog. Mode and flag transitions move the current numeric thread limit between the valid v1/v2 Codex keys; a failed transition restores the original `config.toml`. Changes apply to new Codex sessions, while running sessions keep their pinned surface. ## Combo routing -### `ocx combo <list|show|set|remove> ...` · `ocx route combo ...` +### `ccx combo <list|show|set|remove> ...` · `ccx route combo ...` -Manage combo failover and round-robin virtual models. `ocx route combo` is the hierarchical alias; +Manage combo failover and round-robin virtual models. `ccx route combo` is the hierarchical alias; combo is currently the supported routing resource. Targets use `provider/model[:weight],provider/model[:weight]`. ```bash -ocx combo list -ocx route combo set reliable --targets ark/model-a:2,openai/gpt-5.5 +ccx combo list +ccx route combo set reliable --targets ark/model-a:2,openai/gpt-5.5 ``` See [Combos](/guides/combos/) for routing behavior and configuration guidance. ## Observability and debug -### `ocx observe <logs|usage|storage|memory|debug|claude-inbound|injection> ...` +### `ccx observe <logs|usage|storage|memory|debug|claude-inbound|injection> ...` Inspect proxy requests, usage, storage, memory, and debug data. The direct aliases are: | Alias | Equivalent resource | | --- | --- | -| `ocx logs [filters] [--follow] [--json|--jsonl]` | `ocx observe logs` | -| `ocx usage [--range <7d|30d|all>] [--surface <all|codex|claude|grok>] [--json]` | `ocx observe usage` | -| `ocx storage [--json]` | `ocx observe storage` | -| `ocx memory [--json]` | `ocx observe memory` | +| `ccx logs [filters] [--follow] [--json|--jsonl]` | `ccx observe logs` | +| `ccx usage [--range <7d|30d|all>] [--surface <all|codex|claude|grok>] [--json]` | `ccx observe usage` | +| `ccx storage [--json]` | `ccx observe storage` | +| `ccx memory [--json]` | `ccx observe memory` | ```bash -ocx observe usage --range 30d --json +ccx observe usage --range 30d --json ``` -### `ocx debug <provider|usage|injection|claude> <on|off|status|reset|logs [-f]>` +### `ccx debug <provider|usage|injection|claude> <on|off|status|reset|logs [-f]>` Read or change runtime debug overrides through the running proxy's management API. ```bash -ocx debug provider on|off|status|reset -ocx debug provider logs [-f|--follow] -ocx debug usage on|off|status|reset -ocx debug usage logs [-f|--follow] +ccx debug provider on|off|status|reset +ccx debug provider logs [-f|--follow] +ccx debug usage on|off|status|reset +ccx debug usage logs [-f|--follow] ``` -With no scope, `ocx debug` prints usage and, when the proxy is stopped, the next-start environment -defaults. Provider debug defaults from `OCX_DEBUG=1` (legacy `OCX_DEBUG_FRAMES=1` also works); usage -debug defaults from `OPENCODEX_USAGE_DEBUG=1`. +With no scope, `ccx debug` prints usage and, when the proxy is stopped, the next-start environment +defaults. Provider debug defaults from `CCX_DEBUG=1`; usage +debug defaults from `CODEXCOMMANDER_USAGE_DEBUG=1`. ## API access -### `ocx access <key|endpoints|models|test> ...` +### `ccx access <key|endpoints|models|test> ...` -Manage OpenCodex admission API keys and inspect external endpoints and models. `ocx api-key -<list|create|remove> ...` is an alias of `ocx access key`. +Manage CodexCommander admission API keys and inspect external endpoints and models. `ccx api-key +<list|create|remove> ...` is an alias of `ccx access key`. ```bash -ocx access key create deployment +ccx access key create deployment ``` ## Client integrations -### `ocx integration <claude|grok> ...` +### `ccx integration <claude|grok> ...` Manage supported Claude and Grok integrations. The direct command families below expose their client-specific controls. -### `ocx claude [claude args...]` +### `ccx claude [claude args...]` Ensure the proxy is running, then launch Claude Code with `ANTHROPIC_BASE_URL`, -`ANTHROPIC_AUTH_TOKEN`, `CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1`, and model slots from -`config.claudeCode`. Routed models appear in the native `/model` picker through stable slot aliases +`ANTHROPIC_AUTH_TOKEN`, `CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1`, and the current auth/helper +settings from `config.claudeCode`. Routed models appear in the native `/model` picker through stable aliases with Claude Code 2.1.129 or newer. On older versions, select with `ANTHROPIC_MODEL` or `/model <id>`. User-exported `ANTHROPIC_*` variables always take precedence. Claude Desktop profile commands are: ```text -ocx claude desktop [apply] Save and apply the four-family profile -ocx claude desktop show [--json] Show routes, families, and defaults -ocx claude desktop move <route> <family> [--default] -ocx claude desktop default <family> <route|none> -ocx claude desktop export <path|-> Export versioned JSON (`-` = stdout) -ocx claude desktop import <path> [--apply] Validate and import JSON +ccx claude desktop apply Save and apply the four-family profile +ccx claude desktop show [--json] Show routes, families, and defaults +ccx claude desktop move <route> <family> [--default] +ccx claude desktop default <family> <route|none> +ccx claude desktop export <path|-> Export versioned JSON (`-` = stdout) +ccx claude desktop import <path> [--apply] Validate and import JSON ``` The families are `opus`, `fable`, `sonnet`, and `haiku`; new routes start in `opus`. `none` is valid -only when that family is empty. Legacy apply flags `--static`, `--hybrid`, and `--discovery-only` -remain supported. Use `ocx claude config <status|set> ...` for Claude Code settings. +only when that family is empty. Use `ccx claude config <status|set> ...` for Claude Code settings. -### `ocx opencode [opencode args...]` +### `ccx opencode [opencode args...]` -Ensure the proxy is running, then launch opencode with a generated `provider.opencodex` block in +Ensure the proxy is running, then launch opencode with a generated `provider.codexcommander` block in OpenCode's inline runtime layer (`OPENCODE_CONFIG_CONTENT`). Existing inline config is preserved and -only `provider.opencodex` is replaced for this launch. Global or project `opencode.json` files may be +only `provider.codexcommander` is replaced for this launch. Global or project `opencode.json` files may be read to warn about an existing override, but on-disk files are never modified. Routed models appear -as `opencodex/<provider>/<model>`. This launcher leaves later plain `opencode` launches unchanged; -the separate opt-in dashboard integration is the only path that persists `provider.opencodex`. +as `codexcommander/<provider>/<model>`. This launcher leaves later plain `opencode` launches unchanged; +the separate opt-in dashboard integration is the only path that persists `provider.codexcommander`. -### `ocx grok <status|exclude|include|set|clear|apply> ...` +### `ccx grok <status|exclude|include|set|clear|apply> ...` Manage and apply the Grok Build model fence. ## Client config export -### `ocx export --client <opencode|pi>` +### `ccx export --client <opencode|pi>` Print a client config wired to the running proxy. opencode and [Pi](/guides/pi/) read providers from their own JSON config rather than environment variables, so this command serializes the -`opencodex` provider block — base URL, model list, and the client's env reference — for you to +`codexcommander` provider block — base URL, model list, and the client's env reference — for you to merge into that file. The proxy must be running; the command resolves its live port, reads `/api/models`, and emits only @@ -165,9 +164,9 @@ models Codex can currently see. | `--force` | Allow `--out` to replace an existing file. | ```bash -ocx export --client opencode # config plus destination, merge warning, and counts -ocx export --client pi --json > pi-models.json # byte-exact JSON for a pipe or a diff -ocx export --client opencode --out ~/opencodex-opencode.json +ccx export --client opencode # config plus destination, merge warning, and counts +ccx export --client pi --json > pi-models.json # byte-exact JSON for a pipe or a diff +ccx export --client opencode --out ~/codexcommander-opencode.json ``` Without `--json` the JSON leads, then the canonical destination path, the merge warning, the env @@ -176,14 +175,14 @@ defaults for those). | Client | Canonical destination | Download filename | Env var | | --- | --- | --- | --- | -| `opencode` | `~/.config/opencode/opencode.json` (`XDG_CONFIG_HOME` wins when set) | `opencode.json` | `OPENCODEX_OPENCODE_API_KEY` | -| `pi` | `~/.pi/agent/models.json` | `pi-models.json` | `OPENCODEX_API_KEY` | +| `opencode` | `~/.config/opencode/opencode.json` (`XDG_CONFIG_HOME` wins when set) | `opencode.json` | `CODEXCOMMANDER_OPENCODE_API_KEY` | +| `pi` | `~/.pi/agent/models.json` | `pi-models.json` | `CODEXCOMMANDER_API_KEY` | The two env var names are different, and each client only interpolates its own. opencode reads -`{env:OPENCODEX_OPENCODE_API_KEY}`; Pi reads `$OPENCODEX_API_KEY`. +`{env:CODEXCOMMANDER_OPENCODE_API_KEY}`; Pi reads `$CODEXCOMMANDER_API_KEY`. :::caution[Merge, never replace] -`ocx export` never writes your real client config. The destination is printed for you to merge by +`ccx export` never writes your real client config. The destination is printed for you to merge by hand, and `--out` refuses to overwrite an existing file without `--force`, because replacing a config destroys the other providers, agents, and MCP entries already in it. ::: @@ -200,15 +199,15 @@ the CLI, the API, and the GUI use the same bytes. ## Runtime and configuration -### `ocx system <status|settings|startup|diagnostics|sync|update> ...` +### `ccx system <status|settings|startup|diagnostics|sync> ...` -Manage headless runtime settings, startup, sync, diagnostics, and updates. +Manage headless runtime settings, startup, sync, and diagnostics. ```bash -ocx system settings --stream-mode eager-relay +ccx system settings --stream-mode eager-relay ``` -### `ocx config <show|get|set|unset|validate|export|import> ...` +### `ccx config <show|get|set|unset|validate|export|import> ...` -Inspect and safely modify validated OpenCodex configuration. `show` and `get` mask secrets. Import +Inspect and safely modify validated CodexCommander configuration. `show` and `get` mask secrets. Import validates before writing and requires `--yes`. diff --git a/docs-site/src/content/docs/reference/cli/lifecycle.md b/docs-site/src/content/docs/reference/cli/lifecycle.md index ef1f0f47a4..b9ca85de7d 100644 --- a/docs-site/src/content/docs/reference/cli/lifecycle.md +++ b/docs-site/src/content/docs/reference/cli/lifecycle.md @@ -1,50 +1,50 @@ --- title: CLI Lifecycle -description: Setup, start, stop, service, diagnostics, sync, and update commands. +description: Setup, start, stop, service, diagnostics, and sync commands. --- -These commands install, run, inspect, repair, and update the local opencodex proxy and its Codex integration. +These commands install, run, inspect, and repair the local CodexCommander proxy and its Codex integration. ## Setup -### `ocx init` · `ocx setup` +### `ccx init` · `ccx setup` Interactive setup wizard (`setup` is an alias of `init`). Prompts for a provider (preset or custom), -API key (literal or `${ENV}`), default model, and proxy port; saves `~/.opencodex/config.json`; +API key (literal or `${ENV}`), default model, and proxy port; saves `~/.codexcommander/config.json`; optionally injects the proxy into `$CODEX_HOME/config.toml` (default `~/.codex/config.toml`); and optionally installs the Codex autostart shim. ## Proxy lifecycle -### `ocx start [--port <port>]` +### `ccx start [--port <port>]` -Start the proxy server (preferred port `10100`). If that port is occupied, opencodex selects and +Start the proxy server (preferred port `10100`). If that port is occupied, CodexCommander selects and records another available port. It writes PID/runtime-port state and refuses to start a second live instance. On start it syncs each provider's models into Codex's catalog. On shutdown it restores -native Codex — unless it was launched as a managed service (`OCX_SERVICE=1`). +native Codex — unless it was launched as a managed service (`CCX_SERVICE=1`). ```bash -ocx start -ocx start --port 8080 +ccx start +ccx start --port 8080 ``` -### `ocx stop` +### `ccx stop` Stop the running proxy (by PID), remove the PID file, and restore native Codex. If a managed -background service is installed, `ocx stop` also stops it first so it cannot respawn the proxy. +background service is installed, `ccx stop` also stops it first so it cannot respawn the proxy. The same action is available from the web dashboard's **Stop** button (`POST /api/stop`). -### `ocx restart` +### `ccx restart` Run `stop` followed by `ensure`: stop the proxy/service, restore native Codex, start the proxy in the background, and sync the live port back into Codex. -### `ocx ensure` +### `ccx ensure` Idempotently ensure a background proxy is running, then sync its live model catalog. If `codexAutoStart` is `false`, it prints that autostart is disabled and does nothing. -### `ocx restore [back]` · `ocx eject [back]` +### `ccx restore [back]` · `ccx eject [back]` Restore native Codex **without** stopping the proxy — strips the injected config lines and routed catalog entries so plain `codex` works natively again. `eject` is an alias of `restore`. @@ -53,25 +53,19 @@ Pass `back` to either spelling to re-point plain `codex` at an already-running p the proxy lifecycle: ```bash -ocx restore back -ocx eject back +ccx restore back +ccx eject back ``` -### `ocx recover-history --legacy-openai` - -Explicit recovery for older development builds that remapped Codex App history before reversible -backup support existed. Close Codex first if its history database is locked. - -### `ocx uninstall` · `ocx remove` +### `ccx uninstall` · `ccx remove` Stop the service and proxy, remove the service and Codex shim, restore native Codex, then remove -opencodex local config only if all restore steps succeeded. `remove` is an alias of `uninstall`. -Config cleanup requires ownership metadata created by a fresh install; legacy or shared directories -are left in place. +CodexCommander local config only if all restore steps succeeded. `remove` is an alias of `uninstall`. +Config cleanup requires canonical ownership metadata; unowned or shared directories are left in place. ## Status and health -### `ocx status [--json]` +### `ccx status [--json]` Print a read-only diagnostic summary: proxy PID, `/healthz` reachability, dashboard URL, config path, default provider, Codex autostart setting, service state, shim state, and the redacted effective Codex @@ -85,8 +79,8 @@ quota limited, or refresh conflict) plus an optional `Action:` hint. Account ids and emails are never printed. The `--json` contract does not currently include this health block. ```bash -ocx status -ocx status --json +ccx status +ccx status --json ``` Abbreviated example shape: @@ -107,8 +101,8 @@ Abbreviated example shape: "url": "http://localhost:10100/" }, "paths": { - "config": "/Users/example/.opencodex/config.json", - "pid": "/Users/example/.opencodex/ocx.pid", + "config": "/Users/example/.codexcommander/config.json", + "pid": "/Users/example/.codexcommander/codexcommander.pid", "runtime": "/path/to/bun" }, "runtime": { @@ -124,7 +118,7 @@ Abbreviated example shape: "codexAutostart": true, "defaultProvider": "openai", "service": { - "summary": "not installed (logs: /Users/example/.opencodex/service.log)" + "summary": "not installed (logs: /Users/example/.codexcommander/service.log)" }, "codexShim": { "summary": "Codex autostart shim: not installed" @@ -137,61 +131,61 @@ diagnostics, and bundled Codex plugin diagnostics. The JSON schema is additive-o may add fields, but existing fields should stay stable. It intentionally excludes API keys, OAuth tokens, authorization headers, request content, emails, and account identities. -### `ocx health [--json]` +### `ccx health [--json]` Identity-check the live proxy. Human output reports PID/port; `--json` emits `{ok, pid, port}`. The command exits 0 only when healthy and 1 otherwise, making it suitable for service probes. -### `ocx ready [--json] [--wait [--timeout <seconds>]]` +### `ccx ready [--json] [--wait [--timeout <seconds>]]` Check post-sync readiness through the unauthenticated `GET /readyz` endpoint. It returns `200` when ready, or `503` with `Retry-After: 1` for `pending` and terminal `failed`. Its sanitized HTTP identity -is `{service, version, uptime, pid, port, status}`. Old proxies without `/readyz` fail closed as -`unreachable`; `/healthz` is separate liveness, not readiness. The command performs one probe by +is `{service, version, uptime, pid, port, status}`. `/healthz` is separate liveness, not readiness. +The command performs one probe by default; `--wait` polls until ready or timeout, but exits immediately when it observes the terminal `failed` state. The default timeout is 45 seconds; `--timeout <seconds>` requires `--wait` and accepts positive integer seconds from 1–300. CLI JSON emits `{ready, status, pid, port}`, where `status` is `ready`, `pending`, `failed`, or `unreachable`. Exit codes are 0 for ready; 1 for not-ready, pending, failed, timeout, or unreachable; and 64 for invalid arguments. -### `ocx doctor` +### `ccx doctor` Run read-only environment and connectivity diagnostics: state paths and filesystem type, WSL dual -installs, proxy environment/config, ChatGPT reachability, Codex plugin and project-config warnings, -and pending history migration. The Codex app-home targeting section also detects the narrow Windows -Orca runtime-home mismatch and explains service migration when applicable. Paths shown by this -diagnostic redact the OS username. Doctor prints repair hints but does not apply them. +installs, proxy environment/config, ChatGPT reachability, and Codex plugin and project-config +warnings. The Codex app-home targeting section also detects the narrow Windows Orca runtime-home +mismatch and prints manual uninstall, environment, and reinstall steps when applicable. Paths shown +by this diagnostic redact the OS username. Doctor prints repair hints but does not apply them. The **OAuth reliability** section reports whether credential storage is writable, whether refresh -single-flight/lock files can be created under `OPENCODEX_HOME`, non-healthy OAuth or Codex pool +single-flight/lock files can be created under `CODEXCOMMANDER_HOME`, non-healthy OAuth or Codex pool accounts (redacted ids) with a recovery `Action:`, and a static OK that the Codex forward path does not fabricate official-client metadata. Doctor never mutates credentials or applies repairs. ## Catalog sync -### `ocx sync [--restart-codex]` +### `ccx sync [--restart-codex]` Fetch the live model list from every configured provider and re-inject the merged catalog into Codex. Run it after adding a provider or to refresh available models. -If long-lived Codex `app-server` processes are still running, `ocx sync` warns that they may keep -serving the previous in-memory model list even though `opencodex-catalog.json` / `models_cache.json` +If long-lived Codex `app-server` processes are still running, `ccx sync` warns that they may keep +serving the previous in-memory model list even though `codexcommander-catalog.json` / `models_cache.json` were updated. Pass `--restart-codex` to send `SIGTERM` only to matching `codex … app-server` and `codex-code-mode-host` processes owned by the current user (active turns may be interrupted). Broad `pkill -f codex` matching is intentionally avoided. -### `ocx sync-cache [--restart-codex]` +### `ccx sync-cache [--restart-codex]` -Invalidate Codex's local model picker cache so it is rebuilt from the active opencodex catalog. The -same stale-`app-server` warning and optional `--restart-codex` behavior as `ocx sync` apply. +Invalidate Codex's local model picker cache so it is rebuilt from the active CodexCommander catalog. The +same stale-`app-server` warning and optional `--restart-codex` behavior as `ccx sync` apply. ## Background service -### `ocx service [install|repair|start|stop|status|uninstall|remove]` +### `ccx service [install|repair|start|stop|status|uninstall|remove]` -Run opencodex as a login-managed background service (macOS **launchd**, Linux **systemd user unit**, +Run CodexCommander as a login-managed background service (macOS **launchd**, Linux **systemd user unit**, Windows **Task Scheduler**) that auto-starts on login and auto-restarts on crash. Service runs set -`OCX_SERVICE=1` so a restart does not churn the Codex config. +`CCX_SERVICE=1` so a restart does not churn the Codex config. | Subcommand | Action | | --- | --- | @@ -205,11 +199,11 @@ Windows **Task Scheduler**) that auto-starts on login and auto-restarts on crash | `remove` | Alias of `uninstall`. | ```bash -ocx service -ocx service install -ocx service repair -ocx service status -ocx service uninstall +ccx service +ccx service install +ccx service repair +ccx service status +ccx service uninstall ``` `install`, `start`, and `repair` confirm that a proxy actually answers on the port @@ -217,7 +211,7 @@ baked into the installed service before reporting success — on all three platf They wait up to 20 seconds and then print the serving port: ``` -✅ opencodex service installed and serving on port 10100. +✅ CodexCommander service installed and serving on port 10100. ``` If nothing answers, they warn and **exit non-zero**: @@ -225,15 +219,15 @@ If nothing answers, they warn and **exit non-zero**: ``` ⚠️ Service installed, but no proxy answered on port 10100 within 20s. The manager registered the job; that is not the same as serving. - Log: ~/.opencodex/service.log - Meanwhile: ocx start (serves in the foreground) + Log: ~/.codexcommander/service.log + Meanwhile: ccx start (serves in the foreground) ``` A non-zero exit here means *registered but not serving* — not *not installed*. The service manager accepted the job; the proxy behind it never bound the port. Read the -log named in the message, and use `ocx start` to serve in the foreground meanwhile. +log named in the message, and use `ccx start` to serve in the foreground meanwhile. -`ocx service status` reports the same three states rather than raw manager output: +`ccx service status` reports the same three states rather than raw manager output: ``` ✅ installed and loaded (launchd; logs: …) @@ -244,10 +238,10 @@ log named in the message, and use `ocx start` to serve in the foreground meanwhi ⚠️ installed and loaded (launchd; logs: …) Registered, but no proxy is answering on port 10100. launchd is running an OLDER plist than the one on disk. - Fix: launchctl bootout gui/$(id -u)/com.opencodex.proxy && ocx service repair - Log: ~/.opencodex/service.log - Repair: ocx service repair - Meanwhile: ocx start (serves in the foreground) + Fix: launchctl bootout gui/$(id -u)/com.codexcommander.proxy && ccx service repair + Log: ~/.codexcommander/service.log + Repair: ccx service repair + Meanwhile: ccx start (serves in the foreground) ``` It no longer prints the raw `launchctl list` / `systemctl status` line, which @@ -264,28 +258,28 @@ stderr while exiting 0, so a load that did not take used to leave launchd runnin `install` now fails loudly in that case and names the `launchctl bootout` command that clears the stale job. -On Windows, `ocx service status` reports Task Scheduler registration separately from -identity-verified OpenCodex proxy reachability. It does not print the localized `schtasks` table, +On Windows, `ccx service status` reports Task Scheduler registration separately from +identity-verified CodexCommander proxy reachability. It does not print the localized `schtasks` table, so the summary remains readable across Windows code pages. On Windows, creating the Task Scheduler entry requires elevation. Recognized localized access-denied text keeps the existing guidance path. If that text is unreadable, the fallback -requires the owned command shape `/create /tn opencodex-proxy /xml <non-empty-path> /f`, status 1, +requires the owned command shape `/create /tn codexcommander-proxy /xml <non-empty-path> /f`, status 1, and a confirmed non-elevated token; the dashboard's Startup Safety action can then request UAC automatically. If that fallback cannot determine the token state, it retains the original scheduler error. Foreign tasks and operations can never emit the automatic-elevation marker. Approve the -dashboard UAC prompt or rerun `ocx service install` in an elevated PowerShell window. +dashboard UAC prompt or rerun `ccx service install` in an elevated PowerShell window. -### `ocx codex-shim <install|status|uninstall|remove>` +### `ccx codex-shim <install|status|uninstall|remove>` Wrap a script-based `codex` launcher on PATH with a lightweight autostart script. Real `codex.exe` targets are left untouched to avoid breaking exact executable invocations. -If a completed external Codex update overwrites an installed shim, the next ordinary `ocx` command +If a completed external Codex update overwrites an installed shim, the next ordinary `ccx` command backs up the stable new launcher and restores the shim before dispatch. A launcher that is still changing is left untouched and retried later. Repair failures warn without failing the requested -command; manual fallback: `ocx codex-shim install`. Set `codexShimAutoRestore` to `false`, or set -`OPENCODEX_CODEX_SHIM_AUTO_RESTORE=0` for a process-level opt-out. +command; manual fallback: `ccx codex-shim install`. Set `codexShimAutoRestore` to `false`, or set +`CODEXCOMMANDER_CODEX_SHIM_AUTO_RESTORE=0` for a process-level opt-out. | Subcommand | Action | | --- | --- | @@ -295,17 +289,17 @@ command; manual fallback: `ocx codex-shim install`. Set `codexShimAutoRestore` t | `status` | Report shim state (installed, stale, or missing). | ```bash -ocx codex-shim install -ocx codex-shim status -ocx codex-shim uninstall +ccx codex-shim install +ccx codex-shim status +ccx codex-shim uninstall ``` :::tip[Service vs Shim] -Use `ocx service` for an always-on background proxy (recommended). Use `ocx codex-shim` for +Use `ccx service` for an always-on background proxy (recommended). Use `ccx codex-shim` for lightweight, on-demand startup without a daemon — the proxy starts only when `codex` is launched. ::: -### `ocx tray <install|start|stop|status|uninstall|remove> [--json] [--no-start]` +### `ccx tray <install|start|stop|status|uninstall|remove> [--json] [--no-start]` Install and control the Windows status tray icon. It starts at Windows login and provides one-click proxy controls. `start` and `stop` control the icon only; use its menu to control the proxy. @@ -313,25 +307,7 @@ proxy controls. `start` and `stop` control the icon only; use its menu to contro ## Dashboard -### `ocx gui` +### `ccx gui` Open the [web dashboard](/guides/web-dashboard/) at `http://localhost:<port>`, auto-starting the proxy if it is not running. - -## Updating - -### `ocx update [--tag latest|preview]` - -Self-update opencodex from npm. Stable installs use `@latest`; preview installs stay on `@preview` -unless you pass `--tag latest|preview`. It detects a source checkout and tells you to -`git pull && bun install` instead, and is a no-op if you are already on the newest version for that -tag. A running proxy is stopped before files are replaced; an installed service is rebuilt and -started automatically, while a foreground installation prints `ocx start` as the next step. - -```bash -ocx update -ocx update --tag preview -``` - -New versions become available when the [Release workflow](https://github.com/lidge-jun/opencodex/actions/workflows/release.yml) -publishes them to npm. diff --git a/docs-site/src/content/docs/reference/cli/providers-accounts.md b/docs-site/src/content/docs/reference/cli/providers-accounts.md index dc2ae7cdcc..d95707b705 100644 --- a/docs-site/src/content/docs/reference/cli/providers-accounts.md +++ b/docs-site/src/content/docs/reference/cli/providers-accounts.md @@ -7,7 +7,7 @@ These commands configure upstream providers, authenticate accounts, manage crede ## Providers -### `ocx provider <subcommand>` +### `ccx provider <subcommand>` Non-interactive provider management. Registry entries are seeded by name; a custom name requires both `--adapter` and `--base-url`. @@ -27,13 +27,13 @@ both `--adapter` and `--base-url`. | `account-mode` | `pool`, `direct`, `--json` | Select pooled or direct Codex account routing. | ```bash -ocx provider list --json -ocx provider test ark -ocx provider add anthropic --api-key sk-ant-... --set-default --sync -ocx provider add local-dev --adapter openai-chat --base-url http://localhost:11434/v1 -ocx provider show anthropic --json -ocx models --provider anthropic --json -ocx models live --provider ark --json +ccx provider list --json +ccx provider test ark +ccx provider add anthropic --api-key sk-ant-... --set-default --sync +ccx provider add local-dev --adapter openai-chat --base-url http://localhost:11434/v1 +ccx provider show anthropic --json +ccx models --provider anthropic --json +ccx models live --provider ark --json ``` :::caution[Custom headers are not a credential channel] @@ -57,39 +57,39 @@ Use `--api-key` or an OAuth login for anything secret. ## Authentication -### `ocx login <provider>` +### `ccx login <provider>` Start the provider's registered login flow. Depending on the provider, OAuth login opens a browser -or imports/links a signed-in native CLI session. OpenCodex-owned credentials stored under -`~/.opencodex/` refresh automatically; linked Grok/Kimi CLI access generations are adopted +or imports/links a signed-in native CLI session. CodexCommander-owned credentials stored under +`~/.codexcommander/` refresh automatically; linked Grok/Kimi CLI access generations are adopted read-only and the native CLI remains responsible for renewal. API-key login providers open their key dashboard, prompt for the key, validate it when possible, and save the resulting provider config. The command prints the currently accepted OAuth and API-key provider ids when the name is missing or unknown. -Use the same command to **reauthenticate** after `ocx status` / `ocx doctor` reports +Use the same command to **reauthenticate** after `ccx status` / `ccx doctor` reports reauthentication required or a terminal refresh failure (or use Reauthenticate in the dashboard). -Codex pool accounts are not a public `ocx login` provider — reauthenticate via the dashboard Codex -account pool (Reauthenticate) or the headless `ocx account reauth` flow instead. +Codex pool accounts are not a public `ccx login` provider — reauthenticate via the dashboard Codex +account pool (Reauthenticate) or the headless `ccx account reauth` flow instead. ```bash -ocx login xai -ocx login anthropic +ccx login xai +ccx login anthropic ``` -### `ocx logout <provider>` +### `ccx logout <provider>` Remove the stored OAuth credential for a provider. ## Accounts and key pools -### `ocx account <subcommand>` +### `ccx account <subcommand>` List and switch provider accounts and API-key pools through the running proxy. The shipped help surface is: ```text -Usage: ocx account <list|current|use|refresh|auto-switch|priority|login|reauth|code|cancel|remove|add-key|reset-credits> ... +Usage: ccx account <list|current|use|refresh|auto-switch|priority|login|reauth|code|cancel|remove|add-key|reset-credits> ... list [provider] Codex account pool, OAuth accounts and API keys (identifiers shown masked as the API returns them). current <provider> Show the active account or key. @@ -131,7 +131,7 @@ and the plan/label column falls back across plan, masked email, label, and maske } ``` -### `ocx account list [provider] [--json] [--all]` +### `ccx account list [provider] [--json] [--all]` Without a provider, lists the Codex pool, OAuth accounts, and configured API-key pools. Empty providers are skipped unless `--all` is present. With a provider, lists only that credential family. @@ -145,7 +145,7 @@ returns: { accounts: AccountRow[], notes: string[] } ``` -### `ocx account current <provider> [--json]` +### `ccx account current <provider> [--json]` Shows the active account or key. A Codex pool with no manual pin reports the priority-aware automatic selection: the highest-priority eligible tier is chosen, and the lowest-usage account @@ -156,7 +156,7 @@ that state and still exits 0. `--json` returns: { provider, type, activeId: string | null, autoSwitchThreshold?: number, account: AccountRow | null } ``` -### `ocx account use <provider> <account-or-key-id|main> [--json]` +### `ccx account use <provider> <account-or-key-id|main> [--json]` Selects an existing Codex account, OAuth account, or API key. For `openai`, `main` selects the Codex App login. A Codex Pool selection clears process-local affinity and applies to the next request, @@ -165,10 +165,10 @@ unbound, while in-flight requests keep their captured account. This controls Poo Direct mode keeps using the caller-owned/native main credential. Usage-based proactive switching, 401/403 reauthentication, 429/retry-after cooldowns, exclusion, and pre-output 429/402 failure recovery may later select another eligible Pool account. Those recovery paths remain active when -usage-based switching is off. OpenCodex replays the conversation after an account change, but the +usage-based switching is off. CodexCommander replays the conversation after an account change, but the provider-side prompt cache may be cold. Unknown providers or ids exit 1. On a **401/403**, App login clears that account's process-local affinity and requires reauthentication. -On a **429**, opencodex honors `Retry-After`, starts the account cooldown, clears affinity, and may +On a **429**, CodexCommander honors `Retry-After`, starts the account cooldown, clears affinity, and may rotate the request to another eligible Pool account. These failure transitions remain active with `autoSwitchThreshold: 0`; that setting disables only usage-based proactive switching. `--json` returns: @@ -177,9 +177,9 @@ rotate the request to another eligible Pool account. These failure transitions r { ok: true, provider, type, activeId } ``` -### `ocx account refresh <provider> [--json]` +### `ccx account refresh <provider> [--json]` -For the Codex pool, use `ocx account refresh openai [--json]`. It force-refreshes account quotas and +For the Codex pool, use `ccx account refresh openai [--json]`. It force-refreshes account quotas and prints available weekly/monthly percentages and reset times; missing quota data is reported as unknown, not 0%. Its JSON envelope is `{ accounts: AccountRow[] }`, with `quota` on each Codex row. @@ -190,7 +190,7 @@ token re-login or a plain account-list re-read. `--json` returns failures exit 1; an upstream quota probe that fails or times out degrades to a null or stale report instead (exit 0), matching the dashboard's quota bars. -### `ocx account auto-switch <provider> <on|off|status|threshold <0-100>> [--json]` +### `ccx account auto-switch <provider> <on|off|status|threshold <0-100>> [--json]` Controls only the `openai` Codex account pool. `on` sets 80%, `off` sets 0%, `status` reads the current value, and `threshold <n>` accepts an integer from 0 through 100. Other providers and invalid values @@ -200,12 +200,12 @@ exit 1. `--json` returns: { provider, autoSwitchThreshold: number, enabled: boolean } ``` -### `ocx account priority <provider> <account-id|main> [<-100..100|first|earlier|normal|later|last|reset>] [--json]` +### `ccx account priority <provider> <account-id|main> [<-100..100|first|earlier|normal|later|last|reset>] [--json]` Reads or sets one Codex pool account's selection order: **higher is used earlier**, the default is `0`, and the range is `-100` through `100`. Only the `openai` Codex pool is ordered, so other providers exit 1. `main` targets the Codex Desktop login, which is ordered like any other pool -account — `ocx account priority openai main last` is how you keep it as the reserve. +account — `ccx account priority openai main last` is how you keep it as the reserve. Preset words stand in for small integers: `first` is `+2`, `earlier` is `+1`, `normal` is `0`, `later` is `-1`, and `last` is `-2`. `reset` returns the account to the default and drops its stored @@ -228,12 +228,12 @@ unknown account id, or a value outside the accepted set exits 1. `--json` return { ok: true, provider, id, priority: number, preset: string | null } ``` -### `ocx account login|reauth|code|cancel ...` +### `ccx account login|reauth|code|cancel ...` Run browser-based or manual-code account authentication from a headless shell. Use -`ocx account --help` for the provider-specific command shape. +`ccx account --help` for the provider-specific command shape. -### `ocx account remove <provider> <id|main> --yes [--json]` +### `ccx account remove <provider> <id|main> --yes [--json]` This guarded, non-interactive deletion requires `--yes`. Before deleting, it verifies that the id exists; a missing id exits 1 without sending DELETE. The main Codex App login cannot be removed, so @@ -247,35 +247,35 @@ success and failure shapes are: { error: string } // stderr, exit 1 ``` -### `ocx account add-key <provider> [--label <label>] [--json]` +### `ccx account add-key <provider> [--label <label>] [--json]` Adds and activates a key for an API-key provider. The key is read only from non-TTY piped/redirected stdin; interactive TTY input, empty input, OAuth/Codex providers, and API failures exit 1. The key is never echoed, including when it appears inside a label. Prefer a secret manager or a here-string: ```bash -ocx account add-key openrouter --label personal <<< "$OPENROUTER_API_KEY" -security find-generic-password -w openrouter | ocx account add-key openrouter --json +ccx account add-key openrouter --label personal <<< "$OPENROUTER_API_KEY" +security find-generic-password -w openrouter | ccx account add-key openrouter --json ``` `--json` returns `{ ok: true, id: string | null, label?: string }` and never includes the key. -### `ocx account reset-credits <id|main> [--consume --yes]` +### `ccx account reset-credits <id|main> [--consume --yes]` Inspect Codex reset credits for an account. Consuming a credit is destructive and requires both `--consume` and `--yes`. -### `ocx account main <subcommand>` +### `ccx account main <subcommand>` -Manage named native Codex main-login profiles without changing OpenCodex account-pool routing: +Manage named native Codex main-login profiles without changing CodexCommander account-pool routing: ```text -ocx account main doctor [--json] -ocx account main list [--json] -ocx account main register <label> [--json] -ocx account main add <label> -ocx account main switch <profile-id-or-label> --yes [--json] -ocx account main recover [--rollback --yes] [--json] +ccx account main doctor [--json] +ccx account main list [--json] +ccx account main register <label> [--json] +ccx account main add <label> +ccx account main switch <profile-id-or-label> --yes [--json] +ccx account main recover [--rollback --yes] [--json] ``` Each mutating command reports the canonical effective `CODEX_HOME` returned by the running proxy. @@ -289,38 +289,29 @@ successful switch preserves local tasks and history, then requires Codex to be r `doctor` to inspect profile state and `recover` to finish or roll back an interrupted transition. `switch` accepts either the profile ID or its label. -The v1 recovery matrix covers an OpenCodex process exiting after a transaction file has been +The v1 recovery matrix covers a CodexCommander process exiting after a transaction file has been published by rename. It does not claim durability across an OS or kernel crash or sudden power loss: `atomicWriteFileAsync()` does not `fsync` either the file or its parent directory. The encrypted vault, switch journal, recovery marker, and journal quarantine live in the canonical -`<real CODEX_HOME>/.opencodex-native-main-profiles` directory, so every OpenCodex instance sharing +`<real CODEX_HOME>/.codexcommander-native-main-profiles` directory, so every CodexCommander instance sharing that Codex home observes one owner and one recovery state. Plaintext login staging remains isolated -under each `<OPENCODEX_HOME>/native-main-profile-staging` directory. +under each `<CODEXCOMMANDER_HOME>/native-main-profile-staging` directory. Before native-main traffic or journal recovery is admitted, the lifetime owner takes the exclusive -credential claim and removes only exact `auth.json.ocx.<pid>.<sequence>.tmp` crash residues. Each +credential claim and removes only exact `auth.json.ccx.<pid>.<sequence>.tmp` crash residues. Each candidate must remain a single-linked regular file under the unchanged canonical `CODEX_HOME`; it is truncated, flushed, and then unlinked. Link/reparse substitutions, identity changes, and other ambiguity keep native-main traffic closed, while near-miss names are never removed automatically. -This protects against cooperative OpenCodex crashes, not a malicious process already running as the +This protects against cooperative CodexCommander crashes, not a malicious process already running as the same OS user. That user and the filesystem containing `CODEX_HOME` remain trusted, and truncation does not promise physical erasure from copy-on-write storage, snapshots, or SSD remanence. -Preview builds used `<OPENCODEX_HOME>/native-main-profiles`. That layout is never imported silently. -If `doctor` reports legacy profile state, stop every OpenCodex proxy sharing the same `CODEX_HOME`. -Then either back up and move the matching `*.vault.json`, `*.journal.json`, recovery marker, and any -referenced journal-quarantine file together into the canonical directory while preserving owner-only -permissions, or remove the old preview set and run `ocx account main register` again. Do not choose -between multiple old roots or run both layouts while any sharing proxy is active. -On Windows, preview state keyed by the former case-folded home identity must be reset rather than -moved because its encrypted AAD and operating-system keyring identity are intentionally not reused. - ## Models -### `ocx models [subcommand]` · `ocx model <subcommand>` +### `ccx models [subcommand]` · `ccx model <subcommand>` -`ocx model` is an alias of `ocx models`. With no subcommand, list the models statically seeded in +`ccx model` is an alias of `ccx models`. With no subcommand, list the models statically seeded in configured providers. `--provider` filters one configured provider and `--json` returns model metadata. `live` reads the running catalog; `add`, `edit`, `remove`, and `list-custom` manage manual catalog entries; `enable`, `disable`, and `provider` control visibility; `selected` controls a @@ -330,7 +321,7 @@ shadow-call interception. Every per-model operation the dashboard offers is available here, so a headless install never needs the GUI to manage a catalog. `add`, `remove`, and `list-custom` work against the config file and apply to a running proxy through a catalog sync; the rest talk to the live management API and require the -proxy to be running (`ocx start`, or an installed service). +proxy to be running (`ccx start`, or an installed service). | Subcommand | Supported flags | Action | | --- | --- | --- | @@ -345,18 +336,18 @@ proxy to be running (`ocx start`, or an installed service). | `provider <name> <on\|off>` | `--json` | Enable or disable every model of one provider in a single write. | | `selected <provider>` | `--set <id,id...>`, `--clear`, `--json` | Read or replace the provider model allowlist. `--clear` removes the allowlist so every model is offered. | | `context <status\|value <tokens>\|provider <name> <on\|off>\|all <on\|off>>` | `--json` | Read or set the context-window cap, globally or per provider. | -| `shadow <status\|set> [model\|-]` | `--enabled <on\|off>`, `--json` | Read or set the replacement model for Codex's background helper calls. `-` clears the model. `status` also reports `sourceModels`, the helper slugs the proxy intercepts (default: `gpt-5.6-luna`; clients through 0.144.x used `gpt-5.4-mini`, which an explicit `sourceModels` override can restore). | +| `shadow <status\|set> [model\|-]` | `--enabled <on\|off>`, `--json` | Read or set the replacement model for Codex's background helper calls. `-` clears the model. `status` also reports `sourceModels`, the helper slugs the proxy intercepts (default: `gpt-5.6-luna`; use an explicit override only for current custom helper ids). | ```bash -ocx models live --json # what Codex can actually see right now -ocx models disable anthropic/claude-haiku-4 # hide one routed model -ocx models enable gpt-5.6-sol # no slash, so it is treated as native -ocx models provider zenmux off # hide a noisy provider wholesale -ocx models selected anthropic --set claude-opus-5,claude-fable-5 -ocx models selected anthropic --clear # drop the allowlist again -ocx models add deepseek deepseek-v4 --display-name 'DeepSeek V4' --context-window 128000 --modalities text,image -ocx models list-custom --json # read the custom-id for edit/remove -ocx models remove deepseek/deepseek-v4 --yes +ccx models live --json # what Codex can actually see right now +ccx models disable anthropic/claude-haiku-4 # hide one routed model +ccx models enable gpt-5.6-sol # no slash, so it is treated as native +ccx models provider zenmux off # hide a noisy provider wholesale +ccx models selected anthropic --set claude-opus-5,claude-fable-5 +ccx models selected anthropic --clear # drop the allowlist again +ccx models add deepseek deepseek-v4 --display-name 'DeepSeek V4' --context-window 128000 --modalities text,image +ccx models list-custom --json # read the custom-id for edit/remove +ccx models remove deepseek/deepseek-v4 --yes ``` A model selector with a slash is routed (`anthropic/claude-opus-5`); a bare id is treated as a diff --git a/docs-site/src/content/docs/reference/configuration.md b/docs-site/src/content/docs/reference/configuration.md index 10844a5da5..c959b0c680 100644 --- a/docs-site/src/content/docs/reference/configuration.md +++ b/docs-site/src/content/docs/reference/configuration.md @@ -1,19 +1,19 @@ --- title: Configuration Reference -description: Where opencodex stores configuration, how edits are applied, and links to every configuration domain. +description: Where CodexCommander stores configuration, how edits are applied, and links to every configuration domain. --- -opencodex stores its persistent configuration in `$OPENCODEX_HOME/config.json`, normally -`~/.opencodex/config.json`. On Windows, the default is -`%USERPROFILE%\.opencodex\config.json`. +CodexCommander stores its persistent configuration in `$CODEXCOMMANDER_HOME/config.json`, normally +`~/.codexcommander/config.json`. On Windows, the default is +`%USERPROFILE%\.codexcommander\config.json`. ## Ways to edit configuration Choose the editing channel that fits the task: - **Dashboard:** use the web UI for guided provider, model, agent, access, and storage settings. -- **CLI:** `ocx init` creates the initial file, while commands such as `ocx provider`, `ocx models`, - `ocx combo`, `ocx agent`, and `ocx config` update or inspect their owned settings. +- **CLI:** `ccx init` creates the initial file, while commands such as `ccx provider`, `ccx models`, + `ccx combo`, `ccx agent`, and `ccx config` update or inspect their owned settings. - **File:** edit `config.json` directly for fields without a dedicated UI or CLI command. The file must remain valid JSON. @@ -23,14 +23,14 @@ later live save can rewrite unrelated hand edits from its snapshot. Live saves m `claudeCode` and listener-binding fields where those paths have explicit conflict protection, but that protection does not cover every subtree. -If the file cannot be parsed, opencodex backs it up as +If the file cannot be parsed, CodexCommander backs it up as `config.json.invalid-<timestamp>`, warns on the console, and starts with defaults. A missing file also uses the fresh-install default: one `openai` forward provider. ## Precedence and defaults Valid values in `config.json` override built-in defaults. Missing optional fields use the defaults -documented on the domain pages. `OPENCODEX_HOME` takes precedence over the default configuration +documented on the domain pages. `CODEXCOMMANDER_HOME` takes precedence over the default configuration directory. Fields that accept an environment reference, such as `apiKey: "${PROVIDER_API_KEY}"`, resolve that variable at request time. For outbound proxying, an already-set `HTTP_PROXY` or `HTTPS_PROXY` takes precedence over the top-level `proxy` field. @@ -56,8 +56,8 @@ stored in separate credential stores rather than in `config.json`. Account ids a remain private; use public selector aliases where supported. :::note[Atomic writes] -opencodex writes managed `config.toml` and `opencodex-catalog.json` files through a temporary file +CodexCommander writes managed `config.toml` and `codexcommander-catalog.json` files through a temporary file followed by rename (`atomicWriteFile`). -This prevents partial files when concurrent writers, such as `ocx stop` and the proxy shutdown handler, +This prevents partial files when concurrent writers, such as `ccx stop` and the proxy shutdown handler, restore Codex at the same time. ::: diff --git a/docs-site/src/content/docs/reference/configuration/agents.md b/docs-site/src/content/docs/reference/configuration/agents.md index 7f43051038..0b8f2fea92 100644 --- a/docs-site/src/content/docs/reference/configuration/agents.md +++ b/docs-site/src/content/docs/reference/configuration/agents.md @@ -3,7 +3,7 @@ title: Agent Configuration description: Multi-agent surfaces, delegation guidance, preferred models, fallback chains, native-default sync, and effort caps. --- -Agent settings control which Codex collaboration surface is advertised and how opencodex guides, +Agent settings control which Codex collaboration surface is advertised and how CodexCommander guides, routes, and limits delegated work. ## Agent fields @@ -12,20 +12,20 @@ routes, and limits delegated work. | --- | --- | --- | --- | | `multiAgentMode?` | `"v1" \| "default" \| "v2"` | `"default"` | `v1` stamps every catalog model as v1; `v2` stamps every model as v2. `default` restores upstream pins (Sol/Terra v2, Luna v1) and otherwise follows the native `multi_agent_v2` flag. Applies to new sessions. | | `multiAgentV2MessageDelivery?` | `"encrypted" \| "plaintext"` | `"encrypted"` | V2 parent-message delivery. `encrypted` preserves ChatGPT's reserved backend contract and native-only ciphertext guard. `plaintext` opts subsequent V2 parent requests into experimental mixed-provider compatibility; all delegated messages from that parent become plaintext, and routed parents receive the stock Codex plaintext marker on message-bearing collaboration calls. Start a new session after changing it. | -| `subagentModels?` | `string[]` | `gpt-5.5`, `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna`, `gpt-5.4-mini` | Up to five bare native, account-qualified `<selector>/<native-openai-model>`, or routed `provider/model` ids advertised first in the sub-agent picker. The dashboard preserves configured exact selectors, including account-qualified choices, and reports which saved entries are advertised or excluded. Use `ocx agent subagents set` or edit the configuration for choices that are not in the current catalog. An explicit empty list is preserved. | +| `subagentModels?` | `string[]` | `gpt-5.5`, `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna`, `gpt-5.4-mini` | Up to five bare native, account-qualified `<selector>/<native-openai-model>`, or routed `provider/model` ids advertised first in the sub-agent picker. The dashboard preserves configured exact selectors, including account-qualified choices, and reports which saved entries are advertised or excluded. Use `ccx agent subagents set` or edit the configuration for choices that are not in the current catalog. An explicit empty list is preserved. | | `injectionModel?` | `string` | — | Preferred native or routed sub-agent model used in proxy-authored v2 delegation guidance. | | `injectionEffort?` | `string` | — | Preferred effort (`low` through `ultra`), meaningful only with `injectionModel`. | | `injectionPrompt?` | `string` | — | Replaces the built-in v2 guidance body. Supports `{{model}}`, `{{effort}}`, `{{roster}}`, and `{{fallback}}`. A configured `injectionModel` is sufficient to render the custom prompt. | -| `multiAgentGuidanceEnabled?` | `boolean` | `true` | Controls only opencodex-authored v1/v2 developer guidance; it does not change native agent defaults, tools, routing, rosters, or effort caps. | +| `multiAgentGuidanceEnabled` | `boolean` | `true` | Controls only CodexCommander-authored v1/v2 developer guidance; it does not change native agent defaults, tools, routing, rosters, or effort caps. | | `syncCodexSubagentDefaults?` | `boolean` | `false` | Opt into writing `injectionModel` and optional `injectionEffort` as Codex's native defaults during sync/restart. Requires `injectionModel`. | | `subagentModelFallback?` | `string[]` | `[]` | Priority-ordered global fallback models for spawned child turns. | | `subagentModelFallbackPollMs?` | `number` | `60000` | Availability-probe cache interval. Values below 1000 ms fall back to the default. | | `effortCap?` | `string` | — | Hard ceiling for qualifying v2 main turns and marked spawned-child turns. Accepts `low` through `ultra`. | | `subagentEffortCap?` | `string` | — | Additional ceiling for spawned-child turns only. When both caps apply, the lower wins. | -Manage the surface with the dashboard or `ocx v2 status|on|off|mode <v1|default|v2>|threads <n>`. +Manage the surface with the dashboard or `ccx v2 status|on|off|mode <v1|default|v2>|threads <n>`. Mode changes apply to new sessions. `maxConcurrentThreadsPerSession` is a `PUT /api/v2` field, not a -`config.json` key; `ocx v2 threads <n>` writes `max_concurrent_threads_per_session` under +`config.json` key; `ccx v2 threads <n>` writes `max_concurrent_threads_per_session` under `[features.multi_agent_v2]` in Codex's `$CODEX_HOME/config.toml` after v2 is enabled. The management API exposes `GET`/`PUT /api/v2`, `/api/injection-model`, `/api/effort-caps`, @@ -77,7 +77,7 @@ Spawned-child fallback order is: 2. role-level `model_fallback` from `$CODEX_HOME/agents/*.toml`; then 3. global `subagentModelFallback` entries. -opencodex skips disabled, unroutable, unhealthy, cooling-down, or quota-threshold candidates. The +CodexCommander skips disabled, unroutable, unhealthy, cooling-down, or quota-threshold candidates. The availability snapshot is cached for `subagentModelFallbackPollMs`. Under encrypted delivery, child tasks can restrict the chain to canonical native ChatGPT targets; if none can read the encrypted payload, the request fails instead of routing unreadable ciphertext elsewhere. A recognized plaintext-compatibility @@ -106,7 +106,7 @@ if leaf tools no longer expose collaboration. V1 main turns, `multiAgentMode: "v review, and memory-consolidation turns bypass caps. Caps only lower effort. They snap to the highest advertised rung at or below the cap. If a model has -no effort control or no supported rung fits, opencodex removes the effort and lets the provider default +no effort control or no supported rung fits, CodexCommander removes the effort and lets the provider default apply. `max` and `ultra` are accepted, while the dashboard offers `low` through `xhigh`. For a beginner-oriented explanation of v1, default, and v2 behavior, see diff --git a/docs-site/src/content/docs/reference/configuration/providers.md b/docs-site/src/content/docs/reference/configuration/providers.md index c5ba425f22..00f2df8037 100644 --- a/docs-site/src/content/docs/reference/configuration/providers.md +++ b/docs-site/src/content/docs/reference/configuration/providers.md @@ -3,15 +3,14 @@ title: Provider Configuration description: Provider entries, authentication, endpoints, model catalogs, quotas, context caps, and provider-specific options. --- -A provider tells opencodex where a model lives, which wire adapter it speaks, and how requests are +A provider tells CodexCommander where a model lives, which wire adapter it speaks, and how requests are authenticated. ## Provider-related top-level fields | Field | Type | Default | Meaning | | --- | --- | --- | --- | -| `providers` | `Record<string, OcxProviderConfig>` | — | Map of provider name to provider config. | -| `openaiProviderTierVersion?` | `2` | set by migration | Marks the single option-aware OpenAI projection as complete. | +| `providers` | `Record<string, CodexCommanderProviderConfig>` | — | Map of provider name to provider config. | | `disabledModels?` | `string[]` | — | Models hidden from Codex's catalog and `/v1/models`, but not blocked from direct proxy calls. A routed id is removed from listings. An account-qualified native id hides only that selector row; a bare native GPT id hides the bare row and every account-selector row for that model. The dashboard Models page exposes only routed and bare native rows; use this configuration field directly to hide one selector-qualified row. | | `providerContextCaps?` | `Record<string, number>` | `{}` | Per-provider Codex-visible context caps. A cap only lowers a known context window. | | `contextCapValue?` | `number` | `350000` | Value used by the dashboard context-cap controls; changing it updates every enabled `providerContextCaps` entry. | @@ -19,7 +18,7 @@ authenticated. | `pausedCodexAccountIds?` | `string[]` | `[]` | Accounts excluded from Pool selection until resumed, including the main `__main__` account when paused. | | `codexAccountNamespaces?` | `Record<string, string>` | — | Optional map from an arbitrary public model selector to a stored Codex account target. Each selector whose target is present adds separate `<selector>/<native-openai-model>` rows to the Codex picker; each row uses only that account. With any selector active, bare native rows are hidden in the picker, but their ids remain routable and listed by raw `/v1/models` unless explicitly disabled. | | `activeCodexAccountId?` | `string` | — | Manually selected Pool account for the next request. Selection clears thread affinity; in-flight requests keep captured credentials. | -| `codexAccountPriorities?` | `Record<string, number>` | — | Per-account selection order for the Codex pool: account id → integer from `-100` to `100`, **higher is used earlier**, absent means `0`. This is an ordering boundary, not an eligibility one: selection narrows the already-eligible accounts to the highest tier that still has quota headroom, and `accountPoolStrategy` then picks within that tier. A tier is skipped only when every member is over `autoSwitchThreshold`, cooling down, soft-avoided, paused, or needs reauthentication — unknown quota never drains a tier. Ordering never makes an ineligible account selectable and never re-binds a thread that already has an account. The main `__main__` account participates on equal terms, which is how the Codex Desktop login can be set to drain last. With no entries the pool behaves exactly as before. A malformed map is ignored with a console warning (ordering off, no config repair). Managed by `ocx account priority` and the Codex Auth page. | +| `codexAccountPriorities?` | `Record<string, number>` | — | Per-account selection order for the Codex pool: account id → integer from `-100` to `100`, **higher is used earlier**, absent means `0`. This is an ordering boundary, not an eligibility one: selection narrows the already-eligible accounts to the highest tier that still has quota headroom, and `accountPoolStrategy` then picks within that tier. A tier is skipped only when every member is over `autoSwitchThreshold`, cooling down, soft-avoided, paused, or needs reauthentication — unknown quota never drains a tier. Ordering never makes an ineligible account selectable and never re-binds a thread that already has an account. The main `__main__` account participates on equal terms, which is how the Codex Desktop login can be set to drain last. With no entries the pool behaves exactly as before. A malformed map is ignored with a console warning (ordering off, no config repair). Managed by `ccx account priority` and the Codex Auth page. | | `activeCodexAccountPinned?` | `string` | — | Account id the operator last selected by hand. While set, a higher `codexAccountPriorities` tier cannot preempt it until the pin is released by drain, exclusion, deletion, or an explicit failover/promotion away. Ordinary round-robin movement inside the capped tier does not release it. Writing any `codexAccountPriorities` entry also releases the pin, so a pin made before an order existed cannot outrank one set afterward. `GET /api/codex-auth/active` reports both whether the effective account is pinned (`pinned`) and the account carrying the ceiling (`pinnedAccountId`). | | `autoSwitchThreshold?` | `number` | `80` | Usage threshold for proactive switching. `quota` can re-evaluate both bound and unbound tasks on their next request; `fill-first` uses it only as the drain point for unbound assignment; normal `round-robin` selection does not use it. The score uses the hottest known 5h, weekly, or 30d quota window. `0` disables usage-based proactive switching only, not unbound assignment or failure recovery. | | `accountPoolStrategy?` | `"quota" \| "round-robin" \| "fill-first"` | `"quota"` | Assignment strategy for new/unbound Codex requests. A request is unbound when it has no live (parent thread id, quota scope) affinity; a visible existing task can become unbound after proxy restart or affinity reset. `quota` picks the lowest-usage eligible account when no active account exists, keeps an eligible active account below `autoSwitchThreshold`, and after the threshold may move an unbound request or proactively rebind a bound task to a lower-usage eligible account. `round-robin` distributes unbound requests evenly; `fill-first` keeps assigning unbound requests to the active account until cooldown, unavailability, or the configured drain threshold. | @@ -27,9 +26,9 @@ authenticated. | `upstreamFailoverThreshold?` | `number` | `3` | Consecutive transient failures before future new sessions fail over. Set `0` to disable. Proven pre-connection DNS/TCP reachability failures are tracked at the provider-host level: they never affect account health, cooldowns, thread/session affinity, active-account selection, or Pool routing, and never count toward this threshold. | | `modelCacheTtlMs?` | `number` | `300000` | Freshness window for the per-provider `/models` cache. | | `cacheRetention?` | `"none" \| "short" \| "long"` | `"short"` | Anthropic prompt-cache policy: disabled, 5-minute ephemeral, or 1-hour extended. | -| `tokenGuardian?` | `OcxTokenGuardianConfig` | off | Optional proactive OAuth refresh and Codex-account warmup policy. | +| `tokenGuardian?` | `CodexCommanderTokenGuardianConfig` | off | Optional proactive OAuth refresh and Codex-account warmup policy. | -Selector names are user-chosen public labels; opencodex assigns no account-role semantics to them. +Selector names are user-chosen public labels; CodexCommander assigns no account-role semantics to them. `codexAccountNamespaces` keys are 1–64 characters, starting and ending with an ASCII letter or number, with letters, numbers, `.`, `_`, or `-` inside. Reserved JavaScript object names are rejected. Each value is a valid pool-account id (never internal `__main__`) or `"@main"` @@ -47,19 +46,15 @@ API uses only its configured API key or key pool. Use a bare model or `openai-ap is no cross-route credential fallback. API GPT-5.6 rows carry 1,050,000 context / 922,000 max input metadata, and Pro virtual ids rewrite to the base wire model with `reasoning.mode: "pro"`. -`openaiProviderTierVersion: 2` marks the current single-provider projection. Before migrating a -shipped v1 config, opencodex creates `config.json.pre-openai-tiers-v2.bak` without replacing a -differing backup and rewrites known legacy namespaced selected ids to bare ids. - -## Provider entries (`OcxProviderConfig`) +## Provider entries (`CodexCommanderProviderConfig`) | Field | Type | Meaning | | --- | --- | --- | -| `adapter` | `string` | One of `openai-chat`, `openai-responses`, `anthropic`, `google`, `kiro`, `cursor`, `azure-openai` (or alias `azure`). | +| `adapter` | `string` | One of `openai-chat`, `openai-responses`, `anthropic`, `google`, `kiro`, `cursor`, or `azure-openai`. | | `baseUrl` | `string` | Upstream API base URL. Most built-in fixed endpoints ignore a mismatch; collision-safe key presets preserve an older same-named custom destination. | | `responsesPath?` | `string` | Relative resource path for key-auth `openai-responses` requests. It must start with `/` and contain no scheme, query, or fragment. | | `supportsServiceTier?` | `boolean` | Tri-state `service_tier` capability. `true`: fast mode may inject and caller values are preserved. `false`: the field is stripped and never injected (the upstream documented as not supporting it must not receive it). Absent: the provider is unclassified — caller-supplied values are preserved untouched and fast mode never injects. The registry classifies canonical OpenAI (`true`), DeepSeek, and Volcengine Ark (`false`); set it explicitly only for custom gateways that genuinely support tiers. | -| `preserveResponsesReasoningContent?` | `boolean` | Keep plaintext reasoning content on replayed Responses reasoning items instead of blanking it (blanking is the ChatGPT backend's rule). Enable for upstreams whose contract accepts reasoning replay, such as DeepSeek. Proxy-minted `ocxr1` envelopes are always stripped. | +| `preserveResponsesReasoningContent?` | `boolean` | Keep plaintext reasoning content on replayed Responses reasoning items instead of blanking it (blanking is the ChatGPT backend's rule). Enable for upstreams whose contract accepts reasoning replay, such as DeepSeek. Proxy-minted `ccxr1` envelopes are always stripped. | | `disabled?` | `boolean` | Keep the provider on disk but exclude it from routing and model/catalog listings. | | `apiKey?` | `string` | API key, or an `${ENV_VAR}` / `$ENV_VAR` reference resolved at request time. | | `apiKeyTransport?` | `"x-api-key" \| "bearer"` | Anthropic key header style. Defaults to native `x-api-key`; valid only for key-auth `anthropic` providers. | @@ -111,23 +106,22 @@ differing backup and rewrites known legacy namespaced selected ids to bare ids. | `location?` | `string` | Vertex location; environment fallback is `GOOGLE_CLOUD_LOCATION`. | | `mcpServers?` | `Record<string, CursorMcpServerConfig>` | Cursor only: stdio or Streamable HTTP MCP servers. | | `desktopExecutor?` | `DesktopExecutorConfig` | Cursor only: external computer-use and record-screen commands. | -| `unsafeAllowNativeLocalExec?` | `boolean` | Cursor legacy boolean, equivalent to `nativeLocalExec: "on"` only when the newer field is unset. | -| `nativeLocalExec?` | `"off" \| "codex-sandbox" \| "on"` | Cursor local-exec policy. `off` is default; `codex-sandbox` currently fails closed like `off`. | +| `nativeLocalExec?` | `"off" \| "on"` | Cursor local-exec policy. `off` is the default. | API-key providers may hold a literal key or an environment reference. OAuth providers use the -credential store populated by `ocx login`; subscription-backed Claude Code launch behavior is +credential store populated by `ccx login`; subscription-backed Claude Code launch behavior is configured under [`claudeCode.authMode`](/reference/configuration/server/#claude-code). ## Provider diagnostic outbound safety Dashboard connection tests and live model discovery use a bounded GET-only transport. Without an -outbound proxy, opencodex resolves the hostname once and connects only to that validated address. +outbound proxy, CodexCommander resolves the hostname once and connects only to that validated address. HTTPS retains the original Host, SNI, and certificate verification; provider config cannot disable certificate checks. When `HTTP_PROXY`, `HTTPS_PROXY`, or `ALL_PROXY` applies, these operations keep Bun's native fetch. URL and literal-address checks still run, but the proxy chooses the final route, DNS answer, and peer, -so opencodex cannot pin or verify that peer. This is an explicit security limitation. +so CodexCommander cannot pin or verify that peer. This is an explicit security limitation. Private/local destinations require `allowPrivateNetwork: true` and, when an outbound proxy is active, a matching `NO_PROXY` entry. Loopback is added automatically; list each LAN host explicitly because @@ -151,7 +145,7 @@ changes preserve and replay the conversation context, but provider-side prompt-c accounts is not guaranteed and the cache may need to warm again. On a **401/403**, App login clears that account's process-local affinity and requires reauthentication. -On a **429**, opencodex honors `Retry-After`, starts the account cooldown, clears affinity, and may +On a **429**, CodexCommander honors `Retry-After`, starts the account cooldown, clears affinity, and may rotate the request to another eligible Pool account. These failure transitions remain active with `autoSwitchThreshold: 0`; that setting disables only usage-based proactive switching. @@ -189,7 +183,7 @@ as needing reauthentication. If all eligible accounts are cooling, clients recei :::caution[Experimental] Leave this disabled unless you understand Anthropic account policy risk. Prefer manual -`ocx account use anthropic <id>` switching when unsure. +`ccx account use anthropic <id>` switching when unsure. ::: ### Managed record shapes @@ -198,7 +192,7 @@ Leave this disabled unless you understand Anthropic account policy risk. Prefer `codexAccounts[]` entries require `id`, `email`, and `isMain`, with optional `plan`, `chatgptAccountId`, and privacy-safe `logLabel`. These records are normally dashboard-managed. -### `tokenGuardian` (`OcxTokenGuardianConfig`) +### `tokenGuardian` (`CodexCommanderTokenGuardianConfig`) | Field | Type | Default | Meaning | | --- | --- | --- | --- | @@ -227,7 +221,7 @@ wins over configured `baseUrl`. Four entry types keep the configured URL: Adapters can adjust the resolved URL afterward. Kiro, for example, follows the imported credential's API region for canonical `runtime.{region}.kiro.dev`. See [Adapters](/reference/adapters/). -When routing discards `baseUrl`, opencodex logs the registry endpoint and only the configured origin; +When routing discards `baseUrl`, CodexCommander logs the registry endpoint and only the configured origin; a configured path may itself contain a credential. Remove the unused URL or choose the provider entry matching the intended region. `alibaba-token-plan` is pinned to Beijing, while `alibaba-token-plan-intl` covers international endpoints. @@ -256,7 +250,7 @@ so passthrough stays byte-for-byte identical. ## Cursor provider (`adapter: "cursor"`) -The Cursor bridge is experimental. After `ocx login cursor`, add or edit `providers.cursor`. +The Cursor bridge is experimental. After `ccx login cursor`, add or edit `providers.cursor`. Cursor Router's optimization ladder is exposed as separate Codex ids because the picker cannot render Cursor-specific model parameters: @@ -276,9 +270,6 @@ Cursor server-driven local tools are disabled by default. Codex continues using - `"off"` (default) rejects Cursor-native `read`, `write`, `delete`, `ls`, `grep`, `shell`, and `fetch` execution. - `"on"` opts into trusted-local execution and bypasses Codex approval/sandbox semantics. -- `"codex-sandbox"` is retained for compatibility but fails closed like `"off"`; request prose is - not trustworthy sandbox attestation. - ```json { "providers": { @@ -294,9 +285,8 @@ Cursor server-driven local tools are disabled by default. Codex continues using ``` Set the field on `providers.cursor`, not at the top level. In the dashboard use **Providers → Cursor -→ Edit JSON**, save, then restart. Legacy `unsafeAllowNativeLocalExec: true` equals -`nativeLocalExec: "on"` only when `nativeLocalExec` is unset. MCP, screen recording, and computer use -are controlled separately by `mcpServers` and `desktopExecutor`. +→ Edit JSON**, save, then restart. MCP, screen recording, and computer use are controlled separately +by `mcpServers` and `desktopExecutor`. Each `mcpServers.<name>` accepts either `command` (stdio) or `url` (Streamable HTTP). Stdio also accepts `args`, `env`, and `cwd`; HTTP accepts `headers`. Both support `enabled` (default true) and @@ -342,7 +332,7 @@ eligible provider after the ordered list. `only` is always an allowlist. } ``` -Model keys are exact native OpenRouter ids, without the outer opencodex provider prefix. Selecting +Model keys are exact native OpenRouter ids, without the outer CodexCommander provider prefix. Selecting `openrouter/anthropic-claude-sonnet-5` restores native `anthropic/claude-sonnet-5` before applying the model rule. diff --git a/docs-site/src/content/docs/reference/configuration/routing.md b/docs-site/src/content/docs/reference/configuration/routing.md index 862dd9867c..88d3c08cc9 100644 --- a/docs-site/src/content/docs/reference/configuration/routing.md +++ b/docs-site/src/content/docs/reference/configuration/routing.md @@ -10,12 +10,12 @@ Routing turns the model id sent by a client into one concrete provider and upstr | Field | Type | Default | Meaning | | --- | --- | --- | --- | | `defaultProvider` | `string` | `"openai"` | Final provider used when no earlier model rule matches. It must name an enabled configured provider. | -| `combos?` | `Record<string, OcxComboConfig>` | `{}` | Virtual `combo/<id>` models built from ordered provider/model targets. | -| `routingProfiles?` | `Record<string, OcxRoutingProfileConfig>` | `{}` | Virtual `policy/<id>` models that select among an explicit candidate allowlist using hard capability requirements and deterministic scoring. | +| `combos?` | `Record<string, CodexCommanderComboConfig>` | `{}` | Virtual `combo/<id>` models built from ordered provider/model targets. | +| `routingProfiles?` | `Record<string, CodexCommanderRoutingProfileConfig>` | `{}` | Virtual `policy/<id>` models that select among an explicit candidate allowlist using hard capability requirements and deterministic scoring. | ## Model resolution order -opencodex resolves the requested model in this order: +CodexCommander resolves the requested model in this order: 1. An explicit `policy/<id>` or configured routing-profile alias, executing the policy evaluator and routing the selected candidate. An unknown profile id fails closed. @@ -129,7 +129,7 @@ candidate evidence is provided through the API (`POST /api/routing-profiles/dry- { "routingProfiles": { "fast": { - "alias": "ocx/fast", + "alias": "ccx/fast", "candidates": [ { "provider": "anthropic", "model": "claude-sonnet-5" }, { "provider": "openai", "model": "gpt-5.6-sol" } @@ -148,8 +148,8 @@ candidate evidence is provided through the API (`POST /api/routing-profiles/dry- } ``` -CLI: `ocx route policy list [--json]`, `ocx route policy show <id> [--json]`, and -`ocx route policy dry-run <id> [--model-context <tokens>] [--tools] [--image] [--structured-output] [--json]`. +CLI: `ccx route policy list [--json]`, `ccx route policy show <id> [--json]`, and +`ccx route policy dry-run <id> [--model-context <tokens>] [--tools] [--image] [--structured-output] [--json]`. Dry-run evaluates candidates without sending any upstream request. Quota evidence (`optimize.quota`, `require.minQuotaHeadroom`, `unknownEvidence.quota`) comes from @@ -179,7 +179,7 @@ Per-request route-decision traces are recorded when a policy profile executes. ### Catalog eligibility -A combo remains directly routable even when it cannot be listed. `ocx sync`, `/v1/models`, and the +A combo remains directly routable even when it cannot be listed. `ccx sync`, `/v1/models`, and the Codex picker list it only when every target exposes capabilities that can be intersected: - a positive `contextWindow`, from live metadata, registry hints, or provider @@ -211,14 +211,14 @@ Returned history and route-decision payloads expose only masked request metadata (for example opaque `apiKeyId` labels). They do not include credentials, raw prompt bodies, or provider secrets. -CLI: `ocx logs explain <request-id>`, `ocx logs rebuild-index`, -`ocx logs index-status`, `ocx route policy list | show | dry-run | evaluate`. +CLI: `ccx logs explain <request-id>`, `ccx logs rebuild-index`, +`ccx logs index-status`, `ccx route policy list | show | dry-run | evaluate`. -## Migration +## Existing data `routingProfiles` is optional and additive: existing config files load -unchanged. Old `usage.jsonl` rows without `routeDecision` parse unchanged. +unchanged. `usage.jsonl` rows without `routeDecision` also parse unchanged. The history index is disposable - deleting `routing-history.sqlite` triggers -an automatic rebuild from `usage.jsonl` on the next query; `ocx logs +an automatic rebuild from `usage.jsonl` on the next query; `ccx logs rebuild-index` forces one. Nothing in this system auto-tunes weights, budgets, or candidate sets. diff --git a/docs-site/src/content/docs/reference/configuration/server.md b/docs-site/src/content/docs/reference/configuration/server.md index bc72f17b3b..096498344d 100644 --- a/docs-site/src/content/docs/reference/configuration/server.md +++ b/docs-site/src/content/docs/reference/configuration/server.md @@ -11,26 +11,22 @@ runs helper features around provider requests. | Field | Type | Default | Meaning | | --- | --- | --- | --- | | `port` | `number` | `10100` | Proxy listen port. | -| `hostname?` | `string` | `"127.0.0.1"` | Bind address. Non-loopback binds require `OPENCODEX_API_AUTH_TOKEN`. | +| `hostname?` | `string` | `"127.0.0.1"` | Bind address. Non-loopback binds require `CODEXCOMMANDER_API_AUTH_TOKEN`. | | `proxy?` | `string` | — | Outbound HTTP(S) proxy URL or `${ENV_VAR}`. Applied to `HTTP_PROXY` / `HTTPS_PROXY` only when those variables are unset; loopback remains in `NO_PROXY`. | | `stallTimeoutSec?` | `number` | `300` | Seconds without upstream data before `response.incomplete`. Minimum 1. | | `connectTimeoutMs?` | `number` | `200000` | Per-attempt DNS/TCP/TLS/final-header deadline; it ends before body generation. | | `shutdownTimeoutMs?` | `number` | `5000` | Graceful drain deadline before active turns are aborted. | | `websockets?` | `boolean` | `false` | Advertise `supports_websockets` for the Responses WebSocket path. False keeps HTTP/SSE. | | `corsAllowOrigins?` | `string[]` | `[]` | Additional exact origins allowed by CORS. Loopback origins are always allowed. Authority-based browser extension origins such as `chrome-extension://<extension-id>` are supported; `*` is not a wildcard. Firefox and Safari regenerate the extension UUID (per install / per browser launch), so update the entry when the origin changes. | -| `apiKeys?` | `OcxApiKey[]` | `[]` | Generated `ocx_…` credentials accepted by management and data-plane auth on non-loopback binds. Dashboard-managed. | +| `apiKeys?` | `CodexCommanderApiKey[]` | `[]` | Generated `ccx_data_…` credentials accepted by data-plane auth on non-loopback binds. Dashboard-managed; these keys never authenticate `/api/*`. | | `storageCleanupPolicy?` | `StorageCleanupPolicy` | disabled | Opt-in archived-session cleanup policy. Never enabled implicitly. | | `appOwnedMemoryBudgetMb?` | `number` | `256` | Cap in MiB for evictable app-owned logs, caches, blobs, and continuation payloads. Range 64–4096; not an RSS cap. | -| `codexAutoStart?` | `boolean` | `true` | Let the Codex shim run `ocx ensure` before launching Codex. False makes ensure a no-op. | -| `codexShimAutoRestore?` | `boolean` | `true` | Restore an installed shim after a completed external Codex update replaces it. Environment opt-out: `OPENCODEX_CODEX_SHIM_AUTO_RESTORE=0`. | -| `syncResumeHistory?` | `boolean` | `true` | Reversible Codex App history compatibility. Original metadata is backed up and restored by `ocx stop` / `ocx restore`. | -| `shadowCallIntercept?` | `{ enabled?: boolean; model?: string; sourceModels?: string[] }` | off | Redirect recognized Codex helper/shadow calls to a chosen model at low effort. The default source prefix is `gpt-5.6-luna`; older clients through 0.144.x used `gpt-5.4-mini`, which `sourceModels` can restore. | -| `webSearchSidecar?` | `OcxWebSearchSidecarConfig` | on when usable | Web-search sidecar options. | -| `visionSidecar?` | `OcxVisionSidecarConfig` | on when usable | Image-description sidecar options. | -| `images?` | `OcxImagesConfig` | automatic OpenAI selection | Standalone Images relay options for Codex `image_gen`. | - -If an older development build changed resume-history metadata before backup support existed, run -`ocx recover-history --legacy-openai` to force native-provider recovery. +| `codexAutoStart?` | `boolean` | `true` | Let the Codex shim run `ccx ensure` before launching Codex. False makes ensure a no-op. | +| `codexShimAutoRestore?` | `boolean` | `true` | Restore an installed shim after a completed external Codex update replaces it. Environment opt-out: `CODEXCOMMANDER_CODEX_SHIM_AUTO_RESTORE=0`. | +| `shadowCallIntercept?` | `{ enabled?: boolean; model?: string; sourceModels?: string[] }` | off | Redirect recognized Codex helper/shadow calls to a chosen model at low effort. The default source prefix is `gpt-5.6-luna`; `sourceModels` is an explicit current custom-source override. | +| `webSearchSidecar?` | `CodexCommanderWebSearchSidecarConfig` | on when usable | Web-search sidecar options. | +| `visionSidecar?` | `CodexCommanderVisionSidecarConfig` | on when usable | Image-description sidecar options. | +| `images?` | `CodexCommanderImagesConfig` | automatic OpenAI selection | Standalone Images relay options for Codex `image_gen`. | ## Remote access @@ -38,18 +34,18 @@ The default `127.0.0.1` bind is loopback-only. A non-loopback address such as `0 token authentication on both `/api/*` and the data plane. Export the token before starting: ```bash -export OPENCODEX_API_AUTH_TOKEN="your-secret-token" -ocx start +export CODEXCOMMANDER_API_AUTH_TOKEN="your-secret-token" +ccx start ``` The proxy refuses a remote bind without this variable. For a background service, export it before -`ocx service install` so launchd, systemd, or Task Scheduler receives it. Clients should send: +`ccx service install` so launchd, systemd, or Task Scheduler receives it. Clients should send: ```text -x-opencodex-api-key: your-secret-token +x-codexcommander-api-key: your-secret-token ``` -| Endpoint | `Authorization: Bearer` | `x-opencodex-api-key` | `x-api-key` | +| Endpoint | `Authorization: Bearer` | `x-codexcommander-api-key` | `x-api-key` | | --- | --- | --- | --- | | `/v1/responses` | not accepted | **required** | not accepted | | `/v1/chat/completions` | not accepted | **required** | not accepted | @@ -75,7 +71,7 @@ ssh -L 20100:localhost:10100 you@remote Any local port works. Requests whose Host resolves to `localhost`, `127.0.0.1`, or `::1` remain loopback regardless of port, so `http://localhost:20100/v1` works. Set that base URL in the client; -`ocx` writes only the default local `127.0.0.1` address into managed client config. +`ccx` writes only the default local `127.0.0.1` address into managed client config. Provider OAuth callbacks listen on a fixed remote port. Log in on the remote machine or forward that port too: @@ -101,15 +97,14 @@ with `POST /api/storage/cleanup-policy/run`. ## Claude Code (`claudeCode`) -These settings govern `/v1/messages`, the `ocx claude` launcher, and the Claude dashboard page. +These settings govern `/v1/messages`, the `ccx claude` launcher, and the Claude dashboard page. | Key | Type | Default | Description | | --- | --- | --- | --- | | `claudeCode.bodyStallSec?` | `number` | `90` | Native-passthrough body inactivity budget in seconds while a read is pending, not total duration. Minimum 1; exactly `0` disables. | | `claudeCode.bodyMaxBytes?` | `number` | `67108864` | Cumulative native-passthrough body cap for streamed and buffered responses. Exactly `0` disables. | | `claudeCode.authMode?` | `"proxy" \| "subscription"` | auto | How launch handles `ANTHROPIC_AUTH_TOKEN`. Auto detects auth each launch; an explicit value is never overridden. | -| `claudeCode.authModeMigratedAt?` | `string` | unset | Internal one-time upgrade marker. Do not set manually. | -| `claudeCode.subagentEffort?` | `"low" \| "medium" \| "high" \| "xhigh" \| "max"` | inherit | Effort written to generated `~/.claude/agents/ocx-*.md`; separate from Codex guidance and proxy caps. Restart through `ocx claude` to regenerate. | +| `claudeCode.subagentEffort?` | `"low" \| "medium" \| "high" \| "xhigh" \| "max"` | inherit | Effort written to generated `~/.claude/agents/ccx-*.md`; separate from Codex guidance and proxy caps. Restart through `ccx claude` to regenerate. | Auto auth selects subscription when stored Claude auth is found, proxy when none is found, and subscription with a warning when detection is inconclusive. See @@ -119,10 +114,9 @@ subscription with a warning when detection is inconclusive. See Codex uses small helper models for tasks such as titles and commit messages. Enable `shadowCallIntercept` to redirect recognized source-model prefixes to another configured model. The -replacement runs at low effort. Set `sourceModels` only when a client uses different helper ids. -Codex 0.145.0+ marks request purpose in `x-codex-turn-metadata`: normal `request_kind: "turn"` -requests keep the selected model, while recognized maintenance requests can be redirected. Clients -without that metadata retain the legacy prefix behavior. +replacement runs at low effort. Set `sourceModels` only as an explicit current custom-source +override. Only recognized maintenance request kinds in `x-codex-turn-metadata` are eligible; +normal turns and requests with missing, malformed, or unrecognized metadata are never intercepted. ```json { @@ -136,7 +130,7 @@ without that metadata retain the legacy prefix behavior. ## Sidecars -### `images` (`OcxImagesConfig`) +### `images` (`CodexCommanderImagesConfig`) | Field | Type | Default | Meaning | | --- | --- | --- | --- | @@ -147,13 +141,13 @@ Explicit selection fails closed when the provider is missing, disabled, incompat usable key; it never falls back to another paid upstream. The endpoint must implement the OpenAI Images API paths and response shape expected by Codex. -### `webSearchSidecar` (`OcxWebSearchSidecarConfig`) +### `webSearchSidecar` (`CodexCommanderWebSearchSidecarConfig`) | Field | Type | Default | Meaning | | --- | --- | --- | --- | | `enabled?` | `boolean` | on when usable | Master switch. | | `backend?` | `"openai" \| "anthropic"` | auto | Explicit wins; otherwise usable stored Anthropic OAuth selects `anthropic`, then `openai`. | -| `model?` | `string` | backend-dependent | `gpt-5.6-luna` for OpenAI or `claude-sonnet-5` for Anthropic. Legacy explicit `gpt-5.4-mini` migrates on start. | +| `model?` | `string` | backend-dependent | `gpt-5.6-luna` for OpenAI or `claude-sonnet-5` for Anthropic. | | `reasoning?` | `string` | `low` | Sidecar effort. `minimal` is rejected with web search. | | `maxSearchesPerTurn?` | `number` | `3` | Real searches allowed per main-model turn. | | `routedModelStallTimeoutMs?` | `number` | `200000` | Config-file-only routed-model raw-body inactivity deadline. Integer 1–2147483647; every non-empty chunk resets it. | @@ -169,7 +163,7 @@ Four clocks govern search: base `stallTimeoutSec`, `connectTimeoutMs`, routed-mo hosted-search timeout. The effective bridge watchdog is the maximum plus 30 seconds. Routed stall is an inactivity guard, not a total generation deadline. -### `visionSidecar` (`OcxVisionSidecarConfig`) +### `visionSidecar` (`CodexCommanderVisionSidecarConfig`) | Field | Type | Default | Meaning | | --- | --- | --- | --- | @@ -185,5 +179,5 @@ credential. Successful `data:` descriptions use a bounded cache keyed by backend image bytes, and normalized message context. Hits and same-turn duplicates do not consume the limit. Remote `https:` images and failed or empty descriptions are not cached. -Anthropic OAuth sidecars reuse opencodex's existing Claude Code OAuth fingerprint. Soak-test the +Anthropic OAuth sidecars reuse CodexCommander's existing Claude Code OAuth fingerprint. Soak-test the intended account and workload. diff --git a/docs-site/src/content/docs/reference/management-api.md b/docs-site/src/content/docs/reference/management-api.md index 6c661de28e..9cd41417f1 100644 --- a/docs-site/src/content/docs/reference/management-api.md +++ b/docs-site/src/content/docs/reference/management-api.md @@ -1,10 +1,10 @@ --- title: Management API -description: Authentication, errors, and endpoint reference for the opencodex control plane. +description: Authentication, errors, and endpoint reference for the CodexCommander control plane. --- -The Management API is opencodex's control plane. The dashboard at -`http://localhost:10100` is one client of it; headless `ocx` provider, model, combo, account, +The Management API is CodexCommander's control plane. The dashboard at +`http://localhost:10100` is one client of it; headless `ccx` provider, model, combo, account, settings, diagnostics, and lifecycle commands are clients too. The API is available only while the proxy is running. @@ -14,10 +14,10 @@ building automation. Persistent values ultimately follow [Configuration](/refere ## Authentication model The Management API has its own admin credential, independent of data-plane API keys. At startup, -opencodex resolves it in this order: +CodexCommander resolves it in this order: -1. `OPENCODEX_ADMIN_AUTH_TOKEN`, when set. -2. A generated `ocx_admin_*` token in a hardened secret file. +1. `CODEXCOMMANDER_ADMIN_AUTH_TOKEN`, when set. +2. A generated `ccx_admin_*` token in a hardened secret file. The file-backed token is accepted only after its directory and file permissions or ACLs have been hardened. If that cannot be guaranteed, management authentication fails closed and the API returns @@ -26,7 +26,7 @@ hardened. If that cannot be guaranteed, management authentication fails closed a Send the admin token in either form: ```http -X-OpenCodex-API-Key: <admin-token> +X-CodexCommander-API-Key: <admin-token> ``` ```http @@ -41,7 +41,7 @@ Claude Code, or another model client; it authorizes control-plane mutations. ### Loopback dashboard sessions -On a loopback bind, the dashboard bootstrap can receive a short-lived `ocx_session_*` credential. +On a loopback bind, the dashboard bootstrap can receive a short-lived `ccx_session_*` credential. Each session lasts five minutes and is bound to the exact dashboard origin. Safe requests must match that origin. Unsafe methods also require the browser `Origin` and the session's CSRF token. @@ -56,7 +56,7 @@ route-specific results rather than repeating this table. | Status | Type or code | Meaning | | --- | --- | --- | -| 401 | `opencodex admin token required` | The admin token or GUI session is missing, invalid, expired, origin-mismatched, or missing CSRF evidence | +| 401 | `codexcommander admin token required` | The admin token or GUI session is missing, invalid, expired, origin-mismatched, or missing CSRF evidence | | 403 | `cross-origin request blocked` | The request origin is outside the management allowlist | | 404 | `not_found` | No management route matched the method and path | | 413 | `request body too large` | A POST, PUT, or PATCH body exceeds the 2 MiB management limit | @@ -79,7 +79,7 @@ route-specific results rather than repeating this table. | `PUT /api/grok/selection` | Persist the excluded Grok models | 400 invalid or oversized selection | | `POST /api/grok/apply` | Apply persisted Grok configuration through the managed sync | 409 `grok_apply_busy`; 400/500 apply failure | | `GET, PUT /api/claude-desktop` | Read or persist the Claude Desktop routed/native profile | 400 invalid or unavailable assignment | -| `POST /api/claude-desktop/apply` | Write the saved profile to Claude Desktop's managed config | 400/500 write failure | +| `POST /api/claude-desktop/apply` | Write the saved profile to Claude Desktop's managed config. Requires a JSON object with an explicit `mode`: `static`, `hybrid`, or `discovery` | 400 missing/invalid body or mode; 500 write failure | | `GET /api/claude-desktop/status` | Inspect saved-versus-applied profile and Desktop health | 400 status read failure | | `GET, PUT /api/claude-code` | Read or update Claude Code gateway, auth-mode, model-map, context, agent, and sidecar settings | 400 invalid field or shape | @@ -96,7 +96,7 @@ For the concepts behind the model roster and encrypted worker-task behavior, see See [Combos](/guides/combos/) for target strategies, cooldowns, aliases, and routing failures. -### Configuration, startup, sync, and updates +### Configuration, startup, and sync | Method and path | Purpose | Notable errors | | --- | --- | --- | @@ -108,9 +108,6 @@ See [Combos](/guides/combos/) for target strategies, cooldowns, aliases, and rou | `GET, POST /api/windows-tray` | Read Windows tray state or install/start/stop/uninstall it | 400 unsupported platform/action; 500 operation failure | | `GET /api/diagnostics/project-config` | Read cached project configuration warnings | — | | `POST /api/sync` | Sync the current model catalog into Codex; returns `catalogQuality` (`live`, `retained`, or `native-only`), `rehydrated`, current Codex app-server `catalogState`, and a restart hint when stale | 409 refused write authority; 500 failed sync | -| `GET /api/update/check` | Check the `latest` or `preview` update channel | 400 invalid tag | -| `POST /api/update/run` | Start an update job, optionally followed by restart | 400 invalid body; job-specific conflict/error status | -| `GET /api/update/status` | Poll an update job by id | 404 unknown job | | `GET, PUT /api/sidecar-settings` | Read or update web-search and vision sidecar model/backend settings | 400 invalid shape, backend, or limit | | `GET, PUT /api/shadow-call-settings` | Read or update shadow-call interception settings | 400 invalid shape or value | @@ -158,12 +155,12 @@ first and submit the returned digest. Prefer quarantine when recovery may be nee | Method and path | Purpose | Notable errors | | --- | --- | --- | | `GET /api/integrations/opencode` | Read OpenCode installation detection, managed-connection state, target config path, auto-refresh setting, and OpenCode Go key-verification state | — | -| `POST /api/integrations/opencode/apply` | Generate and surgically apply only `provider.opencodex` to the active OpenCode global JSONC/JSON config; accepts optional `{ "autoConnect": boolean }` | 400 invalid body; 409 malformed, changed, or unsafe external config | +| `POST /api/integrations/opencode/apply` | Generate and surgically apply only `provider.codexcommander` to the active OpenCode global JSONC/JSON config; accepts optional `{ "autoConnect": boolean }` | 400 invalid body; 409 malformed, changed, or unsafe external config | | `PUT /api/integrations/opencode` | Enable or disable opt-in catalog/startup refresh after a connection has been applied | 400 invalid body; 409 no applied connection | | `POST /api/integrations/opencode/restore` | Restore the exact pre-Apply bytes when safe, or surgically restore/remove only the managed provider; optional full mode requires current-hash confirmation | 400 invalid mode/body; 409 changed or unsafe external config | | `POST /api/integrations/opencode/open` | Apply when needed, then one-click launch detected OpenCode Desktop | 409 missing Desktop or integration needs attention | -The persistent integration owns a protected token file under OpenCodex state and a journal/backup; +The persistent integration owns a protected token file under CodexCommander state and a journal/backup; the OpenCode config receives a `{file:…}` reference, never a serialized proxy key. The API never rewrites OpenCode's other config paths or reads its auth store. See [OpenCode](/guides/opencode/) for the user workflow. @@ -212,12 +209,6 @@ shared value atomically. `provider_has_dependent_combos` is a safety barrier: remove or edit the dependent combos before deleting their provider. -### Sidebar - -| Method and path | Purpose | Notable errors | -| --- | --- | --- | -| `GET /api/update/badge` | Read the cheap sidebar update-badge state | — | - ### System lifecycle | Method and path | Purpose | Notable errors | @@ -238,7 +229,7 @@ manager. Its routes are: | `PUT /api/codex-auth/accounts/pause` | Pause or resume one account | 400 invalid account/state; 404 missing account | | `PUT /api/codex-auth/accounts/pause-exhausted` | Pause accounts whose quota is exhausted | Mutation-lock failures become 503 | | `POST /api/codex-auth/accounts/clear-cooldown` | Clear runtime cooldown for one account or all accounts | 400 invalid id | -| `GET, PUT /api/codex-auth/active` | Read or select the active account | 400 invalid or missing account; 409 paused/legacy-row conflict | +| `GET, PUT /api/codex-auth/active` | Read or select the active account | 400 invalid or missing account; 409 paused account | | `PUT /api/codex-auth/auto-switch` | Set the quota threshold for automatic account switching | 400 invalid threshold | | `PUT, PATCH /api/codex-auth/pool-strategy` | Update Codex account-pool selection strategy | 400 invalid strategy/config | | `PUT /api/codex-auth/failover` | Set the account failover threshold | 400 invalid threshold | @@ -257,6 +248,6 @@ that response as a permanent account failure. ## Choosing a client For ordinary administration, the [Web Dashboard](/guides/web-dashboard/) gives the safest guided -workflow. For headless hosts and automation, use the corresponding `ocx` commands: they call this +workflow. For headless hosts and automation, use the corresponding `ccx` commands: they call this same live API and return a nonzero result when the proxy is unreachable or the operation fails. Direct HTTP is most useful for integrations that need the exact endpoint contracts above. diff --git a/docs-site/src/content/docs/reference/proxy-formats.md b/docs-site/src/content/docs/reference/proxy-formats.md index bc65fc4bbc..24d831eb46 100644 --- a/docs-site/src/content/docs/reference/proxy-formats.md +++ b/docs-site/src/content/docs/reference/proxy-formats.md @@ -3,7 +3,7 @@ title: Proxy API Formats description: Wire-level reference for the Responses, Chat Completions, Anthropic Messages, model catalog, WebSocket, realtime, and compaction surfaces. --- -opencodex presents one local proxy in several client dialects. A Codex client can speak the +CodexCommander presents one local proxy in several client dialects. A Codex client can speak the Responses API, an OpenAI-compatible app can speak Chat Completions, and Claude Code can speak Anthropic Messages without requiring every upstream provider to implement every format. @@ -34,7 +34,7 @@ should select among several targets. ## `POST /v1/responses` -This is the native opencodex data-plane shape. The request body must be a JSON object with a +This is the native CodexCommander data-plane shape. The request body must be a JSON object with a non-empty `model`. `input` may be a string or an array of Responses items. ### Accepted request fields @@ -186,7 +186,7 @@ wins unless `client_version` is also present. ## `POST /v1/live` and Realtime sideband `POST /v1/live` accepts the ChatGPT/Codex App Frameless call-creation surface. -`POST /v1/realtime/calls` accepts the OpenAI Realtime call-creation surface. opencodex selects an +`POST /v1/realtime/calls` accepts the OpenAI Realtime call-creation surface. CodexCommander selects an eligible OpenAI-family route, normalizes the call-creation request for the upstream authentication mode, and relays the bounded response. @@ -208,7 +208,7 @@ conversation. | Route type | Behavior | | --- | --- | | Canonical ChatGPT or official OpenAI route | Forwards the request to the native `/responses/compact` endpoint with the resolved account and model authentication | -| Other routed model | Runs an internal, non-streaming, no-tools compaction turn with a `compaction_trigger`; requires exactly one synthetic `compaction` item whose `encrypted_content` is an `ocx1:` envelope; decodes that summary into v1 replacement history | +| Other routed model | Runs an internal, non-streaming, no-tools compaction turn with a `compaction_trigger`; requires exactly one synthetic `compaction` item whose `encrypted_content` is a `ccx1:` envelope; decodes that summary into v1 replacement history | Native compact responses are buffered with a 32 MiB maximum, including responses whose declared `Content-Length` already exceeds the limit. The compact-specific failures include: @@ -220,12 +220,12 @@ Native compact responses are buffered with a 32 MiB maximum, including responses | 499 | `client_cancelled` | The client cancelled while forwarding or buffering | | 502 | `compact_response_too_large` | Native compact output exceeded 32 MiB | | 502 | `upstream_error` | Connection, read, or synthetic compaction turn failure | -| 502 | `invalid_response_error` | The synthetic turn did not produce exactly one valid, non-empty `ocx1:` compaction item | +| 502 | `invalid_response_error` | The synthetic turn did not produce exactly one valid, non-empty `ccx1:` compaction item | ## Authentication matrix On a loopback-only bind, data-plane admission does not require a configured key. On a remote bind, -use the matrix below. “Dedicated” means `X-OpenCodex-API-Key`; the other columns mean +use the matrix below. “Dedicated” means `X-CodexCommander-API-Key`; the other columns mean `Authorization: Bearer ...` and `x-api-key`. | Surface | Dedicated | Bearer | `x-api-key` | @@ -264,13 +264,13 @@ Anthropic-origin failures are rendered in Anthropic's error envelope, so the ori ## Encrypted-content hygiene The proxy treats genuine backend ciphertext as opaque. Structurally valid ciphertext is preserved -byte for byte: opencodex does not decrypt it, translate its contents, or re-encrypt it for another +byte for byte: CodexCommander does not decrypt it, translate its contents, or re-encrypt it for another provider. -Some agent hooks have historically placed plaintext control text in an `encrypted_content` slot. +Some agent hooks place plaintext control text in an `encrypted_content` slot. For compatibility, the proxy separates that plaintext into text parts while retaining any structurally valid Fernet runs unchanged. If an `agent_message` loses all encrypted parts during that repair, it becomes a normal user message. If a current v2 task remains genuinely encrypted -but the selected routed target cannot read native ChatGPT ciphertext, opencodex fails with +but the selected routed target cannot read native ChatGPT ciphertext, CodexCommander fails with `unreadable_encrypted_agent_task` instead of sending unreadable bytes to that provider. See [Sub-agent Surface](/guides/sub-agent-surface/) for the client behavior around worker tasks. diff --git a/docs-site/src/content/docs/ru/benchmarks/index.mdx b/docs-site/src/content/docs/ru/benchmarks/index.mdx index e974ebab6a..5e43cfd7a2 100644 --- a/docs-site/src/content/docs/ru/benchmarks/index.mdx +++ b/docs-site/src/content/docs/ru/benchmarks/index.mdx @@ -4,7 +4,7 @@ description: Снимки публичных бенчмарков кодинг- --- Это **статические снимки** публичных лидербордов, обновляемые вручную, — а не -живые данные учёта OpenCodex. Для каждой таблицы указаны источник, дата снимка и +живые данные учёта CodexCommander. Для каждой таблицы указаны источник, дата снимка и примечание о лицензии. Рейтинги «баллы на доллар» показываются только в таблицах, где каждая строка содержит измеренную источником стоимость на задачу. diff --git a/docs-site/src/content/docs/ru/contributing.md b/docs-site/src/content/docs/ru/contributing.md index f7e6c2da7e..f493f63b61 100644 --- a/docs-site/src/content/docs/ru/contributing.md +++ b/docs-site/src/content/docs/ru/contributing.md @@ -1,13 +1,12 @@ --- title: Участие в разработке -description: Разработка opencodex — настройка окружения, структура, конвенции и добавление провайдера или адаптера. +description: Разработка CodexCommander — настройка окружения, структура, конвенции и добавление провайдера или адаптера. --- ## Настройка окружения ```bash -git clone https://github.com/pavelhov/opencodex.git -cd opencodex +cd /path/to/CodexCommander bun install bun run dev:proxy # прокси-API в режиме разработки bun run dev:gui # dev-сервер дашборда (другой терминал) @@ -43,12 +42,9 @@ bun run prepare:package # обновление лаунчеров/ре cd docs-site && bun install && bun dev ``` -## Публикация документации +## Сайт документации -Публичная документация публикуется на GitHub Pages по адресу <https://opencodex.me/ru/>. -Воркфлоу `.github/workflows/deploy-docs.yml` запускается на push в `main`, затрагивающих -`docs-site/**` или сам воркфлоу, собирает `docs-site` и разворачивает сгенерированный сайт. Перед -push изменений документации выполните: +Документация живёт в `docs-site/`; опубликованного хоста сейчас нет. Перед открытием PR по документации соберите сайт локально: ```bash cd docs-site @@ -56,42 +52,34 @@ bun install --frozen-lockfile bun run build ``` -## CI и релизы +Автоматизация публикации в этот репозиторий не включена. -GitHub Actions намеренно остаются компактными: +## Непрерывная интеграция -- **Cross-platform CI** (`.github/workflows/ci.yml`) запускается на pull request и push в `main`, - затрагивающих файлы рантайма, тестов, пакета, скриптов, TypeScript или воркфлоу. Его Bun-матрица - покрывает Linux, Windows и macOS: install, typecheck, тесты, privacy scan, smoke-сборка - release-helper, сборка GUI и `ocx help`. Отдельная линия на тех же трёх ОС подтверждает, что - npm global install работает без отдельно установленного Bun — за счёт runtime, входящего в - состав пакета. -- **Release** (`.github/workflows/release.yml`) запускается вручную. Он не служит вторым полным - CI-пайплайном; перед dry-run или publish он требует, чтобы для точного релизного коммита - (`GITHUB_SHA`) уже был успешный запуск Cross-platform CI. +Для каждого pull request и каждого push в `main` есть **одна** автоматическая проверка: +**`ci`** (`.github/workflows/ci.yml`). Это единственная обязательная автоматика для +обычных вкладов. -Для релизов используйте helper: +Администраторы репозитория могут использовать bypass GitHub ruleset **Always-allow**, +когда правило ветки или пути блокирует намеренное административное действие. Bypass +нужен для восстановления и исключительного обслуживания, а не вместо review для +контрибьюторов. -```bash -bun run release <version> # коммитит/пушит bump версии; publish workflow по умолчанию dry-run -bun run release <version> --publish # publish после осознанного CI-gated dry-run -bun run release:watch # наблюдение за последним запуском Release workflow -``` - -## Ветки +## Ветки и pull request -- `dev` — единственная цель интеграции. Открывайте все PR сюда. -- `main` — только релизы. Двигается лишь при продвижении из `dev` мейнтейнером; не - открывайте сюда PR с функциональностью. -- `preview` — ветка предрелизов. +- **`main` — единственная default/integration/PR-ветка.** Открывайте feature и fix PR + в `main`. +- Ветвитесь от текущего tip **`main`**. +- В описании укажите, что изменилось, зачем, и как вы это проверили (команды и результаты). + Пустые и placeholder-описания к review не готовы. +- Если затронут UI дашборда, приложите скриншот в описание. +- Изменения поведения требуют сфокусированного регрессионного теста рядом с существующими + тестами подсистемы. Общие routing/adapters/config/server — зелёный полный suite. -Ветка `dev2-go`, которая несла нативный порт на Go, закрыта, и вместе с ней закончилась -политика двух линий интеграции. Её история опубликована только для чтения в -[lidge-jun/opencodex-go-archive](https://github.com/lidge-jun/opencodex-go-archive). -Теперь единственная линия рантайма — Bun-нативный TypeScript в `dev`. +Единственная runtime-линия — Bun-нативный TypeScript на `main`. -Pull request'ы с ребейзом приветствуются: ребейз устаревшей ветки на текущий head — это -обычный вклад, а не шум. Укажите исходные коммиты в описании. +PR с rebase приветствуются. Перенос устаревшей ветки на актуальный head — обычная +поддержка; укажите исходные коммиты в описании. ## Конвенции @@ -102,7 +90,7 @@ Pull request'ы с ребейзом приветствуются: ребейз - **Обрабатывайте асинхронные ошибки на границах** — сайдкары никогда не бросают исключения в путь запроса; они деградируют до корректного маркера. - **Structure SOT** — актуальные инварианты для мейнтейнеров живут в `structure/`. Публичные - пользовательские сценарии держите в `docs-site/`, а исторические заметки расследований — в `docs/`. + пользовательские сценарии держите в `docs-site/`, а поддерживаемые технические заметки — в `docs/`. - **Сохраняйте экспорты** — от них могут зависеть другие модули. ## Добавление провайдера в каталог @@ -124,7 +112,7 @@ Pull request'ы с ребейзом приветствуются: ребейз }, ``` -`src/providers/derive.ts` передаёт эту запись в `ocx init`, `ocx provider`, пресеты дашборда, вход +`src/providers/derive.ts` передаёт эту запись в `ccx init`, `ccx provider`, пресеты дашборда, вход по API-ключу и seed-конфигурации OAuth. `enrichProviderFromCatalog()` копирует метаданные моделей и классификацию возможностей в сохранённую конфигурацию провайдера. Реализации OAuth-протоколов по-прежнему живут в `src/oauth/`; одни лишь метаданные реестра ещё не образуют OAuth-flow. @@ -143,5 +131,5 @@ Pull request'ы с ребейзом приветствуются: ребейз Запускайте самую узкую команду, которая доказывает ваше изменение: `bun run typecheck` для типов, сфокусированный `bun test tests/<name>.test.ts` или runtime-проверку для поведения, а затем более -широкие проверки, соответствующие затронутой области. opencodex предпочитает небольшие проверяемые +широкие проверки, соответствующие затронутой области. CodexCommander предпочитает небольшие проверяемые коммиты крупным пачкам изменений. diff --git a/docs-site/src/content/docs/ru/getting-started/for-agents.md b/docs-site/src/content/docs/ru/getting-started/for-agents.md index 9519b629bd..8a32e2b176 100644 --- a/docs-site/src/content/docs/ru/getting-started/for-agents.md +++ b/docs-site/src/content/docs/ru/getting-started/for-agents.md @@ -1,6 +1,6 @@ --- title: Быстрый старт для агентов -description: Установите и используйте opencodex из агентного или сценарного терминала. +description: Установите и используйте CodexCommander из агентного или сценарного терминала. --- Эта страница предназначена для ИИ-агента или пользователя, который работает из терминала через @@ -8,52 +8,55 @@ description: Установите и используйте opencodex из аг сценарий для человека, откройте [Быстрый старт](/getting-started/quickstart/). Дашборд остаётся доступен для интерактивной настройки; см. [Веб-дашборд](/guides/web-dashboard/). -## Настройте opencodex +## Настройте CodexCommander -Установите опубликованный пакет и убедитесь, что `ocx` доступен в `PATH`: +Используйте существующий исходный checkout. Пакет в реестре сейчас не опубликован: ```bash -npm install -g @bitkyc08/opencodex -ocx --version +bun install +bun run build:gui +bun run src/cli/index.ts --version ``` Выберите один из способов запуска прокси: ```bash # Foreground: blocks this terminal until stopped. -ocx start +bun run src/cli/index.ts start # Background: installs or updates the service, then starts it. -ocx service +bun run src/cli/index.ts service ``` -Запустите `ocx init` в интерактивном терминале. Если `ocx start` уже занимает передний план, +Запустите `ccx init` в интерактивном терминале. Если `ccx start` уже занимает передний план, используйте второй терминал: ```bash -ocx init +bun run src/cli/index.ts init ``` -Мастер записывает `$OPENCODEX_HOME/config.json` (обычно `~/.opencodex/config.json`). Он также может +Далее любую команду `ccx <args>` в этом checkout можно выполнить как `bun run src/cli/index.ts <args>`. + +Мастер записывает `$CODEXCOMMANDER_HOME/config.json` (обычно `~/.codexcommander/config.json`). Он также может вставить адрес прокси в `config.toml` Codex и установить необязательный shim автозапуска Codex. -`ocx init` никогда не запускает прокси. Для полностью неинтерактивной настройки вместо мастера -настройте провайдеров через `ocx provider add`, как показано ниже. +`ccx init` никогда не запускает прокси. Для полностью неинтерактивной настройки вместо мастера +настройте провайдеров через `ccx provider add`, как показано ниже. ## Проверьте headless-установку Используйте эти read-only проверки в сценариях и агентных запусках: ```bash -ocx status -ocx doctor -ocx health --json +ccx status +ccx doctor +ccx health --json ``` -`ocx status` сообщает состояние прокси и службы. `ocx doctor` диагностирует локальную среду, -сеть, рантайм Codex и проблемы со здоровьем аккаунтов. `ocx health` завершаетcя с кодом `0`, +`ccx status` сообщает состояние прокси и службы. `ccx doctor` диагностирует локальную среду, +сеть, рантайм Codex и проблемы со здоровьем аккаунтов. `ccx health` завершаетcя с кодом `0`, когда прокси исправен, и с `1` в противном случае; `--json` возвращает структурированный вывод. -Команды, работающие через management API, например `ocx combo set`, обращаются к живому прокси. +Команды, работающие через management API, например `ccx combo set`, обращаются к живому прокси. Если живой прокси не найден или API недоступен, CLI трактует это как ошибку `503` и завершаетcя с ненулевым кодом. Перед повторной попыткой запустите прокси в foreground или как фоновую службу. Полные поверхности команд и endpoint'ов описаны в [справочнике CLI](/reference/cli/) и @@ -65,20 +68,20 @@ Registry-провайдеры можно добавлять по имени. Н API-ключом и делает его провайдером по умолчанию: ```bash -ocx provider add anthropic-apikey \ +ccx provider add anthropic-apikey \ --api-key "$ANTHROPIC_API_KEY" \ --set-default ``` -`ocx provider add` записывает локальную конфигурацию. Добавьте `--sync`, если живой прокси уже -работает и вы хотите сразу синхронизировать модели в Codex; иначе позже выполните `ocx sync`. +`ccx provider add` записывает локальную конфигурацию. Добавьте `--sync`, если живой прокси уже +работает и вы хотите сразу синхронизировать модели в Codex; иначе позже выполните `ccx sync`. Пользовательские провайдеры, которых нет в registry, требуют одновременно `--adapter` и `--base-url`. Когда все целевые провайдеры настроены и прокси запущен, создайте failover-combo: ```bash -ocx combo set main \ +ccx combo set main \ --targets anthropic/claude-opus-4-8,openai/gpt-5.6-sol \ --strategy failover ``` @@ -90,14 +93,14 @@ ocx combo set main \ ## Удалённые и LAN-привязки Привязка к loopback по умолчанию не требует API-токена. Для не-loopback-привязки, например -`0.0.0.0`, требуется `OPENCODEX_API_AUTH_TOKEN`; без него прокси откажется запускаться. Задайте -эту переменную перед `ocx start` или перед `ocx service install`, чтобы служба тоже её получила: +`0.0.0.0`, требуется `CODEXCOMMANDER_API_AUTH_TOKEN`; без него прокси откажется запускаться. Задайте +эту переменную перед `ccx start` или перед `ccx service install`, чтобы служба тоже её получила: ```bash -export OPENCODEX_API_AUTH_TOKEN="your-secret-token" -ocx service install +export CODEXCOMMANDER_API_AUTH_TOKEN="your-secret-token" +ccx service install ``` После этого клиенты должны аутентифицировать запросы как к management API, так и к модели. -Прежде чем открывать opencodex за пределы локальной машины, прочитайте правила удалённого доступа +Прежде чем открывать CodexCommander за пределы локальной машины, прочитайте правила удалённого доступа в разделе [Конфигурация](/reference/configuration/). diff --git a/docs-site/src/content/docs/ru/getting-started/how-it-works.mdx b/docs-site/src/content/docs/ru/getting-started/how-it-works.mdx index 2e9f2fa9ca..3935cec221 100644 --- a/docs-site/src/content/docs/ru/getting-started/how-it-works.mdx +++ b/docs-site/src/content/docs/ru/getting-started/how-it-works.mdx @@ -1,21 +1,21 @@ --- title: Как это работает -description: Полный жизненный цикл запроса в opencodex — parse, route, adapt, bridge и stream. +description: Полный жизненный цикл запроса в CodexCommander — parse, route, adapt, bridge и stream. --- import { Steps } from '@astrojs/starlight/components'; -Codex общается по протоколу OpenAI **Responses API**. opencodex принимает `POST /v1/responses` по +Codex общается по протоколу OpenAI **Responses API**. CodexCommander принимает `POST /v1/responses` по HTTP с Server-Sent Events, а также опционально поддерживает WebSocket upgrade на том же пути. Он переводит запрос в сетевой формат вашего провайдера, а ответ — обратно в события Responses, поэтому Codex даже не догадывается, что общается не с OpenAI. ``` - ┌──────────────────────────── opencodex ────────────────────────────┐ + ┌──────────────────────────── CodexCommander ────────────────────────────┐ │ │ Codex ──▶ │ parser ──▶ router ──▶ [vision] ──▶ adapter ──▶ provider │ ──▶ Codex (/v1/ │ │ │ │ │ │ │ (SSE / WS) - responses)│ OcxParsed provider describe buildRequest parseStream │ + responses)│ CodexCommanderParsed provider describe buildRequest parseStream │ │ Request +adapter images + fetch AdapterEvent[] │ │ │ │ │ │ [web-search loop] bridge ─▶ SSE │ @@ -26,7 +26,7 @@ Codex даже не догадывается, что общается не с Op ## Выбор аккаунта для аутентификации Codex -Если выбранный провайдер — это passthrough ChatGPT/Codex, opencodex может выбрать аккаунт из +Если выбранный провайдер — это passthrough ChatGPT/Codex, CodexCommander может выбрать аккаунт из сохранённого пула перед тем, как переслать запрос вышестоящему провайдеру. Правило намеренно разделено на части: @@ -34,7 +34,7 @@ Codex даже не догадывается, что общается не с Op (account generation), с которого он начался, поэтому долгая сессия Codex по SSH, в tmux или с подключённого мобильного устройства продолжает использовать один аккаунт и не перераспределяется посреди разговора. -- **Новые сессии могут перераспределяться.** Для нового треда opencodex сравнивает известное +- **Новые сессии могут перераспределяться.** Для нового треда CodexCommander сравнивает известное использование квоты в окнах 5 часов, недели и 30 дней, пропускает аккаунты, требующие повторной аутентификации или находящиеся в кулдауне, и может переключиться на подходящий аккаунт с меньшим использованием, когда активный аккаунт превышает настроенный порог. @@ -57,7 +57,7 @@ Codex даже не догадывается, что общается не с Op <Steps> 1. **Parse** — `responses/parser.ts` проверяет запрос по Zod-схеме (`responses/schema.ts`) - и преобразует его во внутренний `OcxParsedRequest`: системный промпт, нормализованный список + и преобразует его во внутренний `CodexCommanderParsedRequest`: системный промпт, нормализованный список сообщений (текст, изображения, вызовы инструментов, результаты инструментов), определения инструментов, параметры генерации и флаги возможностей, такие как `_webSearch` (запрошен hosted `web_search`) и `_structuredOutput` (задан `text.format` с JSON-схемой или @@ -70,26 +70,26 @@ Codex даже не догадывается, что общается не с Op `models[]` провайдера → запасной вариант `defaultProvider`. См. [Маршрутизация моделей](/ru/guides/model-routing/). -3. **Authenticate** — для провайдера типа `oauth` opencodex подставляет текущий access-токен как - bearer-ключ и соблюдает владельца учётных данных: собственные данные OpenCodex обновляются +3. **Authenticate** — для провайдера типа `oauth` CodexCommander подставляет текущий access-токен как + bearer-ключ и соблюдает владельца учётных данных: собственные данные CodexCommander обновляются автоматически, а поколения связанного нативного Grok/Kimi CLI перечитываются и используются только для чтения. Для аккаунтов пула ChatGPT/Codex `codex/auth-context.ts` сначала определяет аккаунт, и passthrough-адаптер отказывается продолжать, если нужные учётные данные пула недоступны. 4. **Vision-сайдкар (опционально)** — если маршрутизируемая модель указана в - `provider.noVisionModels`, а запрос содержит изображение, opencodex описывает каждое + `provider.noVisionModels`, а запрос содержит изображение, CodexCommander описывает каждое изображение с помощью настроенного vision-сайдкара ChatGPT и заменяет его текстом, чтобы модель без поддержки изображений всё равно могла о нём рассуждать. См. [Сайдкары](/ru/guides/sidecars/). 5. **Быстрый путь passthrough** — если адаптер является passthrough для Responses - (`openai-responses` или `azure-openai`), opencodex сохраняет тело Responses, применяет + (`openai-responses` или `azure-openai`), CodexCommander сохраняет тело Responses, применяет точечные правки для маршрутизации и совместимости, а затем ретранслирует ответ провайдера без преобразования через `AdapterEvent`. 6. **Веб-поисковый сайдкар (опционально)** — если Codex включил hosted `web_search`, но - маршрутизируемая модель не от OpenAI, opencodex предоставляет синтетический function-инструмент + маршрутизируемая модель не от OpenAI, CodexCommander предоставляет синтетический function-инструмент `web_search` и запускает модель в небольшом агентном цикле: реальные поиски по умолчанию выполняются через `gpt-5.6-luna` с использованием вашего входа в ChatGPT, а результаты внедряются обратно как результаты инструментов. @@ -100,7 +100,7 @@ Codex даже не догадывается, что общается не с Op возвращает заменяющую историю в формате, который ожидает Codex. 8. **Adapt** — в остальных случаях `buildRequest()` выбранного адаптера формирует HTTP-запрос к - вышестоящему провайдеру (URL, заголовки, тело) в нативном формате провайдера, и opencodex + вышестоящему провайдеру (URL, заголовки, тело) в нативном формате провайдера, и CodexCommander выполняет его через `fetch`. 9. **Bridge** — `parseStream()` адаптера (или `parseResponse()`) порождает внутренние события @@ -112,10 +112,10 @@ Codex даже не догадывается, что общается не с Op </Steps> -## Почему прокси, а не форк Codex? +## Зачем нужен протокольный прокси? В Codex протокол Responses API жёстко зашит. Выполняя преобразование на границе протокола, -opencodex работает с **CLI, App и SDK** Codex без изменений, переживает обновления Codex и +CodexCommander работает с **CLI, App и SDK** Codex без изменений, переживает обновления Codex и позволяет переключать провайдеров для каждого запроса, не трогая сам Codex. Преобразование двунаправленное и точно сохраняет стриминг: сводки рассуждений, пространства имён MCP-инструментов, freeform-инструменты (`apply_patch`) и обнаружение через `tool_search` — всё корректно проходит в diff --git a/docs-site/src/content/docs/ru/getting-started/installation.md b/docs-site/src/content/docs/ru/getting-started/installation.md index 7825c85993..e8c43cdcd7 100644 --- a/docs-site/src/content/docs/ru/getting-started/installation.md +++ b/docs-site/src/content/docs/ru/getting-started/installation.md @@ -1,9 +1,9 @@ --- title: Установка -description: Установите прокси opencodex (ocx) и необходимые компоненты и убедитесь, что он запускается. +description: Установите прокси CodexCommander (ccx) и необходимые компоненты и убедитесь, что он запускается. --- -opencodex устанавливает два эквивалентных имени команды: `ocx` и `opencodex`. Обе запускают один и +В пакетной или локально связанной сборке CodexCommander предоставляет два эквивалентных имени команды: `ccx` и `codexcommander`. Обе запускают один и тот же небольшой локальный HTTP-сервер (построенный на Bun). Запросы к моделям идут к провайдеру, выбранному маршрутизацией; опциональные сайдкары для vision и веб-поиска также могут использовать ваш вход в ChatGPT, когда они нужны маршрутизируемой модели. @@ -12,87 +12,58 @@ opencodex устанавливает два эквивалентных имен | Требование | Зачем | | --- | --- | -| **[Node](https://nodejs.org) ≥ 18** | `ocx` работает на рантайме Bun, но рантайм автоматически поставляется в комплекте при `npm install` — устанавливать Bun самостоятельно **не нужно**. | -| **[OpenAI Codex](https://openai.com/codex)** (CLI, App или SDK) | Клиент, перед которым работает opencodex. opencodex записывает данные в `$CODEX_HOME/config.toml` (по умолчанию `~/.codex/config.toml`). | +| **[Bun](https://bun.sh)** | Исходный рантайм и скрипты репозитория выполняются непосредственно через Bun. | +| **[OpenAI Codex](https://openai.com/codex)** (CLI, App или SDK) | Клиент, перед которым работает CodexCommander. CodexCommander записывает данные в `$CODEX_HOME/config.toml` (по умолчанию `~/.codex/config.toml`). | | Аккаунт провайдера или API-ключ | Anthropic, xAI, Kimi, Ollama Cloud, OpenRouter, OpenAI-совместимая конечная точка или ваш вход в ChatGPT. | -## Установка +## Запуск исходного checkout ```bash -npm install -g @bitkyc08/opencodex -``` - -:::note[npm заблокировал postinstall-скрипт bun?] -Свежие версии npm могут блокировать postinstall-скрипт bun (`npm warn -install-scripts ... blocked because they are not covered by allowScripts`), -из-за чего встроенный рантайм Bun остаётся неподготовленным. Переустановите -пакет, разрешив скрипт bun, — и обязательно указывайте имя пакета: в -сокращённой подсказке npm его нет, и без него вместо пакета переустановится -текущий каталог: - -```bash -npm install -g --allow-scripts=bun @bitkyc08/opencodex - -# если изначально устанавливали через sudo, продолжайте использовать sudo: -sudo npm install -g --allow-scripts=bun @bitkyc08/opencodex -``` -::: - -Убедитесь, что оба псевдонима команды доступны в `PATH`: - -```bash -ocx --version -opencodex --version +bun install +bun run build:gui +bun run src/cli/index.ts start ``` -### Каналы релизов - -Стабильный канал `latest` уже включает поддержку каталога GPT-5.6 Sol/Terra/Luna для маршрутов -ChatGPT, OpenAI по API-ключу, OpenRouter и экспериментального Cursor. Доступ у вышестоящего -провайдера по-прежнему зависит от аккаунта; сами по себе записи каталога доступ не дают. -Используйте канал preview только для тестирования ещё не выпущенных сборок opencodex: +Пакет в реестре сейчас не опубликован. В этом checkout заменяйте `ccx <args>` на +`bun run src/cli/index.ts <args>`. В другом терминале проверьте рантайм: ```bash -npm install -g @bitkyc08/opencodex@preview -ocx update --tag preview +bun run src/cli/index.ts --version ``` -## Запуск из исходного кода +## Режим разработки -Чтобы работать над самим opencodex: +При изменении UI запускайте прокси и панель управления отдельно: ```bash -git clone https://github.com/pavelhov/opencodex.git -cd opencodex -bun install bun run dev:proxy # запускает API прокси в режиме разработки (src/cli/index.ts start) bun run dev:gui # запускает dev-сервер панели управления (в другом терминале) ``` -`bun run dev` остаётся псевдонимом для `bun run dev:proxy`. API прокси предоставляет `/healthz`, +`bun run dev` — псевдоним для `bun run dev:proxy`. API прокси предоставляет `/healthz`, `/v1/responses` и `/api/*`; `GET /` отдаёт упакованную панель управления только после того, как `bun run build:gui` создаст `gui/dist`. Пока вы работаете над панелью управления, запускайте -фронтенд отдельно командой `bun run dev:gui`. +фронтенд отдельно командой `bun run dev:gui`. Компаньон macOS собирается из того же checkout командами `bun run test:macos && bun run build:macos`; исходная сборка находится в `dist/macos/CodexCommander.app`. ## Что создаётся -Состояние opencodex хранится в `$OPENCODEX_HOME` (по умолчанию `~/.opencodex`). Файлы интеграции +Состояние CodexCommander хранится в `$CODEXCOMMANDER_HOME` (по умолчанию `~/.codexcommander`). Файлы интеграции с Codex находятся в `$CODEX_HOME` (по умолчанию `~/.codex`). | Путь | Назначение | | --- | --- | -| `$OPENCODEX_HOME/config.json` | Ваши провайдеры, провайдер по умолчанию, порт и параметры. | -| `$OPENCODEX_HOME/ocx.pid` | PID запущенного прокси (защита от повторного запуска). | -| `$OPENCODEX_HOME/runtime-port.json` | Текущие PID, имя хоста и порт, включая автоматически выбранный запасной порт. | -| `$OPENCODEX_HOME/auth.json` | Сохранённые учётные данные OAuth (после `ocx login`). | -| `$OPENCODEX_HOME/catalog-backup*.json` | Резервные копии каталога моделей Codex, создаваемые перед тем, как opencodex его изменит. | -| `$CODEX_HOME/config.toml` | На loopback-адресе opencodex добавляет корневой `openai_base_url`, отмеченный собственным маркером; при привязке не к loopback используются `model_provider = "opencodex"` и `[model_providers.opencodex]`, чтобы Codex мог отправлять заголовок API-аутентификации. | -| `$CODEX_HOME/opencodex.config.toml` | Резервный/справочный профиль, записываемый рядом с основной конфигурацией Codex. | -| `$CODEX_HOME/opencodex-catalog.json` | Синхронизированный каталог нативных и маршрутизируемых моделей, используемый Codex. | +| `$CODEXCOMMANDER_HOME/config.json` | Ваши провайдеры, провайдер по умолчанию, порт и параметры. | +| `$CODEXCOMMANDER_HOME/codexcommander.pid` | PID запущенного прокси (защита от повторного запуска). | +| `$CODEXCOMMANDER_HOME/runtime-port.json` | Текущие PID, имя хоста и порт, включая автоматически выбранный запасной порт. | +| `$CODEXCOMMANDER_HOME/auth.json` | Сохранённые учётные данные OAuth (после `ccx login`). | +| `$CODEXCOMMANDER_HOME/catalog-backup-<catalog-id>.json` | Резервные копии каталога моделей Codex, создаваемые перед тем, как CodexCommander его изменит. | +| `$CODEX_HOME/config.toml` | На loopback-адресе CodexCommander добавляет корневой `openai_base_url`, отмеченный собственным маркером; при привязке не к loopback используются `model_provider = "codexcommander"` и `[model_providers.codexcommander]`, чтобы Codex мог отправлять заголовок API-аутентификации. | +| `$CODEX_HOME/codexcommander.config.toml` | Резервный/справочный профиль, записываемый рядом с основной конфигурацией Codex. | +| `$CODEX_HOME/codexcommander-catalog.json` | Синхронизированный каталог нативных и маршрутизируемых моделей, используемый Codex. | :::note -opencodex никогда не удаляет вашу конфигурацию Codex. Каждое внедрение обратимо — `ocx stop`, -`ocx restore` или `ocx eject` убирают ровно те строки, которые добавил opencodex, и восстанавливают +CodexCommander никогда не удаляет вашу конфигурацию Codex. Каждое внедрение обратимо — `ccx stop`, +`ccx restore` или `ccx eject` убирают ровно те строки, которые добавил CodexCommander, и восстанавливают нативный Codex. ::: diff --git a/docs-site/src/content/docs/ru/getting-started/quickstart.md b/docs-site/src/content/docs/ru/getting-started/quickstart.md index 3df7ddb252..7b96f78d80 100644 --- a/docs-site/src/content/docs/ru/getting-started/quickstart.md +++ b/docs-site/src/content/docs/ru/getting-started/quickstart.md @@ -1,6 +1,6 @@ --- title: Быстрый старт -description: Настройте первого провайдера и направьте OpenAI Codex через opencodex тремя командами. +description: Настройте первого провайдера и направьте OpenAI Codex через CodexCommander тремя командами. --- Это руководство проводит от чистой установки до запуска Codex с моделью не от OpenAI. @@ -8,10 +8,10 @@ description: Настройте первого провайдера и напр ## 1. Запустите мастер настройки ```bash -ocx init +ccx init ``` -`ocx init` проведёт вас по следующим шагам: +`ccx init` проведёт вас по следующим шагам: 1. **Выбор провайдера** — выберите один из 76 встроенных пресетов реестра или `custom`, чтобы ввести базовый URL и адаптер вручную. @@ -19,17 +19,17 @@ ocx init 3. **Модель по умолчанию** — для провайдеров с ключом, локальных и `custom` примите значение из пресета или введите id модели. 4. **Порт прокси** — по умолчанию `10100`. -5. **Внедрить в Codex?** — при обычной loopback-настройке opencodex добавляет корневой +5. **Внедрить в Codex?** — при обычной loopback-настройке CodexCommander добавляет корневой `openai_base_url` в `$CODEX_HOME/config.toml` (по умолчанию `~/.codex/config.toml`), чтобы встроенный провайдер `openai` в Codex указывал на прокси. При привязке к удалённым/LAN-адресам вместо этого используется отдельная запись провайдера с заголовком API-аутентификации. 6. **Установить shim автозапуска?** — если включено, при запуске `codex` сначала выполняется - `ocx ensure`. + `ccx ensure`. -Результат сохраняется в `$OPENCODEX_HOME/config.json` (по умолчанию `~/.opencodex/config.json`). +Результат сохраняется в `$CODEXCOMMANDER_HOME/config.json` (по умолчанию `~/.codexcommander/config.json`). :::note[Записи rollout GPT-5.6] -Текущий стабильный релиз добавляет GPT-5.6 Sol/Terra/Luna для passthrough ChatGPT, OpenAI по +Текущее дерево исходников добавляет GPT-5.6 Sol/Terra/Luna для passthrough ChatGPT, OpenAI по API-ключу, OpenRouter и экспериментального адаптера Cursor. Они работают только тогда, когда у соответствующего вышестоящего аккаунта есть доступ. Пресеты OpenAI по API-ключу и OpenRouter заявляют используемое контекстное окно в 372 000 токенов; Cursor сохраняет собственные метаданные @@ -39,30 +39,30 @@ API-ключу, OpenRouter и экспериментального адапте ## 2. Запустите прокси ```bash -ocx start # defaults to port 10100 -ocx start --port 8080 +ccx start # defaults to port 10100 +ccx start --port 8080 ``` -При запуске opencodex: +При запуске CodexCommander: -- записывает свой PID в `~/.opencodex/ocx.pid` (и отказывается запускаться повторно), +- записывает свой PID в `~/.codexcommander/codexcommander.pid` (и отказывается запускаться повторно), - обнаруживает живые модели там, где провайдер это поддерживает, и **синхронизирует нативные и маршрутизируемые записи в каталог моделей Codex**, - слушает `http://localhost:<port>/v1`. -Если запрошенный порт занят, `ocx start` выбирает свободный порт, записывает его в +Если запрошенный порт занят, `ccx start` выбирает свободный порт, записывает его в `runtime-port.json` и обновляет настройки Codex, чтобы тот использовал актуальный адрес. Проверьте: ```bash -ocx status -ocx gui # open the dashboard on the live port +ccx status +ccx gui # open the dashboard on the live port ``` ## 3. Используйте Codex -Теперь Codex прозрачно общается с opencodex: +Теперь Codex прозрачно общается с CodexCommander: ```bash codex "Refactor this function for readability" @@ -79,7 +79,7 @@ codex -m "ollama-cloud/glm-5.2" "Write a SQL migration" ## Выбор моделей подагентов (опционально) В свежей конфигурации в селекторе подагентов Codex представлены пять нативных моделей: `gpt-5.5`, -`gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna` и `gpt-5.4-mini`. Откройте `ocx gui`, чтобы +`gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna` и `gpt-5.4-mini`. Откройте `ccx gui`, чтобы заменить или переупорядочить до пяти нативных или маршрутизируемых моделей. В панели управления также можно задать одну предпочитаемую модель подагента и уровень рассуждений. Раздел [Поверхность подагентов](/guides/sub-agent-surface/) поможет выбрать v1/base/v2 и понять, когда @@ -88,12 +88,12 @@ codex -m "ollama-cloud/glm-5.2" "Write a SQL migration" ## Вход в аккаунт вместо вставки ключа Некоторые провайдеры поддерживают полноценный вход в аккаунт. OAuth-данные, принадлежащие -OpenCodex, обновляются автоматически; связанные сессии нативного Grok/Kimi CLI остаются во +CodexCommander, обновляются автоматически; связанные сессии нативного Grok/Kimi CLI остаются во владении CLI: ```bash -ocx login xai # or: anthropic, kimi, kiro, google-antigravity, cursor -ocx logout xai +ccx login xai # or: anthropic, kimi, kiro, google-antigravity, cursor +ccx logout xai ``` Самому OpenAI ключ **не нужен** — провайдер по умолчанию напрямую пересылает ваши существующие @@ -102,9 +102,9 @@ ocx logout xai ## Остановка и восстановление ```bash -ocx stop # stop the proxy and restore native Codex -ocx restore # restore native Codex without stopping (alias: ocx eject) -ocx restore back # route Codex through the still-running proxy again +ccx stop # stop the proxy and restore native Codex +ccx restore # restore native Codex without stopping (alias: ccx eject) +ccx restore back # route Codex through the still-running proxy again ``` ## Далее diff --git a/docs-site/src/content/docs/ru/guides/claude-code.md b/docs-site/src/content/docs/ru/guides/claude-code.md index 7d3a65ce91..819d1754b1 100644 --- a/docs-site/src/content/docs/ru/guides/claude-code.md +++ b/docs-site/src/content/docs/ru/guides/claude-code.md @@ -1,9 +1,9 @@ --- title: Claude Code -description: Используйте любую маршрутизируемую модель из Claude Code — opencodex обслуживает Anthropic Messages API и обнаружение моделей шлюза на одном и том же порту. +description: Используйте любую маршрутизируемую модель из Claude Code — CodexCommander обслуживает Anthropic Messages API и обнаружение моделей шлюза на одном и том же порту. --- -opencodex обслуживает `POST /v1/messages` (а также `count_tokens`) наряду с `/v1/responses`, поэтому +CodexCommander обслуживает `POST /v1/messages` (а также `count_tokens`) наряду с `/v1/responses`, поэтому Claude Code может использовать все маршрутизируемые провайдеры — включая OAuth-входы, пулы аккаунтов, отказоустойчивое переключение (failover) ключей и сайдкары — без какой-либо дополнительной работы по аутентификации. @@ -11,10 +11,10 @@ Claude Code может использовать все маршрутизиру ## Быстрый старт ```bash -ocx claude +ccx claude ``` -`ocx claude` убеждается, что прокси запущен, а затем запускает Claude Code с уже настроенным окружением: +`ccx claude` убеждается, что прокси запущен, а затем запускает Claude Code с уже настроенным окружением: | Переменная | Значение | | --- | --- | @@ -22,27 +22,24 @@ ocx claude | `ANTHROPIC_AUTH_TOKEN` | Только когда прокси требует API-ключ — иначе переменная НЕ устанавливается, поэтому ваш вход в claude.ai (подписка + коннекторы) остаётся активным | | `CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY` | `1` (обнаружение моделей в нативном селекторе `/model`) | | `CLAUDE_CODE_AUTO_COMPACT_WINDOW` | Порог автосжатия контекста (по умолчанию `350000`); внедряется только при включённом автоконтексте | -| `ANTHROPIC_MODEL` | `claudeCode.model` (необязательно) | -| `ANTHROPIC_DEFAULT_HAIKU_MODEL` | `claudeCode.tierModels.haiku ?? claudeCode.smallFastModel` (необязательно; поддерживается и устаревшая `ANTHROPIC_SMALL_FAST_MODEL`) | -| `ANTHROPIC_DEFAULT_{OPUS,SONNET,FABLE}_MODEL` | `claudeCode.tierModels.*` (необязательно) | -| `CLAUDE_CODE_ALWAYS_ENABLE_EFFORT` | `1`, когда включён `alwaysEnableEffort` (условно) | -| `CLAUDE_CODE_MAX_CONTEXT_TOKENS` / `DISABLE_COMPACT` | Устаревшее переопределение контекста, когда задан `maxContextTokens` (условно) | -Переменные, которые вы экспортируете сами, всегда имеют приоритет. Дополнительные аргументы передаются как есть: `ocx claude -p "hello"`. +| `ANTHROPIC_DEFAULT_HAIKU_MODEL` / `ANTHROPIC_SMALL_FAST_MODEL` | `claudeCode.smallFastModel`, если настроен | + +Переменные, которые вы экспортируете сами, всегда имеют приоритет. Дополнительные аргументы передаются как есть: `ccx claude -p "hello"`. ## Интеграция с системным окружением (macOS) -Когда `claudeCode.systemEnv` установлен в `true` (по умолчанию: **выключено**), `ocx start` +Когда `claudeCode.systemEnv` установлен в `true` (по умолчанию: **выключено**), `ccx start` использует `launchctl setenv`, чтобы внедрить `ANTHROPIC_BASE_URL` и связанные переменные окружения Claude Code на уровне всей системы. Поэтому новые окна и вкладки терминала направляют -обычные команды `claude` через прокси без обёртки `ocx claude`. Уже открытые оболочки не +обычные команды `claude` через прокси без обёртки `ccx claude`. Уже открытые оболочки не затрагиваются — их нужно открыть заново. -`ocx stop` и остановка прокси **снимают внедрённые ключи** (прежние значения не восстанавливаются — -удаляются только ключи, внедрённые opencodex). Прокси также записывает `~/.opencodex/claude-env.sh`; -`ocx start` устанавливает source-хук в `.zshrc`, который загружает этот файл автоматически. +`ccx stop` и остановка прокси **снимают внедрённые ключи** (прежние значения не восстанавливаются — +удаляются только ключи, внедрённые CodexCommander). Прокси также записывает `~/.codexcommander/claude-env.sh`; +`ccx start` устанавливает source-хук в `.zshrc`, который загружает этот файл автоматически. Отключить можно параметром `claudeCode.systemEnv: false` в конфигурации или переключателем в GUI. -Функция доступна только на macOS; на других платформах используйте `ocx claude`. +Функция доступна только на macOS; на других платформах используйте `ccx claude`. ## Нативный проброс Claude (прямое подключение подписки) @@ -54,13 +51,13 @@ ocx claude работать в той же сессии через алиасы селектора. **Обработка заголовков:** hop-by-hop-заголовки, а также `host`, `content-length`, -`accept-encoding`, `x-opencodex-api-key` и `origin` удаляются перед пересылкой. Все остальные +`accept-encoding`, `x-codexcommander-api-key` и `origin` удаляются перед пересылкой. Все остальные заголовки (включая `anthropic-beta` и `anthropic-version`) проходят без изменений. Проброс срабатывает, когда выполнены **все четыре** условия: `nativePassthrough` не равен `false`; имя модели начинается с `claude` или `anthropic`; bearer или `x-api-key` начинается с `sk-ant-`; и разрешение алиасов и карты моделей возвращает ту же модель без изменений. Это также означает, -что предупреждение «claude.ai connectors are disabled» с `ocx claude` больше не появляется. +что предупреждение «claude.ai connectors are disabled» с `ccx claude` больше не появляется. Отключается параметром `claudeCode.nativePassthrough: false`; другой адрес задаётся через `claudeCode.anthropicBaseUrl`. @@ -69,30 +66,26 @@ ocx claude Claude Code 2.1.129+ обнаруживает модели шлюза через `GET /v1/models?limit=1000` и показывает их в нативном селекторе `/model` в разделе «From gateway». Поскольку селектор принимает только id, -начинающиеся с `claude` или `anthropic`, opencodex публикует маршрутизируемые модели как +начинающиеся с `claude` или `anthropic`, CodexCommander публикует маршрутизируемые модели как стабильные обратимые алиасы: | Интерфейс | Формат | Пример | | --- | --- | --- | -| Claude Code CLI | `claude-ocx-<provider>--<model>` (plain) или `claude-ocx2-…` (escaped) | `claude-ocx-native--gpt-5.6-sol` | +| Claude Code CLI | `claude-ccx2-<provider>--<model>` (plain) или `claude-ccx2-…` (escaped) | `claude-ccx2-native--gpt-5.6-sol` | | Claude Desktop 3P | `claude-opus-4-8-<code>` (3-символьный base36-хеш) | `claude-opus-4-8-ncb` | Прокси выбирает семейство для каждого запроса: приоритет у `?ids=cli` или `?ids=desktop`; иначе user-agent `claude-code/*` получает читаемую CLI-форму, а остальные клиенты — Desktop-хеш. Оба -семейства декодируются бессрочно — модель, сохранённая в `settings.json` в любой из форм, -продолжает работать. +текущих семейства разрешаются через реестр алиасов запущенного процесса. Если нижний селектор Claude Desktop не переключает модель в уже запущенном 3P-диалоге, -используйте `/model <id>` внутри этого диалога. OpenCodex не видит состояние селектора и +используйте `/model <id>` внутри этого диалога. CodexCommander не видит состояние селектора и маршрутизирует id модели из каждого запроса. Результат можно проверить в **Logs → requestedModel**. **Правила грамматики алиасов:** provider не может содержать `/` или `--` и не может быть равен -`native`. Обычные id моделей (без `/` и `~`) остаются с префиксом v1 `claude-ocx-…`. Id с `/` -или `~` выпускаются с префиксом v2 `claude-ocx2-…` и экранированием (`/` → `~s`, `~` → `~t`), +`native`. Текущая кодировка `claude-ccx2-…` экранирует `/` как `~s`, а `~` как `~t`, например `openrouter/anthropic/claude-opus-4-8` → -`claude-ocx2-openrouter--anthropic~sclaude-opus-4-8`. Алиасы v1 декодируются литерально (исторические -двухсимвольные последовательности `~s` / `~t` в id модели сохраняются); алиасы v2 раскрывают -экранирование. Маршруты, которые невозможно выразить читаемой формой, откатываются на +`claude-ccx2-openrouter--anthropic~sclaude-opus-4-8`. Маршруты, которые невозможно выразить читаемой формой, откатываются на хешированный алиас. Id моделей МОГУТ содержать `--` (при разрешении разбиение выполняется только по первому `--`); нативные слаги с `--` откатываются на хешированную форму. @@ -121,11 +114,10 @@ Anthropic сохраняют канонические id в обоих инте 2. Внедряется `CLAUDE_CODE_AUTO_COMPACT_WINDOW` (по умолчанию `350000`, диапазон `100000`–`1000000`), чтобы в этой точке диалог автоматически резюмировался. -Три состояния конфигурации: +Два состояния конфигурации: - **отсутствует / `true`:** включено (по умолчанию) - **`false`:** выключено — ни маркеров, ни внедрения окна сжатия -- **задан устаревший `maxContextTokens`:** автоконтекст неявно отключается Значение сжатия настраивается на странице Claude. **Предупреждение:** если поднять его выше реального окна модели, эта модель ломается — чат завершится ошибкой раньше, чем успеет сработать @@ -138,39 +130,37 @@ Anthropic сохраняют канонические id в обоих инте ### Эффективное окружение моделей -`effectiveModelEnv` вычисляет шесть слотов, внедряемых `ocx claude`, системным окружением и -shell-файлом: `ANTHROPIC_MODEL`, четыре `ANTHROPIC_DEFAULT_{OPUS,SONNET,HAIKU,FABLE}_MODEL` и -устаревший `ANTHROPIC_SMALL_FAST_MODEL`. Эффективное значение Haiku — `tierModels.haiku ?? -smallFastModel`; оно подставляется в обе переменные Haiku. +`effectiveModelEnv` вычисляет два вспомогательных слота, внедряемых `ccx claude`, системным +окружением и shell-файлом: `ANTHROPIC_DEFAULT_HAIKU_MODEL` и `ANTHROPIC_SMALL_FAST_MODEL`. +Оба получают значение `claudeCode.smallFastModel`. -Если отсутствуют и `tierModels.haiku`, и `smallFastModel`, OpenCodex оставляет обе переменные вспомогательной модели незаданными. Затем Claude Code выбирает нативную вспомогательную модель (сейчас Sonnet), что может привести к расходам у нативного провайдера. +Если `smallFastModel` отсутствует, CodexCommander оставляет обе переменные вспомогательной модели незаданными. Затем Claude Code выбирает нативную вспомогательную модель, что может привести к расходам у нативного провайдера. ## Агенты из ростера (injectAgents) -`ocx claude` (и демон системного окружения) синхронизирует ваш ростер избранных подагентов -(вкладка Subagents, до 5 моделей) плюс `ocx-self` в `~/.claude/agents/ocx-*.md`. +`ccx claude` (и демон системного окружения) синхронизирует ваш ростер избранных подагентов +(вкладка Subagents, до 5 моделей) плюс `ccx-self` в `~/.claude/agents/ccx-*.md`. -- **`ocx-self`** закрепляет модель по умолчанию из селектора `/model` (с откатом на - `claudeCode.model`); если нет ни того, ни другого, файл не создаётся. Наследование модели - НЕ используется. -- В теле каждого агента есть директива `<!-- ocx-route: <model> -->` — по ней прокси закрепляет +- **`ccx-self`** закрепляет модель по умолчанию из селектора `/model`; если её нет, файл не + создаётся. Наследование модели НЕ используется. +- В теле каждого агента есть директива `<!-- ccx-route: <model> -->` — по ней прокси закрепляет реальный маршрут. Поэтому аргумент `model` инструмента Agent не действует; передавайте `"haiku"` как плейсхолдер. - Frontmatter содержит алиас; маршрутизация определяется директивой. -- Перезаписываются или удаляются только проверенные по маркеру файлы `ocx-*.md`, содержащие - `generated-by: opencodex`; ваши собственные агенты никогда не затрагиваются. +- Перезаписываются или удаляются только проверенные по маркеру файлы `ccx-*.md`, содержащие + `generated-by: codexcommander`; ваши собственные агенты никогда не затрагиваются. - Каждый файл синхронизируется атомарно (write + rename). - `enabled: false` или `injectAgents: false` удаляет все определения с подтверждённым владением. - PUT из GUI и изменения ростера пересинхронизируются немедленно; лаунчер и системное окружение синхронизируются при запуске. -Диспетчеризация: `subagent_type: "ocx-gpt-5-6-sol"`. Цели с поддержкой 1M автоматически получают `[1m]`. +Диспетчеризация: `subagent_type: "ccx-gpt-5-6-sol"`. Цели с поддержкой 1M автоматически получают `[1m]`. ## Подмена встроенных скиллов (blockedSkills) Встроенный в Claude Code скилл `claude-api` внедряет ~840 КБ (~136k токенов) документации Anthropic и автоматически срабатывает при упоминании моделей Claude. Маршрутизируемые модели на -этом пакете не обучались, поэтому по умолчанию opencodex подменяет содержимое скилла короткой +этом пакете не обучались, поэтому по умолчанию CodexCommander подменяет содержимое скилла короткой заглушкой в **маршрутизируемых** запросах. Нативный проброс Anthropic не затрагивается. **Обрабатываются два способа доставки:** @@ -204,7 +194,7 @@ Anthropic и автоматически срабатывает при упоми ## Матрица сайдкаров: веб-поиск и понимание изображений Не у всех маршрутизируемых моделей одинаковый набор серверных (hosted) инструментов и поддержка -изображений. opencodex закрывает эти пробелы до того, как ответит основная модель: +изображений. CodexCommander закрывает эти пробелы до того, как ответит основная модель: - **Сайдкар веб-поиска** выполняет настоящий серверный поиск, а затем передаёт маршрутизируемой модели ответ и источники как результат инструмента. @@ -218,10 +208,10 @@ Anthropic и автоматически срабатывает при упоми | `openai` | Небольшая GPT-модель через провайдер ChatGPT `forward` | Вход в ChatGPT и включённый провайдер с `authMode: "forward"` | | `anthropic` | Claude через сохранённый Anthropic OAuth; веб-поиск использует `web_search_20250305`, а vision отправляет изображение Claude для описания | Включённый провайдер с `adapter: "anthropic"`, `authMode: "oauth"`, чей активный сохранённый аккаунт не помечен `needsReauth` | -Явно указанный `backend` всегда имеет приоритет. Если он не задан, opencodex выбирает +Явно указанный `backend` всегда имеет приоритет. Если он не задан, CodexCommander выбирает `anthropic`, когда существует пригодный сохранённый аккаунт Anthropic OAuth; иначе — `openai`. Явный выбор `anthropic` без пригодных учётных данных **завершается отказом (fail closed)**: -opencodex не заимствует втихую учётные данные ChatGPT и не переключает бэкенды. Бэкенд OpenAI +CodexCommander не заимствует втихую учётные данные ChatGPT и не переключает бэкенды. Бэкенд OpenAI точно так же не включается без одновременного наличия входа в ChatGPT и forward-провайдера. При внутреннем повторе маршрутизируемых запросов, пришедших из Claude, к запросу прикрепляется @@ -336,8 +326,8 @@ id/name; именованный `tool_choice` без имени. ## Отладочный захват -Захват входящих запросов управляется командой `ocx debug claude on|off|status|reset`, переменной -`OCX_CLAUDE_DEBUG=1` или запросом `PUT /api/debug {"claude": true}`. +Захват входящих запросов управляется командой `ccx debug claude on|off|status|reset`, переменной +`CCX_CLAUDE_DEBUG=1` или запросом `PUT /api/debug {"claude": true}`. `GET /api/claude/inbound-debug` возвращает `{enabled, entries}` (сначала новые, кольцевой буфер на 20 записей). @@ -353,7 +343,7 @@ id/name; именованный `tool_choice` без имени. **Claude ON** (надпись намеренно одинакова на всех языках). Страница показывает: - Аварийный выключатель входящего трафика (переключатель enabled) -- Быстрый старт (`ocx claude`) и блок ручной настройки окружения +- Быстрый старт (`ccx claude`) и блок ручной настройки окружения - Селектор Fast Mode (Auto / ON / OFF) - Переключатель автоконтекста и выпадающий список порога сжатия - Переключатель автоматической регистрации подагентов @@ -369,8 +359,8 @@ id/name; именованный `tool_choice` без имени. **Claude Code пишет «Did 0 searches»** — текущие сборки преобразуют завершённые элементы Responses `web_search_call` в парные блоки Anthropic `server_tool_use` и -`web_search_tool_result`, включая `usage.server_tool_use.web_search_requests`. Если в старой -сборке поиск выполнялся, но Claude Code всё равно насчитывал ноль, обновите opencodex. +`web_search_tool_result`, включая `usage.server_tool_use.web_search_requests`. Если поиск выполняется, +но Claude Code всё равно насчитывает ноль, проверьте, что запущенный процесс CodexCommander пересобран из текущего checkout. **Сайдкар не активируется** — для `backend: "openai"` проверьте, что выполнен вход в ChatGPT и есть включённый провайдер с `authMode: "forward"`. Для `backend: "anthropic"` проверьте, что @@ -378,18 +368,18 @@ Responses `web_search_call` в парные блоки Anthropic `server_tool_us таких учётных данных намеренно завершается отказом. **«claude.ai connectors are disabled»** — в вашей оболочке задан `ANTHROPIC_API_KEY` или -`ANTHROPIC_AUTH_TOKEN`. `ocx claude` намеренно НЕ устанавливает `ANTHROPIC_API_KEY`; если вы -экспортировали его сами, снимите переменную. `ocx claude` внедряет `ANTHROPIC_BASE_URL`, +`ANTHROPIC_AUTH_TOKEN`. `ccx claude` намеренно НЕ устанавливает `ANTHROPIC_API_KEY`; если вы +экспортировали его сами, снимите переменную. `ccx claude` внедряет `ANTHROPIC_BASE_URL`, обнаружение моделей, автоконтекст и настроенные слоты моделей — но никогда `ANTHROPIC_API_KEY`. **Модели не появляются в селекторе /model** — убедитесь, что установлена -`CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1` (с `ocx claude` — автоматически). Запустите -`ocx claude`, чтобы обновить кеш моделей шлюза в `~/.claude/cache/gateway-models.json`. +`CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1` (с `ccx claude` — автоматически). Запустите +`ccx claude`, чтобы обновить кеш моделей шлюза в `~/.claude/cache/gateway-models.json`. Проверьте, что `claudeCode.enabled` не равен `false`. -**Устаревшее окружение после смены порта** — если порт прокси изменился, в старых оболочках -может остаться устаревший `ANTHROPIC_BASE_URL`. Откройте новый терминал или повторно запустите -`ocx claude`. +**Окружение после смены порта** — если порт прокси изменился, в уже открытых оболочках +может остаться прежний `ANTHROPIC_BASE_URL`. Откройте новый терминал или повторно запустите +`ccx claude`. **Потолок контекста 200k, хотя модель больше** — выберите в селекторе вариант `[1m]` или включите автоконтекст (включён по умолчанию). Если строки `[1m]` в селекторе нет, подтверждённое @@ -397,9 +387,9 @@ Responses `web_search_call` в парные блоки Anthropic `server_tool_us **Большой расход токенов при загрузке скиллов** — встроенный скилл `claude-api` (~136k токенов) автоматически загружается при упоминании моделей Claude. Для нативного проброса это нормально; -для маршрутизируемых моделей opencodex по умолчанию подставляет заглушку +для маршрутизируемых моделей CodexCommander по умолчанию подставляет заглушку (`blockedSkills: ["claude-api"]`). -**Подагент отправляется не в ту модель** — агенты из ростера (`ocx-*`) используют директивы -`<!-- ocx-route: ... -->`, а не аргумент `model` инструмента Agent. Убедитесь, что директива +**Подагент отправляется не в ту модель** — агенты из ростера (`ccx-*`) используют директивы +`<!-- ccx-route: ... -->`, а не аргумент `model` инструмента Agent. Убедитесь, что директива соответствует нужному маршруту. В качестве плейсхолдера модели передавайте `"haiku"`. diff --git a/docs-site/src/content/docs/ru/guides/codex-app-models.md b/docs-site/src/content/docs/ru/guides/codex-app-models.md index 938c594949..343d068875 100644 --- a/docs-site/src/content/docs/ru/guides/codex-app-models.md +++ b/docs-site/src/content/docs/ru/guides/codex-app-models.md @@ -1,16 +1,16 @@ --- title: Селектор моделей Codex App -description: Как модели opencodex появляются в Codex App, Codex CLI и Codex TUI через общий каталог Codex. +description: Как модели CodexCommander появляются в Codex App, Codex CLI и Codex TUI через общий каталог Codex. --- -opencodex не патчит Codex App. Он записывает ту же конфигурацию Codex и тот же каталог моделей, +CodexCommander не патчит Codex App. Он записывает ту же конфигурацию Codex и тот же каталог моделей, которыми уже пользуются Codex CLI/TUI. Поскольку Codex App читает это общее состояние, маршрутизируемые модели могут появляться в picker'е App как обычные записи каталога Codex. Записи OpenAI используют два credential-транспорта: нативный вход Codex и namespaced-транспорт API-ключа `openai-apikey/<model>`. Само по себе переключение `codexAccountMode` между Pool и Direct не меняет id в picker'е. Однако если в `codexAccountNamespaces` есть подходящие селекторы, -opencodex добавляет для сопоставленных аккаунтов отдельные строки +CodexCommander добавляет для сопоставленных аккаунтов отдельные строки `<selector>/<native-openai-model>` и скрывает bare native-строки из picker'а. Имена селекторов — это публичные метки, которые выбирает пользователь; встроенного смысла роли аккаунта у них нет. Выбор строки с селектором использует только сопоставленный аккаунт, не меняет активный аккаунт Pool @@ -33,26 +33,17 @@ gpt-5.6-sol # bare-маршрут входа Codex че openai-apikey/gpt-5.6-sol # API key ``` -Свежие установки и конфигурации без сохранённого режима по умолчанию используют Pool. Текущие -конфигурации помечены marker 2 и сохраняют исходник shipped v1 в -`~/.opencodex/config.json.pre-openai-tiers-v2.bak`; вернуть его можно так: - -```sh -cp ~/.opencodex/config.json.pre-openai-tiers-v2.bak ~/.opencodex/config.json -``` - -Более ранние трёхпровайдерные конфигурации v1 автоматически мигрируют в одну строку с -переключаемым режимом. +Свежие установки и конфигурации без сохранённого режима по умолчанию используют Pool. ## Путь интеграции -`ocx init`, `ocx start` и `ocx sync` подключают общий конфиг и каталог Codex к прокси; подробности +`ccx init`, `ccx start` и `ccx sync` подключают общий конфиг и каталог Codex к прокси; подробности о внедрении конфигурации, синхронизации каталога, shim'ах, fallback с WebSocket и механике восстановления см. в [Интеграции с Codex](/guides/codex-integration/). ## Почему появляются маршрутизируемые модели -Picker моделей Codex ожидает записи каталога в формате Codex. opencodex строит маршрутизируемые +Picker моделей Codex ожидает записи каталога в формате Codex. CodexCommander строит маршрутизируемые записи, клонируя шаблон нативной модели Codex и затем заменяя идентичность на routed-модель: ```text @@ -62,13 +53,13 @@ visibility = "list" ``` Клон сохраняет поля, нужные строгому парсеру: reasoning level'ы, тип shell, флаги поддержки API и -базовые инструкции. После этого opencodex убирает нативные возможности, которые данный маршрут +базовые инструкции. После этого CodexCommander убирает нативные возможности, которые данный маршрут не может честно поддержать, включая service-tier metadata OpenAI. ## Текущее покрытие стабильных моделей Нативный fallback-набор включает `gpt-5.5`, `gpt-5.4`, `gpt-5.4-mini`, -`gpt-5.3-codex-spark` и GPT-5.6 Sol/Terra/Luna. Для семейства GPT-5.5/5.4 opencodex сохраняет +`gpt-5.3-codex-spark` и GPT-5.6 Sol/Terra/Luna. Для семейства GPT-5.5/5.4 CodexCommander сохраняет более богатые живые записи установленного каталога Codex и синтезирует только отсутствующую запись. Bundled upstream-snapshot используется только для GPT-5.6, где он даёт настоящую per-model identity и метаданные вместо приближения по старому шаблону. @@ -139,7 +130,7 @@ service_tier = "fast" fast_mode = true ``` -Но каталог моделей и id tier'а во время выполнения используют `priority`. opencodex сохраняет это +Но каталог моделей и id tier'а во время выполнения используют `priority`. CodexCommander сохраняет это разделение. Нативные passthrough-модели OpenAI сохраняют поддержку fast; routed-провайдеры ограничены capability-гейтом — `service_tier` удаляется только когда провайдер объявил `supportsServiceTier: false` (registry классифицирует canonical OpenAI как `true`, DeepSeek и Volcengine Ark как `false`); неклассифицированные custom gateway'и сохраняют значения вызывающего без изменений и не получают подстановку. Так что опция fast не рекламируется там, где её нельзя выполнить, а custom gateway'и могут включить её явно через `true`. @@ -150,7 +141,7 @@ Codex сортирует видимые в picker'е записи каталог пять как model-override для `spawn_agent`. **Agent Command Center** в дашборде позволяет выбрать и сохранить до пяти bare native-id или routed provider-id `provider/model`. Уже настроенные account-qualified id `<selector>/<native-openai-model>` сохраняются, а интерфейс сообщает, какие -сохранённые записи реально рекламируются или исключены. opencodex назначает им низкие приоритеты +сохранённые записи реально рекламируются или исключены. CodexCommander назначает им низкие приоритеты каталога в выбранном порядке; при активных селекторах аккаунтов bare native-выбор разворачивается в группы selector-qualified строк. Остальные модели всё равно можно вызывать по точному id. @@ -164,9 +155,9 @@ Active Roster отделён от выбора **Sub-agent delegation** в да поверхность Codex: ```bash -ocx sync +ccx sync ``` -Каждый раз, когда меняются видимость, priority или metadata каталога, opencodex переписывает +Каждый раз, когда меняются видимость, priority или metadata каталога, CodexCommander переписывает `models_cache.json` с намеренно устаревшей cache-wrapper, чтобы следующее обновление моделей в Codex прочитало новый каталог. diff --git a/docs-site/src/content/docs/ru/guides/codex-integration.md b/docs-site/src/content/docs/ru/guides/codex-integration.md index 394c66dd33..8fbb933978 100644 --- a/docs-site/src/content/docs/ru/guides/codex-integration.md +++ b/docs-site/src/content/docs/ru/guides/codex-integration.md @@ -1,27 +1,26 @@ --- title: Интеграция с Codex -description: Как opencodex внедряется в Codex, синхронизирует каталог моделей, устанавливает shim'ы и чисто восстанавливает исходное состояние. +description: Как CodexCommander внедряется в Codex, синхронизирует каталог моделей, устанавливает shim'ы и чисто восстанавливает исходное состояние. --- -opencodex заставляет Codex маршрутизировать запросы через прокси, редактируя две сущности, +CodexCommander заставляет Codex маршрутизировать запросы через прокси, редактируя две сущности, которые читает Codex: его конфигурацию (`$CODEX_HOME/config.toml`, по умолчанию `~/.codex/config.toml`) и его каталог моделей. Все правки идемпотентны и обратимы. Прокси предоставляет один «голый» маршрут входа Codex `openai` с режимами аккаунтов Pool (по умолчанию) и Direct, а также `openai-apikey/<model>` для настроенного API-ключа. Pool включает основной и добавленные аккаунты; Direct использует только bearer текущего вызывающего -или основного входа. Маршруты не откатываются друг в друга. Поставляемые v1-конфигурации -мигрируют на marker 2 и сохраняют `config.json.pre-openai-tiers-v2.bak` для ручного отката. +или основного входа. Маршруты не откатываются друг в друга. ## Внедрение в конфигурацию -`ocx init`, `ocx start` и `ocx sync` вызывают injector. На loopback-привязке по умолчанию он -сохраняет встроенный id провайдера Codex `openai` и направляет его на opencodex: +`ccx init`, `ccx start` и `ccx sync` вызывают injector. На loopback-привязке по умолчанию он +сохраняет встроенный id провайдера Codex `openai` и направляет его на CodexCommander: ```toml # root keys, before the first table -model_catalog_json = "/absolute/path/to/opencodex-catalog.json" -# Auto-injected by opencodex +model_catalog_json = "/absolute/path/to/codexcommander-catalog.json" +# Auto-injected by CodexCommander openai_base_url = "http://127.0.0.1:10100/v1" # только если fastMode задан; без него таблица [features] не создаётся @@ -42,7 +41,7 @@ fast_mode = true Встроенный tool Codex `image_gen` идёт не через `/v1/responses` — расширение codex-rs напрямую отправляет POST на `{base_url}/images/generations` (или `/images/edits`, если приложены reference-image), используя тот же bearer ChatGPT, что и для чата. Поскольку внедрённый -`base_url` указывает на opencodex, прокси ретранслирует эти вызовы в upstream OpenAI. +`base_url` указывает на CodexCommander, прокси ретранслирует эти вызовы в upstream OpenAI. Это отдельно от [Image Bridge](/guides/image-bridge/), который активируется только тогда, когда **Responses**-ход перечисляет hosted tool `image_generation`, а в качестве модели выбрана @@ -64,7 +63,7 @@ reference-image), используя тот же bearer ChatGPT, что и дл Antigravity **Cloud Code Assist** с моделью `gemini-3.1-flash-image`. Этот fallback также включается после провала разрешения OpenAI auth (например, если credential ChatGPT просрочен или отсутствует), а не только в ситуации полного отсутствия кандидата OpenAI. Для этого нужен - `ocx login google-antigravity`; OAuth-токен отправляется только на закреплённый registry-host + `ccx login google-antigravity`; OAuth-токен отправляется только на закреплённый registry-host CCA, а не на override `baseUrl` из конфигурации. Ответ возвращается в той же форме `{created, data:[{b64_json}]}`, которую ожидает Codex. - **Ничего из этого:** прокси возвращает понятную ошибку вместо общего 404. Маршрутизируемые @@ -73,9 +72,9 @@ reference-image), используя тот же bearer ChatGPT, что и дл `codex features disable image_generation` (`[features] image_generation = false` в `config.toml`). Объявление tool всё равно идёт вместе с Responses-запросом модели. Для Responses-провайдеров по -API-ключу opencodex понижает приватное пространство имён Codex `image_gen` до безопасного для +API-ключу CodexCommander понижает приватное пространство имён Codex `image_gen` до безопасного для upstream alias `image_gen__<inner-name>` (например, `image_gen__imagegen`). Когда этот рабочий -alias заменяет клиентское объявление, opencodex удаляет дублирующее hosted-объявление +alias заменяет клиентское объявление, CodexCommander удаляет дублирующее hosted-объявление `image_generation`. Перед тем как Codex увидит вызов, proxy отображает function call обратно в явное пространство имён `image_gen`, а при последующем replay истории вверх по потоку снова кодирует нативный вызов. Так client-side image generation остаётся вызываемой даже на @@ -117,21 +116,21 @@ caller bearer перед отправкой upstream-запроса. ```toml # root keys -model_provider = "opencodex" -model_catalog_json = "/absolute/path/to/opencodex-catalog.json" +model_provider = "codexcommander" +model_catalog_json = "/absolute/path/to/codexcommander-catalog.json" # appended at the end of the file -# Auto-injected by opencodex -[model_providers.opencodex] -name = "OpenCodex Proxy" +# Auto-injected by CodexCommander +[model_providers.codexcommander] +name = "CodexCommander Proxy" base_url = "http://your-host:10100/v1" wire_api = "responses" requires_openai_auth = true -env_http_headers = { "x-opencodex-api-key" = "OPENCODEX_API_AUTH_TOKEN" } +env_http_headers = { "x-codexcommander-api-key" = "CODEXCOMMANDER_API_AUTH_TOKEN" } # supports_websockets = true # only when config.websockets is true ``` -Когда маршрутизацией владеет OpenCodex, оба режима пишут `$CODEX_HOME/opencodex.config.toml` как +Когда маршрутизацией владеет CodexCommander, оба режима пишут `$CODEX_HOME/codexcommander.config.toml` как reference/fallback-конфиг. На loopback в нём лежат root key, которые можно вручную влить обратно, если автоматическое внедрение убрали; на не-loopback — форма с выделенным провайдером. Режим external-provider этот профиль не трогает. @@ -145,17 +144,17 @@ Root key вроде `openai_base_url`, `model_provider` и `model_catalog_json` ## Общий каталог моделей -Codex CLI, TUI, App и SDK читают один и тот же Codex home. opencodex определяет этот каталог из +Codex CLI, TUI, App и SDK читают один и тот же Codex home. CodexCommander определяет этот каталог из `CODEX_HOME`, а если он не задан — из `~/.codex`, и управляет файлами: ```text $CODEX_HOME/config.toml -$CODEX_HOME/opencodex.config.toml -$CODEX_HOME/opencodex-catalog.json +$CODEX_HOME/codexcommander.config.toml +$CODEX_HOME/codexcommander-catalog.json $CODEX_HOME/models_cache.json ``` -В WSL, если `CODEX_HOME` не задан и Linux-файл `~/.codex/config.toml` отсутствует, opencodex +В WSL, если `CODEX_HOME` не задан и Linux-файл `~/.codex/config.toml` отсутствует, CodexCommander дополнительно проверяет, нет ли единственного Windows-home Codex Desktop в `/mnt/c/Users/*/.codex/config.toml`. Если существует ровно один такой кандидат, используется его каталог, чтобы режим app-server в WSL и Windows Codex Desktop разделяли одни и те же config- и @@ -163,33 +162,24 @@ auth-файлы. Чтобы переопределить это обнаруже На Windows оболочка Orca может одновременно задавать `CODEX_HOME` и `ORCA_CODEX_HOME` на bundled runtime-home Orca, тогда как приложение ChatGPT/Codex всё ещё читает `%USERPROFILE%\\.codex`. -`ocx status` и `ocx doctor` предупреждают именно об этом рассогласовании и печатают замаскированные +`ccx status` и `ccx doctor` предупреждают именно об этом рассогласовании и печатают замаскированные целевые пути. Если фоновая служба была установлена из такой оболочки Orca, сначала удалите её из исходной оболочки, затем перенаправьте `CODEX_HOME` на home приложения, уберите `ORCA_CODEX_HOME`, повторите sync/restore и снова установите службу. В режиме выделенного провайдера `requires_openai_auth = true` держит account-gated surface App/TUI -в согласии с нативным Codex. opencodex также обслуживает `/v1/responses` по WebSocket. +в согласии с нативным Codex. CodexCommander также обслуживает `/v1/responses` по WebSocket. Выделенный провайдер объявляет `supports_websockets = true` только когда `"websockets": true`; на loopback встроенный провайдер Codex может сначала пробовать WebSocket, и отключённый прокси ответит `426`, после чего Codex откатится на HTTP/SSE. -## Идентичность тредов и история - -Форма loopback по умолчанию сохраняет новые треды помеченными нативным провайдером Codex -`openai`, поэтому обычной resume-history не нужен никакой remap. При первом sync она также -перемещает треды, помеченные более старыми сборками opencodex, обратно на `openai`. В режиме -выделенного не-loopback-провайдера история во время работы зеркалируется под провайдером -`opencodex` и при выходе восстанавливает сохранённые метаданные. Задайте -`syncResumeHistory: false`, если не хотите трогать историю. - ## Синхронизация каталога моделей -Codex показывает модели из каталога на диске (`$CODEX_HOME/opencodex-catalog.json` по -умолчанию). При старте и при `ocx sync` opencodex: +Codex показывает модели из каталога на диске (`$CODEX_HOME/codexcommander-catalog.json` по +умолчанию). При старте и при `ccx sync` CodexCommander: -1. **Создаёт резервную копию** исходного каталога один раз в `~/.opencodex/catalog-backup.json` - (чтобы «feature»-правки были обратимы). +1. **Создаёт резервную копию** исходного каталога один раз в + `~/.codexcommander/catalog-backup-<catalog-id>.json` (чтобы «feature»-правки были обратимы). 2. **Получает** живые каталоги моделей подходящих провайдеров (кэш примерно на 5 минут; при ошибке использует последний успешный список, затем настроенный `models[]`). У forward auth нет model-endpoint'а, а Cursor использует свой RPC `GetUsableModels`, а не `/models`. @@ -214,55 +204,55 @@ picker'е Codex, не меняя саму маршрутизацию. Display na Добавить display name можно из CLI (если прокси запущен, каталог синхронизируется сразу): ```bash -ocx models add deepseek deepseek-v4 --display-name "DeepSeek V4" --context-window 128000 +ccx models add deepseek deepseek-v4 --display-name "DeepSeek V4" --context-window 128000 ``` Удалённые клиенты Codex могут получить тот же сгенерированный каталог через management API (с тем же admission token, что и для других маршрутов `/api/*`): ```bash -dest="${CODEX_HOME:-$HOME/.codex}/opencodex-catalog.json" +dest="${CODEX_HOME:-$HOME/.codex}/codexcommander-catalog.json" tmp="$(mktemp "${dest}.XXXXXX")" -curl -fsS -H "x-opencodex-api-key: $OPENCODEX_ADMIN_AUTH_TOKEN" \ +curl -fsS -H "x-codexcommander-api-key: $CODEXCOMMANDER_ADMIN_AUTH_TOKEN" \ "https://proxy.example.com/api/catalog" > "$tmp" \ && mv "$tmp" "$dest" -ocx sync-cache +ccx sync-cache ``` -Ответ — это сырой документ `opencodex-catalog.json` (без credential'ов провайдеров). Если -доступен заголовок `x-opencodex-codex-version`, он сообщает версию рантайма Codex на сервере, +Ответ — это сырой документ `codexcommander-catalog.json` (без credential'ов провайдеров). Если +доступен заголовок `x-codexcommander-codex-version`, он сообщает версию рантайма Codex на сервере, чтобы клиенты могли заметить version skew. Display name можно задать или отредактировать и через management API (`POST /api/custom-models`, `PUT /api/custom-models/<id>` с полем `displayName`) и через веб-дашборд. Символ `/` запрещён, потому что он столкнулся бы с разделителем routed-slug. -Display name — это **только отображение, и оно устойчиво к перегенерации**. Каждый `ocx sync` и +Display name — это **только отображение, и оно устойчиво к перегенерации**. Каждый `ccx sync` и каждое обновление каталога заново выводят маршрутизируемые записи из `config.json` (включая `customModels`), поэтому настроенное имя накладывается снова и не «дрейфует» обратно к routed slug. Управляемый сервис тоже пытается выполнить этот sync вскоре после bind'а прокси. Если такой best-effort sync при старте не удался, например во время offline-login, сохраняется -предыдущий каталог, а следующий успешный `ocx sync` снова применит настроенное имя. Настоящие +предыдущий каталог, а следующий успешный `ccx sync` снова применит настроенное имя. Настоящие upstream native name'ы (например, `gpt-5.6-sol` → "GPT-5.6-Sol") приходят из закреплённого upstream snapshot и никогда не перекрываются пользовательским display name. ### Внешние provider manager'ы -Если `config.toml` уже выбирает провайдера, отличного от `openai` или `opencodex`, OpenCodex -оставляет файл без изменений и пропускает запись profile, обновление catalog/cache и как -немедленную, так и фоновую миграцию истории Codex. Инструменты, управляющие custom-провайдером, +Если `config.toml` уже выбирает провайдера, отличного от `openai` или `codexcommander`, CodexCommander +оставляет файл без изменений и пропускает запись profile, обновление catalog/cache и синхронизацию +истории Codex. Инструменты, управляющие custom-провайдером, часто помечают существующие сессии своим provider id; замена активного id может привести к тому, -что рабочие сессии просто исчезнут из history view Codex. Та же защита действует и для внешнего -провайдера, выбранного через legacy root profile. +что рабочие сессии просто исчезнут из history view Codex. Та же защита действует всегда, когда +активен внешний провайдер. Держите владельцем конфигурации провайдера Codex только один инструмент. Если вы хотите -использовать OpenCodex позади уже существующего provider manager'а, направьте этот провайдер на +использовать CodexCommander позади уже существующего provider manager'а, направьте этот провайдер на `http://127.0.0.1:10100/v1` с passthrough Responses (`wire_api = "responses"` в TOML Codex), а не через перевод в Chat Completions. Когда включена proxy API auth, передавайте и -`x-opencodex-api-key` из `OPENCODEX_API_AUTH_TOKEN`, то есть ровно так, как в форме -не-loopback-провайдера выше. Чтобы снова дать OpenCodex самому внедрить routing, сначала верните +`x-codexcommander-api-key` из `CODEXCOMMANDER_API_AUTH_TOKEN`, то есть ровно так, как в форме +не-loopback-провайдера выше. Чтобы снова дать CodexCommander самому внедрить routing, сначала верните Codex на встроенный провайдер `openai` и удалите любой user-owned root `openai_base_url`, после -чего снова выполните `ocx start`. +чего снова выполните `ccx start`. ### Устранение проблем с каталогом @@ -275,45 +265,45 @@ Codex на встроенный провайдер `openai` и удалите л 2. **`disabledModels`** (верхний уровень) — скрывает модели и из каталога, и из `/v1/models`, а у голых нативных GPT-slug устанавливает `visibility: "hide"`. 3. **`liveModels: false` и пустой `models`** — если живое обнаружение выключено, а `models` пуст - или отсутствует, opencodex не показывает ни одной маршрутизируемой модели этого провайдера. + или отсутствует, CodexCommander не показывает ни одной маршрутизируемой модели этого провайдера. 4. **Cursor `GetUsableModels`** — адаптер Cursor получает модели через protobuf RPC `GetUsableModels`, а не через `/models`, поэтому изменение на стороне Cursor может менять видимые id независимо от остальных провайдеров. -5. **Кэш и `ocx sync`** — живые каталоги кэшируются примерно на пять минут (`modelCacheTtlMs`, - по умолчанию `300000`). Выполните `ocx sync`, чтобы принудительно обновить список и немедленно +5. **Кэш и `ccx sync`** — живые каталоги кэшируются примерно на пять минут (`modelCacheTtlMs`, + по умолчанию `300000`). Выполните `ccx sync`, чтобы принудительно обновить список и немедленно переписать каталог. 6. **Запущенный Codex `app-server`** — переписать каталог на диске недостаточно, если долгоживущий `app-server` Codex (Desktop / CLI background host) держит в памяти старый список. - `ocx sync` и `ocx sync-cache` предупреждают, когда находят такие процессы. Перезапустите их - через `ocx sync --restart-codex` (или остановите подходящие процессы `app-server` вручную), а + `ccx sync` и `ccx sync-cache` предупреждают, когда находят такие процессы. Перезапустите их + через `ccx sync --restart-codex` (или остановите подходящие процессы `app-server` вручную), а затем дайте Codex создать их заново. :::caution[Другие локальные writer'ы] -Записи каталога (`opencodex-catalog.json`, `config.toml`) атомарны **только внутри** opencodex, то -есть защищают лишь от полузаписанных файлов, когда гоняются два writer'а самого opencodex. Это +Записи каталога (`codexcommander-catalog.json`, `config.toml`) атомарны **только внутри** CodexCommander, то +есть защищают лишь от полузаписанных файлов, когда гоняются два writer'а самого CodexCommander. Это **не** мешает другому локальному процессу, file watcher'у или sync-agent'у переписать видимость или -порядок каталога после того, как opencodex уже записал свой вариант. У Codex есть отдельный +порядок каталога после того, как CodexCommander уже записал свой вариант. У Codex есть отдельный `models_cache.json`, и он может обновить его независимо, меняя видимый список без перезаписи -`opencodex-catalog.json`. Если модели неожиданно «перещёлкиваются», пока прокси работает, -остановите или перенастройте конкурирующих writer'ов, а затем выполните `ocx sync` — это риск -внешнего writer'а, а не подтверждённый дефект opencodex. +`codexcommander-catalog.json`. Если модели неожиданно «перещёлкиваются», пока прокси работает, +остановите или перенастройте конкурирующих writer'ов, а затем выполните `ccx sync` — это риск +внешнего writer'а, а не подтверждённый дефект CodexCommander. ::: ## Ошибки подключения к прокси Если Codex несколько раз пробует и затем завершается ошибкой вроде `stream disconnected before completion: error sending request for url (http://127.0.0.1:10100/v1/responses)` -— или Claude Code сообщает о похожем connection failure — прокси opencodex просто не запущен: +— или Claude Code сообщает о похожем connection failure — прокси CodexCommander просто не запущен: ничто не слушает настроенный порт, и клиент показывает эту сырую ошибку соединения как есть. Перезапустите прокси: ```bash -ocx start # foreground -ocx service install # persistent: auto-starts on login and respawns on crash +ccx start # foreground +ccx service install # persistent: auto-starts on login and respawns on crash ``` -`ocx status` показывает, запущен ли прокси, и печатает ту же подсказку о перезапуске, если он не -работает; `ocx doctor` сообщает, насколько безопасен перезапуск (покрытие service/shim). +`ccx status` показывает, запущен ли прокси, и печатает ту же подсказку о перезапуске, если он не +работает; `ccx doctor` сообщает, насколько безопасен перезапуск (покрытие service/shim). ## Picker подагентов @@ -324,7 +314,7 @@ v1/base/v2 при делегировании и fallback — в ## Прогрев аккаунтов Codex -Когда аккаунт ChatGPT добавляется в пул аккаунтов Codex, opencodex проверяет его до сохранения +Когда аккаунт ChatGPT добавляется в пул аккаунтов Codex, CodexCommander проверяет его до сохранения небольшим streaming-запросом в backend Codex Responses. Запрос использует настоящий массив Responses item'ов (`input: [{ type: "message", ... }]`), ждёт `response.completed` и по умолчанию использует `gpt-5.4-mini`. Если эта модель отвечает HTTP 400, выполняется повтор с `gpt-5.5`; @@ -335,17 +325,17 @@ Responses item'ов (`input: [{ type: "message", ... }]`), ждёт `response.co ## Восстановление нативного Codex -opencodex не запирает вас внутри себя. **`ocx stop` — это единственная команда, которая полностью +CodexCommander не запирает вас внутри себя. **`ccx stop` — это единственная команда, которая полностью возвращает нативный Codex**: она останавливает прокси, останавливает фоновую службу, если она установлена, и убирает все внедрённые строки и маршрутизируемые записи каталога, так что обычный -`codex` снова работает так, будто opencodex никогда не существовал: +`codex` снова работает так, будто CodexCommander никогда не существовал: ```bash -ocx stop # stop the proxy + service, restore native Codex -ocx restore # restore without stopping (alias: ocx eject) -ocx restore back # point plain Codex at the running proxy again +ccx stop # stop the proxy + service, restore native Codex +ccx restore # restore without stopping (alias: ccx eject) +ccx restore back # point plain Codex at the running proxy again ``` -Когда opencodex работает как управляемая [фоновая служба](/reference/cli/#ocx-service), он -устанавливает `OCX_SERVICE=1`, чтобы service-driven restart **не** дёргал конфигурацию Codex — -только явный `ocx stop` / `ocx service stop` восстанавливает нативный Codex. +Когда CodexCommander работает как управляемая [фоновая служба](/reference/cli/#ccx-service), он +устанавливает `CCX_SERVICE=1`, чтобы service-driven restart **не** дёргал конфигурацию Codex — +только явный `ccx stop` / `ccx service stop` восстанавливает нативный Codex. diff --git a/docs-site/src/content/docs/ru/guides/combos.md b/docs-site/src/content/docs/ru/guides/combos.md index 6ffff0603a..2d79b6c6f6 100644 --- a/docs-site/src/content/docs/ru/guides/combos.md +++ b/docs-site/src/content/docs/ru/guides/combos.md @@ -4,7 +4,7 @@ description: Направляйте одну виртуальную модель --- **Combo** — это одна виртуальная модель, за которой стоит упорядоченный список реальных целей -provider/model. Клиент запрашивает `combo/<id>`, opencodex выбирает цель, переписывает запрос на +provider/model. Клиент запрашивает `combo/<id>`, CodexCommander выбирает цель, переписывает запрос на конкретный `provider/model` и при сбое, допускающем повтор, может попробовать следующую цель. Это полезно, если вам нужно одно из двух: @@ -22,11 +22,11 @@ Combo работают поверх обычной маршрутизации п должны существовать и быть включены. ```bash -ocx combo set main --targets anthropic/claude-opus-4-8,openai/gpt-5.6-sol +ccx combo set main --targets anthropic/claude-opus-4-8,openai/gpt-5.6-sol ``` Стратегия по умолчанию — failover, поэтому обычный запрос уйдёт в -`anthropic/claude-opus-4-8`. Если эта попытка завершится retryable-сбоем, opencodex сможет +`anthropic/claude-opus-4-8`. Если эта попытка завершится retryable-сбоем, CodexCommander сможет переключиться на `openai/gpt-5.6-sol`. Используйте виртуальную модель везде, где вы обычно передаёте id модели: @@ -41,7 +41,7 @@ ocx combo set main --targets anthropic/claude-opus-4-8,openai/gpt-5.6-sol Проверьте сохранённое определение: ```bash -ocx combo show main +ccx combo show main ``` :::tip @@ -51,7 +51,7 @@ ocx combo show main ## Как работают имена combo -Идентификатор combo в `ocx combo set <id>` должен начинаться с буквы или цифры. Дальше он может +Идентификатор combo в `ccx combo set <id>` должен начинаться с буквы или цифры. Дальше он может содержать буквы, цифры, `.`, `_` или `-`, общей длиной до 64 символов. Канонический id модели всегда имеет вид `combo/<id>`; например, id `main` превращается в `combo/main`. @@ -105,7 +105,7 @@ retryable-сбой OpenAI может перевести его на Google. Term Создайте combo 2:1 с партиями по два успешных запроса: ```bash -ocx combo set balanced \ +ccx combo set balanced \ --targets anthropic/claude-opus-4-8:2,openai/gpt-5.6-sol:1 \ --strategy round-robin \ --sticky 2 @@ -139,7 +139,7 @@ ocx combo set balanced \ | Любая другая неклассифицированная ошибка | Остановиться и вернуть ошибку. | Цель, по которой произошёл hop, по умолчанию уходит в cooldown на 60 секунд. Если ответ upstream -содержит корректный `Retry-After`, opencodex использует его. Поддерживаются и числовые секунды, и +содержит корректный `Retry-After`, CodexCommander использует его. Поддерживаются и числовые секунды, и значения в формате HTTP-date; любой cooldown ограничивается 10 минутами. Текущий запрос никогда не повторяет уже опробованную цель. Более поздние запросы пропускают её, @@ -159,11 +159,11 @@ Failover намеренно ограничен. Он помогает при п 2. вызывающая сторона сама не указала effort; и 3. каталог выбранной цели объявляет поддержку именно этого effort. -Если в запросе нет объекта `reasoning`, opencodex создаёт его. Если `reasoning` есть, но в нём нет +Если в запросе нет объекта `reasoning`, CodexCommander создаёт его. Если `reasoning` есть, но в нём нет свойства `effort`, остальные поля сохраняются, а значение по умолчанию добавляется. Effort, заданный вызывающей стороной, никогда не перезаписывается. -Если возможности цели неизвестны или не включают настроенный effort, opencodex опускает значение +Если возможности цели неизвестны или не включают настроенный effort, CodexCommander опускает значение по умолчанию и оставляет нативное поведение цели без изменений. Поддерживаются `low`, `medium`, `high`, `xhigh`, `max` и `ultra`; опустите поле или задайте `null`, чтобы полностью оставить выбор effort вызывающей стороне и цели. @@ -171,12 +171,12 @@ effort вызывающей стороне и цели. ## Шифрованные задачи подагентов v2 Есть одно важное ограничение для подагентов Codex v2 -([issue #92](https://github.com/lidge-jun/opencodex/issues/92)). Нативный родитель может отправить +([issue #92](https://github.com/pavelhov/CodexCommander/issues/92)). Нативный родитель может отправить задачу новому воркеру только как ciphertext, выпущенный для нативного backend ChatGPT. Внешний провайдер не может прочитать эту нагрузку. Для такого запроса combo фильтрует подходящие цели до канонических нативных маршрутов ChatGPT, в -том числе после retryable-сбоя. Если в combo нет цели, способной расшифровать задачу, opencodex +том числе после retryable-сбоя. Если в combo нет цели, способной расшифровать задачу, CodexCommander останавливается ещё до dispatch и возвращает HTTP 400: ```json @@ -213,16 +213,16 @@ effort вызывающей стороне и цели. Основные команды: ```bash -ocx combo list -ocx combo show <id> -ocx combo set <id> --targets provider/model[:weight],... -ocx combo remove <id> --yes +ccx combo list +ccx combo show <id> +ccx combo set <id> --targets provider/model[:weight],... +ccx combo remove <id> --yes ``` `set` также принимает `--strategy`, `--sticky`, `--effort`, `--alias` и `--rename-from`. Чтобы очистить поле, используйте `-` в качестве значения для `--effort` или `--alias`. `create` и `update` — это alias для `set`; `delete` — alias для `remove`; те же подкоманды доступны и через -`ocx route combo`. +`ccx route combo`. ### Management API @@ -267,9 +267,9 @@ Combo хранятся в объекте верхнего уровня `combos`, ### Почему `combo/<id>` возвращает 404? -Id combo неизвестен. Ответ — HTTP 404 с типом `invalid_request_error`. Запустите `ocx combo list`, +Id combo неизвестен. Ответ — HTTP 404 с типом `invalid_request_error`. Запустите `ccx combo list`, проверьте написание и регистр, а также убедитесь, что management-команда записывала в тот же -запущенный экземпляр opencodex, который принимает запросы к моделям. +запущенный экземпляр CodexCommander, который принимает запросы к моделям. ### Почему я получаю `combo_unavailable`? diff --git a/docs-site/src/content/docs/ru/guides/grok-build.md b/docs-site/src/content/docs/ru/guides/grok-build.md index d04473c609..555908ead8 100644 --- a/docs-site/src/content/docs/ru/guides/grok-build.md +++ b/docs-site/src/content/docs/ru/guides/grok-build.md @@ -1,67 +1,67 @@ --- title: Grok Build -description: Используйте любую модель, маршрутизируемую opencodex, из CLI xAI Grok Build — пока прокси работает, модели автоматически регистрируются в ~/.grok/config.toml. +description: Используйте любую модель, маршрутизируемую CodexCommander, из CLI xAI Grok Build — пока прокси работает, модели автоматически регистрируются в ~/.grok/config.toml. --- -opencodex отдаёт OpenAI-совместимый `POST /v1/chat/completions` (и `/v1/responses`) на своём +CodexCommander отдаёт OpenAI-совместимый `POST /v1/chat/completions` (и `/v1/responses`) на своём локальном порту, а Grok Build поддерживает custom-модели поверх OpenAI-совместимых серверов. -Начиная с этой интеграции, opencodex автоматически регистрирует весь свой видимый каталог в +Начиная с этой интеграции, CodexCommander автоматически регистрирует весь свой видимый каталог в Grok Build — вручную редактировать конфигурацию не нужно. ## Авторегистрация -Когда существует `~/.grok`, `ocx start` (а также `ocx ensure` и `ocx restart`) записывает +Когда существует `~/.grok`, `ccx start` (а также `ccx ensure` и `ccx restart`) записывает управляемый блок в `~/.grok/config.toml`: ```toml -# >>> opencodex managed block — do not edit (removed by `ocx stop`) >>> -[model.ocx-gpt-5-6-sol] +# >>> CodexCommander managed block — do not edit (removed by `ccx stop`) >>> +[model.ccx-gpt-5-6-sol] model = "gpt-5.6-sol" base_url = "http://127.0.0.1:10100/v1" api_backend = "chat_completions" -api_key = "opencodex-loopback" -name = "OCX gpt-5.6-sol" -# ... one [model.ocx-*] table per visible model ... -# <<< opencodex managed block <<< +api_key = "codexcommander-loopback" +name = "CodexCommander gpt-5.6-sol" +# ... one [model.ccx-*] table per visible model ... +# <<< CodexCommander managed block <<< ``` - **Additive:** ваша собственная конфигурация вне fenced-блока никогда не трогается. Перед первым внедрением в уже существующий файл создаётся одноразовая резервная копия - `~/.grok/config.toml.bak-opencodex`. -- **Idempotent:** каждый `ocx start` (и `ocx ensure`, когда включён автозапуск) заменяет fenced-блок + `~/.grok/config.toml.bak-codexcommander`. +- **Idempotent:** каждый `ccx start` (и `ccx ensure`, когда включён автозапуск) заменяет fenced-блок текущим каталогом. -- **Removed on teardown:** `ocx stop`, `ocx eject`, `ocx uninstall` и корректное завершение +- **Removed on teardown:** `ccx stop`, `ccx eject`, `ccx uninstall` и корректное завершение не-service-демона удаляют fenced-блок и побайтно восстанавливают ваш файл. Под service manager - teardown выполняется через `ocx stop`/`ocx uninstall` (процессы service-mode намеренно + teardown выполняется через `ccx stop`/`ccx uninstall` (процессы service-mode намеренно сохраняют блок между respawn'ами). -- **Conflict-safe:** alias, уже объявленные в ваших `[model.*]`, уважаются (opencodex добавляет +- **Conflict-safe:** alias, уже объявленные в ваших `[model.*]`, уважаются (CodexCommander добавляет суффиксы к своим записям); повреждённый fence (маркер начала без маркера конца) запрещает любые автоматические изменения и просит ручного исправления. После этого выберите модель в Grok Build: ```bash -grok models # lists ocx-* entries alongside native grok models -grok -m ocx-anthropic-claude-opus-4-8 -p "hello" -# or in the TUI: /model ocx-anthropic-claude-opus-4-8 +grok models # lists ccx-* entries alongside native grok models +grok -m ccx-anthropic-claude-opus-4-8 -p "hello" +# or in the TUI: /model ccx-anthropic-claude-opus-4-8 ``` ## Замечание об аутентификации Grok Build требует непустой API-ключ для custom-моделей даже на loopback. Внедряемые записи несут -placeholder (`opencodex-loopback`) — opencodex игнорирует admission key для loopback-подключений, +placeholder (`codexcommander-loopback`) — CodexCommander игнорирует admission key для loopback-подключений, так что реальный секрет тут не используется. -**Авторегистрация работает только на loopback.** Когда opencodex привязывается к не-loopback-хосту +**Авторегистрация работает только на loopback.** Когда CodexCommander привязывается к не-loopback-хосту — включая wildcard `0.0.0.0` и `::`, открывающие все интерфейсы, — запросам нужен ваш настоящий admission token, а управляемый блок не может безопасно его хранить. Запись буквального токена поместила бы ваш секрет в `~/.grok/config.toml` и перезаписывала бы установленное вами значение -при каждом `ocx start`/`ensure`/`restart`. Поэтому в этом случае opencodex вообще ничего не +при каждом `ccx start`/`ensure`/`restart`. Поэтому в этом случае CodexCommander вообще ничего не записывает (и удаляет блок, оставшийся от прежней loopback-привязки), а вы настраиваете модели -сами, вне managed-маркеров, где opencodex ничего не сможет затереть. Точный пример таблицы см. в +сами, вне managed-маркеров, где CodexCommander ничего не сможет затереть. Точный пример таблицы см. в [ручном рецепте](#manual-recipe-without-auto-registration), а в `base_url` укажите хост, который действительно достижим из того места, где вы запускаете `grok`, и в `api_key` укажите -`OPENCODEX_API_AUTH_TOKEN`. +`CODEXCOMMANDER_API_AUTH_TOKEN`. Не заменяйте здесь `api_key` на `env_key`. Если `model_provider` не задан, `env_key`, который не разрешился, не останавливает запрос — Grok откатывается к вашему session token xAI и отправляет @@ -69,33 +69,33 @@ admission token, а управляемый блок не может безопа который не является xAI. Внедрённый `api_key` на уровне модели стоит первым в цепочке учётных данных Grok для этих моделей, -поэтому ходам через opencodex не нужен дополнительный `grok login`. Обычную настройку +поэтому ходам через CodexCommander не нужен дополнительный `grok login`. Обычную настройку `grok login` / `XAI_API_KEY` сохраняйте для нативных grok-моделей и любых harness-функций, которые напрямую обращаются к xAI. ## Ручной рецепт без авторегистрации -Если вы управляете `~/.grok/config.toml` сами — либо opencodex привязан не к loopback, — +Если вы управляете `~/.grok/config.toml` сами — либо CodexCommander привязан не к loopback, — добавляйте таблицы по одной модели с **прямыми полями**, вне маркеров -`# >>> opencodex managed block`: +`# >>> CodexCommander managed block`: ```toml -[model.ocx-opus] +[model.ccx-opus] model = "anthropic/claude-opus-4-8" base_url = "http://127.0.0.1:10100/v1" api_backend = "chat_completions" -api_key = "opencodex-loopback" +api_key = "codexcommander-loopback" ``` Для прокси, доступного по сети, укажите в `base_url` адрес, до которого `grok` реально может дозвониться, и используйте свой admission token: ```toml -[model.ocx-opus] +[model.ccx-opus] model = "anthropic/claude-opus-4-8" base_url = "http://192.168.1.10:10100/v1" # the reachable host, not 127.0.0.1 api_backend = "chat_completions" -api_key = "your-OPENCODEX_API_AUTH_TOKEN" +api_key = "your-CODEXCOMMANDER_API_AUTH_TOKEN" ``` Не полагайтесь на наследование `[model_providers.<id>]` для endpoint'а: по состоянию на Grok Build @@ -107,25 +107,25 @@ api_key = "your-OPENCODEX_API_AUTH_TOKEN" ## Известные ограничения -- **Responses backend и keep-alive:** во время тишины upstream opencodex посылает keep-alive +- **Responses backend и keep-alive:** во время тишины upstream CodexCommander посылает keep-alive `response.heartbeat` в потоках `/v1/responses`. Декодер Responses в Grok Build отвергает неизвестные типы событий, поэтому вручную настроенная модель с `api_backend = "responses"` может оборваться посреди хода на медленных upstream. Автоматически зарегистрированные записи жёстко используют `api_backend = "chat_completions"`, где сырые heartbeat-кадры никогда не видны. -- **`ocx restart`, установленный как service:** когда opencodex работает под service manager, - `ocx restart` сейчас останавливает службу и заменяет её неуправляемым процессом — persistence - службы (автоперезапуск, старт при логине) теряется до следующего `ocx service`, а если этот +- **`ccx restart`, установленный как service:** когда CodexCommander работает под service manager, + `ccx restart` сейчас останавливает службу и заменяет её неуправляемым процессом — persistence + службы (автоперезапуск, старт при логине) теряется до следующего `ccx service`, а если этот неуправляемый процесс погибнет, managed block может указывать на уже мёртвый прокси, пока - следующий `ocx start`/`ocx ensure` не обновит его. + следующий `ccx start`/`ccx ensure` не обновит его. - **Время чтения конфигурации:** для наиболее предсказуемого поведения сначала запускайте - opencodex, а затем `grok`. Grok Build отслеживает `~/.grok/config.toml` и перезагружает его, + CodexCommander, а затем `grok`. Grok Build отслеживает `~/.grok/config.toml` и перезагружает его, когда секция `[model]` действительно меняется (порядка секунды debounce, сравнение по содержимому), поэтому обновлённый блок доходит до уже открытой сессии без перезапуска. Чтобы проверить, что именно разобрал Grok, выполните `grok inspect`: он перечисляет источники конфигурации и предупреждает о полях, которые отверг. Список разрешённых моделей при этом не печатается. Учтите, что одна TOML-ошибка делает недействительным *весь* пользовательский слой - конфигурации, поэтому opencodex пишет файл атомарно — Grok никогда не увидит полузаписанный + конфигурации, поэтому CodexCommander пишет файл атомарно — Grok никогда не увидит полузаписанный `config.toml`. - **Обновления каталога:** fenced-блок отражает каталог на момент внедрения. После добавления - провайдеров или моделей выполните `ocx ensure` (или перезапустите прокси), чтобы его обновить. + провайдеров или моделей выполните `ccx ensure` (или перезапустите прокси), чтобы его обновить. diff --git a/docs-site/src/content/docs/ru/guides/image-bridge.md b/docs-site/src/content/docs/ru/guides/image-bridge.md index 77fffeee8f..e53a71a574 100644 --- a/docs-site/src/content/docs/ru/guides/image-bridge.md +++ b/docs-site/src/content/docs/ru/guides/image-bridge.md @@ -16,7 +16,7 @@ Image Bridge обнаруживает такие вызовы и прозрач чтобы не создавать неожиданных расходов xAI — см. [Конфигурацию](#configuration) ниже). - Нужна запись провайдера `xai` с **API-ключом**. Bridge жёстко привязывает выполнение к registry-endpoint'у xAI Images (`https://api.x.ai/v1`); любой настроенный override `baseUrl` - для image-вызовов игнорируется. Одного OAuth / `ocx login xai` для активации bridge + для image-вызовов игнорируется. Одного OAuth / `ccx login xai` для активации bridge недостаточно (OAuth-транспорт Grok CLI ориентирован на чат и не используется для `/images/*`). ```json @@ -32,7 +32,7 @@ Image Bridge обнаруживает такие вызовы и прозрач ## Конфигурация -Параметры Image Bridge находятся под `images` в `~/.opencodex/config.json`. Bridging — +Параметры Image Bridge находятся под `images` в `~/.codexcommander/config.json`. Bridging — **opt-in**: чтобы включить платную генерацию через xAI Grok Imagine, нужно явно задать `bridgeEnabled: true`: @@ -57,7 +57,7 @@ Image Bridge обнаруживает такие вызовы и прозрач ## Хранение артефактов -Сгенерированные изображения записываются в `~/.opencodex/artifacts/`. Чтобы в долгоживущих +Сгенерированные изображения записываются в `~/.codexcommander/artifacts/`. Чтобы в долгоживущих сессиях каталог не рос бесконечно, после каждого выполненного image-вызова он автоматически prune'ится (когда вся партия этого вызова уже записана на диск): самые старые файлы по времени модификации удаляются, если количество превышает настроенный максимум (по умолчанию 200, @@ -72,13 +72,13 @@ Image Bridge активируется только на **Responses**-ходах напрямую в `/v1/images/generations` (или `/images/edits`) — этот путь описан отдельно в [Интеграции с Codex](/guides/codex-integration/#built-in-image-generation-image_gen). -1. Когда Responses-запрос перечисляет `image_generation` в `tools`, OpenCodex замечает это на +1. Когда Responses-запрос перечисляет `image_generation` в `tools`, CodexCommander замечает это на этапе предобработки. 2. Hosted tool заменяется на **синтетический function tool**, который маршрутизируемая модель может вызвать обычным образом — вместо непрозрачного hosted tool модель видит вызываемый tool. -3. Когда модель вызывает этот tool, OpenCodex перехватывает вызов и отправляет prompt в API +3. Когда модель вызывает этот tool, CodexCommander перехватывает вызов и отправляет prompt в API генерации изображений xAI. -4. Сгенерированные изображения сохраняются в `~/.opencodex/artifacts/`, а **локальный путь к +4. Сгенерированные изображения сохраняются в `~/.codexcommander/artifacts/`, а **локальный путь к файлу** возвращается модели как результат tool. 5. Модель продолжает разговор уже зная о сгенерированном изображении и его местоположении. diff --git a/docs-site/src/content/docs/ru/guides/macos-menu-bar.md b/docs-site/src/content/docs/ru/guides/macos-menu-bar.md index aa4189b98c..bef53ab549 100644 --- a/docs-site/src/content/docs/ru/guides/macos-menu-bar.md +++ b/docs-site/src/content/docs/ru/guides/macos-menu-bar.md @@ -1,59 +1,37 @@ --- title: Компаньон для строки меню macOS -description: Установка и использование нативного компаньона OpenCodex для статуса, активности агентов и квот провайдеров. +description: Установка и использование нативного компаньона CodexCommander для статуса, активности агентов и квот провайдеров. --- -Компаньон для macOS выводит наиболее полезное состояние OpenCodex в строку меню, не заменяя +Компаньон для macOS выводит наиболее полезное состояние CodexCommander в строку меню, не заменяя прокси и не дублируя веб-панель. Это нативное приложение на Swift/AppKit, которое обращается -только к экземпляру OpenCodex, запущенному на том же Mac. +только к экземпляру CodexCommander, запущенному на том же Mac. ## Установка -1. Скачайте <code>OpenCodex-<version>-macos-universal.zip</code> и соответствующий файл - <code>.sha256</code> из нужного релиза GitHub. -2. Проверьте архив: - - shasum -a 256 -c OpenCodex-<version>-macos-universal.zip.sha256 - -3. Распакуйте его и переместите <code>OpenCodex.app</code> в **Программы**. -4. Откройте приложение. В него уже входят Bun, прокси, рабочие зависимости и файлы панели, поэтому - отдельная установка npm, Bun или <code>ocx</code> не требуется. Его значок появится в строке меню; - значок в Dock добавлен не будет. При первом запуске из стабильного расположения включается **Launch at Login**. - -Встроенный runtime использует существующее состояние пользователя в <code>~/.opencodex</code> и -<code>~/.codex</code>. Учетные данные не копируются в пакет приложения или Keychain. OAuth и API-ключи -провайдеров настраиваются в локальной панели. - -Пока релиз не подписан с помощью Developer ID и не нотарифицирован, macOS может заблокировать -первый запуск скачанного приложения. Щёлкните приложение, удерживая Control, выберите -**Открыть**, затем подтвердите **Открыть**. У локальной сборки нет атрибута карантина, -присваиваемого скачанным файлам. - -Встроенный runtime доступен только для чтения. Для обновления нужно заменить пакет последним -подписанным <code>OpenCodex.app</code>; npm, Bun и обновление из исходного checkout не изменяют -подписанный <code>Contents/Resources</code>. +Пакетное приложение macOS сейчас не опубликовано. Запускайте его из существующего checkout по инструкции [Сборка из исходного кода](#сборка-из-исходного-кода). Оставляйте приложение разработки в `dist/macos/CodexCommander.app` и не копируйте его в Application Support. ## Режимы запуска - **Desktop** — приложение меню открывается при входе и подключается ровно к одному серверу или запускает его. -- **Headless** — запускается только отдельно установленная служба `ocx service`, без приложения меню. -- **Off** — автозапуск выключен; используйте приложение или `ocx start` вручную. +- **Headless** — запускается только отдельно установленная служба `ccx service`, без приложения меню. +- **Off** — автозапуск выключен; используйте приложение или `ccx start` вручную. Переключатель **Launch at Login** находится в строке запуска. Если требуется разрешение, приложение открывает настройки Login Items macOS. Переключатель не устанавливает, не останавливает и не удаляет фоновую службу. -Видимое приложение и фоновый прокси работают независимо. Когда панель OpenCodex активна, +Видимое приложение и фоновый прокси работают независимо. Когда панель CodexCommander активна, **Quit Menu Bar** (`⌘Q`) закрывает только -UI компаньона и оставляет маршрутизацию активной. **Stop OpenCodex and Quit…** (`⌥⌘Q`) — явный +UI компаньона и оставляет маршрутизацию активной. **Stop CodexCommander and Quit…** (`⌥⌘Q`) — явный разрушительный выход: после подтверждения он останавливает прокси и службу, восстанавливает нативную маршрутизацию Codex и закрывает компаньон только после подтверждения остановки. ## Что показывает панель - **Активность агентов** — текущее число активных элементов и строки моделей/провайдеров в - реальном времени. Порождённый дочерний агент отображается вложенным, только когда OpenCodex + реальном времени. Порождённый дочерний агент отображается вложенным, только когда CodexCommander может подтвердить его активного родителя по метаданным запроса; в противном случае он показывается как отдельный субагент. Компаньон никогда не выдумывает историю состояний «в очереди», «на проверке», «ограничено по частоте» или «завершено». @@ -67,7 +45,7 @@ UI компаньона и оставляет маршрутизацию акт API-ключа, повторная аутентификация, переключение аккаунтов и настройка провайдера остаются в веб-панели. - **Agent catalog update ready** — постоянная неаварийная карточка, которая появляется, если - работающие фоновые процессы Codex всё ещё используют прежний список моделей. Прокси OpenCodex + работающие фоновые процессы Codex всё ещё используют прежний список моделей. Прокси CodexCommander остаётся исправным и продолжает работать. - **Apply agent catalog…** — открывает подтверждение, по возможности показывает свежую активность запросов, предупреждает о возможном прерывании ответа и предлагает **Apply Now** или **Later**. @@ -78,7 +56,7 @@ UI компаньона и оставляет маршрутизацию акт не выдаётся за завершение: приложение ждёт, пока новый процесс пройдёт проверку идентичности. - **Quit Menu Bar** — закрывает только UI компаньона; прокси, служба и маршрутизация клиентов не останавливаются. Когда панель активна, это безопасное действие `⌘Q`. -- **Stop OpenCodex and Quit…** — после подтверждения останавливает фоновый прокси и службу, +- **Stop CodexCommander and Quit…** — после подтверждения останавливает фоновый прокси и службу, восстанавливает нативную маршрутизацию Codex и выходит только после подтверждённой остановки. При ошибке компаньон остаётся открытым и показывает её. Когда панель активна, сочетание клавиш — `⌥⌘Q`. @@ -95,8 +73,8 @@ ChatGPT отображается первым и раскрытым, когда ## Обновления каталога агентов При открытии приложение автоматически синхронизирует каталог моделей Codex с провайдерами, -настроенными в OpenCodex. Если процессы Codex не запущены, новый список будет готов к следующей -задаче Codex. Если долгоживущий процесс загрузил прежний список, OpenCodex продолжает работать, +настроенными в CodexCommander. Если процессы Codex не запущены, новый список будет готов к следующей +задаче Codex. Если долгоживущий процесс загрузил прежний список, CodexCommander продолжает работать, а в панели остаётся неаварийная карточка **Agent catalog update ready**. Выберите **Apply agent catalog…**, чтобы оценить риск прерывания. По возможности непосредственно @@ -104,34 +82,34 @@ ChatGPT отображается первым и раскрытым, когда доказательство простоя Codex: новый запрос может начаться до выполнения действия. **Apply Now** ещё раз синхронизирует каталог, отправляет `SIGTERM` только точно совпавшим процессам текущего пользователя `codex … app-server` и `codex-code-mode-host` и кратко проверяет завершение прежних PID. Широкий -`pkill` не используется; прокси OpenCodex не перезапускается, а приложение меню не закрывается. +`pkill` не используется; прокси CodexCommander не перезапускается, а приложение меню не закрывается. В следующей задаче Codex создаёт новый фоновый процесс и загружает текущий список. -В этом выпуске нет **Apply when idle**. Если ответ ещё формируется, выберите **Later** и примените +В текущем приложении-компаньоне нет **Apply when idle**. Если ответ ещё формируется, выберите **Later** и примените обновление, когда будете готовы; карточка останется доступной. Расширенный запасной вариант CLI: ```bash -ocx sync --restart-codex +ccx sync --restart-codex ``` ## Аутентификация и конфиденциальность -Компаньон не создаёт отдельную систему входа, не переносит данные в macOS Keychain и не читает -учётные данные провайдеров из Keychain. +Компаньон не создаёт отдельную систему входа, не использует macOS Keychain и не читает оттуда +учётные данные провайдеров. -Текущие версии OpenCodex создают независимые учётные данные управления в -<code>~/.opencodex/admin-api-token</code> (или -<code>$OPENCODEX_HOME/admin-api-token</code>). Компаньон читает этот существующий файл через +Текущие версии CodexCommander создают независимые учётные данные управления в +<code>~/.codexcommander/admin-api-token</code> (или +<code>$CODEXCOMMANDER_HOME/admin-api-token</code>). Компаньон читает этот существующий файл через проверенный файловый дескриптор без перехода по символическим ссылкам, хранит значение только -в памяти процесса и отправляет его только процессу OpenCodex на loopback-интерфейсе, прошедшему +в памяти процесса и отправляет его только процессу CodexCommander на loopback-интерфейсе, прошедшему проверку идентичности. Он никогда не показывает, не журналирует, не копирует и не сохраняет токен и не помещает его в URL браузера. -Учётные данные провайдеров остаются под управлением OpenCodex. Компаньон никогда не читает +Учётные данные провайдеров остаются под управлением CodexCommander. Компаньон никогда не читает токены ChatGPT, Kimi, Grok, Anthropic или других провайдеров и никогда напрямую не вызывает эндпоинты входа провайдеров. -Установка, настроенная только с помощью <code>OPENCODEX_ADMIN_AUTH_TOKEN</code>, работает, когда +Установка, настроенная только с помощью <code>CODEXCOMMANDER_ADMIN_AUTH_TOKEN</code>, работает, когда эта переменная наследуется процессом приложения. Приложения, запущенные из Finder, обычно не наследуют переменные оболочки; если защищённого файла токена нет, компаньон сообщает, что аутентификация управления недоступна, вместо того чтобы показывать форму ввода токена. @@ -146,49 +124,47 @@ ocx sync --restart-codex Когда панель открыта, приложение часто обновляет лёгкие данные об активности, а после её закрытия снижает частоту. Квоты провайдеров обновляются отдельно и реже, с использованием -временных меток источника, сообщаемых OpenCodex. При повторных сбоях задержка автоматически +временных меток источника, сообщаемых CodexCommander. При повторных сбоях задержка автоматически увеличивается, а перекрывающиеся обновления объединяются. Используйте **Обновить**, чтобы немедленно обновить активность и принудительно обновить квоты. ## Сборка из исходного кода -Требуются macOS 13 или новее и Xcode Command Line Tools. Для универсальной релизной сборки под -Intel + Apple silicon требуется полная версия Xcode. +Требуются macOS 13 или новее и Xcode Command Line Tools. Для универсальной сборки под Intel + Apple silicon требуется полная версия Xcode. ```bash -git clone https://github.com/pavelhov/opencodex.git -cd opencodex +cd /path/to/CodexCommander bun install bun run test:macos bun run build:macos -open dist/macos/OpenCodex.app +open dist/macos/CodexCommander.app ``` -Исходное приложение находится ровно в `dist/macos/OpenCodex.app`. Для него нужны зависимости из +Исходное приложение находится ровно в `dist/macos/CodexCommander.app`. Для него нужны зависимости из `bun install`: оно использует Bun и CLI из того же checkout. Оставляйте его там во время разработки, не копируйте в Application Support. Двойной щелчок пытается запустить прокси, но при сбое или работе офлайн не закрывает приложение: панель и кнопка **Start** остаются доступными. -Каждая сборка записывает точную ревизию Git в `OpenCodexSourceRevision` файла `Info.plist` внутри +Каждая сборка записывает точную ревизию Git в `CodexCommanderSourceRevision` файла `Info.plist` внутри пакета и печатает её после сборки. Для незакоммиченного исходного кода добавляется `-dirty`, поэтому -перед финальной распространяемой сборкой сначала создайте коммит. +перед финальной сборкой сначала создайте коммит. ## Устранение неполадок -- **Прокси недоступен** — запустите его командой <code>ocx start</code> или установите фоновую - службу командой <code>ocx service install</code>. -- **Аутентификация недоступна** — выполните <code>ocx doctor</code>; убедитесь, что каталог - состояния OpenCodex и <code>admin-api-token</code> принадлежат вашему пользователю и недоступны +- **Прокси недоступен** — запустите его командой <code>ccx start</code> или установите фоновую + службу командой <code>ccx service install</code>. +- **Аутентификация недоступна** — выполните <code>ccx doctor</code>; убедитесь, что каталог + состояния CodexCommander и <code>admin-api-token</code> принадлежат вашему пользователю и недоступны для группы и остальных пользователей. - **Квота недоступна** — откройте раздел **Управление** нужного провайдера и подключите или повторно аутентифицируйте аккаунт. Если Grok показывает **Требуется обновить вход**, завершите вход - командой <code>grok</code>, затем нажмите **Обновить** в OpenCodex; для Kimi используйте + командой <code>grok</code>, затем нажмите **Обновить** в CodexCommander; для Kimi используйте <code>kimi</code>. Некоторые провайдеры не предоставляют API квот. - **Не удалось восстановиться после перезапуска** — откройте **Logs** и выполните - <code>ocx status</code>. Компаньон никогда не завершает процесс принудительно и не + <code>ccx status</code>. Компаньон никогда не завершает процесс принудительно и не перезаписывает состояние службы в качестве запасного варианта. -- **После остановки, обновления или холодного запуска видны только нативные модели** — снова - откройте OpenCodex. При запуске каталог синхронизируется автоматически, а если обнаружение +- **После остановки, обновления Codex или холодного запуска видны только нативные модели** — снова + откройте CodexCommander. При запуске каталог синхронизируется автоматически, а если обнаружение провайдеров временно вернуло пустой результат, всё ещё настроенные маршрутизируемые модели восстанавливаются из защищённого последнего рабочего каталога. Если карточка **Agent catalog update ready** остаётся видимой, выберите **Apply agent catalog…** или используйте запасной @@ -196,7 +172,7 @@ open dist/macos/OpenCodex.app ## Удаление -Выключите **Launch at Login**, завершите работу компаньона и переместите <code>OpenCodex.app</code> +Выключите **Launch at Login**, завершите работу компаньона и переместите <code>CodexCommander.app</code> в Корзину. Он не хранит учётные данные провайдеров и не создаёт записей Keychain. Удаление -компаньона не останавливает и не удаляет прокси OpenCodex. Выполните отдельно -<code>ocx service uninstall</code>, только если нужно удалить и фоновую службу. +компаньона не останавливает и не удаляет прокси CodexCommander. Выполните отдельно +<code>ccx service uninstall</code>, только если нужно удалить и фоновую службу. diff --git a/docs-site/src/content/docs/ru/guides/model-ordering.md b/docs-site/src/content/docs/ru/guides/model-ordering.md index fe12d0de01..d63b24fe87 100644 --- a/docs-site/src/content/docs/ru/guides/model-ordering.md +++ b/docs-site/src/content/docs/ru/guides/model-ordering.md @@ -1,10 +1,10 @@ --- title: Порядок моделей -description: Как opencodex определяет порядок моделей в селекторе Codex и в переопределениях модели spawn_agent. +description: Как CodexCommander определяет порядок моделей в селекторе Codex и в переопределениях модели spawn_agent. --- Селектор модели Codex не сохраняет порядок объявления провайдеров или массивов моделей в -конфигурации opencodex. Итоговый порядок определяется приоритетами каталога, а маршрутизируемые +конфигурации CodexCommander. Итоговый порядок определяется приоритетами каталога, а маршрутизируемые модели с одинаковым приоритетом упорядочиваются детерминированно по алфавиту. ## Правило, которое применяет Codex @@ -14,7 +14,7 @@ description: Как opencodex определяет порядок моделей началу сгенерированного JSON-массива не передвигает её ближе к началу селектора. Это ограничение зафиксировано прямо в реализации, в `src/codex/catalog/sync.ts`. -Поэтому opencodex управляет размещением избранных моделей, назначая более низкие приоритеты, а +Поэтому CodexCommander управляет размещением избранных моделей, назначая более низкие приоритеты, а не полагаясь на позицию в массиве. Фиксированные значения в этой таблице и пример ниже относятся к конфигурации без подходящих селекторов аккаунтов. При наличии `N` селекторов каждая выбранная bare native-модель с настроенным рангом `i` разворачивается в строки с приоритетами `i * N + j`, @@ -75,7 +75,7 @@ API управления ограничивает `subagentModels` пятью з 3. Невыбранные нативные модели, сдвинутые ниже блока избранных при слиянии каталога. Без `subagentModels` маршрутизируемые модели остаются с приоритетом `5`, нативные GPT-записи -используют обычный приоритет (для записей, построенных opencodex, обычно `9`), а группа +используют обычный приоритет (для записей, построенных CodexCommander, обычно `9`), а группа маршрутизируемых моделей сохраняет алфавитный порядок «провайдер/id». ## Пример @@ -120,14 +120,14 @@ native-выбора в selector-qualified группы. точному id, если доступен её маршрут, а ограничение в пять слотов применяется только к переопределениям, первыми объявляемым `spawn_agent`. -Используйте `ocx agent subagents set` или отредактируйте конфигурацию opencodex, чтобы добавить точные +Используйте `ccx agent subagents set` или отредактируйте конфигурацию CodexCommander, чтобы добавить точные варианты `<selector>/<native-openai-model>`, которых нет в живой библиотеке. Командный центр сохраняет и позволяет переупорядочивать уже настроенные точные селекторы, даже когда их провайдер временно недоступен. При активных селекторах одна bare native-модель может развернуться в несколько selector-qualified строк, поэтому число настроенных вариантов и объявляемых строк не обязательно совпадает. -Общих настроек `modelOrder`, `providerOrder` или карты приоритетов в `OcxConfig` сейчас нет. +Общих настроек `modelOrder`, `providerOrder` или карты приоритетов в `CodexCommanderConfig` сейчас нет. Поддерживаемое поле порядка — `subagentModels`; `disabledModels` и `selectedModels` каждого провайдера — поля видимости. Изменение остальной части порядка селектора потребовало бы изменения поведения на уровне кода, а не правки конфигурации. diff --git a/docs-site/src/content/docs/ru/guides/model-routing.md b/docs-site/src/content/docs/ru/guides/model-routing.md index 6aef7ebe33..6e84965a46 100644 --- a/docs-site/src/content/docs/ru/guides/model-routing.md +++ b/docs-site/src/content/docs/ru/guides/model-routing.md @@ -1,6 +1,6 @@ --- title: Маршрутизация моделей -description: Как opencodex решает, какой провайдер будет обслуживать заданный id модели. +description: Как CodexCommander решает, какой провайдер будет обслуживать заданный id модели. --- Когда Codex запрашивает модель, `router.ts` разрешает её ровно в одного настроенного провайдера. @@ -27,7 +27,7 @@ description: Как opencodex решает, какой провайдер буд 2. **Id или алиас combo** — пока настроен хотя бы один combo, канонический `combo/<id>` или настроенный алиас combo выбирает конкретную цель до проверки пространств имён провайдеров. - Если combo не настроены, legacy physical provider с буквальным именем `combo` остаётся обычным + Если combo не настроены, physical provider с буквальным именем `combo` остаётся обычным пространством имён провайдера. Выбор целей и поведение failover описаны в разделе [Combo](/ru/guides/combos/). diff --git a/docs-site/src/content/docs/ru/guides/opencode.md b/docs-site/src/content/docs/ru/guides/opencode.md index 22c7494271..01b8057d41 100644 --- a/docs-site/src/content/docs/ru/guides/opencode.md +++ b/docs-site/src/content/docs/ru/guides/opencode.md @@ -1,28 +1,28 @@ --- title: opencode -description: Используйте любую маршрутизируемую модель из opencode — opencodex внедряет блок провайдера времени выполнения и не меняет вашу конфигурацию opencode. +description: Используйте любую маршрутизируемую модель из opencode — CodexCommander внедряет блок провайдера времени выполнения и не меняет вашу конфигурацию opencode. --- opencode читает провайдеров из объединённых JSON-слоёв конфигурации, а не из переменных окружения, -поэтому здесь нет слота вроде `ANTHROPIC_BASE_URL`, который можно просто подменить. `ocx opencode` +поэтому здесь нет слота вроде `ANTHROPIC_BASE_URL`, который можно просто подменить. `ccx opencode` закрывает этот пробел: он убеждается, что прокси запущен, строит блок провайдера из видимого каталога и внедряет его через inline runtime layer OpenCode (`OPENCODE_CONFIG_CONTENT`). ## Быстрый старт ```bash -ocx opencode +ccx opencode ``` Команда убеждается, что прокси запущен, и запускает opencode, внедряя для этого процесса только -сгенерированный блок `provider.opencodex`. Дополнительные аргументы передаются дальше: -`ocx opencode run "hello"`. +сгенерированный блок `provider.codexcommander`. Дополнительные аргументы передаются дальше: +`ccx opencode run "hello"`. -Маршрутизируемые модели появляются в picker под провайдером `opencodex`: +Маршрутизируемые модели появляются в picker под провайдером `codexcommander`: ```text -opencodex/kiro/glm-5 -opencodex/gpt-5.6-sol # native slugs stay unprefixed +codexcommander/kiro/glm-5 +codexcommander/gpt-5.6-sol # native slugs stay unprefixed ``` ## Ваша собственная конфигурация никогда не меняется @@ -30,54 +30,54 @@ opencodex/gpt-5.6-sol # native slugs stay unprefixed Лончер не копирует и не переписывает `~/.config/opencode/opencode.json`, проектные `opencode.json` / `opencode.jsonc` и любые другие конфигурационные слои на диске. Он может читать глобальную или проектную конфигурацию, чтобы обнаружить override -`provider.opencodex`, но ваши существующие провайдеры, агенты, keybind'ы, записи MCP и +`provider.codexcommander`, но ваши существующие провайдеры, агенты, keybind'ы, записи MCP и относительные ссылки `{file:…}` продолжают разрешаться из исходных файлов. -Только для этого запуска opencodex добавляет сгенерированный блок `provider.opencodex` через +Только для этого запуска CodexCommander добавляет сгенерированный блок `provider.codexcommander` через inline runtime layer OpenCode. Этот слой сливается после глобальной/custom/project-конфигурации и переопределяет только конфликтующие ключи дочернего процесса. -| Слой | Поведение с `ocx opencode` | +| Слой | Поведение с `ccx opencode` | | --- | --- | | Global / custom / project config | Остаётся на диске ровно в том виде, в каком вы её записали | -| Inline runtime (`OPENCODE_CONFIG_CONTENT`) | Получает только сгенерированный блок `provider.opencodex` | +| Inline runtime (`OPENCODE_CONFIG_CONTENT`) | Получает только сгенерированный блок `provider.codexcommander` | | Relative `{file:…}` paths | Всё так же разрешаются относительно конфигурационного файла, где были определены | -Если глобальная или проектная конфигурация тоже определяет `provider.opencodex`, лончер печатает -информационное замечание: runtime layer из `ocx opencode` переопределяет её только для этого +Если глобальная или проектная конфигурация тоже определяет `provider.codexcommander`, лончер печатает +информационное замечание: runtime layer из `ccx opencode` переопределяет её только для этого запуска. ## Постоянное подключение через Dashboard (необязательно) Для обычного OpenCode, редакторских интеграций или запуска Desktop одним нажатием откройте -**Integrations** в панели OpenCodex и выберите **Apply connection**. Это отдельный путь от -`ocx opencode`: +**Integrations** в панели CodexCommander и выберите **Apply connection**. Это отдельный путь от +`ccx opencode`: - выбирается активный глобальный файл OpenCode под `XDG_CONFIG_HOME` (обычно `~/.config/opencode/`): существующий `opencode.jsonc`, иначе `opencode.json`; -- JSONC-редактор меняет только `provider.opencodex`, сохраняя комментарии, форматирование и все +- JSONC-редактор меняет только `provider.codexcommander`, сохраняя комментарии, форматирование и все остальные ключи; -- токен допуска остаётся в защищённом состоянии OpenCodex, а конфигурация OpenCode получает лишь +- токен допуска остаётся в защищённом состоянии CodexCommander, а конфигурация OpenCode получает лишь ссылку `{file:/абсолютный/путь}` — токен и хранилище авторизации OpenCode не читаются; - **Always keep OpenCode connected** выключен по умолчанию и после явного включения обновляет только этот блок при старте прокси или изменении видимого каталога. **Restore** восстанавливает исходные байты точно, когда journal допускает точное восстановление. -Иначе Dashboard восстанавливает или удаляет только управляемый `provider.opencodex`, не затрагивая +Иначе Dashboard восстанавливает или удаляет только управляемый `provider.codexcommander`, не затрагивая поздние правки пользователя. **Open OpenCode** запускает OpenCode Desktop одним нажатием; при наличии только -CLI используйте `ocx opencode`, который остаётся временным и не меняет файлы. +CLI используйте `ccx opencode`, который остаётся временным и не меняет файлы. ## Как перенести блок в свою конфигурацию -`ocx opencode` внедряет блок провайдера только на один запуск. Если постоянное подключение Dashboard +`ccx opencode` внедряет блок провайдера только на один запуск. Если постоянное подключение Dashboard выше не применено, обычный `opencode` по-прежнему ничего не знает о прокси. Если вы хотите, чтобы маршрутизируемые модели были доступны и из обычного `opencode` — либо из расширения редактора, которое никогда не проходит через этот -лончер, — `ocx export` напечатает тот же блок провайдера, чтобы вы сами слили его в свою +лончер, — `ccx export` напечатает тот же блок провайдера, чтобы вы сами слили его в свою конфигурацию: ```bash -ocx export --client opencode +ccx export --client opencode ``` Прокси должен быть запущен. Команда печатает конфиг, канонический путь назначения @@ -87,32 +87,32 @@ ocx export --client opencode вашим действием. :::caution[Сливать, а не заменять] -Слейте блок `provider.opencodex` со своей существующей конфигурацией. Если заменить им весь файл, +Слейте блок `provider.codexcommander` со своей существующей конфигурацией. Если заменить им весь файл, вы уничтожите остальные провайдеры, агенты, keybind'ы и записи MCP. Именно поэтому -`ocx export --out` отказывается перезаписывать существующий файл, так что указывайте `--out` на +`ccx export --out` отказывается перезаписывать существующий файл, так что указывайте `--out` на временный путь и потом переносите только нужный блок: ```bash -ocx export --client opencode --out ~/opencodex-opencode.json +ccx export --client opencode --out ~/codexcommander-opencode.json ``` ::: В отличие от runtime-блока лончера, слитый блок — это статический снимок: он не следует за вашим каталогом. После добавления провайдера или изменения видимости моделей заново выполните -`ocx export`. +`ccx export`. После merge экспортируйте admission key перед запуском opencode — если только прокси не работает на loopback, где ключ не нужен: ```bash -export OPENCODEX_OPENCODE_API_KEY=<your key> +export CODEXCOMMANDER_OPENCODE_API_KEY=<your key> ``` ## Admission key не пишется на диск Когда прокси требует API-ключ, inline runtime config содержит ссылку `{env:…}` opencode, а не сам секрет. На loopback эта ссылка используется как `apiKey`; на не-loopback привязке она уходит -только через `x-opencodex-api-key`, чтобы admission прокси оставался отделённым от любого +только через `x-codexcommander-api-key`, чтобы admission прокси оставался отделённым от любого upstream-заголовка `Authorization`. Пример для loopback: @@ -120,7 +120,7 @@ upstream-заголовка `Authorization`. ```json "options": { "baseURL": "http://127.0.0.1:10100/v1", - "apiKey": "{env:OPENCODEX_OPENCODE_API_KEY}" + "apiKey": "{env:CODEXCOMMANDER_OPENCODE_API_KEY}" } ``` @@ -130,24 +130,24 @@ upstream-заголовка `Authorization`. "options": { "baseURL": "http://192.168.1.10:10100/v1", "headers": { - "x-opencodex-api-key": "{env:OPENCODEX_OPENCODE_API_KEY}" + "x-codexcommander-api-key": "{env:CODEXCOMMANDER_OPENCODE_API_KEY}" } } ``` Реальное значение передаётся только через окружение дочернего процесса. -`OPENCODEX_API_AUTH_TOKEN` имеет приоритет, затем идёт hardened service token file, затем +`CODEXCOMMANDER_API_AUTH_TOKEN` имеет приоритет, затем идёт hardened service token file, затем настроенный API key — именно он требуется для не-loopback-привязки. Loopback-привязка (`127.0.0.1`, по умолчанию) не требует аутентификации, поэтому ссылка `{env:…}` остаётся инертной, и переменную можно не задавать. Она важна только когда `hostname` выходит за пределы loopback; см. [Удалённый доступ](/reference/configuration/#remote-access). Этот admission key -относится к самому opencodex и не связан с upstream-ключами провайдеров, настраиваемыми в +относится к самому CodexCommander и не связан с upstream-ключами провайдеров, настраиваемыми в [Провайдерах](/guides/providers/). ## Откат -Для временного запуска `ocx opencode` откатывать нечего: конфигурация OpenCode не меняется. +Для временного запуска `ccx opencode` откатывать нечего: конфигурация OpenCode не меняется. Для подключения Dashboard выберите **Restore** в **Integrations**: при безопасном точном восстановлении вернутся исходные байты, иначе будет хирургически восстановлен только управляемый провайдер. @@ -162,7 +162,7 @@ Loopback-привязка (`127.0.0.1`, по умолчанию) не требу получалось `output > context`. Эта цифра существует только для удовлетворения схемы — она не утверждает ничего о реальном максимуме какой-либо модели. -Блок провайдера `opencodex` пересобирается при каждом запуске, поэтому внесённые вами правки +Блок провайдера `codexcommander` пересобирается при каждом запуске, поэтому внесённые вами правки внутри него не сохранятся. Для пользовательских записей держите отдельный provider key. ## Требования diff --git a/docs-site/src/content/docs/ru/guides/pi.md b/docs-site/src/content/docs/ru/guides/pi.md index 0960ecf49a..e58bc68b55 100644 --- a/docs-site/src/content/docs/ru/guides/pi.md +++ b/docs-site/src/content/docs/ru/guides/pi.md @@ -1,11 +1,11 @@ --- title: Pi -description: Используйте любую маршрутизируемую модель из Pi — ocx export создаёт пользовательский блок провайдера для models.json Pi, направленный на работающий прокси. +description: Используйте любую маршрутизируемую модель из Pi — ccx export создаёт пользовательский блок провайдера для models.json Pi, направленный на работающий прокси. --- Pi читает провайдеров из одного глобального JSON-файла, а не из переменных окружения, поэтому -opencodex не запускает его сам. Вместо этого `ocx export` сериализует блок провайдера -`opencodex` — base URL, список моделей и env-ссылку, которую интерполирует Pi, — а вы сливаете +CodexCommander не запускает его сам. Вместо этого `ccx export` сериализует блок провайдера +`codexcommander` — base URL, список моделей и env-ссылку, которую интерполирует Pi, — а вы сливаете его в свою конфигурацию. ## Быстрый старт @@ -13,8 +13,8 @@ opencodex не запускает его сам. Вместо этого `ocx ex Сначала запустите прокси, затем выведите конфиг: ```bash -ocx start -ocx export --client pi +ccx start +ccx export --client pi ``` Сначала выводится JSON, затем путь назначения, предупреждение о merge, строка `export` для @@ -23,10 +23,10 @@ ocx export --client pi ```json { "providers": { - "opencodex": { + "codexcommander": { "baseUrl": "http://127.0.0.1:10100/v1", "api": "openai-completions", - "apiKey": "$OPENCODEX_API_KEY", + "apiKey": "$CODEXCOMMANDER_API_KEY", "models": [ { "id": "anthropic/claude-opus-5", @@ -55,18 +55,18 @@ Id моделей — это канонические селекторы про ``` :::caution[Сливать, а не заменять] -`ocx export` никогда не пишет в этот файл. Слейте в него блок `providers.opencodex` — если +`ccx export` никогда не пишет в этот файл. Слейте в него блок `providers.codexcommander` — если заменить файл целиком, вы уничтожите всех остальных провайдеров, уже настроенных в нём. `--out` предназначен для временного пути и не позволит перезаписать существующий файл без `--force`: ```bash -ocx export --client pi --out ~/opencodex-pi-models.json -ocx export --client pi --json > ~/opencodex-pi-models.json # or redirect the byte-exact JSON +ccx export --client pi --out ~/codexcommander-pi-models.json +ccx export --client pi --json > ~/codexcommander-pi-models.json # or redirect the byte-exact JSON ``` ::: Экспортируемый блок — это статический снимок, а не живое представление. После добавления -провайдера или изменения видимости моделей заново выполняйте `ocx export`, а новый блок вливайте +провайдера или изменения видимости моделей заново выполняйте `ccx export`, а новый блок вливайте поверх старого. ## Admission key @@ -75,21 +75,21 @@ ocx export --client pi --json > ~/opencodex-pi-models.json # or redirect the b | Ключ | Что это | Где хранится | | --- | --- | --- | -| Ключ допуска прокси | собственная учётная запись opencodex, генерируемая на вкладке **API** в дашборде | указывается в `apiKey` как `$OPENCODEX_API_KEY`; само значение остаётся в окружении | -| Ключ провайдера | ваш ключ Anthropic / OpenAI / OpenRouter | хранится в конфигурации самого opencodex, см. [Провайдеры](/guides/providers/) | +| Ключ допуска прокси | собственная учётная запись CodexCommander, генерируемая на вкладке **API** в дашборде | указывается в `apiKey` как `$CODEXCOMMANDER_API_KEY`; само значение остаётся в окружении | +| Ключ провайдера | ваш ключ Anthropic / OpenAI / OpenRouter | хранится в конфигурации самого CodexCommander, см. [Провайдеры](/guides/providers/) | Экспортируемая конфигурация несёт только ссылку, а не секрет. Pi интерполирует голый `$NAME`, поэтому переменная должна выглядеть так: ```bash -export OPENCODEX_API_KEY=<your key> +export CODEXCOMMANDER_API_KEY=<your key> ``` Это имя переменной относится только к Pi. opencode использует другую переменную -(`OPENCODEX_OPENCODE_API_KEY` в форме `{env:…}`) — см. [руководство по opencode](/guides/opencode/). +(`CODEXCOMMANDER_OPENCODE_API_KEY` в форме `{env:…}`) — см. [руководство по opencode](/guides/opencode/). -**Прокси на loopback вообще не требует ключа.** По умолчанию opencodex привязывается к -`127.0.0.1` и ничего там не аутентифицирует, поэтому ссылка `$OPENCODEX_API_KEY` инертна и +**Прокси на loopback вообще не требует ключа.** По умолчанию CodexCommander привязывается к +`127.0.0.1` и ничего там не аутентифицирует, поэтому ссылка `$CODEXCOMMANDER_API_KEY` инертна и переменную можно не задавать. Она нужна только когда `hostname` выходит за пределы loopback — а именно в этом случае прокси и отказывается запускаться без токена; см. [Удалённый доступ](/reference/configuration/#remote-access). @@ -98,13 +98,13 @@ export OPENCODEX_API_KEY=<your key> `contextWindow` и `maxTokens` выводятся только тогда, когда каталог сообщает авторитетное контекстное окно. Если его нет, оба поля для этой модели опускаются, и Pi использует собственные -значения по умолчанию; `ocx export` печатает, сколько строк попали в эту категорию. +значения по умолчанию; `ccx export` печатает, сколько строк попали в эту категорию. `maxTokens` — это удовлетворяющий схеме бюджет `32000`, ограниченный сверху контекстным окном, чтобы у модели с маленьким контекстом никогда не было больше output, чем сам context. Это не утверждение о реальном максимуме какой-либо модели. -Два поля намеренно отсутствуют. `cost` требует всех четырёх ценовых полей, а у opencodex нет +Два поля намеренно отсутствуют. `cost` требует всех четырёх ценовых полей, а у CodexCommander нет данных о ценах для маршрутизируемых моделей — вывести нули означало бы заявить, что каждая модель бесплатна. `reasoning` в Pi — булево поле, тогда как каталог несёт целую лестницу effort, и отображать одно на другое пришлось бы догадкой. @@ -115,11 +115,11 @@ export OPENCODEX_API_KEY=<your key> Форма выше соответствует опубликованной документации Pi по custom-провайдерам. Она **не была проверена** на реальном `~/.pi/agent/models.json` на машине с установленным Pi. Если Pi отвергнет экспортированный блок, несоответствие на нашей стороне — пожалуйста, -[создайте issue](https://github.com/lidge-jun/opencodex/issues) и приложите то, что сообщил Pi. +[создайте issue](https://github.com/pavelhov/CodexCommander/issues) и приложите то, что сообщил Pi. ::: ## Требования -Нужны запущенный прокси opencodex (`ocx start`) и установленный Pi. `ocx export` читает живой +Нужны запущенный прокси CodexCommander (`ccx start`) и установленный Pi. `ccx export` читает живой каталог через management API прокси, поэтому конфиг никогда не будет сгенерирован с пустым списком моделей. diff --git a/docs-site/src/content/docs/ru/guides/providers.md b/docs-site/src/content/docs/ru/guides/providers.md index 1b06542817..11543189fe 100644 --- a/docs-site/src/content/docs/ru/guides/providers.md +++ b/docs-site/src/content/docs/ru/guides/providers.md @@ -1,11 +1,11 @@ --- title: Провайдеры -description: Все способы, которыми opencodex аутентифицируется и общается с LLM-провайдером — OAuth, API-ключ, форвард ChatGPT и локальные серверы. +description: Все способы, которыми CodexCommander аутентифицируется и общается с LLM-провайдером — OAuth, API-ключ, форвард ChatGPT и локальные серверы. --- **Провайдер** — это одна вышестоящая конечная точка LLM плюс способ подключения к ней: адаптер, базовый URL, режим аутентификации и необязательный список моделей. Провайдеры находятся в -`~/.opencodex/config.json` в секции `providers`. +`~/.codexcommander/config.json` в секции `providers`. ## Режимы аккаунтов OpenAI @@ -46,11 +46,6 @@ description: Все способы, которыми opencodex аутентиф и настройки маршрутизации описаны в разделе [пула аккаунтов Codex Auth](/ru/guides/web-dashboard/#codex-auth-and-account-pools). -Поставляемые v1-конфигурации автоматически мигрируют на маркер 2 и одну строку с поддержкой опций. -Исходная конфигурация один раз сохраняется в `~/.opencodex/config.json.pre-openai-tiers-v2.bak`; -восстановить её можно командой -`cp ~/.opencodex/config.json.pre-openai-tiers-v2.bak ~/.opencodex/config.json`. - ## Режимы аутентификации Конфигурация провайдера принимает три значения `authMode` (по умолчанию — `key`). Встроенный реестр @@ -60,7 +55,7 @@ description: Все способы, которыми opencodex аутентиф | --- | --- | --- | | `key` | Отправляет ваш API-ключ (`Authorization: Bearer …` либо `x-api-key` / `api-key` в зависимости от адаптера). Ключ может быть литералом или ссылкой вида `${ENV_VAR}`. | Большинство провайдеров. | | `forward` | Передаёт провайдеру **входящие заголовки аутентификации Codex** без изменений — ключ не хранится. Это сквозной режим (passthrough) входа через ChatGPT. | OpenAI (адаптер `openai-responses`). | -| `oauth` | Берёт сохранённый OAuth-токен как bearer-ключ и соблюдает владельца учётных данных. Учётные данные OpenCodex обновляются до истечения срока; связанные данные Grok/Kimi CLI принимаются только для чтения и остаются во владении нативного CLI. | xAI, Anthropic, Kimi, Kiro, Google Antigravity, Cursor, GitHub Copilot. | +| `oauth` | Берёт сохранённый OAuth-токен как bearer-ключ и соблюдает владельца учётных данных. Учётные данные CodexCommander обновляются до истечения срока; связанные данные Grok/Kimi CLI принимаются только для чтения и остаются во владении нативного CLI. | xAI, Anthropic, Kimi, Kiro, Google Antigravity, Cursor, GitHub Copilot. | Повтор при 429 на том же ключе ([`retryOn429`](/ru/reference/configuration/)) применим только к провайдерам с API-ключом (`authMode: "key"`). Пресеты OAuth, forward и local исключены — их @@ -94,41 +89,41 @@ account id, OpenAI beta/originator/session — см. [Адаптеры](/ru/refe ## 2. Вход по аккаунту (OAuth) Семь пресетов провайдеров используют вход через OAuth — плюс GitHub Copilot через -экспериментальный неофициальный мост device flow. opencodex хранит их учётные данные в -`~/.opencodex/auth.json`. Учётные данные, принадлежащие OpenCodex, обновляются автоматически. -При подключении активной сессии Grok или Kimi CLI opencodex принимает текущее поколение доступа +экспериментальный неофициальный мост device flow. CodexCommander хранит их учётные данные в +`~/.codexcommander/auth.json`. Учётные данные, принадлежащие CodexCommander, обновляются автоматически. +При подключении активной сессии Grok или Kimi CLI CodexCommander принимает текущее поколение доступа только для чтения, а обновление остаётся обязанностью нативного CLI. CLI входа также принимает `chatgpt`: эта команда получает учётные данные ChatGPT и одновременно создаёт запись провайдера в режиме `forward`. ```bash -ocx login xai # xAI Grok -ocx login anthropic # Anthropic Claude (Pro/Max) -ocx login kimi # Moonshot Kimi -ocx login kiro # импорт учётных данных kiro-cli (с фолбэком на токен) -ocx login google-antigravity -ocx login cursor # отдельный PKCE-вход Cursor -ocx login command-code # браузерный OAuth Command Code (или импорт ~/.commandcode/auth.json) -ocx login github-copilot # device flow GitHub → токен Copilot (Copilot Pro/Business) -ocx login chatgpt # отдельный OAuth-вход ChatGPT -ocx logout <provider> +ccx login xai # xAI Grok +ccx login anthropic # Anthropic Claude (Pro/Max) +ccx login kimi # Moonshot Kimi +ccx login kiro # импорт учётных данных kiro-cli (с фолбэком на токен) +ccx login google-antigravity +ccx login cursor # отдельный PKCE-вход Cursor +ccx login command-code # браузерный OAuth Command Code (или импорт ~/.commandcode/auth.json) +ccx login github-copilot # device flow GitHub → токен Copilot (Copilot Pro/Business) +ccx login chatgpt # отдельный OAuth-вход ChatGPT +ccx logout <provider> ``` | Провайдер | Адаптер | Базовый URL | Примечания | | --- | --- | --- | --- | | `xai` | `openai-chat` | `https://api.x.ai/v1` | Каталог Grok загружается в реальном времени; фолбэк по умолчанию — `grok-4.5`. | | `anthropic` | `anthropic` | `https://api.anthropic.com` | Модели Claude; актуальный список моделей загружается из `/v1/models`. | -| `kimi` | `openai-chat` | `https://api.kimi.com/coding/v1` | Kimi K3 (`k3`, контекст 1M), фиксированное окно `k3-256k`, алиас совместимости `k3[1m]` и прежние модели K2.7/K2.6/K2.5. | -| `kiro` | `kiro` | `https://runtime.us-east-1.kiro.dev` | Первый вход импортирует существующую сессию после установки Kiro CLI (в Unix: `curl -fsSL https://cli.kiro.dev/install | bash`; в Windows PowerShell: `irm 'https://cli.kiro.dev/install.ps1' | iex`; затем выполните `kiro-cli login`). **Добавить аккаунт** выполняет выход из `kiro-cli`, запускает новый вход через браузер, переключает аккаунт самого `kiro-cli` и сохраняет метаданные профиля отдельно для каждого аккаунта. Существующие аккаунты OpenCodex сохраняются; при отмене или сбое восстанавливается предыдущая сессия `kiro-cli`. | +| `kimi` | `openai-chat` | `https://api.kimi.com/coding/v1` | Kimi K3 (`k3`, контекст 1M), фиксированное окно `k3-256k`, алиас совместимости `k3[1m]` и модели K2.7/K2.6/K2.5. | +| `kiro` | `kiro` | `https://runtime.us-east-1.kiro.dev` | Первый вход импортирует существующую сессию после установки Kiro CLI (в Unix: `curl -fsSL https://cli.kiro.dev/install | bash`; в Windows PowerShell: `irm 'https://cli.kiro.dev/install.ps1' | iex`; затем выполните `kiro-cli login`). **Добавить аккаунт** выполняет выход из `kiro-cli`, запускает новый вход через браузер, переключает аккаунт самого `kiro-cli` и сохраняет метаданные профиля отдельно для каждого аккаунта. Существующие аккаунты CodexCommander сохраняются; при отмене или сбое восстанавливается предыдущая сессия `kiro-cli`. | | `google-antigravity` | `google` | `https://daily-cloudcode-pa.googleapis.com` | Google OAuth поверх протокола Cloud Code Assist. Используется поддерживаемый статический каталог из шести моделей, поскольку CCA не предоставляет общий эндпоинт `/models`. | | `cursor` | `cursor` | `https://api2.cursor.sh` | Экспериментальный PKCE-вход, живой транспорт HTTP/2 и обнаружение моделей с фильтрацией по аккаунту. | | `github-copilot` | `openai-chat` | `https://api.githubcopilot.com` | Экспериментально. Device flow GitHub + обмен `copilot_internal` (OAuth-клиент VS Code). Требуется активная подписка Copilot; это не официальный сторонний API. | Для канонических пресетов Kimi Coding Plan (вход через аккаунт `kimi` и API-ключ `kimi-code`) -opencodex передаёт в запрос Chat Completions только стабильный `prompt_cache_key`, предоставленный +CodexCommander передаёт в запрос Chat Completions только стабильный `prompt_cache_key`, предоставленный вызывающей стороной, и никогда не создаёт его сам. Документация Kimi требует стабильный ключ сессии/задачи для повышения доли попаданий в кэш Code Plan; запрос без ключа остаётся без ключа. -Если включённый провайдер отклоняет поле, opencodex не удаляет его для повторной попытки и не +Если включённый провайдер отклоняет поле, CodexCommander не удаляет его для повторной попытки и не изменяет сохранённую конфигурацию. Для остальных провайдеров действует deny-by-default. OAuth можно запустить и из [веб-дашборда](/ru/guides/web-dashboard/). @@ -139,25 +134,25 @@ OAuth-провайдеры, чьи учётные данные содержат несколько входов. Страница Providers показывает эти аккаунты в выпадающем списке, позволяет добавить ещё один и переключает активный аккаунт, не выполняя выход из остальных. Учётные данные Только учётные данные Kimi без идентификатора заменяют активный слот; аккаунты Kiro сохраняются по ARN профиля. -`chatgpt` всегда занимает один слот, поскольку у пула аккаунтов Codex отдельный реестр. Токены остаются в `~/.opencodex/auth.json`; +`chatgpt` всегда занимает один слот, поскольку у пула аккаунтов Codex отдельный реестр. Токены остаются в `~/.codexcommander/auth.json`; `/api/oauth/accounts` возвращает только маскированные метаданные. ### Импорт учётных данных Kiro -Для входа Kiro требуется Kiro CLI: в Unix установите его командой `curl -fsSL https://cli.kiro.dev/install | bash`, в Windows PowerShell — `irm 'https://cli.kiro.dev/install.ps1' | iex`, затем сначала выполните `kiro-cli login`. Если сессии `kiro-cli` нет, `ocx login kiro` использует вставленный токен доступа или переменную окружения `KIRO_ACCESS_TOKEN`. +Для входа Kiro требуется Kiro CLI: в Unix установите его командой `curl -fsSL https://cli.kiro.dev/install | bash`, в Windows PowerShell — `irm 'https://cli.kiro.dev/install.ps1' | iex`, затем сначала выполните `kiro-cli login`. Если сессии `kiro-cli` нет, `ccx login kiro` использует вставленный токен доступа или переменную окружения `KIRO_ACCESS_TOKEN`. -Обычный импорт `ocx login kiro` открывает базу SQLite CLI только для чтения и не изменяет базу, WAL или SHM. +Обычный импорт `ccx login kiro` открывает базу SQLite CLI только для чтения и не изменяет базу, WAL или SHM. - `KIROCLI_DB_PATH` выбирает нестандартную базу SQLite Kiro CLI; указанная база должна уже существовать. - `KIROCLI_TOKEN_KEY` выбирает точный ключ строки `auth_kv`, если найдено несколько неоднозначных строк с токенами. Без выбора вход завершается ошибкой, а не пытается угадать строку. -Импортированные учётные данные сохраняются в `~/.opencodex/auth.json`. Откат **Добавить аккаунт** — отдельная операция: при восстановлении предыдущего снимка она заменяет базу и удаляет текущие sidecar-файлы WAL, SHM и journal. +Импортированные учётные данные сохраняются в `~/.codexcommander/auth.json`. Откат **Добавить аккаунт** — отдельная операция: при восстановлении предыдущего снимка она заменяет базу и удаляет текущие sidecar-файлы WAL, SHM и journal. Поскольку откат возможен только при наличии снимка, **Добавить аккаунт** откажется выходить из `kiro-cli`, если хранилище сессии существует, но его нельзя захватить (файл не читается, несовпадение схемы, неоднозначный выбор токена), если `KIROCLI_DB_PATH` / `KIRO_CLI_DB_FILE` направляют импорт не на активное хранилище CLI, или если в основной базе CLI нет распознаваемой строки токена. Исправьте или удалите повреждённую базу по обычному пути данных `kiro-cli`, снимите селекторы только для импорта и повторите попытку. На машины без существующей сессии `kiro-cli` это не влияет. ## 3. Каталог API-ключей -opencodex поставляется с 76 встроенными пресетами: 64 на основе ключей, восемь OAuth, три локальных и +CodexCommander поставляется с 76 встроенными пресетами: 64 на основе ключей, восемь OAuth, три локальных и один пресет ChatGPT-форварда по умолчанию. Селектор **Add provider** в дашборде открывает страницу выдачи ключей провайдера, проверяет ключ и сохраняет его; проверка зависит от провайдера. Наиболее заметные записи: @@ -165,9 +160,9 @@ opencodex поставляется с 76 встроенными пресетам **ClinePass** подключается с помощью Cline API key к [официальному каталогу подписки](https://docs.cline.bot/getting-started/clinepass) и [Chat Completions endpoint](https://docs.cline.bot/api/chat-completions). Оператор — Cline Bot Inc., указанный в [условиях Cline](https://cline.bot/tos). Маршрут вида `cline-pass/cline-pass/kimi-k3` -намеренный: первая часть выбирает провайдера opencodex, а полный slug `cline-pass/kimi-k3` +намеренный: первая часть выбирает провайдера CodexCommander, а полный slug `cline-pass/kimi-k3` отправляется upstream. Использование учитывается в общих для аккаунта скользящем 5-часовом, -недельном и месячном лимитах. Сейчас opencodex публикует только проверенный на живом API reasoning tier +недельном и месячном лимитах. Сейчас CodexCommander публикует только проверенный на живом API reasoning tier `low`; более высокие запросы ограничиваются до `low`, пока шлюз не опубликует или не подтвердит более широкий диапазон. **Cline** использует тот же ключ и эндпоинт с оплатой по мере использования и доступом к 100+ моделям @@ -228,8 +223,8 @@ Volcengine Agent Plan использует нативную конечную т `opencode-go` — это подписочный провайдер OpenCode Go с адресом `https://opencode.ai/zen/go/v1`, а не OpenCode Desktop/CLI. Создайте ключ в [консоли OpenCode](https://opencode.ai/console), затем добавьте **OpenCode Go** на странице -**Providers** дашборда или настройте пресет `opencode-go` с этим ключом. OpenCodex не читает -хранилище авторизации OpenCode и не переносит ключ в Keychain. +**Providers** дашборда или настройте пресет `opencode-go` с этим ключом. CodexCommander не читает +хранилище авторизации OpenCode и не сохраняет ключ в Keychain. Публичный каталог моделей не доказывает работоспособность ключа: он считается **непроверенным** до первого успешного inference с активным ключом. Опубликованные лимиты — справочные: **$12 / 5 часов**, @@ -238,7 +233,7 @@ Volcengine Agent Plan использует нативную конечную т его явно сообщает upstream. Встроенный пресет использует API-ключ, поэтому Add Provider относит его к **Paid**, а не к входам по -аккаунту; OAuth-потока OpenCode Go в OpenCodex нет. Он также отличается от клиента **OpenCode** в +аккаунту; OAuth-потока OpenCode Go в CodexCommander нет. Он также отличается от клиента **OpenCode** в разделе Client Apps и от не требующего ключа провайдера **OpenCode Free**. Поиск Add Provider охватывает Accounts, Free и Paid одновременно, поэтому запрос `opencode` на любой вкладке показывает все совпавшие пресеты с их категориями. @@ -276,7 +271,7 @@ Service token Nscale создаётся в [Nscale Console](https://console.nsca **Discovery для Command Code.** Пресет читает список `/provider/v1/models` с фиксированного хоста Provider API, сохраняет нативные id моделей со знаком `/` и ограничивает live discovery размером -256 KiB и 256 исходными строками. `ocx login command-code` поддерживает вход через OAuth в браузере +256 KiB и 256 исходными строками. `ccx login command-code` поддерживает вход через OAuth в браузере (с возможностью импорта локальных учётных данных CLI из `~/.commandcode/auth.json` для существующих пользователей CLI Command Code); каталог моделей привязан к учётной записи и берётся из аутентифицированного discovery endpoint после входа. Запросы чата используют настроенный bearer-ключ. @@ -319,7 +314,7 @@ Project ID и dedicated deployment настраиваются как custom prov Пользовательский провайдер с `openai-chat`, `authMode: "key"` и каноническим адресом `https://api.a6api.com` или `https://api.a6api.com/v1` показывает расход кредитов A6API в -дашборде и в `ocx account refresh <provider>`. Имя провайдера может быть любым. Единицы токенов +дашборде и в `ccx account refresh <provider>`. Имя провайдера может быть любым. Единицы токенов пересчитываются в USD по hard credit limit учётной записи; отображаются процент расхода и остаток. Срок действия токена не считается сбросом квоты, поскольку он не означает пополнение. Только активный ключ отправляется на канонический хост, перенаправления отклоняются, а отрицательные или несогласованные итоги биллинга @@ -343,14 +338,14 @@ Providers, сохраняется в `provider.apiKeyPool`, становится ### Переключение аккаунтов из терминала -Используйте `ocx account list`, `ocx account current` и `ocx account use`, чтобы просматривать и +Используйте `ccx account list`, `ccx account current` и `ccx account use`, чтобы просматривать и переключать те же пулы Codex, OAuth и API-ключей, не открывая дашборд. Команды, JSON-вывод и поведение в новых сессиях описаны в разделе -[Справочник CLI](/ru/reference/cli/#ocx-account-subcommand). +[Справочник CLI](/ru/reference/cli/#ccx-account-subcommand). ### Превью-маршруты GPT-5.6 -GPT-5.6 Sol/Terra/Luna заранее внесены в резервные списки провайдеров, чтобы `ocx sync` сохранял +GPT-5.6 Sol/Terra/Luna заранее внесены в резервные списки провайдеров, чтобы `ccx sync` сохранял модели видимыми, даже когда живые каталоги отстают: | Маршрут Codex | Предзаданные id моделей | Контекст, видимый Codex | @@ -367,19 +362,19 @@ Luna есть `max`, но нет `ultra`). Маршрутизируемые за предзаданный список до моделей, доступных вошедшему аккаунту. :::note[Шлюзы и прокси по подписке] -Провайдер попадает в список, когда у opencodex есть подходящий wire-адаптер, а **не** в зависимости +Провайдер попадает в список, когда у CodexCommander есть подходящий wire-адаптер, а **не** в зависимости от того, является ли он «агентским» продуктом. Текущие id адаптеров: `openai-chat`, `openai-responses`, `anthropic`, `google` (режимы AI Studio, Vertex и Antigravity/Cloud Code -Assist), `azure` / `azure-openai`, `kiro` и `cursor`. Проприетарный API без одной из этих +Assist), `azure-openai`, `kiro` и `cursor`. Проприетарный API без одной из этих реализаций — например, нативный Amazon Bedrock — напрямую не поддерживается. -**GitHub Copilot** — это OAuth-провайдер (`ocx login github-copilot`), который обменивает вход +**GitHub Copilot** — это OAuth-провайдер (`ccx login github-copilot`), который обменивает вход через device flow GitHub на короткоживущий API-токен Copilot, а не принимает вставленный API-ключ. **GitLab Duo** остаётся шлюзом с ключом/токеном подписки на своей OpenAI-совместимой конечной точке. **Cloudflare AI Gateway** требует подставить в URL id аккаунта и шлюза. Copilot предоставляет каталог со смешанными проводами: его семейство GPT-5 (`gpt-5.3-codex`, `gpt-5.4`, `gpt-5.4-mini`, `gpt-5.5`, `gpt-5.6-luna`, `gpt-5.6-sol`, `gpt-5.6-terra`) -отклоняет `/chat/completions` для агентного трафика, поэтому opencodex по умолчанию +отклоняет `/chat/completions` для агентного трафика, поэтому CodexCommander по умолчанию маршрутизирует эти модели через Responses API, а все остальные модели Copilot остаются на chat completions. Приоритет: жёсткий wire-пин → явная запись [`modelAdapters`](/ru/reference/configuration/providers/) → дефолт реестра → adapter всего @@ -387,21 +382,21 @@ chat completions. Приоритет: жёсткий wire-пин → явная Responses, задайте `"modelAdapters": { "gpt-5.4-nano": "openai-responses" }`. Cursor отслеживается отдельно как экспериментальный адаптер. `adapter: "cursor"` появляется в -`ocx init` и в селекторе Add Provider дашборда как экспериментальная запись локальной конфигурации +`ccx init` и в селекторе Add Provider дашборда как экспериментальная запись локальной конфигурации с метаданными статического резервного каталога моделей Cursor. Когда настроен токен доступа Cursor, -opencodex использует живой транспорт HTTP/2 Cursor. Его встроенный резервный список включает +CodexCommander использует живой транспорт HTTP/2 Cursor. Его встроенный резервный список включает `gpt-5.6-sol` / `terra` / `luna` (контекст 1M), `grok-4.5` / `grok-4.5-fast` (500K) и `kimi-k3` (262K); живое обнаружение решает, какие из них останутся видимыми для аккаунта. Cursor отдаёт Kimi K3 только через wire id с суффиксом усилия, поэтому `cursor/kimi-k3` предоставляет лестницу `low` / `high` / `max` и по умолчанию использует `max` — как и задокументированное значение по умолчанию в API модели. Управляемое сервером Cursor нативное выполнение read/write/delete/ls/grep/shell/fetch по умолчанию отключено, поскольку оно -обходит путь одобрений и песочницу Codex; устанавливайте `unsafeAllowNativeLocalExec: true` в -объекте `providers.cursor` файла `~/.opencodex/config.json` только для доверенных локальных +обходит путь одобрений и песочницу Codex; устанавливайте `nativeLocalExec: "on"` в +объекте `providers.cursor` файла `~/.codexcommander/config.json` только для доверенных локальных экспериментов (или через **Providers → Cursor → Edit JSON** в дашборде). Полный пример см. в [справочнике по конфигурации](/ru/reference/configuration/#cursor-provider-adapter-cursor). MCP, запись экрана и computer-use доступны как хуки исполнителя; без настроенного локального -исполнителя opencodex возвращает типизированные результаты «нет исполнителя», а не блокирует запрос +исполнителя CodexCommander возвращает типизированные результаты «нет исполнителя», а не блокирует запрос политикой. Для этого экспериментального адаптера включены Cursor OAuth и живое обнаружение моделей; при этом Cursor по-прежнему не показывается в списках входа по ключу. ::: @@ -410,7 +405,7 @@ MCP, запись экрана и computer-use доступны как хуки Ollama Cloud — это размещённая в облаке (не локальная) Ollama, OpenAI-совместимая по адресу `https://ollama.com/v1`, с ключом со страницы -[ollama.com/settings/keys](https://ollama.com/settings/keys). opencodex классифицирует её облачную +[ollama.com/settings/keys](https://ollama.com/settings/keys). CodexCommander классифицирует её облачную линейку по поддержке изображений, чтобы [vision-сайдкар](/ru/guides/sidecars/) включался только для текстовых моделей. Текстовые модели (например, `glm-5.2`, `deepseek-v4-pro`, `gpt-oss`, `qwen3-coder`, `minimax-m2.x`, `nemotron-3-*`) перечислены в `noVisionModels`; модели с нативной @@ -420,7 +415,7 @@ Ollama Cloud — это размещённая в облаке (не локал ## 4. Локальные провайдеры -Направьте opencodex на локальный OpenAI-совместимый сервер — обычно с пустым ключом: +Направьте CodexCommander на локальный OpenAI-совместимый сервер — обычно с пустым ключом: | Провайдер | Базовый URL | | --- | --- | @@ -431,6 +426,6 @@ Ollama Cloud — это размещённая в облаке (не локал ## Любая OpenAI-совместимая конечная точка Если провайдер поддерживает Chat Completions, с ним справится адаптер `openai-chat` — выберите -**Custom** в дашборде или `custom` в `ocx init` и введите базовый URL. Все поля провайдера +**Custom** в дашборде или `custom` в `ccx init` и введите базовый URL. Все поля провайдера (`headers`, `noReasoningModels`, `noVisionModels`, `models`, …) описаны в [справочнике по конфигурации](/ru/reference/configuration/). diff --git a/docs-site/src/content/docs/ru/guides/sidecars.md b/docs-site/src/content/docs/ru/guides/sidecars.md index 861d4bb05b..f6273556a6 100644 --- a/docs-site/src/content/docs/ru/guides/sidecars.md +++ b/docs-site/src/content/docs/ru/guides/sidecars.md @@ -4,13 +4,13 @@ description: Настоящий веб-поиск для маршрутизир --- Не все маршрутизируемые модели предоставляют hosted **веб-поиск** или нативный **ввод -изображений**. opencodex восполняет эти возможности двумя сайдкарами. Каждый может работать через +изображений**. CodexCommander восполняет эти возможности двумя сайдкарами. Каждый может работать через провайдера входа ChatGPT (`forward`) или через сохранённого OAuth-провайдера Anthropic. Ошибки сайдкара превращаются в ограниченные по размеру результаты инструментов или маркеры изображений, а не приводят к сбою всего хода. :::note[Автоматический выбор бэкенда] -Явно заданный `backend` имеет приоритет. Если он не задан, opencodex использует `anthropic`, когда +Явно заданный `backend` имеет приоритет. Если он не задан, CodexCommander использует `anthropic`, когда у включённого OAuth-провайдера Anthropic есть активный аккаунт без пометки `needsReauth`; иначе используется `openai`. Явный `anthropic` без таких учётных данных завершается отказом (fail closed). Для `openai` нужны одновременно аутентификация через вход ChatGPT и включённый провайдер @@ -20,13 +20,13 @@ closed). Для `openai` нужны одновременно аутентифи ## Сайдкар веб-поиска Когда Codex запрашивает hosted `web_search` для маршрутизируемой модели вне сквозного режима, -opencodex: +CodexCommander: 1. **Убирает** hosted-инструмент `web_search` и вместо него предоставляет маршрутизируемой модели синтетический функциональный инструмент `web_search(query)`. Исходные опции hosted-инструмента сохраняются для вызова сайдкара. 2. Запускает маршрутизируемую модель в небольшом **агентном цикле**. Когда она вызывает - `web_search`, opencodex использует выбранный бэкенд сайдкара: OpenAI выполняет hosted + `web_search`, CodexCommander использует выбранный бэкенд сайдкара: OpenAI выполняет hosted `web_search` по умолчанию с `gpt-5.6-luna`; Anthropic выполняет `web_search_20250305` по умолчанию с `claude-sonnet-5`. Потоковый ответ и цитаты становятся результатом инструмента. 3. **Повторяет цикл**, пока модель не ответит или суммарный бюджет реальных запросов не достигнет @@ -35,7 +35,7 @@ opencodex: ход, чтобы эти вызовы дошли до Codex. Каждая итерация маршрутизируемой модели запрашивает у вышестоящего провайдера `stream: true`, но -opencodex полностью буферизует семантические события внутри, прежде чем решить, искать дальше или +CodexCommander полностью буферизует семантические события внутри, прежде чем решить, искать дальше или вернуть финальный ответ. Заранее получаются только финальные заголовки/статус первой итерации и ротации ключей по 429. Поэтому синтетические поисковые вызовы и промежуточный вывод никогда не попадают к клиенту как видимый вывод модели. @@ -79,9 +79,8 @@ SSE-событие `response.failed`. ## Vision-сайдкар Когда маршрутизируемая модель указана в `noVisionModels` своего провайдера, а запрос содержит -изображение, opencodex описывает каждое изображение **до** основного вызова и заменяет его текстом. -Дашборд и API управления показывают `gpt-5.6-luna` как текущее значение по умолчанию, а при запуске -явно сохранённое устаревшее значение `gpt-5.4-mini` мигрирует на Luna. Если поле +изображение, CodexCommander описывает каждое изображение **до** основного вызова и заменяет его текстом. +Дашборд и API управления показывают `gpt-5.6-luna` как текущее значение по умолчанию. Если поле `visionSidecar.model` полностью отсутствует, путь выполнения vision всё же имеет зашитый в код фолбэк `gpt-5.4-mini`. diff --git a/docs-site/src/content/docs/ru/guides/sub-agent-surface.md b/docs-site/src/content/docs/ru/guides/sub-agent-surface.md index 5ed7d36aff..600afdbc87 100644 --- a/docs-site/src/content/docs/ru/guides/sub-agent-surface.md +++ b/docs-site/src/content/docs/ru/guides/sub-agent-surface.md @@ -7,9 +7,9 @@ description: Управляйте тем, как Codex создаёт и обс Подагент — это отдельный воркер Codex, которого основной агент может создать для узкой задачи. У него собственный контекст и собственные инструменты, поэтому несколько независимых задач могут -идти параллельно. opencodex управляет тем, какая collaboration surface Codex раскрывает для этих +идти параллельно. CodexCommander управляет тем, какая collaboration surface Codex раскрывает для этих воркеров, какие модели Codex предлагает для них и как выполняется fallback при сбое модели. Когда -именно основной агент должен делегировать задачу, opencodex не решает. +именно основной агент должен делегировать задачу, CodexCommander не решает. ## Режимы @@ -38,7 +38,7 @@ Codex: flag'ом `multi_agent_v2`. - **v2** записывает `multi_agent_version = "v2"` для каждой модели. -opencodex применяет это как финальный проход и к живому каталогу `/v1/models`, и к каталогу, +CodexCommander применяет это как финальный проход и к живому каталогу `/v1/models`, и к каталогу, синхронизированному на диск. Поэтому смена режима одинаково влияет на новые App-, CLI- и TUI-сессии. @@ -50,12 +50,12 @@ TUI-сессии. Раздел **Sub-agent delegation** в дашборде управляет тремя связанными настройками: -- `injectionModel` — предпочитаемая модель воркера, которую opencodex упоминает в guidance. +- `injectionModel` — предпочитаемая модель воркера, которую CodexCommander упоминает в guidance. - `injectionEffort` — необязательный `reasoning_effort`, запрашиваемый для этой модели. - `injectionPrompt` — замена встроенного текста guidance для v2. `multiAgentGuidanceEnabled` по умолчанию включён и служит главным переключателем -guidance-сообщений, которые opencodex пишет сам, на обеих поверхностях. Если выключить его, +guidance-сообщений, которые CodexCommander пишет сам, на обеих поверхностях. Если выключить его, подавляются и блок v2 designation, и proactive text для v1. Это инструкции для основного агента, а не proxy-side spawn router. На v2 полный форк истории @@ -72,33 +72,33 @@ guidance-сообщений, которые opencodex пишет сам, на о | `{{roster}}` | Разрешённый ростер, видимый в picker и совместимый с поверхностью | | `{{fallback}}` | Настроенное глобальное fallback guidance | -Встроенное guidance для v2 ограничено 700 символами. Если оно не укладывается, opencodex сначала +Встроенное guidance для v2 ограничено 700 символами. Если оно не укладывается, CodexCommander сначала убирает ростер, а не обрезает ядро инструкций для spawn. Встроенное guidance включается только тогда, когда разрешается предпочитаемая модель, допустимый ростер или fallback chain. Настроенного `injectionModel` достаточно, чтобы отобразить пользовательский prompt; если значение без селектора нельзя разрешить однозначно, `{{model}}` заменяется пустой строкой. -На v1 opencodex внедряет только upstream-style proactive guidance о делегировании на уровнях +На v1 CodexCommander внедряет только upstream-style proactive guidance о делегировании на уровнях effort `max` или `ultra`. Предпочитаемую модель, ростер, fallback list и custom prompt на v1 он не добавляет. Опция `syncCodexSubagentDefaults`, выключенная по умолчанию, отделена от guidance. Когда -opencodex владеет активной маршрутизацией Codex, sync или restart могут записать выбранные +CodexCommander владеет активной маршрутизацией Codex, sync или restart могут записать выбранные значения как marker-owned поля `[agents] default_subagent_model` и -`default_subagent_reasoning_effort` в TOML Codex. opencodex обновляет или удаляет только те поля, +`default_subagent_reasoning_effort` в TOML Codex. CodexCommander обновляет или удаляет только те поля, которые помечены его marker'ами. Если любое из целевых полей принадлежит пользователю, пара остаётся без изменений вместо частичной записи; неоднозначный TOML отклоняется без записи. Внешние provider manager'ы и user-owned root routing тоже сохраняют приоритет. ## Fallback chains -Для порождённого воркера opencodex строит такой порядок приоритета: +Для порождённого воркера CodexCommander строит такой порядок приоритета: 1. Запрошенная основная модель. 2. Список `model_fallback` роли из её определения `$CODEX_HOME/agents/*.toml`. -3. Глобальный список `subagentModelFallback` в конфигурации opencodex. +3. Глобальный список `subagentModelFallback` в конфигурации CodexCommander. -Дубликаты id моделей удаляются с сохранением первого вхождения. При выборе opencodex пропускает +Дубликаты id моделей удаляются с сохранением первого вхождения. При выборе CodexCommander пропускает кандидатов, которые отключены, немаршрутизируемы, опираются на отключённого провайдера, помечены как unhealthy, находятся в cooldown, не имеют доступного pooled-аккаунта Codex или вышли за настроенный порог квоты. Результаты availability probe кэшируются на @@ -112,11 +112,11 @@ ChatGPT, выбор ограничивается каноническими на Codex может отправить задачу child v2 из native-to-routed пути только как backend-encrypted `encrypted_content`. Эту нагрузку может прочитать нативный backend ChatGPT, но не внешний -провайдер. Это известное ограничение [#92](https://github.com/lidge-jun/opencodex/issues/92). +провайдер. Это известное ограничение [#92](https://github.com/pavelhov/CodexCommander/issues/92). Так ведёт себя политика по умолчанию `multiAgentV2MessageDelivery: "encrypted"`. Экспериментальная политика `"plaintext"` преобразует только полный распознанный V2-контракт во внешнее незарезервированное пространство имён и восстанавливает `collaboration` перед Codex. Поэтому нативный родитель вроде Sol может делегировать Kimi, Grok и DeepSeek, сохраняя V2 lifecycle. Цена совместимости: все V2-сообщения этого родителя, включая сообщения нативным дочерним агентам, становятся plaintext. После сохранения нужна новая сессия; неизвестная или частичная схема не преобразуется и завершается безопасной ошибкой. -opencodex завершаетcя безопасно и не пересылает пустую или нечитаемую задачу: +CodexCommander завершаетcя безопасно и не пересылает пустую или нечитаемую задачу: - Прямой не-нативный маршрут возвращает HTTP 400 с `error.code = "unreadable_encrypted_agent_task"` и не отражает ciphertext назад. @@ -154,27 +154,27 @@ combo, использовать v1 для делегирования между ### CLI -Для collaboration surface и native feature settings используйте `ocx v2`: +Для collaboration surface и native feature settings используйте `ccx v2`: ```bash -ocx v2 status -ocx v2 mode v1 -ocx v2 mode default -ocx v2 mode v2 -ocx v2 threads 8 +ccx v2 status +ccx v2 mode v1 +ccx v2 mode default +ccx v2 mode v2 +ccx v2 threads 8 ``` -Для делегирования, ростера, effort cap и fallback settings используйте `ocx agent`: +Для делегирования, ростера, effort cap и fallback settings используйте `ccx agent`: ```bash -ocx agent status -ocx agent injection set --model anthropic/claude-sonnet-5 --effort xhigh -ocx agent subagents set gpt-5.6-sol,anthropic/claude-sonnet-5 -ocx agent fallback set gpt-5.4-mini,xai/grok-4.5 --poll-ms 60000 -ocx agent effort set --subagent max +ccx agent status +ccx agent injection set --model anthropic/claude-sonnet-5 --effort xhigh +ccx agent subagents set gpt-5.6-sol,anthropic/claude-sonnet-5 +ccx agent fallback set gpt-5.4-mini,xai/grok-4.5 --poll-ms 60000 +ccx agent effort set --subagent max ``` -Чтобы очистить nullable-значение у `ocx agent injection`, передайте `-`, либо используйте +Чтобы очистить nullable-значение у `ccx agent injection`, передайте `-`, либо используйте соответствующее действие `clear` для ростера или fallback list. Полный состав семейств команд см. в [справочнике CLI](/reference/cli/). @@ -224,13 +224,13 @@ model- или effort-override. ### Смена режима влияет на уже запущенные сессии? Нет. После смены режима начните новую сессию Codex. Если долго живущий App host всё ещё показывает -устаревшее состояние каталога, выполните `ocx sync` и перезапустите нужную поверхность Codex. +устаревшее состояние каталога, выполните `ccx sync` и перезапустите нужную поверхность Codex. ### Reasoning effort `injectionEffort` влияет только на guidance для делегированных воркеров и, если это явно включено, на нативные default'ы подагентов в Codex. На effort родительской сессии он не влияет. -`ultra` — это верхний client-facing tier, который Codex переводит в `max`; затем opencodex +`ultra` — это верхний client-facing tier, который Codex переводит в `max`; затем CodexCommander сопоставляет или ограничивает это значение под выбранного провайдера. ### Context cap diff --git a/docs-site/src/content/docs/ru/guides/video-bridge.md b/docs-site/src/content/docs/ru/guides/video-bridge.md index 850c5b0ebe..c4c197de93 100644 --- a/docs-site/src/content/docs/ru/guides/video-bridge.md +++ b/docs-site/src/content/docs/ru/guides/video-bridge.md @@ -6,17 +6,17 @@ description: Генерируйте видео через Grok Imagine Video и ## Обзор Video Bridge позволяет использовать генерацию xAI Grok Imagine Video через любую не-OpenAI модель, -маршрутизируемую opencodex. Когда мост включён, в разговор добавляется синтетический tool -`video_gen`. Модель вызывает его как обычный function tool; opencodex перехватывает вызов, +маршрутизируемую CodexCommander. Когда мост включён, в разговор добавляется синтетический tool +`video_gen`. Модель вызывает его как обычный function tool; CodexCommander перехватывает вызов, отправляет job на генерацию видео в xAI, опрашивает её до завершения и скачивает результат. ## Предварительные требования -- Нужна запись провайдера `xai` с **API-ключом** (`ocx login xai` сам по себе недостаточен — +- Нужна запись провайдера `xai` с **API-ключом** (`ccx login xai` сам по себе недостаточен — video bridge требует key auth, а не OAuth) - Активной маршрутизируемой моделью должна быть не-OpenAI модель (например, Anthropic Claude или Google Gemini) -- opencodex должен быть настроен на маршрутизацию через этого не-OpenAI провайдера +- CodexCommander должен быть настроен на маршрутизацию через этого не-OpenAI провайдера > **⚠ Provider key required:** Video Bridge активируется только тогда, когда провайдер `xai` > использует аутентификацию по API-ключу. Добавьте в конфигурацию: @@ -29,7 +29,7 @@ Video Bridge позволяет использовать генерацию xAI > } > ``` > -> Если вы подключали его через `ocx login xai` (OAuth), провайдер останется в +> Если вы подключали его через `ccx login xai` (OAuth), провайдер останется в > `authMode: "oauth"`, и bridge просто не активируется. Задайте `XAI_API_KEY` в окружении > **или** укажите ключ прямо в конфигурации, как выше. @@ -58,9 +58,9 @@ Video Bridge позволяет использовать генерацию xAI ## Как это работает -1. opencodex обнаруживает не-OpenAI маршрутизируемую модель с `videoBridgeEnabled: true` +1. CodexCommander обнаруживает не-OpenAI маршрутизируемую модель с `videoBridgeEnabled: true` 2. В разговор внедряется синтетический function tool `video_gen` -3. Когда модель вызывает `video_gen`, opencodex отправляет job в `/videos/generations` xAI +3. Когда модель вызывает `video_gen`, CodexCommander отправляет job в `/videos/generations` xAI 4. Bridge опрашивает статус job каждые 5-15 секунд и отправляет heartbeat-сообщения, чтобы поток не умер 5. Когда видео готово, оно скачивается в каталог artifacts 6. Локальный путь к файлу возвращается модели как результат tool diff --git a/docs-site/src/content/docs/ru/guides/web-dashboard.md b/docs-site/src/content/docs/ru/guides/web-dashboard.md index b3c35a980c..3f1e7c898d 100644 --- a/docs-site/src/content/docs/ru/guides/web-dashboard.md +++ b/docs-site/src/content/docs/ru/guides/web-dashboard.md @@ -1,29 +1,29 @@ --- title: Веб-дашборд -description: GUI opencodex для состояния прокси, провайдеров, моделей, инструкций делегирования, пулов аутентификации, использования и логов. +description: GUI CodexCommander для состояния прокси, провайдеров, моделей, инструкций делегирования, пулов аутентификации, использования и логов. --- -opencodex включает локальный веб-дашборд (Vite/React-приложение в каталоге `gui/`), который раздаёт +CodexCommander включает локальный веб-дашборд (Vite/React-приложение в каталоге `gui/`), который раздаёт сам прокси. Это кратчайший путь к управлению провайдерами, аккаунтами Codex/ChatGPT, моделями каталога, сайдкарами, настройками подагентов и трафиком запросов. ## Как открыть ```bash -ocx gui +ccx gui ``` Команда открывает `http://localhost:<port>` в браузере, при необходимости сначала автоматически запуская прокси. При разработке dev-сервер GUI можно запускать отдельно поверх работающего прокси: ```bash -ocx start +ccx start bun run dev:gui ``` ## Вход -При открытии дашборда через loopback-адрес, например `localhost` или `127.0.0.1`, он автоматически получает краткоживущую GUI-сессию, поэтому ввод токена обычно не требуется. Для дашборда на любом другом хосте нужен административный токен из `OPENCODEX_ADMIN_AUTH_TOKEN` или автоматически созданного файла `~/.opencodex/admin-api-token`. +При открытии дашборда через loopback-адрес, например `localhost` или `127.0.0.1`, он автоматически получает краткоживущую GUI-сессию, поэтому ввод токена обычно не требуется. Для дашборда на любом другом хосте нужен административный токен из `CODEXCOMMANDER_ADMIN_AUTH_TOKEN` или автоматически созданного файла `~/.codexcommander/admin-api-token`. Удалённый дашборд показывает стандартную форму пароля, поэтому менеджер паролей браузера может предложить сохранить и автозаполнять токен. Сам дашборд хранит токен только в памяти и не записывает его в `localStorage` или `sessionStorage`; решение о сохранении полностью остаётся за браузером или менеджером паролей. @@ -32,19 +32,19 @@ bun run dev:gui | Раздел | Что делает | | --- | --- | | **Сводка Dashboard** | Мультиагентный режим, состояние онлайн, версия, время работы, число провайдеров, сумма токенов за 30 дней, активные провайдеры и доступные нативные/маршрутизируемые модели. | -| **Sub-agent delegation** | Выбор нативной/маршрутизируемой модели и необязательного уровня рассуждений, общих для руководства OpenCodex по делегированию и опциональных нативных значений подагентов Codex по умолчанию. Это не маршрутизатор отдельных порождений; см. ниже. | +| **Sub-agent delegation** | Выбор нативной/маршрутизируемой модели и необязательного уровня рассуждений, общих для руководства CodexCommander по делегированию и опциональных нативных значений подагентов Codex по умолчанию. Это не маршрутизатор отдельных порождений; см. ниже. | | **Сайдкары** | Выбор модели и уровня рассуждений для веб-поиска, а также модели описания изображений. Изменения применяются со следующего запроса. | -| **Maintenance** | Пересинхронизация каталога моделей Codex, просмотр предупреждений об обходе через проектную локальную конфигурацию, проверка последнего или предварительного выпуска и запуск обновления с необязательным перезапуском прокси. | +| **Maintenance** | Пересинхронизация каталога моделей Codex и просмотр предупреждений об обходе через проектную локальную конфигурацию. | | **Безопасность запуска** | Показывает, сохранит ли внедрённая маршрутизация Codex работоспособность после перезагрузки, отдельно отображая службу, launcher shim и точные команды исправления. | | **Трей Windows** | Устанавливает пользовательский значок входа для запуска, остановки, перезапуска, панели и состояния прокси одним щелчком. Трей не является службой перезапуска. | -| **Автозапуск Codex** | Разрешает уже установленному launcher shim Codex выполнять `ocx ensure`. Переключатель не устанавливает shim или фоновую службу. | +| **Автозапуск Codex** | Разрешает уже установленному launcher shim Codex выполнять `ccx ensure`. Переключатель не устанавливает shim или фоновую службу. | | **Providers** | Добавление, редактирование, назначение провайдера по умолчанию (только включённые), включение/отключение и удаление провайдеров; управление пулами OAuth-аккаунтов и пулами API-ключей там, где они поддерживаются. При удалении текущего провайдера по умолчанию выбирается первый оставшийся включённый провайдер, если он есть; иначе удаление отклоняется и текущий default сохраняется. Для пулов Claude (Anthropic) OAuth у каждого вошедшего аккаунта свои полосы 5-часового и недельного лимита (использование по учётным данным); при сбое опроса сохраняются последние известные значения с пометкой недоступности. | | **Add provider** | Поиск по пресетам из реестра: вход по аккаунту, сервисы с API-ключом, локальные серверы или пользовательская конечная точка. Запрос ищет одновременно в Accounts, Free и Paid; вкладки остаются для просмотра. | | **Codex Auth** | Добавление аккаунтов пула ChatGPT/Codex, выбор аккаунта для следующей сессии, обновление квот 5 ч / недельных / 30-дневных, включение или отключение автопереключения, настройка его порога 1–100% и failover при временных сбоях. | | **Subagents** | В **Agent Command Center** можно выбрать и упорядочить пять моделей, рекламируемых `spawn_agent`, искать в текущем каталоге и настроить Run Policy: протокол, доставку V2, guidance, fallback и лимит потоков. Сохранённые, но не рекламируемые записи показываются явно. | | **Models** | Включение и отключение нативных GPT и маршрутизируемых моделей, настройка allowlist'ов провайдеров и лимитов контекста, выбор **Classic v1**, **Follow Codex defaults** или **Concurrent v2** и настройка лимита потоков v2. Карточка Current behavior показывает контекст как **Uncapped**, **Limited** или **Mixed limits**. Для каждого маршрутизируемого провайдера отображается **Автообнаружение включено** или **Только статический каталог** со ссылкой на соответствующую настройку провайдера. | | **Client Apps** | Просмотр настроенных и доступных локальных клиентов, применение или удаление управляемой конфигурации там, где это поддерживается, проверка резервных копий и доступ к Codex, Claude Code/Desktop, Grok Build, OpenCode и файловым клиентам без смешения клиентов с провайдерами. | -| **API Access** | Выпуск и управление ключами, которыми другие приложения аутентифицируются в прокси OpenCodex. Учётные данные вышестоящих провайдеров остаются в Providers. | +| **API Access** | Выпуск и управление ключами, которыми другие приложения аутентифицируются в прокси CodexCommander. Учётные данные вышестоящих провайдеров остаются в Providers. | | **Logs** | Автообновляемый список недавних запросов: токены, запрошенный и, когда доступен, фактически отправленный уровень рассуждений, фактическая модель, провайдер, статус, id запроса, длительность и подробности ошибок. Если адаптер отправляет параметр рассуждений, в подробностях также отображается точное wire-поле. Можно фильтровать по непрозрачному id диалога/сессии (если клиент его передаёт) и суммировать токены и оценочную стоимость по прайс-листу в пределах загруженного кольца Logs. | | **Usage / Debug** | Просмотр покрытия и трендов расхода токенов либо включение опциональной диагностики транспорта провайдеров и извлечения данных об использовании. | | **Storage** | Только чтение разбивки диска CODEX_HOME (сессии, архивы, БД, вложения). Опциональная очистка архива: предпросмотр самых старых N%, затем карантин в `CODEX_HOME/.trash` (по умолчанию) или безвозвратное удаление по явному флажку. **Политика автоочистки** — opt-in и **по умолчанию ВЫКЛ** (`storageCleanupPolicy.enabled`); порог/цель/расписание/режим на странице Storage или **Запустить сейчас**. Записи карантина можно восстановить со страницы Storage (JSONL + threads). Активные сессии только для чтения. Очистка и восстановление отклоняются, пока Codex держит блокировку новейшего/активного `state_*.sqlite`. | @@ -52,7 +52,7 @@ bun run dev:gui ### Ссылки на разделы -Макет теперь один, поэтому переключать нечего. Зато у разделов Dashboard есть собственные адреса: `#dashboard` открывает Overview, а `#dashboard/providers` и `#dashboard/models` — два других раздела. Перезагрузка, закладка и кнопка «Назад» сохраняют выбранный раздел. **Logs** работает так же — `#logs` и `#logs/debug`. Старая закладка `#providers/workspace` теперь ведёт на `#providers`. +Макет теперь один, поэтому переключать нечего. Зато у разделов Dashboard есть собственные адреса: `#dashboard` открывает Overview, а `#dashboard/providers` и `#dashboard/models` — два других раздела. Перезагрузка, закладка и кнопка «Назад» сохраняют выбранный раздел. **Logs** работает так же — `#logs` и `#logs/debug`. Значения стоимости в **Logs** и **Usage** — это эквиваленты стоимости по прайс-листу API, рассчитанные на основе сообщённых токенов. Они не являются счётом и не подтверждают фактическое @@ -67,19 +67,19 @@ bun run dev:gui ## Селектор делегирования и маршрутизация порождений Селектор **Sub-agent delegation** в дашборде сохраняет `injectionModel` и, при желании, -`injectionEffort`. Выбранные значения используются в добавляемом OpenCodex руководстве по +`injectionEffort`. Выбранные значения используются в добавляемом CodexCommander руководстве по делегированию, которое отдельно управляется полем `multiAgentGuidanceEnabled`. Очистка модели также очищает сохранённый уровень и отключает синхронизацию нативных значений по умолчанию. Если включить **Использовать как нативные значения подагентов Codex по умолчанию**, следующая синхронизация или перезапуск применит выбранные модель и уровень как нативные значения `[agents]`, -когда активной маршрутизацией Codex управляет OpenCodex. Внешняя пользовательская конфигурация +когда активной маршрутизацией Codex управляет CodexCommander. Внешняя пользовательская конфигурация провайдера остаётся неизменной. Они действуют только для вновь создаваемых задач Codex, и эта настройка сама по себе не запускает делегирование. Существующие пользовательские значения `[agents]` не перезаписываются, а сохраняются, поэтому запрошенные и фактические значения Codex по умолчанию могут различаться. :::caution -Эти два переключателя независимы. Отключение руководства OpenCodex по делегированию не отключает +Эти два переключателя независимы. Отключение руководства CodexCommander по делегированию не отключает синхронизацию нативных значений по умолчанию; включение синхронизации не включает руководство и не вызывает делегирование. Ни одна из настроек не является кросс-модельным маршрутизатором отдельных порождений на стороне прокси. Каноничное поведение v1/base/v2 описано на странице @@ -108,7 +108,7 @@ bun run dev:gui Изменённый порядок действует начиная со **следующего непривязанного запроса** и никогда не перемещает уже привязанный поток. Аккаунт Codex Desktop (основной) упорядочивается наравне с остальными, поэтому его можно поставить **Последним** и держать в резерве. Порядок, заданный через - `ocx account priority` вне этих пяти пресетов, остаётся видимым и выбираемым на карточке. + `ccx account priority` вне этих пяти пресетов, остаётся видимым и выбираемым на карточке. - Привязка потока предотвращает метание между аккаунтами на каждом запросе. При включённом автопереключении по квоте долгоживущий поток периодически переоценивается и может перепривязаться, когда его релевантное использование достигает порога и существует подходящий @@ -135,7 +135,6 @@ GUI — это тонкий клиент поверх JSON-API управлен | `GET /api/startup-health` | Чтение безопасной диагностики маршрутизации, службы, shim и устойчивости к перезагрузке. | | `GET` / `POST /api/windows-tray` | Чтение или изменение установки и видимости трея Windows; POST поддерживает `install`, `start`, `stop`, `uninstall`. | | `POST /api/sync` | Пересборка общего каталога моделей и инвалидация кэша моделей Codex. | -| `GET /api/update/check` · `POST /api/update/run` · `GET /api/update/status` | Проверка, запуск и мониторинг задач самообновления. | | `GET` / `PUT /api/sidecar-settings` | Чтение или настройка моделей сайдкаров поиска/vision. | | `GET` / `PUT /api/injection-model` | Чтение или настройка модели/уровня руководства по делегированию, его переключателя и переключателя синхронизации нативных значений подагентов Codex по умолчанию. | | `GET` / `PUT /api/v2` | Чтение или настройка режима поверхности, фиче-флага Codex и лимита потоков v2. | diff --git a/docs-site/src/content/docs/ru/index.mdx b/docs-site/src/content/docs/ru/index.mdx index 7203f756db..6a367e43ef 100644 --- a/docs-site/src/content/docs/ru/index.mdx +++ b/docs-site/src/content/docs/ru/index.mdx @@ -1,10 +1,10 @@ --- -title: "opencodex — Запускайте Codex на любой LLM" +title: "CodexCommander — Запускайте Codex на любой LLM" description: Универсальный прокси провайдеров для OpenAI Codex и Claude Code — используйте любую LLM с Codex CLI, App, SDK и Claude Code. template: splash head: - tag: title - content: "opencodex — Запускайте Codex на любой LLM" + content: "CodexCommander — Запускайте Codex на любой LLM" - tag: meta attrs: property: og:locale diff --git a/docs-site/src/content/docs/ru/reference/adapters.md b/docs-site/src/content/docs/ru/reference/adapters.md index d84c86693b..6daa6d8ef0 100644 --- a/docs-site/src/content/docs/ru/reference/adapters.md +++ b/docs-site/src/content/docs/ru/reference/adapters.md @@ -3,7 +3,7 @@ title: Адаптеры description: Семь адаптеров провайдеров — назначение каждого, способ построения запросов и особенности. --- -**Адаптер** выполняет преобразование между внутренней моделью запросов/ответов opencodex и +**Адаптер** выполняет преобразование между внутренней моделью запросов/ответов CodexCommander и wire-форматом одного провайдера. Каждый адаптер реализует интерфейс `ProviderAdapter` (`src/adapters/base.ts`): @@ -18,7 +18,7 @@ interface ProviderAdapter { } ``` -`buildRequest` понижает `OcxParsedRequest` до HTTP-запроса к вышестоящему провайдеру; +`buildRequest` понижает `CodexCommanderParsedRequest` до HTTP-запроса к вышестоящему провайдеру; `parseStream` / `parseResponse` поднимают ответ провайдера обратно во внутренние события `AdapterEvent`. `fetchResponse` позволяет адаптеру самому управлять повторными попытками и таймаутами, а `runTurn` поддерживает транспорты, которые нельзя представить как один HTTP-запрос @@ -62,7 +62,7 @@ interface ProviderAdapter { том же ключе, как и в переводимом пути `openai-chat`/Anthropic. Пользовательские транспорты `runTurn` в цикл HTTP-повторов не входят. -- URL для `forward` → `{baseUrl}/responses`. Провайдер с `key` по умолчанию сохраняет прежнее построение `{baseUrl}/v1/responses`. +- URL для `forward` → `{baseUrl}/responses`. URL по умолчанию для провайдера с `key` — `{baseUrl}/v1/responses`. - Провайдер с `key` может задать проверенный относительный `responsesPath`: адаптер удаляет один завершающий `/` из `baseUrl` и отправляет запрос на `{trimmedBaseUrl}{responsesPath}`. Для Ark Agent Plan используйте `baseUrl: "https://ark.cn-beijing.volces.com/api/plan/v3"` и `responsesPath: "/responses"`. - В режиме `forward` ретранслируется только безопасный allowlist заголовков (`FORWARD_HEADERS`): authorization, ChatGPT account id и заголовки OpenAI beta/originator/session. Это путь входа @@ -123,7 +123,7 @@ Kiro (`https://runtime.{region}.kiro.dev/`). неповторяемой ошибкой context-length, фильтрация и срабатывание guardrail — отфильтрованным incomplete. `TOOL_USE` без фактического вызова инструмента трактуется как противоречие, а не прогресс. -В ходе с инструментами opencodex добавляет приватный `codex_kiro_final_answer`. Повторная попытка не +В ходе с инструментами CodexCommander добавляет приватный `codex_kiro_final_answer`. Повторная попытка не создаёт пустые assistant/user-сообщения, сохраняет исходный user/tool-result и перед отправкой проверяет чередование ролей, непустые структурные сообщения и пары tool use/result. Ответ инструмента завершения всегда выдаётся как `final_answer`, даже если он совпадает с предыдущим commentary. @@ -152,10 +152,10 @@ authorization. `grok-4.5`, помещая отдельные значения `effort` и `fast=true` в `requested_model.parameters`. - Нативное для Cursor локальное выполнение операций с файловой системой/shell/сетью по умолчанию запрещено. Явные интеграции `mcpServers` и `desktopExecutor` включаются отдельно; - `unsafeAllowNativeLocalExec` включает более широкий встроенный executor и обходит семантику + `nativeLocalExec: "on"` включает более широкий встроенный executor и обходит семантику одобрений/песочницы Codex. -## `azure-openai` (алиас: `azure`) +## `azure-openai` **Назначение:** **Azure OpenAI**. Обёртка над `openai-responses` (поэтому тоже `passthrough: true`). diff --git a/docs-site/src/content/docs/ru/reference/architecture.md b/docs-site/src/content/docs/ru/reference/architecture.md index 569652c6a4..22cdaf4f5c 100644 --- a/docs-site/src/content/docs/ru/reference/architecture.md +++ b/docs-site/src/content/docs/ru/reference/architecture.md @@ -1,9 +1,9 @@ --- title: Архитектура -description: Внутреннее устройство opencodex — карта модулей, мост AdapterEvent, парсер запросов и кэширование. +description: Внутреннее устройство CodexCommander — карта модулей, мост AdapterEvent, парсер запросов и кэширование. --- -opencodex — это один процесс Bun. Запрос приходит как OpenAI Responses, нормализуется во +CodexCommander — это один процесс Bun. Запрос приходит как OpenAI Responses, нормализуется во внутреннюю модель, маршрутизируется, отправляется провайдеру через адаптер и мостом преобразуется обратно в Responses SSE. Сквозной поток описан в разделе [Как это работает](/ru/getting-started/how-it-works/). @@ -12,7 +12,7 @@ opencodex — это один процесс Bun. Запрос приходит ``` src/ -├── cli/ # ocx command dispatch, init, status, provider commands +├── cli/ # ccx command dispatch, init, status, provider commands ├── server/ # Bun.serve, /v1/* proxy, /api/* management API, WS bridge ├── codex/ # Codex config injection, catalog sync, auth/account integration ├── providers/ # provider metadata, API-key pool, quota and labels @@ -22,12 +22,12 @@ src/ ├── lib/ # runtime, process, retry, privacy, token estimate helpers ├── web-search/ # web-search sidecar (synthetic tool, loop, executor, parser) ├── vision/ # vision sidecar (describe + plan) -├── config.ts # ~/.opencodex/config.json, defaults, PID, env resolution +├── config.ts # ~/.codexcommander/config.json, defaults, PID, env resolution ├── router.ts # model id → provider + adapter ├── bridge.ts # AdapterEvent stream → Responses SSE / JSON ├── reasoning-effort.ts # reasoning-effort translation, clamping, and catalog levels ├── responses/ -│ ├── parser.ts # Responses request → OcxParsedRequest +│ ├── parser.ts # Responses request → CodexCommanderParsedRequest │ ├── schema.ts # Zod validation │ └── compaction.ts # remote compaction prompts, envelopes, compact history ├── service.ts # launchd / systemd / Task Scheduler background service @@ -35,15 +35,14 @@ src/ └── index.ts # public entry ``` -Три прежних крупных входных файла теперь служат фасадами совместимости: `codex/catalog.ts` -экспортирует семь модулей `codex/catalog/*.ts`, `server/management-api.ts` направляет запросы в +`codex/catalog.ts` экспортирует семь модулей `codex/catalog/*.ts`, `server/management-api.ts` направляет запросы в девять модулей `server/management/*.ts`, а `server/responses.ts` экспортирует пять модулей `server/responses/*.ts`. ## Поток запроса `server/index.ts` владеет HTTP-границей и делегирует плоскость данных Responses в -фасад `server/responses.ts` и его модули `server/responses/*.ts`: +`server/responses.ts` и его модули `server/responses/*.ts`: 1. `server/index.ts` применяет CORS и аутентификацию API, отклоняет новую работу во время завершения (drain) и записывает метаданные жизненного цикла запроса. Он обслуживает @@ -77,9 +76,9 @@ src/ ## Парсер `responses/parser.ts` валидирует входящий запрос через `responses/schema.ts` (Zod), затем строит -`OcxParsedRequest`: +`CodexCommanderParsedRequest`: -- **Сообщения** — элементы `input` становятся нормализованным `OcxMessage[]`: user / developer / +- **Сообщения** — элементы `input` становятся нормализованным `CodexCommanderMessage[]`: user / developer / assistant / toolResult. Элементы `reasoning` становятся блоками thinking; элементы `function_call`, `custom_tool_call` и `tool_search_call` становятся вызовами инструментов; их аналоги `*_output` становятся результатами инструментов. @@ -132,20 +131,20 @@ src/ v2, синхронизацию каталога, диагностику и отладочные логи, использование и квоты, настройки сайдкаров, обновления, сгенерированные клиентские API-ключи, вход/статус/выход OAuth и выбор аккаунта, управление аккаунтами Codex и корректную остановку. `server/auth-cors.ts` требует -`OPENCODEX_API_AUTH_TOKEN` и для `/api/*`, и для `/v1/*`, когда прокси привязан за пределами +`CODEXCOMMANDER_API_AUTH_TOKEN` и для `/api/*`, и для `/v1/*`, когда прокси привязан за пределами loopback; настроенные записи `corsAllowOrigins` расширяют allowlist локальных origin. Реализации OAuth живут в `oauth/`; access-токены загружаются или обновляются непосредственно перед маршрутизируемым вызовом, а `oauth/token-guardian.ts` может проактивно обновлять только тех провайдеров, чья политика это разрешает. Учётные данные пула Codex/ChatGPT и привязка потоков живут в `codex/` и не попадают в ответы management API. Использование по запросам нормализуется в -`OcxUsage`, отражается в терминальных событиях Responses и агрегируется модулем `usage/` для +`CodexCommanderUsage`, отражается в терминальных событиях Responses и агрегируется модулем `usage/` для дашборда и необязательной JSONL-диагностики. ## Транспорт и compaction `server/index.ts` по умолчанию обслуживает HTTP/SSE на `/v1/responses`. Если Codex пытается -выполнить WebSocket-апгрейд Responses, пока `websockets` равно `false`, opencodex возвращает +выполнить WebSocket-апгрейд Responses, пока `websockets` равно `false`, CodexCommander возвращает `426 upgrade_required`; Codex тогда откатывается на HTTP для этой сессии. Когда установлено `"websockets": true`, та же конечная точка принимает апгрейд и использует WebSocket-мост. @@ -160,7 +159,7 @@ Compaction контекста Codex работает для маршрутизи - `codex/model-cache.ts` держит в памяти TTL-кэш живых результатов `/models` для каждого провайдера (по умолчанию 5 минут, как у собственного кэша Codex) с откатом на устаревшие данные при неудачном запросе. -- `codex/catalog/sync.ts`, экспортируемый через фасад `codex/catalog.ts`, сливает маршрутизируемые +- `codex/catalog/sync.ts`, экспортируемый через `codex/catalog.ts`, сливает маршрутизируемые модели в каталог Codex как записи с пространствами имён, ставит рекомендуемые [модели подагентов](/ru/guides/codex-integration/#the-subagent-picker) первыми, @@ -183,8 +182,8 @@ Compaction контекста Codex работает для маршрутизи ## Основные типы -Внутренняя модель живёт в `types.ts`: `OcxParsedRequest`, `OcxContext`, объединение `OcxMessage`, -`OcxContentPart` (text / image), `OcxToolCall`, `OcxTool`, `AdapterEvent` и типы конфигурации -(`OcxConfig`, `OcxProviderConfig`). Широко используются два хелпера: `namespacedToolName()` и +Внутренняя модель живёт в `types.ts`: `CodexCommanderParsedRequest`, `CodexCommanderContext`, объединение `CodexCommanderMessage`, +`CodexCommanderContentPart` (text / image), `CodexCommanderToolCall`, `CodexCommanderTool`, `AdapterEvent` и типы конфигурации +(`CodexCommanderConfig`, `CodexCommanderProviderConfig`). Широко используются два хелпера: `namespacedToolName()` и `modelInList()` (толерантное сопоставление с тегом `:size` для `noVisionModels` / `noReasoningModels`). diff --git a/docs-site/src/content/docs/ru/reference/cli.md b/docs-site/src/content/docs/ru/reference/cli.md index 4e61f3b516..4a87029591 100644 --- a/docs-site/src/content/docs/ru/reference/cli.md +++ b/docs-site/src/content/docs/ru/reference/cli.md @@ -1,21 +1,21 @@ --- title: Справочник CLI -description: Диспетчеризация команд, коды выхода и ссылки на все семейства команд ocx. +description: Диспетчеризация команд, коды выхода и ссылки на все семейства команд ccx. --- -CLI opencodex — это `ocx`. Он диспетчеризует по первому имени команды, при этом документированные +CLI CodexCommander — это `ccx`. Он диспетчеризует по первому имени команды, при этом документированные alias вроде `setup`/`init`, `restore`/`eject` и `models`/`model` приводят к одной и той же операции. Неизвестные команды и некорректные формы вызова считаются ошибками. -Запускайте `ocx help` (или `ocx --help` / `ocx -h`) для верхнеуровневой справки. Для команды, -зарегистрированной в таблице help, используйте `ocx help <command>`, `ocx <command> --help` или -`ocx <command> -h`. Команды help и version — read-only: они не запускают, не останавливают, не -устанавливают, не удаляют и не переписывают состояние Codex или opencodex. +Запускайте `ccx help` (или `ccx --help` / `ccx -h`) для верхнеуровневой справки. Для команды, +зарегистрированной в таблице help, используйте `ccx help <command>`, `ccx <command> --help` или +`ccx <command> -h`. Команды help и version — read-only: они не запускают, не останавливают, не +устанавливают, не удаляют и не переписывают состояние Codex или CodexCommander. ## Семейства команд - [Lifecycle](/reference/cli/lifecycle/) — настройка, жизненный цикл прокси и службы, health, - диагностика, синхронизация каталога, дашборд и обновления. + диагностика, синхронизация каталога и дашборд. - [Providers, accounts, and models](/reference/cli/providers-accounts/) — конфигурация провайдеров, аутентификация, credential pool'ы, квоты, custom model'и, видимость, selected model'и и context cap'ы. @@ -33,29 +33,22 @@ runtime port и проверку identity, а не поддерживая вто Там, где это недвусмысленно, `list` или `status` являются действием по умолчанию. Для структурированных снимков используйте `--json`, а для потокового лога запросов — -`ocx observe logs --follow --jsonl`. Theme, language, navigation и прочее чисто визуальное +`ccx observe logs --follow --jsonl`. Theme, language, navigation и прочее чисто визуальное browser-state CLI не покрывает; настройка Cloudflare Tunnel тоже вне этого набора команд. ## Коды выхода и подтверждение Успешные команды завершаются с кодом 0. Некорректное использование, неизвестные команды или ресурсы, неудачные API-операции и недоступность обязательных служб приводят к ненулевому коду. -Команда `ocx health` специально возвращает 0 только когда прокси здоров, и 1 во всех остальных +Команда `ccx health` специально возвращает 0 только когда прокси здоров, и 1 во всех остальных случаях, поэтому её можно использовать как service probe. Сценарии должны проверять код выхода, а не разбирать человекочитаемый вывод. -Разрушающие операции удаления, импорта, расходования кредитов и обновления, которые документируют +Разрушающие операции удаления, импорта и расходования кредитов, которые документируют подтверждение, в неинтерактивном использовании требуют `--yes`. Этот флаг — явное согласие; отсутствие флага не должно молча подтверждать действие. -## Version и внутренние dispatch-target'ы +## Version -`ocx --version`, `ocx -v` и `ocx version` печатают одну строку с версией, пригодную для +`ccx --version`, `ccx -v` и `ccx version` печатают одну строку с версией, пригодную для сценариев, и завершаются. - -Две точки диспетчеризации намеренно исключены из обычной справки: -`__refresh-version [preview]` обновляет кэш уведомлений об обновлении в отдельном процессе, а -`__gui-update-worker <job-id> [latest|preview] [restart]` исполняет update job дашборда. Это -внутренние детали реализации, а не стабильные пользовательские команды. Дашборд записывает PID -worker'а, умеет восстанавливать активную job, если её worker умер, считает старые активные записи -без PID устаревшими через десять минут и защищает живой worker от конкурентных обновлений. diff --git a/docs-site/src/content/docs/ru/reference/cli/agents.md b/docs-site/src/content/docs/ru/reference/cli/agents.md index 57f2310f84..69c534b5d2 100644 --- a/docs-site/src/content/docs/ru/reference/cli/agents.md +++ b/docs-site/src/content/docs/ru/reference/cli/agents.md @@ -4,11 +4,11 @@ description: Multi-agent, combo, observability, access, integration, system и c --- Эти команды управляют политикой агентов и routing'ом, проверяют живой прокси и подключают -поддерживаемых клиентов к opencodex. +поддерживаемых клиентов к CodexCommander. ## Политика агентов -### `ocx agent <status|injection|effort|subagents|fallback|sidecar> ...` +### `ccx agent <status|injection|effort|subagents|fallback|sidecar> ...` Управляйте headless-ростером multi-agent, effort cap'ами, prompt injection, fallback'ом и настройками sidecar'ов. Для просмотра текущей политики используйте `status`. Как соотносятся @@ -16,10 +16,10 @@ surface mode, delegation, effort и fallback, описано в [Поверхности подагентов](/guides/sub-agent-surface/). ```bash -ocx agent subagents set ark/model-a,openai/gpt-5.5 +ccx agent subagents set ark/model-a,openai/gpt-5.5 ``` -### `ocx v2 <status|on|off|mode <v1|default|v2>|threads <n>>` +### `ccx v2 <status|on|off|mode <v1|default|v2>|threads <n>>` Управляйте feature flag'ом Codex `multi_agent_v2` и трёхсостоянием multi-agent surface mode. @@ -34,14 +34,14 @@ ocx agent subagents set ark/model-a,openai/gpt-5.5 | `threads <n>` | Задать активный v1/v2 thread limit как целое число не меньше 1. | ```bash -ocx v2 status -ocx v2 mode v1 -ocx v2 mode default -ocx v2 on -ocx v2 threads 16 +ccx v2 status +ccx v2 mode v1 +ccx v2 mode default +ccx v2 on +ccx v2 threads 16 ``` -Подкоманда `mode` записывает `multiAgentMode` в конфиг opencodex и заново синхронизирует каталог +Подкоманда `mode` записывает `multiAgentMode` в конфиг CodexCommander и заново синхронизирует каталог Codex. При переходах mode и feature flag текущий числовой thread limit переносится между допустимыми ключами Codex для v1/v2; если переход не удался, исходный `config.toml` восстанавливается. Изменения применяются к новым сессиям Codex, а уже запущенные сохраняют свою @@ -49,115 +49,114 @@ Codex. При переходах mode и feature flag текущий число ## Combo routing -### `ocx combo <list|show|set|remove> ...` · `ocx route combo ...` +### `ccx combo <list|show|set|remove> ...` · `ccx route combo ...` -Управляйте virtual-моделями combo с failover и round-robin. `ocx route combo` — это иерархический +Управляйте virtual-моделями combo с failover и round-robin. `ccx route combo` — это иерархический alias; на данный момент combo — единственный поддерживаемый routing-resource. Цели используют форму `provider/model[:weight],provider/model[:weight]`. ```bash -ocx combo list -ocx route combo set reliable --targets ark/model-a:2,openai/gpt-5.5 +ccx combo list +ccx route combo set reliable --targets ark/model-a:2,openai/gpt-5.5 ``` О поведении маршрутизации и рекомендациях по конфигурации см. [Combos](/guides/combos/). ## Observability и debug -### `ocx observe <logs|usage|storage|memory|debug|claude-inbound|injection> ...` +### `ccx observe <logs|usage|storage|memory|debug|claude-inbound|injection> ...` Проверяйте proxy-request'ы, usage, storage, memory и debug-data. Прямые alias'ы: | Алиас | Эквивалентный ресурс | | --- | --- | -| `ocx logs [filters] [--follow] [--json|--jsonl]` | `ocx observe logs` | -| `ocx usage [--range <7d|30d|all>] [--surface <all|codex|claude|grok>] [--json]` | `ocx observe usage` | -| `ocx storage [--json]` | `ocx observe storage` | -| `ocx memory [--json]` | `ocx observe memory` | +| `ccx logs [filters] [--follow] [--json|--jsonl]` | `ccx observe logs` | +| `ccx usage [--range <7d|30d|all>] [--surface <all|codex|claude|grok>] [--json]` | `ccx observe usage` | +| `ccx storage [--json]` | `ccx observe storage` | +| `ccx memory [--json]` | `ccx observe memory` | ```bash -ocx observe usage --range 30d --json +ccx observe usage --range 30d --json ``` -### `ocx debug <provider|usage|injection|claude> <on|off|status|reset|logs [-f]>` +### `ccx debug <provider|usage|injection|claude> <on|off|status|reset|logs [-f]>` Прочитать или изменить runtime debug-override'ы через management API работающего прокси. ```bash -ocx debug provider on|off|status|reset -ocx debug provider logs [-f|--follow] -ocx debug usage on|off|status|reset -ocx debug usage logs [-f|--follow] +ccx debug provider on|off|status|reset +ccx debug provider logs [-f|--follow] +ccx debug usage on|off|status|reset +ccx debug usage logs [-f|--follow] ``` -Без указания scope `ocx debug` печатает usage и, если прокси остановлен, environment-default'ы -для следующего запуска. Provider debug по умолчанию берётся из `OCX_DEBUG=1` -(legacy `OCX_DEBUG_FRAMES=1` тоже работает); usage debug — из `OPENCODEX_USAGE_DEBUG=1`. +Без указания scope `ccx debug` печатает usage и, если прокси остановлен, environment-default'ы +для следующего запуска. Provider debug по умолчанию берётся из `CCX_DEBUG=1`; +usage debug — из `CODEXCOMMANDER_USAGE_DEBUG=1`. ## Доступ к API -### `ocx access <key|endpoints|models|test> ...` +### `ccx access <key|endpoints|models|test> ...` -Управляйте admission API-key'ами OpenCodex и проверяйте внешние endpoint'ы и модели. -`ocx api-key <list|create|remove> ...` — alias `ocx access key`. +Управляйте admission API-key'ами CodexCommander и проверяйте внешние endpoint'ы и модели. +`ccx api-key <list|create|remove> ...` — alias `ccx access key`. ```bash -ocx access key create deployment +ccx access key create deployment ``` ## Интеграции клиентов -### `ocx integration <claude|grok> ...` +### `ccx integration <claude|grok> ...` Управляйте поддерживаемыми интеграциями Claude и Grok. Прямые семейства команд ниже предоставляют элементы управления, специфичные для каждого клиента. -### `ocx claude [claude args...]` +### `ccx claude [claude args...]` Убедиться, что прокси запущен, а затем запустить Claude Code с `ANTHROPIC_BASE_URL`, -`ANTHROPIC_AUTH_TOKEN`, `CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1` и model slot'ами из -`config.claudeCode`. Маршрутизируемые модели появляются в native-picker'е `/model` через стабильные -slot-alias'ы, начиная с Claude Code 2.1.129. На более старых версиях модель выбирается через +`ANTHROPIC_AUTH_TOKEN`, `CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1` и текущими настройками +аутентификации/helper из `config.claudeCode`. Маршрутизируемые модели появляются в native-picker'е +`/model` через стабильные alias'ы, начиная с Claude Code 2.1.129. На более старых версиях модель выбирается через `ANTHROPIC_MODEL` или `/model <id>`. Пользовательские `ANTHROPIC_*`, экспортированные в окружение, всегда имеют приоритет. Команды для профиля Claude Desktop: ```text -ocx claude desktop [apply] Save and apply the four-family profile -ocx claude desktop show [--json] Show routes, families, and defaults -ocx claude desktop move <route> <family> [--default] -ocx claude desktop default <family> <route|none> -ocx claude desktop export <path|-> Export versioned JSON (`-` = stdout) -ocx claude desktop import <path> [--apply] Validate and import JSON +ccx claude desktop apply Save and apply the four-family profile +ccx claude desktop show [--json] Show routes, families, and defaults +ccx claude desktop move <route> <family> [--default] +ccx claude desktop default <family> <route|none> +ccx claude desktop export <path|-> Export versioned JSON (`-` = stdout) +ccx claude desktop import <path> [--apply] Validate and import JSON ``` Семейства — `opus`, `fable`, `sonnet` и `haiku`; новые маршруты по умолчанию попадают в `opus`. -`none` допустимо только когда соответствующее семейство пусто. Legacy-flags `--static`, -`--hybrid` и `--discovery-only` для apply по-прежнему поддерживаются. Для настроек Claude Code -используйте `ocx claude config <status|set> ...`. +`none` допустимо только когда соответствующее семейство пусто. Для настроек Claude Code +используйте `ccx claude config <status|set> ...`. -### `ocx opencode [opencode args...]` +### `ccx opencode [opencode args...]` Убедиться, что прокси запущен, и затем запустить opencode со сгенерированным блоком -`provider.opencodex` в inline runtime layer OpenCode (`OPENCODE_CONFIG_CONTENT`). Существующая -inline-конфигурация сохраняется, а только `provider.opencodex` заменяется для этого запуска. +`provider.codexcommander` в inline runtime layer OpenCode (`OPENCODE_CONFIG_CONTENT`). Существующая +inline-конфигурация сохраняется, а только `provider.codexcommander` заменяется для этого запуска. Глобальные или проектные `opencode.json` могут читаться, чтобы выдать warning о существующем override, но файлы на диске никогда не меняются. Маршрутизируемые модели появляются как -`opencodex/<provider>/<model>`. Этот лончер не меняет последующие обычные запуски `opencode`; -единственный постоянный путь для `provider.opencodex` — отдельная opt-in интеграция Dashboard. +`codexcommander/<provider>/<model>`. Этот лончер не меняет последующие обычные запуски `opencode`; +единственный постоянный путь для `provider.codexcommander` — отдельная opt-in интеграция Dashboard. -### `ocx grok <status|exclude|include|set|clear|apply> ...` +### `ccx grok <status|exclude|include|set|clear|apply> ...` Управляйте fence'ом моделей для Grok Build и применяйте его. ## Экспорт client config -### `ocx export --client <opencode|pi>` +### `ccx export --client <opencode|pi>` Печатает client config, направленный на работающий прокси. opencode и [Pi](/guides/pi/) читают провайдеров из собственных JSON-конфигов, а не из переменных окружения, поэтому команда -сериализует для вас блок провайдера `opencodex` — base URL, список моделей и env-reference +сериализует для вас блок провайдера `codexcommander` — base URL, список моделей и env-reference конкретного клиента. Прокси должен быть запущен; команда определяет его живой порт, читает `/api/models` и выводит @@ -171,9 +170,9 @@ override, но файлы на диске никогда не меняются. | `--force` | Разрешить `--out` заменить существующий файл. | ```bash -ocx export --client opencode # config plus destination, merge warning, and counts -ocx export --client pi --json > pi-models.json # byte-exact JSON for a pipe or a diff -ocx export --client opencode --out ~/opencodex-opencode.json +ccx export --client opencode # config plus destination, merge warning, and counts +ccx export --client pi --json > pi-models.json # byte-exact JSON for a pipe or a diff +ccx export --client opencode --out ~/codexcommander-opencode.json ``` Без `--json` сначала идёт JSON, затем канонический путь назначения, предупреждение о merge, строка @@ -182,14 +181,14 @@ limit'а (для них клиент применяет собственные d | Клиент | Канонический путь | Имя скачиваемого файла | Переменная окружения | | --- | --- | --- | --- | -| `opencode` | `~/.config/opencode/opencode.json` (`XDG_CONFIG_HOME` имеет приоритет, если задан) | `opencode.json` | `OPENCODEX_OPENCODE_API_KEY` | -| `pi` | `~/.pi/agent/models.json` | `pi-models.json` | `OPENCODEX_API_KEY` | +| `opencode` | `~/.config/opencode/opencode.json` (`XDG_CONFIG_HOME` имеет приоритет, если задан) | `opencode.json` | `CODEXCOMMANDER_OPENCODE_API_KEY` | +| `pi` | `~/.pi/agent/models.json` | `pi-models.json` | `CODEXCOMMANDER_API_KEY` | Имена этих двух env-переменных различаются, и каждый клиент интерполирует только свою. opencode -читает `{env:OPENCODEX_OPENCODE_API_KEY}`; Pi читает `$OPENCODEX_API_KEY`. +читает `{env:CODEXCOMMANDER_OPENCODE_API_KEY}`; Pi читает `$CODEXCOMMANDER_API_KEY`. :::caution[Сливать, а не заменять] -`ocx export` никогда не пишет в ваш реальный клиентский конфиг. Путь назначения лишь +`ccx export` никогда не пишет в ваш реальный клиентский конфиг. Путь назначения лишь печатается, чтобы вы вручную выполнили merge, а `--out` без `--force` отказывается перезаписать существующий файл именно потому, что полная замена уничтожила бы остальные провайдеры, агенты и MCP-записи. @@ -207,15 +206,15 @@ admission key — ссылка просто остаётся неиспольз ## Runtime и configuration -### `ocx system <status|settings|startup|diagnostics|sync|update> ...` +### `ccx system <status|settings|startup|diagnostics|sync> ...` -Управляйте headless runtime-setting'ами, startup, sync, diagnostics и update. +Управляйте headless runtime-setting'ами, startup, sync и diagnostics. ```bash -ocx system settings --stream-mode eager-relay +ccx system settings --stream-mode eager-relay ``` -### `ocx config <show|get|set|unset|validate|export|import> ...` +### `ccx config <show|get|set|unset|validate|export|import> ...` -Проверяйте и безопасно меняйте валидированную конфигурацию OpenCodex. `show` и `get` +Проверяйте и безопасно меняйте валидированную конфигурацию CodexCommander. `show` и `get` маскируют секреты. Импорт выполняет валидацию перед записью и требует `--yes`. diff --git a/docs-site/src/content/docs/ru/reference/cli/lifecycle.md b/docs-site/src/content/docs/ru/reference/cli/lifecycle.md index 62dc3d5556..930756831d 100644 --- a/docs-site/src/content/docs/ru/reference/cli/lifecycle.md +++ b/docs-site/src/content/docs/ru/reference/cli/lifecycle.md @@ -1,55 +1,55 @@ --- title: Жизненный цикл CLI -description: Настройка, запуск, остановка, служба, диагностика, sync и update-команды. +description: Настройка, запуск, остановка, служба, диагностика и sync-команды. --- -Эти команды устанавливают, запускают, проверяют, ремонтируют и обновляют локальный прокси -opencodex и его интеграцию с Codex. +Эти команды устанавливают, запускают, проверяют и ремонтируют локальный прокси +CodexCommander и его интеграцию с Codex. ## Настройка -### `ocx init` · `ocx setup` +### `ccx init` · `ccx setup` Интерактивный мастер настройки (`setup` — alias команды `init`). Он спрашивает провайдера (preset или custom), API-key (буквально или `${ENV}`), модель по умолчанию и порт прокси, -сохраняет `~/.opencodex/config.json`; при желании внедряет прокси в +сохраняет `~/.codexcommander/config.json`; при желании внедряет прокси в `$CODEX_HOME/config.toml` (по умолчанию `~/.codex/config.toml`) и при необходимости устанавливает shim автозапуска Codex. ## Жизненный цикл прокси -### `ocx start [--port <port>]` +### `ccx start [--port <port>]` -Запустить proxy server (предпочтительный порт `10100`). Если этот порт занят, opencodex выбирает и +Запустить proxy server (предпочтительный порт `10100`). Если этот порт занят, CodexCommander выбирает и записывает другой свободный порт. При запуске пишется состояние PID/runtime-port, а попытка поднять второй живой экземпляр отвергается. На старте прокси синхронизирует модели каждого провайдера в каталог Codex. При shutdown он восстанавливает native Codex — если только прокси не -был запущен как managed service (`OCX_SERVICE=1`). +был запущен как managed service (`CCX_SERVICE=1`). ```bash -ocx start -ocx start --port 8080 +ccx start +ccx start --port 8080 ``` -### `ocx stop` +### `ccx stop` Остановить работающий прокси (по PID), удалить PID-file и восстановить native Codex. Если -установлена managed background service, `ocx stop` сначала останавливает и её, чтобы она не +установлена managed background service, `ccx stop` сначала останавливает и её, чтобы она не перезапустила прокси обратно. То же действие доступно из кнопки **Stop** в веб-дашборде (`POST /api/stop`). -### `ocx restart` +### `ccx restart` Выполнить `stop`, затем `ensure`: остановить прокси/службу, восстановить native Codex, поднять прокси в фоне и синхронизировать живой порт обратно в Codex. -### `ocx ensure` +### `ccx ensure` Идемпотентно убедиться, что фоновый прокси запущен, а затем синхронизировать его живой каталог моделей. Если `codexAutoStart` равен `false`, команда сообщает, что автозапуск отключён, и ничего не делает. -### `ocx restore [back]` · `ocx eject [back]` +### `ccx restore [back]` · `ccx eject [back]` Восстановить native Codex **без** остановки прокси — удалить внедрённые строки конфигурации и маршрутизируемые записи каталога, чтобы обычный `codex` снова работал нативно. `eject` — alias @@ -59,26 +59,20 @@ ocx start --port 8080 прокси, не меняя жизненный цикл самого прокси: ```bash -ocx restore back -ocx eject back +ccx restore back +ccx eject back ``` -### `ocx recover-history --legacy-openai` - -Явное восстановление для старых development-сборок, которые переназначали историю Codex App ещё -до появления обратимого backup-механизма. Если база истории Codex заблокирована, сначала -закройте Codex. - -### `ocx uninstall` · `ocx remove` +### `ccx uninstall` · `ccx remove` Остановить службу и прокси, удалить службу и Codex shim, восстановить native Codex, а затем -удалить локальную конфигурацию opencodex только если все шаги восстановления завершились успешно. +удалить локальную конфигурацию CodexCommander только если все шаги восстановления завершились успешно. `remove` — alias команды `uninstall`. Очистка конфигурации требует ownership metadata, созданных -при свежей установке; legacy- или shared-directory остаются на месте. +канонической метадатой владения; каталоги без владельца или shared-directory остаются на месте. ## Status и health -### `ocx status [--json]` +### `ccx status [--json]` Печатает read-only диагностическую сводку: PID прокси, достижимость `/healthz`, URL дашборда, путь к конфигу, провайдера по умолчанию, настройку автозапуска Codex, состояние службы, состояние @@ -94,8 +88,8 @@ redacted-строкой на каждый нездоровый аккаунт ( контракт `--json` этот health-блок пока не входит. ```bash -ocx status -ocx status --json +ccx status +ccx status --json ``` Сокращённая форма JSON: @@ -116,8 +110,8 @@ ocx status --json "url": "http://localhost:10100/" }, "paths": { - "config": "/Users/example/.opencodex/config.json", - "pid": "/Users/example/.opencodex/ocx.pid", + "config": "/Users/example/.codexcommander/config.json", + "pid": "/Users/example/.codexcommander/codexcommander.pid", "runtime": "/path/to/bun" }, "runtime": { @@ -133,7 +127,7 @@ ocx status --json "codexAutostart": true, "defaultProvider": "openai", "service": { - "summary": "not installed (logs: /Users/example/.opencodex/service.log)" + "summary": "not installed (logs: /Users/example/.codexcommander/service.log)" }, "codexShim": { "summary": "Codex autostart shim: not installed" @@ -147,68 +141,68 @@ ocx status --json включает API-key'и, OAuth-token'ы, заголовки авторизации, содержимое запросов, email и идентификаторы аккаунтов. -### `ocx health [--json]` +### `ccx health [--json]` Identity-check живого прокси. Текстовый вывод сообщает PID/порт; `--json` отдаёт `{ok, pid, port}`. Команда завершается кодом 0 только когда прокси здоров, и 1 во всех остальных случаях, поэтому подходит для service probe. -### `ocx ready [--json] [--wait [--timeout <seconds>]]` +### `ccx ready [--json] [--wait [--timeout <seconds>]]` Проверяет готовность после синхронизации через не требующий аутентификации `GET /readyz`. При готовности возвращается `200`; для `pending` и терминального `failed` возвращается `503` с `Retry-After: 1`. Санитизированные поля HTTP-ответа: `{service, version, uptime, pid, port, status}`. -Старые прокси без `/readyz` fail-closed как `unreachable`; `/healthz` — отдельная проверка liveness, -а не готовности. По умолчанию команда выполняет одну пробу. `--wait` опрашивает до готовности или +`/healthz` — отдельная проверка liveness, а не готовности. По умолчанию команда выполняет одну пробу. +`--wait` опрашивает до готовности или тайм-аута, но при терминальном `failed` завершается немедленно. Тайм-аут по умолчанию — 45 секунд; `--timeout <seconds>` требует `--wait` и принимает целые положительные значения 1–300 секунд. CLI JSON выдаёт `{ready, status, pid, port}`, где `status` — `ready`, `pending`, `failed` или `unreachable`. Коды завершения: 0 — готово; 1 — не готово, pending, failed, тайм-аут или недоступность; 64 — недопустимые аргументы. -### `ocx doctor` +### `ccx doctor` Запускает read-only диагностику среды и связности: пути состояний и тип файловой системы, двойные установки WSL, proxy environment/config, достижимость ChatGPT, предупреждения о plugin'е -и project-config Codex, а также ожидающую миграцию истории. Раздел, касающийся app-home Codex, -тоже обнаруживает узкий mismatch runtime-home Windows Orca и при необходимости объясняет миграцию -службы. Пути в этом выводе маскируют имя пользователя ОС. Doctor печатает подсказки по ремонту, -но ничего не меняет. +и project-config Codex. Раздел, касающийся app-home Codex, тоже обнаруживает узкий mismatch +runtime-home Windows Orca и при необходимости показывает ручные шаги удаления, настройки окружения +и повторной установки. Пути в этом выводе маскируют имя пользователя ОС. Doctor печатает подсказки +по ремонту, но ничего не меняет. Раздел **OAuth reliability** показывает, можно ли записывать credential storage, удаётся ли -создавать refresh single-flight/lock file'ы в `OPENCODEX_HOME`, есть ли нездоровые OAuth- или +создавать refresh single-flight/lock file'ы в `CODEXCOMMANDER_HOME`, есть ли нездоровые OAuth- или Codex-pool-аккаунты (с masked-id) с подсказкой `Action:`, а также статическое OK-подтверждение, что путь Codex forward не подделывает metadata официального клиента. Doctor никогда не мутирует credential'ы и не выполняет repair. ## Синхронизация каталога -### `ocx sync [--restart-codex]` +### `ccx sync [--restart-codex]` Получить живой список моделей от каждого настроенного провайдера и заново внедрить объединённый каталог в Codex. Запускайте после добавления провайдера или когда нужно обновить доступные модели. -Если всё ещё работают долгоживущие процессы Codex `app-server`, `ocx sync` предупредит, что они +Если всё ещё работают долгоживущие процессы Codex `app-server`, `ccx sync` предупредит, что они могут продолжать отдавать старый in-memory список моделей, хотя файлы -`opencodex-catalog.json` / `models_cache.json` уже обновлены. Передайте `--restart-codex`, чтобы +`codexcommander-catalog.json` / `models_cache.json` уже обновлены. Передайте `--restart-codex`, чтобы послать `SIGTERM` только подходящим процессам `codex … app-server` и `codex-code-mode-host`, принадлежащим текущему пользователю (активные turn'ы при этом могут оборваться). Широкий `pkill -f codex` намеренно не используется. -### `ocx sync-cache [--restart-codex]` +### `ccx sync-cache [--restart-codex]` Инвалидировать локальный кэш model picker'а Codex, чтобы он пересобрался из активного каталога -opencodex. Предупреждение о stale-`app-server` и optional `--restart-codex` работают так же, как -и у `ocx sync`. +CodexCommander. Предупреждение о stale-`app-server` и optional `--restart-codex` работают так же, как +и у `ccx sync`. ## Фоновая служба -### `ocx service [install|repair|start|stop|status|uninstall|remove]` +### `ccx service [install|repair|start|stop|status|uninstall|remove]` -Запустить opencodex как login-managed background service (macOS **launchd**, Linux **systemd user +Запустить CodexCommander как login-managed background service (macOS **launchd**, Linux **systemd user unit**, Windows **Task Scheduler**), которая автоматически стартует при логине и сама -перезапускается при crash. Запуски службы выставляют `OCX_SERVICE=1`, чтобы restart не дёргал +перезапускается при crash. Запуски службы выставляют `CCX_SERVICE=1`, чтобы restart не дёргал конфиг Codex. | Подкоманда | Действие | @@ -223,37 +217,37 @@ unit**, Windows **Task Scheduler**), которая автоматически | `remove` | Alias команды `uninstall`. | ```bash -ocx service -ocx service install -ocx service repair -ocx service status -ocx service uninstall +ccx service +ccx service install +ccx service repair +ccx service status +ccx service uninstall ``` -На Windows `ocx service status` отдельно показывает регистрацию в Task Scheduler и -identity-проверенную достижимость прокси OpenCodex. Он не печатает локализованную таблицу +На Windows `ccx service status` отдельно показывает регистрацию в Task Scheduler и +identity-проверенную достижимость прокси CodexCommander. Он не печатает локализованную таблицу `schtasks`, чтобы сводка оставалась читаемой на любых code page Windows. На Windows создание записи в Task Scheduler требует elevation. Когда распознан локализованный текст access-denied, остаётся прежний путь guidance. Если текст неразборчив, fallback использует -владение command-shape `/create /tn opencodex-proxy /xml <non-empty-path> /f`, status 1 и +владение command-shape `/create /tn codexcommander-proxy /xml <non-empty-path> /f`, status 1 и подтверждённый non-elevated token; после этого действие Startup Safety в дашборде может само запросить UAC. Если fallback не смог определить состояние token'а, он оставляет исходную scheduler-error. Чужие задачи и чужие операции никогда не получают automatic-elevation marker. -Либо подтвердите UAC через дашборд, либо заново выполните `ocx service install` в elevated +Либо подтвердите UAC через дашборд, либо заново выполните `ccx service install` в elevated окне PowerShell. -### `ocx codex-shim <install|status|uninstall|remove>` +### `ccx codex-shim <install|status|uninstall|remove>` Обернуть script-based launcher `codex` на `PATH` лёгким автозапусковым скриптом. Настоящие target'ы `codex.exe` не трогаются, чтобы не ломать точные вызовы исполняемого файла. Если завершённое внешнее обновление Codex перезаписало установленный shim, следующая обычная -команда `ocx` сохранит новый стабильный launcher и восстановит shim перед выполнением запроса. +команда `ccx` сохранит новый стабильный launcher и восстановит shim перед выполнением запроса. Launcher, который всё ещё меняется, не трогается, а попытка откладывается до следующего раза. Сбои repair'а приводят только к warning и не ломают запрошенную команду; ручной запасной путь — -`ocx codex-shim install`. Чтобы отключить автоматику, задайте `codexShimAutoRestore: false` или -установите `OPENCODEX_CODEX_SHIM_AUTO_RESTORE=0`. +`ccx codex-shim install`. Чтобы отключить автоматику, задайте `codexShimAutoRestore: false` или +установите `CODEXCOMMANDER_CODEX_SHIM_AUTO_RESTORE=0`. | Подкоманда | Действие | | --- | --- | @@ -263,18 +257,18 @@ Launcher, который всё ещё меняется, не трогается | `status` | Показать состояние shim'а (installed, stale или missing). | ```bash -ocx codex-shim install -ocx codex-shim status -ocx codex-shim uninstall +ccx codex-shim install +ccx codex-shim status +ccx codex-shim uninstall ``` :::tip[Service vs Shim] -Используйте `ocx service` для всегда работающего фонового прокси (рекомендуется). Используйте -`ocx codex-shim` для лёгкого on-demand запуска без демона — в этом случае прокси стартует только +Используйте `ccx service` для всегда работающего фонового прокси (рекомендуется). Используйте +`ccx codex-shim` для лёгкого on-demand запуска без демона — в этом случае прокси стартует только когда запускается `codex`. ::: -### `ocx tray <install|start|stop|status|uninstall|remove> [--json] [--no-start]` +### `ccx tray <install|start|stop|status|uninstall|remove> [--json] [--no-start]` Установить и управлять Windows tray icon со статусом. Иконка стартует при логине в Windows и даёт one-click управление прокси. `start` и `stop` управляют только иконкой; самим прокси нужно @@ -283,27 +277,7 @@ one-click управление прокси. `start` и `stop` управляю ## Дашборд -### `ocx gui` +### `ccx gui` Открыть [веб-дашборд](/guides/web-dashboard/) по адресу `http://localhost:<port>`, автоматически запустив прокси, если он ещё не работает. - -## Обновление - -### `ocx update [--tag latest|preview]` - -Самообновить opencodex из npm. Стабильные установки используют `@latest`; preview-установки -остаются на `@preview`, если только вы не передадите `--tag latest|preview`. Команда распознаёт -source checkout и предлагает вместо этого `git pull && bun install`, а если у вас уже новейшая -версия для выбранного тега, становится no-op. Перед заменой файлов работающий прокси -останавливается; установленная служба автоматически пересобирается и запускается заново, а для -foreground-установки печатается подсказка `ocx start`. - -```bash -ocx update -ocx update --tag preview -``` - -Новые версии становятся доступны, когда -[Release workflow](https://github.com/lidge-jun/opencodex/actions/workflows/release.yml) -публикует их в npm. diff --git a/docs-site/src/content/docs/ru/reference/cli/providers-accounts.md b/docs-site/src/content/docs/ru/reference/cli/providers-accounts.md index ad4c756311..9001b260fb 100644 --- a/docs-site/src/content/docs/ru/reference/cli/providers-accounts.md +++ b/docs-site/src/content/docs/ru/reference/cli/providers-accounts.md @@ -8,7 +8,7 @@ pool'ами и контролируют каталог моделей, кото ## Провайдеры -### `ocx provider <subcommand>` +### `ccx provider <subcommand>` Неинтерактивное управление провайдерами. Записи из registry задаются по имени; для custom-имени нужно одновременно передать и `--adapter`, и `--base-url`. @@ -28,13 +28,13 @@ pool'ами и контролируют каталог моделей, кото | `account-mode` | `pool`, `direct`, `--json` | Выбрать pooled или direct routing для аккаунтов Codex. | ```bash -ocx provider list --json -ocx provider test ark -ocx provider add anthropic --api-key sk-ant-... --set-default --sync -ocx provider add local-dev --adapter openai-chat --base-url http://localhost:11434/v1 -ocx provider show anthropic --json -ocx models --provider anthropic --json -ocx models live --provider ark --json +ccx provider list --json +ccx provider test ark +ccx provider add anthropic --api-key sk-ant-... --set-default --sync +ccx provider add local-dev --adapter openai-chat --base-url http://localhost:11434/v1 +ccx provider show anthropic --json +ccx models --provider anthropic --json +ccx models live --provider ark --json ``` :::caution[Пользовательские заголовки — не канал для учётных данных] @@ -58,40 +58,40 @@ ocx models live --provider ark --json ## Аутентификация -### `ocx login <provider>` +### `ccx login <provider>` Запустить зарегистрированный login-flow провайдера. В зависимости от провайдера OAuth-вход открывает браузер либо импортирует/подключает активную сессию нативного CLI. Учётные данные в -`~/.opencodex/`, принадлежащие OpenCodex, обновляются автоматически; поколения доступа связанного +`~/.codexcommander/`, принадлежащие CodexCommander, обновляются автоматически; поколения доступа связанного Grok/Kimi CLI принимаются только для чтения, а обновление остаётся обязанностью нативного CLI. API-key login-провайдеры открывают свою key-dashboard, запрашивают ключ, по возможности валидируют его и сохраняют результат в конфиг провайдера. Если имя отсутствует или неизвестно, команда печатает список принимаемых id OAuth- и API-key-провайдеров. -Ту же команду используйте и для **reauthentication**, когда `ocx status` / `ocx doctor` +Ту же команду используйте и для **reauthentication**, когда `ccx status` / `ccx doctor` сообщают, что нужна переавторизация или refresh завершился терминальной ошибкой (либо используйте -Reauthenticate в дашборде). Аккаунты пула Codex не являются публичным провайдером для `ocx login` +Reauthenticate в дашборде). Аккаунты пула Codex не являются публичным провайдером для `ccx login` — переавторизовать их нужно либо через пул аккаунтов Codex в дашборде, либо через headless-flow -`ocx account reauth`. +`ccx account reauth`. ```bash -ocx login xai -ocx login anthropic +ccx login xai +ccx login anthropic ``` -### `ocx logout <provider>` +### `ccx logout <provider>` Удалить сохранённый OAuth credential провайдера. ## Аккаунты и key pool'ы -### `ocx account <subcommand>` +### `ccx account <subcommand>` Показывать и переключать provider-account'ы и API-key pool'ы через работающий прокси. Поставляемая help-surface выглядит так: ```text -Usage: ocx account <list|current|use|refresh|auto-switch|priority|login|reauth|code|cancel|remove|add-key|reset-credits> ... +Usage: ccx account <list|current|use|refresh|auto-switch|priority|login|reauth|code|cancel|remove|add-key|reset-credits> ... list [provider] Codex account pool, OAuth accounts and API keys (identifiers shown masked as the API returns them). current <provider> Show the active account or key. @@ -134,7 +134,7 @@ label и masked key. } ``` -### `ocx account list [provider] [--json] [--all]` +### `ccx account list [provider] [--json] [--all]` Без провайдера команда показывает пул Codex, OAuth-аккаунты и настроенные API-key pool'ы. Пустые провайдеры пропускаются, если не задан `--all`. С провайдером выводится только это @@ -148,7 +148,7 @@ label и masked key. { accounts: AccountRow[], notes: string[] } ``` -### `ocx account current <provider> [--json]` +### `ccx account current <provider> [--json]` Показывает активный аккаунт или ключ. Если в пуле Codex нет ручного pin'а, команда сообщает об автоматическом выборе с учётом порядка: выбирается самый высокий подходящий уровень, а внутри него при quota-маршрутизации аккаунт с наименьшим usage; если в другом семействе нет активного @@ -159,10 +159,10 @@ credential'а, это состояние тоже печатается, но к { provider, type, activeId: string | null, autoSwitchThreshold?: number, account: AccountRow | null } ``` -### `ocx account use <provider> <account-or-key-id|main> [--json]` +### `ccx account use <provider> <account-or-key-id|main> [--json]` Выбирает существующий аккаунт Codex, OAuth-аккаунт или API-ключ. Для `openai` значение `main` -выбирает вход Codex App. Выбор Codex Pool очищает process-local affinity и применяется к следующему запросу, включая запрос существующей видимой задачи; после перезапуска прокси или affinity eviction задача также может стать непривязанной, а выполняющиеся запросы сохраняют захваченный аккаунт. Это управляет только Pool routing; Direct mode продолжает использовать caller-owned/native main credential. Проактивное переключение по использованию, повторная аутентификация 401/403, cooldown 429/retry-after, исключение и восстановление после отказа 429/402 до вывода могут позже выбрать другой подходящий Pool-аккаунт. Эти пути восстановления остаются активными, когда переключение по использованию выключено. После смены аккаунта OpenCodex воспроизводит контекст разговора, но prompt cache провайдера может потребовать прогрева. Неизвестные провайдеры +выбирает вход Codex App. Выбор Codex Pool очищает process-local affinity и применяется к следующему запросу, включая запрос существующей видимой задачи; после перезапуска прокси или affinity eviction задача также может стать непривязанной, а выполняющиеся запросы сохраняют захваченный аккаунт. Это управляет только Pool routing; Direct mode продолжает использовать caller-owned/native main credential. Проактивное переключение по использованию, повторная аутентификация 401/403, cooldown 429/retry-after, исключение и восстановление после отказа 429/402 до вывода могут позже выбрать другой подходящий Pool-аккаунт. Эти пути восстановления остаются активными, когда переключение по использованию выключено. После смены аккаунта CodexCommander воспроизводит контекст разговора, но prompt cache провайдера может потребовать прогрева. Неизвестные провайдеры или id завершаются с кодом 1. `--json` возвращает: При **401/403** локальная для процесса привязка к аккаунту сбрасывается и требуется повторная аутентификация. При **429** учитывается `Retry-After`, для аккаунта запускается cooldown, привязка сбрасывается, @@ -173,9 +173,9 @@ credential'а, это состояние тоже печатается, но к { ok: true, provider, type, activeId } ``` -### `ocx account refresh <provider> [--json]` +### `ccx account refresh <provider> [--json]` -Для пула Codex используйте `ocx account refresh openai [--json]`. Команда принудительно +Для пула Codex используйте `ccx account refresh openai [--json]`. Команда принудительно обновляет account quota и печатает проценты недельной/месячной квоты и reset-time; отсутствующие данные о quota сообщаются как unknown, а не как 0%. JSON-envelope имеет форму `{ accounts: AccountRow[] }`, причём на каждой строке Codex присутствует `quota`. @@ -188,7 +188,7 @@ credential'а, это состояние тоже печатается, но к таймауту, результат деградирует до `null` или stale report, но остаётся успехом (код 0), как и у quota-bar'ов дашборда. -### `ocx account auto-switch <provider> <on|off|status|threshold <0-100>> [--json]` +### `ccx account auto-switch <provider> <on|off|status|threshold <0-100>> [--json]` Управляет только пулом аккаунтов Codex `openai`. `on` ставит 80%, `off` — 0%, `status` читает текущее значение, а `threshold <n>` принимает целое число от 0 до 100. Для других провайдеров и @@ -198,12 +198,12 @@ quota-bar'ов дашборда. { provider, autoSwitchThreshold: number, enabled: boolean } ``` -### `ocx account priority <provider> <account-id|main> [<-100..100|first|earlier|normal|later|last|reset>] [--json]` +### `ccx account priority <provider> <account-id|main> [<-100..100|first|earlier|normal|later|last|reset>] [--json]` Читает или задаёт порядок выбора одного аккаунта пула Codex: **больше — используется раньше**, значение по умолчанию `0`, диапазон от `-100` до `100`. Порядок есть только у пула Codex `openai`, поэтому другие провайдеры завершаются с кодом 1. `main` указывает на логин Codex Desktop, который -упорядочивается наравне с остальными: `ocx account priority openai main last` оставляет его резервным. +упорядочивается наравне с остальными: `ccx account priority openai main last` оставляет его резервным. Слова-пресеты заменяют небольшие целые числа: `first` — это `+2`, `earlier` — `+1`, `normal` — `0`, `later` — `-1`, `last` — `-2`. `reset` возвращает значение по умолчанию и удаляет сохранённую запись. @@ -223,12 +223,12 @@ quota-bar'ов дашборда. ``` -### `ocx account login|reauth|code|cancel ...` +### `ccx account login|reauth|code|cancel ...` Запускать browser-based или manual-code account-authentication из headless-shell. Для -provider-specific формы команды используйте `ocx account --help`. +provider-specific формы команды используйте `ccx account --help`. -### `ocx account remove <provider> <id|main> --yes [--json]` +### `ccx account remove <provider> <id|main> --yes [--json]` Это защищённое неинтерактивное удаление требует `--yes`. Перед удалением оно проверяет, что id существует; если id отсутствует, команда завершается кодом 1 и DELETE даже не отправляется. @@ -243,7 +243,7 @@ provider-specific формы команды используйте `ocx account { error: string } // stderr, exit 1 ``` -### `ocx account add-key <provider> [--label <label>] [--json]` +### `ccx account add-key <provider> [--label <label>] [--json]` Добавить и активировать ключ для API-key-провайдера. Ключ читается только из piped/redirected stdin, который не является TTY; интерактивный TTY-ввод, пустой ввод, OAuth/Codex-провайдеры и @@ -251,29 +251,29 @@ stdin, который не является TTY; интерактивный TTY- label. Предпочитайте secret manager или here-string: ```bash -ocx account add-key openrouter --label personal <<< "$OPENROUTER_API_KEY" -security find-generic-password -w openrouter | ocx account add-key openrouter --json +ccx account add-key openrouter --label personal <<< "$OPENROUTER_API_KEY" +security find-generic-password -w openrouter | ccx account add-key openrouter --json ``` `--json` возвращает `{ ok: true, id: string | null, label?: string }` и никогда не включает сам ключ. -### `ocx account reset-credits <id|main> [--consume --yes]` +### `ccx account reset-credits <id|main> [--consume --yes]` Проверить reset-credit'ы Codex для аккаунта. Расходование кредита разрушительно и требует сразу оба флага: и `--consume`, и `--yes`. -### `ocx account main <subcommand>` +### `ccx account main <subcommand>` -Управлять именованными профилями нативного основного логина Codex, не изменяя маршрутизацию пула аккаунтов OpenCodex. +Управлять именованными профилями нативного основного логина Codex, не изменяя маршрутизацию пула аккаунтов CodexCommander. ```text -ocx account main doctor [--json] -ocx account main list [--json] -ocx account main register <label> [--json] -ocx account main add <label> -ocx account main switch <profile-id-or-label> --yes [--json] -ocx account main recover [--rollback --yes] [--json] +ccx account main doctor [--json] +ccx account main list [--json] +ccx account main register <label> [--json] +ccx account main add <label> +ccx account main switch <profile-id-or-label> --yes [--json] +ccx account main recover [--rollback --yes] [--json] ``` Каждая изменяющая команда показывает канонический эффективный `CODEX_HOME`, возвращенный @@ -282,19 +282,17 @@ ocx account main recover [--rollback --yes] [--json] Версия 1 поддерживает файловую аутентификацию Codex, шифрует сохранённые профили с помощью AES-256-GCM и хранит ключ шифрования в хранилище учётных данных операционной системы. `add` запускает официальный вход Codex в промежуточной среде перед импортом полученных учётных данных. Перед переключением профиля закройте Codex. Успешное переключение сохраняет локальные задачи и историю, после чего Codex необходимо перезапустить. Используйте `doctor` для проверки состояния профилей, а `recover` для завершения или отката прерванного перехода. `switch` принимает ID профиля или его label. -Матрица восстановления v1 охватывает завершение процесса OpenCodex после публикации файла транзакции переименованием. Она не заявляет устойчивость при сбое ОС или ядра либо внезапном отключении питания: `atomicWriteFileAsync()` не вызывает `fsync` ни для файла, ни для родительского каталога. +Матрица восстановления v1 охватывает завершение процесса CodexCommander после публикации файла транзакции переименованием. Она не заявляет устойчивость при сбое ОС или ядра либо внезапном отключении питания: `atomicWriteFileAsync()` не вызывает `fsync` ни для файла, ни для родительского каталога. -Зашифрованное хранилище (vault), журнал переключения, маркер восстановления и файл карантина журнала находятся в каноническом каталоге `<real CODEX_HOME>/.opencodex-native-main-profiles`. Поэтому все экземпляры OpenCodex, использующие один и тот же Codex home, видят одного владельца и одно состояние восстановления. Промежуточные данные входа в незашифрованном виде остаются изолированными в каталоге `<OPENCODEX_HOME>/native-main-profile-staging` каждого экземпляра. +Зашифрованное хранилище (vault), журнал переключения, маркер восстановления и файл карантина журнала находятся в каноническом каталоге `<real CODEX_HOME>/.codexcommander-native-main-profiles`. Поэтому все экземпляры CodexCommander, использующие один и тот же Codex home, видят одного владельца и одно состояние восстановления. Промежуточные данные входа в незашифрованном виде остаются изолированными в каталоге `<CODEXCOMMANDER_HOME>/native-main-profile-staging` каждого экземпляра. -До допуска трафика native-main или восстановления по журналу владелец на весь срок жизни получает исключительное право на учётные данные и удаляет только остаточные после сбоя файлы, имена которых точно соответствуют `auth.json.ocx.<pid>.<sequence>.tmp`. Каждый файл-кандидат должен оставаться обычным файлом ровно с одной жёсткой ссылкой внутри неизменившегося канонического `CODEX_HOME`; его усекают, сбрасывают его буферы, а затем удаляют ссылку на него (unlink). Подмена ссылкой или точкой повторной обработки (reparse point), изменение идентификационных данных файла или любая другая неоднозначность сохраняют запрет на трафик native-main; файлы с лишь похожими именами никогда не удаляются автоматически. Эта защита рассчитана на сбои добросовестно взаимодействующих экземпляров OpenCodex, а не на вредоносный процесс, уже запущенный от имени того же пользователя ОС. Этот пользователь и файловая система, содержащая `CODEX_HOME`, остаются доверенными, а усечение файла не гарантирует физического стирания данных из хранилища с копированием при записи, снимков или остаточных данных SSD. - -Предварительные сборки использовали `<OPENCODEX_HOME>/native-main-profiles`. Эта схема никогда не импортируется без явного действия. Если `doctor` сообщает о состоянии профилей старого формата, остановите все прокси OpenCodex, использующие тот же `CODEX_HOME`. Затем создайте резервную копию и вместе переместите соответствующие `*.vault.json`, `*.journal.json`, маркер восстановления и любой указанный файл карантина журнала в канонический каталог, сохранив права доступа только для владельца. Либо удалите старый набор файлов предварительной версии и снова выполните `ocx account main register`. Пока работает хотя бы один прокси, использующий тот же `CODEX_HOME`, не выбирайте один из нескольких старых корневых каталогов и не используйте обе схемы одновременно. В Windows состояние предварительной версии, привязанное к прежнему идентификатору домашнего каталога без учёта регистра, необходимо сбросить, а не перемещать, поскольку его зашифрованные AAD и идентификатор в системном хранилище ключей намеренно не используются повторно. +До допуска трафика native-main или восстановления по журналу владелец на весь срок жизни получает исключительное право на учётные данные и удаляет только остаточные после сбоя файлы, имена которых точно соответствуют `auth.json.ccx.<pid>.<sequence>.tmp`. Каждый файл-кандидат должен оставаться обычным файлом ровно с одной жёсткой ссылкой внутри неизменившегося канонического `CODEX_HOME`; его усекают, сбрасывают его буферы, а затем удаляют ссылку на него (unlink). Подмена ссылкой или точкой повторной обработки (reparse point), изменение идентификационных данных файла или любая другая неоднозначность сохраняют запрет на трафик native-main; файлы с лишь похожими именами никогда не удаляются автоматически. Эта защита рассчитана на сбои добросовестно взаимодействующих экземпляров CodexCommander, а не на вредоносный процесс, уже запущенный от имени того же пользователя ОС. Этот пользователь и файловая система, содержащая `CODEX_HOME`, остаются доверенными, а усечение файла не гарантирует физического стирания данных из хранилища с копированием при записи, снимков или остаточных данных SSD. ## Модели -### `ocx models [subcommand]` · `ocx model <subcommand>` +### `ccx models [subcommand]` · `ccx model <subcommand>` -`ocx model` — alias команды `ocx models`. Без подкоманды команда показывает модели, статически +`ccx model` — alias команды `ccx models`. Без подкоманды команда показывает модели, статически засеянные в настроенных провайдерах. `--provider` фильтрует один провайдер, а `--json` возвращает метаданные моделей. `live` читает работающий каталог; `add`, `edit`, `remove` и `list-custom` управляют ручными записями каталога; `enable`, `disable` и `provider` управляют видимостью; @@ -304,7 +302,7 @@ ocx account main recover [--rollback --yes] [--json] Любая per-model операция, которую умеет дашборд, доступна и здесь, так что headless-установке не нужен GUI для управления каталогом. `add`, `remove` и `list-custom` работают напрямую с файлом конфига и применяются к работающему прокси через sync каталога; остальные обращаются к live -management API и требуют, чтобы прокси уже работал (`ocx start` или установленная служба). +management API и требуют, чтобы прокси уже работал (`ccx start` или установленная служба). | Подкоманда | Поддерживаемые флаги | Действие | | --- | --- | --- | @@ -319,18 +317,18 @@ management API и требуют, чтобы прокси уже работал | `provider <name> <on\|off>` | `--json` | Включить или выключить сразу все модели одного провайдера одним действием. | | `selected <provider>` | `--set <id,id...>`, `--clear`, `--json` | Прочитать или заменить allowlist моделей провайдера. `--clear` удаляет allowlist, и тогда доступны все модели. | | `context <status\|value <tokens>\|provider <name> <on\|off>\|all <on\|off>>` | `--json` | Прочитать или задать context-window cap глобально либо по провайдерам. | -| `shadow <status\|set> [model\|-]` | `--enabled <on\|off>`, `--json` | Прочитать или задать модель-замену для background helper-call'ов Codex. `-` очищает модель. `status` также показывает `sourceModels` — helper-slug'и, которые перехватывает proxy (по умолчанию `gpt-5.6-luna`; `gpt-5.4-mini` для клиентов до 0.144.x включительно можно восстановить явным переопределением `sourceModels`). | +| `shadow <status\|set> [model\|-]` | `--enabled <on\|off>`, `--json` | Прочитать или задать модель-замену для background helper-call'ов Codex. `-` очищает модель. `status` также показывает `sourceModels` — helper-slug'и, которые перехватывает proxy (по умолчанию `gpt-5.6-luna`; явное переопределение предназначено только для текущих пользовательских helper-id). | ```bash -ocx models live --json # what Codex can actually see right now -ocx models disable anthropic/claude-haiku-4 # hide one routed model -ocx models enable gpt-5.6-sol # no slash, so it is treated as native -ocx models provider zenmux off # hide a noisy provider wholesale -ocx models selected anthropic --set claude-opus-5,claude-fable-5 -ocx models selected anthropic --clear # drop the allowlist again -ocx models add deepseek deepseek-v4 --display-name 'DeepSeek V4' --context-window 128000 --modalities text,image -ocx models list-custom --json # read the custom-id for edit/remove -ocx models remove deepseek/deepseek-v4 --yes +ccx models live --json # what Codex can actually see right now +ccx models disable anthropic/claude-haiku-4 # hide one routed model +ccx models enable gpt-5.6-sol # no slash, so it is treated as native +ccx models provider zenmux off # hide a noisy provider wholesale +ccx models selected anthropic --set claude-opus-5,claude-fable-5 +ccx models selected anthropic --clear # drop the allowlist again +ccx models add deepseek deepseek-v4 --display-name 'DeepSeek V4' --context-window 128000 --modalities text,image +ccx models list-custom --json # read the custom-id for edit/remove +ccx models remove deepseek/deepseek-v4 --yes ``` Селектор модели со слэшем трактуется как routed (`anthropic/claude-opus-5`); bare-id считается diff --git a/docs-site/src/content/docs/ru/reference/configuration.md b/docs-site/src/content/docs/ru/reference/configuration.md index 25f0894ede..7e43616529 100644 --- a/docs-site/src/content/docs/ru/reference/configuration.md +++ b/docs-site/src/content/docs/ru/reference/configuration.md @@ -1,11 +1,11 @@ --- title: Справочник конфигурации -description: Где opencodex хранит конфигурацию, как применяются правки и где искать ссылки на все домены настроек. +description: Где CodexCommander хранит конфигурацию, как применяются правки и где искать ссылки на все домены настроек. --- -opencodex хранит постоянную конфигурацию в `$OPENCODEX_HOME/config.json`, обычно в -`~/.opencodex/config.json`. На Windows путь по умолчанию — -`%USERPROFILE%\.opencodex\config.json`. +CodexCommander хранит постоянную конфигурацию в `$CODEXCOMMANDER_HOME/config.json`, обычно в +`~/.codexcommander/config.json`. На Windows путь по умолчанию — +`%USERPROFILE%\.codexcommander\config.json`. ## Способы редактировать конфигурацию @@ -13,8 +13,8 @@ opencodex хранит постоянную конфигурацию в `$OPENCO - **Dashboard:** используйте web UI для пошаговой настройки провайдеров, моделей, агентов, доступа и хранилища. -- **CLI:** `ocx init` создаёт исходный файл, а команды вроде `ocx provider`, `ocx models`, - `ocx combo`, `ocx agent` и `ocx config` обновляют или показывают принадлежащие им настройки. +- **CLI:** `ccx init` создаёт исходный файл, а команды вроде `ccx provider`, `ccx models`, + `ccx combo`, `ccx agent` и `ccx config` обновляют или показывают принадлежащие им настройки. - **File:** редактируйте `config.json` напрямую для полей, у которых нет отдельной UI- или CLI-команды. Файл должен оставаться корректным JSON. @@ -25,7 +25,7 @@ Dashboard, management API и mutating-команды CLI записывают в `claudeCode` и listener binding там, где для этих путей есть явная защита конфликтов, но эта защита покрывает не все поддеревья. -Если файл не удаётся распарсить, opencodex сохраняет его резервную копию как +Если файл не удаётся распарсить, CodexCommander сохраняет его резервную копию как `config.json.invalid-<timestamp>`, пишет предупреждение в консоль и стартует с настройками по умолчанию. Если файла нет, используется тот же свежий дефолт: один forward-провайдер `openai`. @@ -33,7 +33,7 @@ Dashboard, management API и mutating-команды CLI записывают в Корректные значения из `config.json` перекрывают встроенные дефолты. Для отсутствующих необязательных полей применяются значения по умолчанию, описанные на страницах соответствующих -доменов. `OPENCODEX_HOME` имеет приоритет над каталогом конфигурации по умолчанию. Поля, которые +доменов. `CODEXCOMMANDER_HOME` имеет приоритет над каталогом конфигурации по умолчанию. Поля, которые принимают ссылку на окружение, например `apiKey: "${PROVIDER_API_KEY}"`, разрешают эту переменную в момент запроса. Для outbound-proxying уже заданные `HTTP_PROXY` или `HTTPS_PROXY` имеют приоритет над верхнеуровневым полем `proxy`. @@ -61,8 +61,8 @@ Dashboard, management API и mutating-команды CLI записывают в возможно, используйте публичные alias для селекторов. :::note[Atomic writes] -opencodex записывает управляемые файлы `config.toml` и `opencodex-catalog.json` через временный +CodexCommander записывает управляемые файлы `config.toml` и `codexcommander-catalog.json` через временный файл с последующим rename (`atomicWriteFile`). Это предотвращает частично записанные файлы, когда одновременно срабатывают несколько writer'ов, -например `ocx stop` и shutdown handler самого прокси, оба восстанавливающие Codex. +например `ccx stop` и shutdown handler самого прокси, оба восстанавливающие Codex. ::: diff --git a/docs-site/src/content/docs/ru/reference/configuration/agents.md b/docs-site/src/content/docs/ru/reference/configuration/agents.md index ad7462e07c..0a22390292 100644 --- a/docs-site/src/content/docs/ru/reference/configuration/agents.md +++ b/docs-site/src/content/docs/ru/reference/configuration/agents.md @@ -3,7 +3,7 @@ title: Конфигурация агентов description: Multi-agent surface, guidance при делегировании, preferred model'и, fallback chain'ы, sync native default'ов и effort cap'ы. --- -Настройки агентов управляют тем, какая collaboration surface Codex рекламируется и как opencodex +Настройки агентов управляют тем, какая collaboration surface Codex рекламируется и как CodexCommander подсказывает, маршрутизирует и ограничивает делегированную работу. ## Поля агентов @@ -12,20 +12,20 @@ description: Multi-agent surface, guidance при делегировании, pr | --- | --- | --- | --- | | `multiAgentMode?` | `"v1" \| "default" \| "v2"` | `"default"` | `v1` штампует все модели как v1; `v2` штампует все модели как v2. `default` восстанавливает upstream pin'ы (Sol/Terra — v2, Luna — v1) и для остальных следует native flag `multi_agent_v2`. Применяется к новым сессиям. | | `multiAgentV2MessageDelivery?` | `"encrypted" \| "plaintext"` | `"encrypted"` | Политика доставки сообщений V2-родителя. `encrypted` сохраняет зарезервированный шифрованный контракт ChatGPT. Экспериментальный `plaintext` включает совместимость между провайдерами для последующих V2-запросов родителя и делает все его сообщения делегирования открытыми; вызовы сообщений маршрутизируемого родителя также получают plaintext-маркер Codex. После изменения начните новую сессию. | -| `subagentModels?` | `string[]` | `gpt-5.5`, `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna`, `gpt-5.4-mini` | До пяти bare native-id, account-qualified id `<selector>/<native-openai-model>` или routed-id `provider/model`, которые первыми рекламируются в picker'е подагентов. Дашборд сохраняет настроенные exact selector'ы, включая account-qualified варианты, и показывает, какие сохранённые записи реально рекламируются или исключены. Для вариантов, отсутствующих в текущем каталоге, используйте `ocx agent subagents set` или отредактируйте конфигурацию. Явный пустой список сохраняется. | +| `subagentModels?` | `string[]` | `gpt-5.5`, `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna`, `gpt-5.4-mini` | До пяти bare native-id, account-qualified id `<selector>/<native-openai-model>` или routed-id `provider/model`, которые первыми рекламируются в picker'е подагентов. Дашборд сохраняет настроенные exact selector'ы, включая account-qualified варианты, и показывает, какие сохранённые записи реально рекламируются или исключены. Для вариантов, отсутствующих в текущем каталоге, используйте `ccx agent subagents set` или отредактируйте конфигурацию. Явный пустой список сохраняется. | | `injectionModel?` | `string` | — | Предпочитаемая native- или routed-модель подагента, которую proxy использует в собственном guidance v2. | | `injectionEffort?` | `string` | — | Предпочитаемый effort (`low`–`ultra`), имеющий смысл только вместе с `injectionModel`. | | `injectionPrompt?` | `string` | — | Заменяет встроенное тело guidance для v2. Поддерживает `{{model}}`, `{{effort}}`, `{{roster}}` и `{{fallback}}`. Настроенного `injectionModel` достаточно, чтобы отобразить пользовательский prompt. | -| `multiAgentGuidanceEnabled?` | `boolean` | `true` | Управляет только developer-guidance, написанным самим opencodex, для v1/v2; не меняет native default'ы агентов, tools, routing, roster'ы и effort cap'ы. | +| `multiAgentGuidanceEnabled` | `boolean` | `true` | Управляет только developer-guidance, написанным самим CodexCommander, для v1/v2; не меняет native default'ы агентов, tools, routing, roster'ы и effort cap'ы. | | `syncCodexSubagentDefaults?` | `boolean` | `false` | Разрешает записывать `injectionModel` и, при наличии, `injectionEffort` как native default'ы Codex при sync/restart. Требует `injectionModel`. | | `subagentModelFallback?` | `string[]` | `[]` | Глобальные fallback-модели для порождённых child-turn'ов в порядке приоритета. | | `subagentModelFallbackPollMs?` | `number` | `60000` | Интервал кэша для availability probe. Значения ниже 1000 ms возвращаются к дефолту. | | `effortCap?` | `string` | — | Жёсткий потолок effort для qualifying v2 main-turn'ов и помеченных spawned-child turn'ов. Принимает `low`–`ultra`. | | `subagentEffortCap?` | `string` | — | Дополнительный потолок только для spawned-child turn'ов. Если применимы оба cap'а, выигрывает более низкий. | -Управляйте surface через дашборд или `ocx v2 status|on|off|mode <v1|default|v2>|threads <n>`. +Управляйте surface через дашборд или `ccx v2 status|on|off|mode <v1|default|v2>|threads <n>`. Смена режима применяется к новым сессиям. `maxConcurrentThreadsPerSession` — это поле -`PUT /api/v2`, а не ключ `config.json`; `ocx v2 threads <n>` записывает +`PUT /api/v2`, а не ключ `config.json`; `ccx v2 threads <n>` записывает `max_concurrent_threads_per_session` в `[features.multi_agent_v2]` файла `$CODEX_HOME/config.toml` после включения v2. @@ -73,7 +73,7 @@ user-owned target field'ы считаются конфликтом и сохра 2. role-level `model_fallback` из `$CODEX_HOME/agents/*.toml`; затем 3. глобальные записи `subagentModelFallback`. -opencodex пропускает кандидатов, которые отключены, не маршрутизируются, unhealthy, находятся в +CodexCommander пропускает кандидатов, которые отключены, не маршрутизируются, unhealthy, находятся в cooldown либо уже достигли порога quota. Availability-снимок кэшируется на `subagentModelFallbackPollMs`. Шифрованные child-task'и могут ограничить цепочку каноническими native ChatGPT-target'ами; если ни одна из них не может прочитать encrypted payload, запрос @@ -103,7 +103,7 @@ surface v2, а child-turn — когда он помечен точными mark Cap'ы умеют только понижать effort. Они опускают значение до самой высокой объявленной ступени, которая не выше cap'а. Если у модели нет управления effort или ни одна поддерживаемая ступень не -помещается под cap, opencodex убирает поле effort и позволяет провайдеру применить собственный +помещается под cap, CodexCommander убирает поле effort и позволяет провайдеру применить собственный дефолт. `max` и `ultra` принимаются, хотя дашборд предлагает только `low`–`xhigh`. Если нужен объясняющий вариант для начинающих о поведении v1, default и v2, см. diff --git a/docs-site/src/content/docs/ru/reference/configuration/providers.md b/docs-site/src/content/docs/ru/reference/configuration/providers.md index a0aeac4c1d..f6d119807e 100644 --- a/docs-site/src/content/docs/ru/reference/configuration/providers.md +++ b/docs-site/src/content/docs/ru/reference/configuration/providers.md @@ -3,15 +3,14 @@ title: Конфигурация провайдеров description: Записи провайдеров, аутентификация, endpoint'ы, каталоги моделей, quota, context cap'ы и provider-specific options. --- -Провайдер сообщает opencodex, где живёт модель, на каком wire-adapter'е она работает и как +Провайдер сообщает CodexCommander, где живёт модель, на каком wire-adapter'е она работает и как аутентифицируются запросы. ## Верхнеуровневые поля, связанные с провайдерами | Поле | Тип | По умолчанию | Значение | | --- | --- | --- | --- | -| `providers` | `Record<string, OcxProviderConfig>` | — | Map вида provider name → provider config. | -| `openaiProviderTierVersion?` | `2` | set by migration | Отмечает, что единая projection OpenAI с учётом режима уже завершена. | +| `providers` | `Record<string, CodexCommanderProviderConfig>` | — | Map вида provider name → provider config. | | `disabledModels?` | `string[]` | — | Модели, скрытые из каталога Codex и `/v1/models`, но не заблокированные для прямых вызовов прокси. Routed-id удаляются из списков. Account-qualified native-id скрывает только строку этого селектора; bare native GPT-id скрывает bare-строку и строки всех селекторов аккаунтов для этой модели. Страница Models показывает только bare native- и routed-строки; чтобы скрыть одну selector-qualified строку, задайте это поле конфигурации напрямую. | | `providerContextCaps?` | `Record<string, number>` | `{}` | Context cap'ы, видимые Codex, по каждому провайдеру. Cap может только понижать известное context window. | | `contextCapValue?` | `number` | `350000` | Значение, используемое элементами управления context-cap в дашборде; его изменение обновляет все включённые записи `providerContextCaps`. | @@ -19,16 +18,16 @@ description: Записи провайдеров, аутентификация, | `pausedCodexAccountIds?` | `string[]` | `[]` | Аккаунты, исключённые из выбора Pool до снятия паузы, включая основной аккаунт `__main__`, если он поставлен на паузу. | | `codexAccountNamespaces?` | `Record<string, string>` | — | Необязательное сопоставление произвольного публичного селектора модели с сохранённым аккаунтом Codex. Каждый селектор с существующей целью добавляет в model picker Codex отдельные строки `<selector>/<native-openai-model>`; каждая строка использует только этот аккаунт. Если активен хотя бы один селектор, bare native-строки скрываются в picker, но их id остаются маршрутизируемыми и перечисляются raw `/v1/models`, если они не отключены явно. | | `activeCodexAccountId?` | `string` | — | Вручную выбранный аккаунт Pool для следующего запроса. Выбор очищает thread affinity; in-flight-запросы сохраняют уже захваченные credential'ы. | -| `codexAccountPriorities?` | `Record<string,number>` | — | Порядок выбора для каждого аккаунта пула Codex: id аккаунта → целое число от `-100` до `100`, **больше — используется раньше**, отсутствие означает `0`. Это граница порядка, а не пригодности: выбор сужает уже подходящие аккаунты до самого высокого уровня, у которого ещё есть запас квоты, а внутри этого уровня аккаунт выбирает `accountPoolStrategy`. Уровень пропускается, только когда все его аккаунты превысили `autoSwitchThreshold`, находятся в cooldown, под soft-avoid, на паузе или требуют повторной аутентификации; неизвестный usage никогда не исчерпывает уровень. Порядок не делает выбираемым непригодный аккаунт и не перепривязывает поток, у которого аккаунт уже есть. Основной аккаунт `__main__` участвует на равных — именно так логин Codex Desktop можно оставить на самый конец. Без записей поведение остаётся прежним. Некорректная map игнорируется с предупреждением в консоли (порядок отключается, восстановление config не запускается). Управляется через `ocx account priority` и страницу Codex Auth. | +| `codexAccountPriorities?` | `Record<string,number>` | — | Порядок выбора для каждого аккаунта пула Codex: id аккаунта → целое число от `-100` до `100`, **больше — используется раньше**, отсутствие означает `0`. Это граница порядка, а не пригодности: выбор сужает уже подходящие аккаунты до самого высокого уровня, у которого ещё есть запас квоты, а внутри этого уровня аккаунт выбирает `accountPoolStrategy`. Уровень пропускается, только когда все его аккаунты превысили `autoSwitchThreshold`, находятся в cooldown, под soft-avoid, на паузе или требуют повторной аутентификации; неизвестный usage никогда не исчерпывает уровень. Порядок не делает выбираемым непригодный аккаунт и не перепривязывает поток, у которого аккаунт уже есть. Основной аккаунт `__main__` участвует на равных — именно так логин Codex Desktop можно оставить на самый конец. Без записей приоритет всех аккаунтов равен `0`. Некорректная map игнорируется с предупреждением в консоли (порядок отключается, восстановление config не запускается). Управляется через `ccx account priority` и страницу Codex Auth. | | `autoSwitchThreshold?` | `number` | `80` | Порог проактивного переключения по использованию. `quota` может повторно оценить следующий запрос как привязанной, так и непривязанной задачи; `fill-first` использует его только как точку исчерпания для непривязанных назначений; обычный `round-robin` его не использует. Оценка берёт самое горячее из окон 5 часов, недели и 30 дней. `0` отключает только переключение по использованию, но не назначение непривязанных задач и не восстановление после сбоев. | | `accountPoolStrategy?` | `"quota" \| "round-robin" \| "fill-first"` | `"quota"` | Стратегия назначения для новых/непривязанных запросов Codex. Запрос непривязан, если у него нет live affinity `(parent thread id, quota scope)`; видимая существующая задача может стать непривязанной после перезапуска прокси или сброса affinity. `quota` выбирает подходящий аккаунт с наименьшим известным usage, когда активного аккаунта нет, сохраняет подходящий активный аккаунт ниже `autoSwitchThreshold`, а после порога может перевести непривязанный запрос или следующий запрос привязанной задачи на подходящий аккаунт с меньшим usage. `round-robin` равномерно распределяет непривязанные запросы; `fill-first` назначает их активному аккаунту до cooldown, недоступности или порога исчерпания. | | `accountPoolStickyLimit?` | `number` | `1` | Число назначений новых/непривязанных задач на одном выборе round-robin перед переходом дальше. Счётчик растёт при привязке задачи, а не после успеха upstream. Диапазон 1–100; только при `accountPoolStrategy` = `round-robin`. | | `upstreamFailoverThreshold?` | `number` | `3` | Сколько подряд transient failure допустить, прежде чем новые сессии начнут делать failover. `0` отключает эту логику. Доказанные ошибки доступности DNS/TCP до соединения учитываются на уровне пары «провайдер, хост» и не влияют на здоровье аккаунта, кулдауны, привязку потока/сессии, выбор активного аккаунта или маршрутизацию пула, а также не учитываются в этом пороге. | | `modelCacheTtlMs?` | `number` | `300000` | Окно свежести для кэша `/models` на уровне провайдера. | | `cacheRetention?` | `"none" \| "short" \| "long"` | `"short"` | Политика prompt-cache Anthropic: отключено, 5-минутный ephemeral или 1-часовой extended. | -| `tokenGuardian?` | `OcxTokenGuardianConfig` | off | Необязательная политика proactive OAuth refresh и warmup'а аккаунтов Codex. | +| `tokenGuardian?` | `CodexCommanderTokenGuardianConfig` | off | Необязательная политика proactive OAuth refresh и warmup'а аккаунтов Codex. | -Имена селекторов — выбранные пользователем публичные метки; opencodex не придаёт им семантики ролей +Имена селекторов — выбранные пользователем публичные метки; CodexCommander не придаёт им семантики ролей аккаунтов. Ключи `codexAccountNamespaces` имеют длину 1–64 символа. Они должны начинаться и заканчиваться ASCII-буквой или цифрой; внутри разрешены буквы, цифры, `.`, `_` и `-`. Зарезервированные имена объектов JavaScript запрещены. Значение — допустимый id аккаунта пула (кроме внутреннего `__main__`) @@ -48,20 +47,15 @@ cross-route credential fallback не существует. Строки API GPT- 1,050,000 / max input 922,000, а виртуальные Pro-id переписываются в базовую wire-модель с `reasoning.mode: "pro"`. -`openaiProviderTierVersion: 2` отмечает текущую single-provider projection. Перед миграцией -поставляемой v1-конфигурации opencodex создаёт `config.json.pre-openai-tiers-v2.bak`, не -перезаписывая отличающуюся backup-копию, и переписывает известные legacy namespaced-id, -выбранные в `selectedModels`, в bare-id. - -## Записи провайдеров (`OcxProviderConfig`) +## Записи провайдеров (`CodexCommanderProviderConfig`) | Поле | Тип | Значение | | --- | --- | --- | -| `adapter` | `string` | Один из `openai-chat`, `openai-responses`, `anthropic`, `google`, `kiro`, `cursor`, `azure-openai` (или alias `azure`). | +| `adapter` | `string` | Один из `openai-chat`, `openai-responses`, `anthropic`, `google`, `kiro`, `cursor`, `azure-openai`. | | `baseUrl` | `string` | Базовый URL API upstream'а. Большинство built-in fixed-endpoint'ов игнорируют несовпадение; collision-safe key-preset'ы сохраняют старый custom destination с тем же именем. | | `responsesPath?` | `string` | Relative resource path для key-auth запросов `openai-responses`. Должен начинаться с `/` и не может содержать scheme, query или fragment. | | `supportsServiceTier?` | `boolean` | Три состояния поддержки `service_tier`. `true`: fast mode может подставлять поле, значения вызывающего сохраняются. `false`: поле удаляется и никогда не подставляется (апстрим, для которого задокументировано отсутствие поддержки, не должен его получать). Не задано: провайдер не классифицирован — значения вызывающего сохраняются без изменений, fast mode не подставляет. Registry классифицирует canonical OpenAI (`true`), DeepSeek и Volcengine Ark (`false`); задавайте явно только для custom gateway'ев, реально поддерживающих tier'ы. | -| `preserveResponsesReasoningContent?` | `boolean` | Сохранять plaintext reasoning content в replay'нутых Responses reasoning item'ах вместо очистки (очистка — правило ChatGPT backend'а). Включайте для upstream'ов, чей контракт принимает reasoning replay, например DeepSeek. Proxy-minted `ocxr1` envelope'ы удаляются всегда. | +| `preserveResponsesReasoningContent?` | `boolean` | Сохранять plaintext reasoning content в replay'нутых Responses reasoning item'ах вместо очистки (очистка — правило ChatGPT backend'а). Включайте для upstream'ов, чей контракт принимает reasoning replay, например DeepSeek. Proxy-minted `ccxr1` envelope'ы удаляются всегда. | | `disabled?` | `boolean` | Сохранить провайдера на диске, но исключить его из routing'а и из model/catalog-listing'ов. | | `apiKey?` | `string` | API-key либо ссылка `${ENV_VAR}` / `$ENV_VAR`, разрешаемая при каждом запросе. | | `apiKeyTransport?` | `"x-api-key" \| "bearer"` | Header-style для ключа Anthropic. По умолчанию нативный `x-api-key`; допустим только для key-auth-провайдеров `anthropic`. | @@ -113,24 +107,23 @@ cross-route credential fallback не существует. Строки API GPT- | `location?` | `string` | Локация Vertex; fallback через окружение — `GOOGLE_CLOUD_LOCATION`. | | `mcpServers?` | `Record<string, CursorMcpServerConfig>` | Только Cursor: MCP-серверы в режимах stdio или Streamable HTTP. | | `desktopExecutor?` | `DesktopExecutorConfig` | Только Cursor: команды внешнего computer-use и record-screen. | -| `unsafeAllowNativeLocalExec?` | `boolean` | Legacy boolean Cursor, эквивалентен `nativeLocalExec: "on"` только если новое поле не задано. | -| `nativeLocalExec?` | `"off" \| "codex-sandbox" \| "on"` | Политика local-exec для Cursor. `off` — дефолт; `codex-sandbox` сейчас ведёт себя fail-closed как `off`. | +| `nativeLocalExec?` | `"off" \| "on"` | Политика local-exec для Cursor. `off` — значение по умолчанию. | Провайдеры с API-key могут хранить literal key или environment-reference. OAuth-провайдеры -используют credential store, заполняемый через `ocx login`; поведение subscription-backed launcher'а +используют credential store, заполняемый через `ccx login`; поведение subscription-backed launcher'а Claude Code настраивается через [`claudeCode.authMode`](/reference/configuration/server/#claude-code). ## Безопасность исходящих диагностических запросов Тест подключения из дашборда и live discovery моделей используют ограниченный transport только для -GET-запросов. Если outbound-proxy не настроен, opencodex один раз разрешает hostname и затем +GET-запросов. Если outbound-proxy не настроен, CodexCommander один раз разрешает hostname и затем подключается только к этому проверенному адресу. Для HTTPS сохраняются исходные Host, SNI и проверка сертификата; отключить проверку сертификата конфигурация провайдера не может. Если активны `HTTP_PROXY`, `HTTPS_PROXY` или `ALL_PROXY`, эти операции оставляют встроенный fetch Bun. Проверки URL и literal-address всё равно выполняются, но итоговый маршрут, DNS-ответ и peer -всё же выбирает прокси, поэтому opencodex не может зафиксировать или проверить этого peer'а. Это +всё же выбирает прокси, поэтому CodexCommander не может зафиксировать или проверить этого peer'а. Это осознанное ограничение безопасности. Private/local destination требуют `allowPrivateNetwork: true` и, если активен outbound-proxy, @@ -193,7 +186,7 @@ backoff и может переключить аккаунт уже внутри :::caution[Experimental] Оставляйте эту функцию выключенной, если не понимаете policy-risk аккаунтов Anthropic. Если сомневаетесь, безопаснее переключать аккаунты вручную через -`ocx account use anthropic <id>`. +`ccx account use anthropic <id>`. ::: ### Формы управляемых записей @@ -202,7 +195,7 @@ backoff и может переключить аккаунт уже внутри Элементы `codexAccounts[]` требуют `id`, `email` и `isMain`, а также могут нести `plan`, `chatgptAccountId` и privacy-safe `logLabel`. Обычно этими записями управляет дашборд. -### `tokenGuardian` (`OcxTokenGuardianConfig`) +### `tokenGuardian` (`CodexCommanderTokenGuardianConfig`) | Поле | Тип | По умолчанию | Значение | | --- | --- | --- | --- | @@ -234,7 +227,7 @@ registry-endpoint имеет приоритет над настроенным `b API-регионом импортированного credential'а и использует канонический `runtime.{region}.kiro.dev`. См. [Adapters](/reference/adapters/). -Когда routing выбрасывает `baseUrl`, opencodex пишет в лог registry-endpoint и лишь origin из +Когда routing выбрасывает `baseUrl`, CodexCommander пишет в лог registry-endpoint и лишь origin из конфига; сам настроенный путь может содержать credential. Уберите неиспользуемый URL или выберите provider-entry, соответствующий нужному региону. `alibaba-token-plan` закреплён за Beijing, а `alibaba-token-plan-intl` обслуживает международные endpoint'ы. @@ -263,7 +256,7 @@ Beijing, а `alibaba-token-plan-intl` обслуживает междунаро ## Провайдер Cursor (`adapter: "cursor"`) -Bridge Cursor экспериментальный. После `ocx login cursor` добавьте или отредактируйте +Bridge Cursor экспериментальный. После `ccx login cursor` добавьте или отредактируйте `providers.cursor`. Optimization ladder Cursor Router раскрывается как отдельные id для Codex, потому что picker не умеет показывать специфичные для Cursor model-parameter'ы: @@ -283,9 +276,6 @@ Server-driven local tool'ы Cursor по умолчанию выключены. C - `"off"` (по умолчанию) отвергает нативное выполнение `read`, `write`, `delete`, `ls`, `grep`, `shell` и `fetch` со стороны Cursor. - `"on"` включает trusted local execution и обходит approval/sandbox semantics Codex. -- `"codex-sandbox"` сохранён ради совместимости, но закрывается с ошибкой так же, как `"off"`; на - prose запроса нельзя полагаться как на достоверную sandbox-attestation. - ```json { "providers": { @@ -301,10 +291,8 @@ Server-driven local tool'ы Cursor по умолчанию выключены. C ``` Задавайте это поле именно в `providers.cursor`, а не на верхнем уровне. В дашборде откройте -**Providers → Cursor → Edit JSON**, сохраните и затем перезапустите. Legacy-поле -`unsafeAllowNativeLocalExec: true` эквивалентно `nativeLocalExec: "on"` только если поле -`nativeLocalExec` не задано. MCP, screen recording и computer use управляются отдельно через -`mcpServers` и `desktopExecutor`. +**Providers → Cursor → Edit JSON**, сохраните и затем перезапустите. MCP, screen recording и computer +use управляются отдельно через `mcpServers` и `desktopExecutor`. Каждый `mcpServers.<name>` принимает либо `command` (stdio), либо `url` (Streamable HTTP). Для stdio также допустимы `args`, `env` и `cwd`; для HTTP — `headers`. Оба типа поддерживают @@ -354,7 +342,7 @@ OpenRouter может обслуживать одну и ту же модель ``` Ключи моделей здесь должны быть exact native OpenRouter id, без внешнего префикса провайдера -opencodex. При выборе `openrouter/anthropic-claude-sonnet-5` система сначала восстанавливает +CodexCommander. При выборе `openrouter/anthropic-claude-sonnet-5` система сначала восстанавливает native-id `anthropic/claude-sonnet-5`, а уже затем применяет model rule. ## Статические allowlist'ы моделей diff --git a/docs-site/src/content/docs/ru/reference/configuration/routing.md b/docs-site/src/content/docs/ru/reference/configuration/routing.md index 429610c00d..ed4efd97c8 100644 --- a/docs-site/src/content/docs/ru/reference/configuration/routing.md +++ b/docs-site/src/content/docs/ru/reference/configuration/routing.md @@ -11,11 +11,11 @@ upstream. | Поле | Тип | По умолчанию | Значение | | --- | --- | --- | --- | | `defaultProvider` | `string` | `"openai"` | Последний провайдер, используемый, если ни одно более раннее правило модели не совпало. Должен называть включённого настроенного провайдера. | -| `combos?` | `Record<string, OcxComboConfig>` | `{}` | Виртуальные модели `combo/<id>`, построенные из упорядоченных целей provider/model. | +| `combos?` | `Record<string, CodexCommanderComboConfig>` | `{}` | Виртуальные модели `combo/<id>`, построенные из упорядоченных целей provider/model. | ## Порядок разрешения модели -opencodex разрешает запрошенную модель в следующем порядке: +CodexCommander разрешает запрошенную модель в следующем порядке: 1. Настроенное пространство имён `<account-selector>/<native-openai-model>`, направляемое только через сопоставленный сохранённый аккаунт Codex. Некорректная или недоступная exact target завершается fail closed. @@ -86,7 +86,7 @@ opencodex разрешает запрошенную модель в следую ### Допустимость в каталоге -Combo остаётся доступной для прямой маршрутизации, даже если её нельзя вывести в списке. `ocx sync`, +Combo остаётся доступной для прямой маршрутизации, даже если её нельзя вывести в списке. `ccx sync`, `/v1/models` и селектор Codex показывают её, только когда у каждой цели есть возможности, которые можно пересечь: @@ -104,7 +104,7 @@ Combo остаётся доступной для прямой маршрутиз Явно запрошенный `policy/<id>` (или настроенный псевдоним) выбирает среди фиксированного разрешённого списка кандидатов по жёстким требованиям к возможностям и детерминированной объяснимой оценке. Существующие идентификаторы моделей никогда не проходят через профиль неявно. Поддерживаются: `candidates` (явный список), необязательный `alias`, `require` (`minContextWindow`, `minQuotaHeadroom`, `tools`, `imageInput`, `structuredOutput`, `localOnly`, `remoteAllowed`, `encryptedCodexTasks`, `reasoningEffort`, `serviceTier`), `optimize` (веса latency/health/cost/quota), `limits.maxEstimatedCostUsd`, `unknownEvidence` (allow/penalize/exclude). Неизвестное не становится нулём или бесплатным. -CLI: `ocx route policy list`, `ocx route policy show <id>`, `ocx route policy dry-run <id> --model-context <tokens> --tools`, `ocx route policy evaluate <id>`. +CLI: `ccx route policy list`, `ccx route policy show <id>`, `ccx route policy dry-run <id> --model-context <tokens> --tools`, `ccx route policy evaluate <id>`. Комбо — это явная маршрутизация с порядком/весами и отказоустойчивостью. Профиль — это выбор на основе доказательств среди кандидатов. @@ -117,8 +117,8 @@ CLI: `ocx route policy list`, `ocx route policy show <id>`, `ocx route policy dr Возвращаемые записи истории и решений маршрута содержат только маскированные метаданные запроса (например, непрозрачные метки `apiKeyId`). Учётные данные, сырые тела промптов и секреты провайдеров не включаются. -CLI: `ocx logs explain <request-id>`, `ocx logs rebuild-index`, `ocx logs index-status`. +CLI: `ccx logs explain <request-id>`, `ccx logs rebuild-index`, `ccx logs index-status`. -## Миграция +## Существующие данные -`routingProfiles` — необязательная аддитивная настройка. Существующие конфиги и старые строки `usage.jsonl` загружаются без изменений. Индекс одноразовый: при удалении он автоматически перестраивается из `usage.jsonl` при следующем запросе. Автонастройки нет. +`routingProfiles` — необязательная аддитивная настройка. Существующие конфиги и строки `usage.jsonl` без `routeDecision` также загружаются. Индекс одноразовый: при удалении он автоматически перестраивается из `usage.jsonl` при следующем запросе. Автонастройки нет. diff --git a/docs-site/src/content/docs/ru/reference/configuration/server.md b/docs-site/src/content/docs/ru/reference/configuration/server.md index 4fd226855b..3e4922d4bd 100644 --- a/docs-site/src/content/docs/ru/reference/configuration/server.md +++ b/docs-site/src/content/docs/ru/reference/configuration/server.md @@ -11,27 +11,22 @@ description: Listener, удалённый доступ, admission key, тайм | Поле | Тип | По умолчанию | Значение | | --- | --- | --- | --- | | `port` | `number` | `10100` | Порт, который слушает прокси. | -| `hostname?` | `string` | `"127.0.0.1"` | Адрес bind'а. Не-loopback bind требует `OPENCODEX_API_AUTH_TOKEN`. | +| `hostname?` | `string` | `"127.0.0.1"` | Адрес bind'а. Не-loopback bind требует `CODEXCOMMANDER_API_AUTH_TOKEN`. | | `proxy?` | `string` | — | URL исходящего HTTP(S)-прокси или `${ENV_VAR}`. Применяется к `HTTP_PROXY` / `HTTPS_PROXY` только когда эти переменные не заданы; loopback всегда остаётся в `NO_PROXY`. | | `stallTimeoutSec?` | `number` | `300` | Секунды без upstream-данных до `response.incomplete`. Минимум 1. | | `connectTimeoutMs?` | `number` | `200000` | Дедлайн одной попытки DNS/TCP/TLS/final-header; он завершается до генерации тела ответа. | | `shutdownTimeoutMs?` | `number` | `5000` | Дедлайн graceful-drain до принудительного прерывания активных turn'ов. | | `websockets?` | `boolean` | `false` | Объявлять `supports_websockets` для WebSocket-пути Responses. Значение false удерживает HTTP/SSE. | | `corsAllowOrigins?` | `string[]` | `[]` | Дополнительные точные origin, разрешённые CORS. Loopback-origin разрешены всегда. Поддерживаются authority-based origin браузерных расширений, например `chrome-extension://<extension-id>`; `*` не является маской. Firefox и Safari пересоздают UUID расширения (при каждой установке/запуске браузера), поэтому обновляйте запись при смене origin. | -| `apiKeys?` | `OcxApiKey[]` | `[]` | Сгенерированные credentials `ocx_…`, принимаемые для management и data-plane auth на не-loopback bind'ах. Управляются через дашборд. | +| `apiKeys?` | `CodexCommanderApiKey[]` | `[]` | Сгенерированные credentials `ccx_data_…`, принимаемые data-plane auth на не-loopback bind'ах. Управляются через дашборд и не аутентифицируют `/api/*`. | | `storageCleanupPolicy?` | `StorageCleanupPolicy` | disabled | Opt-in policy очистки архивированных сессий. Никогда не включается неявно. | | `appOwnedMemoryBudgetMb?` | `number` | `256` | Лимит в MiB для eviction-friendly app-owned log'ов, cache'ей, blob'ов и continuation payload'ов. Это не RSS-cap. Диапазон 64–4096. | -| `codexAutoStart?` | `boolean` | `true` | Разрешает shim'у Codex запускать `ocx ensure` перед стартом Codex. При false `ensure` становится no-op. | -| `codexShimAutoRestore?` | `boolean` | `true` | Восстанавливает установленный shim после завершённого внешнего обновления Codex, которое заменило его. Для отключения через окружение: `OPENCODEX_CODEX_SHIM_AUTO_RESTORE=0`. | -| `syncResumeHistory?` | `boolean` | `true` | Обратимый режим совместимости истории Codex App. Исходные metadata резервируются и восстанавливаются через `ocx stop` / `ocx restore`. | -| `shadowCallIntercept?` | `{ enabled?: boolean; model?: string; sourceModels?: string[] }` | off | Перенаправляет распознанные helper/shadow-call'ы Codex на выбранную модель с low effort. Source-prefix по умолчанию: `gpt-5.6-luna`; клиенты до 0.144.x включительно использовали `gpt-5.4-mini`, который можно восстановить через `sourceModels`. | -| `webSearchSidecar?` | `OcxWebSearchSidecarConfig` | on when usable | Настройки sidecar'а web-search. | -| `visionSidecar?` | `OcxVisionSidecarConfig` | on when usable | Настройки sidecar'а описания изображений. | -| `images?` | `OcxImagesConfig` | automatic OpenAI selection | Настройки standalone Images relay для Codex `image_gen`. | - -Если более старая development-сборка изменила metadata resume-history до появления резервного -backup'а, выполните `ocx recover-history --legacy-openai`, чтобы принудительно вернуть -native-provider history. +| `codexAutoStart?` | `boolean` | `true` | Разрешает shim'у Codex запускать `ccx ensure` перед стартом Codex. При false `ensure` становится no-op. | +| `codexShimAutoRestore?` | `boolean` | `true` | Восстанавливает установленный shim после завершённого внешнего обновления Codex, которое заменило его. Для отключения через окружение: `CODEXCOMMANDER_CODEX_SHIM_AUTO_RESTORE=0`. | +| `shadowCallIntercept?` | `{ enabled?: boolean; model?: string; sourceModels?: string[] }` | off | Перенаправляет распознанные helper/shadow-call'ы Codex на выбранную модель с low effort. Source-prefix по умолчанию: `gpt-5.6-luna`; `sourceModels` — явное переопределение для текущего пользовательского источника. | +| `webSearchSidecar?` | `CodexCommanderWebSearchSidecarConfig` | on when usable | Настройки sidecar'а web-search. | +| `visionSidecar?` | `CodexCommanderVisionSidecarConfig` | on when usable | Настройки sidecar'а описания изображений. | +| `images?` | `CodexCommanderImagesConfig` | automatic OpenAI selection | Настройки standalone Images relay для Codex `image_gen`. | ## Удалённый доступ @@ -39,19 +34,19 @@ native-provider history. `0.0.0.0`, требует token-auth и для `/api/*`, и для data plane. Экспортируйте токен перед стартом: ```bash -export OPENCODEX_API_AUTH_TOKEN="your-secret-token" -ocx start +export CODEXCOMMANDER_API_AUTH_TOKEN="your-secret-token" +ccx start ``` Без этой переменной прокси откажется подниматься на удалённом bind'е. Для фоновой службы -экспортируйте её до `ocx service install`, чтобы launchd, systemd или Task Scheduler получили +экспортируйте её до `ccx service install`, чтобы launchd, systemd или Task Scheduler получили значение. Затем клиенты должны отправлять: ```text -x-opencodex-api-key: your-secret-token +x-codexcommander-api-key: your-secret-token ``` -| Эндпоинт | `Authorization: Bearer` | `x-opencodex-api-key` | `x-api-key` | +| Эндпоинт | `Authorization: Bearer` | `x-codexcommander-api-key` | `x-api-key` | | --- | --- | --- | --- | | `/v1/responses` | not accepted | **required** | not accepted | | `/v1/chat/completions` | not accepted | **required** | not accepted | @@ -77,7 +72,7 @@ ssh -L 20100:localhost:10100 you@remote Локальный порт может быть любым. Если Host в запросе разрешается в `localhost`, `127.0.0.1` или `::1`, то запрос остаётся loopback-независимо от порта, так что `http://localhost:20100/v1` -работает. Укажите этот base URL клиенту; сам `ocx` продолжает записывать в managed client config +работает. Укажите этот base URL клиенту; сам `ccx` продолжает записывать в managed client config только стандартный локальный адрес `127.0.0.1`. OAuth-callback провайдера слушает на фиксированном remote-port'е. Логиньтесь на удалённой машине @@ -106,15 +101,14 @@ ssh -L 20100:localhost:10100 -L 1455:localhost:1455 you@remote ## Claude Code (`claudeCode`) -Эти настройки управляют `/v1/messages`, launcher'ом `ocx claude` и страницей Claude в дашборде. +Эти настройки управляют `/v1/messages`, launcher'ом `ccx claude` и страницей Claude в дашборде. | Ключ | Тип | По умолчанию | Описание | | --- | --- | --- | --- | | `claudeCode.bodyStallSec?` | `number` | `90` | Бюджет бездействия тела ответа в режиме native-passthrough, в секундах, пока чтение ждёт данные; это не общий лимит длительности. Минимум 1; ровно `0` отключает. | | `claudeCode.bodyMaxBytes?` | `number` | `67108864` | Совокупный лимит native-passthrough тела для stream- и buffered-ответов. Ровно `0` отключает. | | `claudeCode.authMode?` | `"proxy" \| "subscription"` | auto | Как launcher управляет `ANTHROPIC_AUTH_TOKEN`. Auto каждый запуск заново определяет auth; явно заданное значение не переопределяется. | -| `claudeCode.authModeMigratedAt?` | `string` | unset | Внутренний одноразовый маркер миграции. Не задавайте вручную. | -| `claudeCode.subagentEffort?` | `"low" \| "medium" \| "high" \| "xhigh" \| "max"` | inherit | Effort, записываемый в сгенерированные `~/.claude/agents/ocx-*.md`; это отдельно от guidance Codex и proxy cap'ов. Чтобы перегенерировать файлы, перезапускайте через `ocx claude`. | +| `claudeCode.subagentEffort?` | `"low" \| "medium" \| "high" \| "xhigh" \| "max"` | inherit | Effort, записываемый в сгенерированные `~/.claude/agents/ccx-*.md`; это отдельно от guidance Codex и proxy cap'ов. Чтобы перегенерировать файлы, перезапускайте через `ccx claude`. | Авто-режим аутентификации выбирает subscription, если найдена сохранённая auth Claude, proxy — если auth нет, и subscription с предупреждением, если детектировать однозначно не удалось. См. @@ -124,8 +118,10 @@ ssh -L 20100:localhost:10100 -L 1455:localhost:1455 you@remote Codex использует маленькие helper-model'и для задач вроде заголовков и commit message. Включите `shadowCallIntercept`, чтобы перенаправлять распознанные `sourceModels` на другую настроенную -модель. Замещающая модель работает с low effort. `sourceModels` задавайте только если клиент -использует другие helper-id. +модель. Замещающая модель работает с low effort. `sourceModels` задавайте только как явное +переопределение текущего пользовательского источника. Перехватываются только распознанные +служебные запросы из `x-codex-turn-metadata`; обычные запросы и запросы без metadata, с +повреждёнными или неизвестными metadata не перехватываются. ```json { @@ -139,7 +135,7 @@ Codex использует маленькие helper-model'и для задач ## Sidecar'ы -### `images` (`OcxImagesConfig`) +### `images` (`CodexCommanderImagesConfig`) | Поле | Тип | По умолчанию | Значение | | --- | --- | --- | --- | @@ -150,13 +146,13 @@ Codex использует маленькие helper-model'и для задач рабочего ключа; fallback на другой платный upstream здесь невозможен. Endpoint должен реализовывать OpenAI Images API-path'и и форму ответа, которую ожидает Codex. -### `webSearchSidecar` (`OcxWebSearchSidecarConfig`) +### `webSearchSidecar` (`CodexCommanderWebSearchSidecarConfig`) | Поле | Тип | По умолчанию | Значение | | --- | --- | --- | --- | | `enabled?` | `boolean` | on when usable | Главный переключатель. | | `backend?` | `"openai" \| "anthropic"` | auto | Явный выбор выигрывает; иначе usable stored Anthropic OAuth выбирает `anthropic`, затем `openai`. | -| `model?` | `string` | backend-dependent | `gpt-5.6-luna` для OpenAI или `claude-sonnet-5` для Anthropic. Старый явный `gpt-5.4-mini` мигрирует при старте. | +| `model?` | `string` | backend-dependent | `gpt-5.6-luna` для OpenAI или `claude-sonnet-5` для Anthropic. | | `reasoning?` | `string` | `low` | Effort sidecar'а. Значение `minimal` с web search отклоняется. | | `maxSearchesPerTurn?` | `number` | `3` | Число реальных поисков, разрешённых за один turn основной модели. | | `routedModelStallTimeoutMs?` | `number` | `200000` | Config-file-only дедлайн бездействия raw-body у routed-model. Целое 1–2147483647; каждый непустой chunk сбрасывает таймер. | @@ -172,7 +168,7 @@ Anthropic-backend без рабочего аккаунта закрываетс routed-model и hosted-search timeout. Эффективный watchdog моста равен максимуму этих значений плюс 30 секунд. Таймаут routed stall — это защита от бездействия, а не общий дедлайн генерации. -### `visionSidecar` (`OcxVisionSidecarConfig`) +### `visionSidecar` (`CodexCommanderVisionSidecarConfig`) | Поле | Тип | По умолчанию | Значение | | --- | --- | --- | --- | @@ -190,4 +186,4 @@ context. Попадания в cache и дубликаты в пределах `https:`-изображения, а также пустые и неуспешные описания не кэшируются. Sidecar'ы Anthropic OAuth повторно используют уже существующий OAuth fingerprint Claude Code от -opencodex. Перед использованием прогоните soak-test на нужном аккаунте и ожидаемой нагрузке. +CodexCommander. Перед использованием прогоните soak-test на нужном аккаунте и ожидаемой нагрузке. diff --git a/docs-site/src/content/docs/ru/reference/management-api.md b/docs-site/src/content/docs/ru/reference/management-api.md index f5640152a6..44d1e77564 100644 --- a/docs-site/src/content/docs/ru/reference/management-api.md +++ b/docs-site/src/content/docs/ru/reference/management-api.md @@ -1,10 +1,10 @@ --- title: API управления -description: Аутентификация, ошибки и справочник эндпоинтов плоскости управления opencodex. +description: Аутентификация, ошибки и справочник эндпоинтов плоскости управления CodexCommander. --- -Management API — это control plane opencodex. Дашборд на `http://localhost:10100` — лишь один из -его клиентов; headless-команды `ocx` для провайдеров, моделей, combo, аккаунтов, настроек, +Management API — это control plane CodexCommander. Дашборд на `http://localhost:10100` — лишь один из +его клиентов; headless-команды `ccx` для провайдеров, моделей, combo, аккаунтов, настроек, диагностики и lifecycle тоже используют его. API доступен только пока прокси запущен. Для интерактивной работы используйте [Веб-дашборд](/guides/web-dashboard/), а этот справочник @@ -14,10 +14,10 @@ Management API — это control plane opencodex. Дашборд на `http://l ## Модель аутентификации У Management API свой admin credential, независимый от data-plane API-key'ов. При старте -opencodex разрешает его в таком порядке: +CodexCommander разрешает его в таком порядке: -1. `OPENCODEX_ADMIN_AUTH_TOKEN`, если переменная задана. -2. Сгенерированный токен `ocx_admin_*` в hardened secret file. +1. `CODEXCOMMANDER_ADMIN_AUTH_TOKEN`, если переменная задана. +2. Сгенерированный токен `ccx_admin_*` в hardened secret file. Токен из файла принимается только после того, как каталог и файл подтверждённо получили hardened-permissions или ACL. Если это гарантировать нельзя, management-аутентификация @@ -26,7 +26,7 @@ hardened-permissions или ACL. Если это гарантировать не Передавайте admin-token в любой из двух форм: ```http -X-OpenCodex-API-Key: <admin-token> +X-CodexCommander-API-Key: <admin-token> ``` ```http @@ -41,7 +41,7 @@ Claude Code или любого другого клиента моделей; о ### Loopback-сессии дашборда -На loopback-привязке bootstrap дашборда может получить short-lived credential `ocx_session_*`. +На loopback-привязке bootstrap дашборда может получить short-lived credential `ccx_session_*`. Каждая такая сессия живёт пять минут и привязана к точному origin дашборда. Safe-запросы должны совпадать с этим origin. Для unsafe-method'ов браузер дополнительно обязан передать `Origin` и CSRF-token этой сессии. @@ -57,7 +57,7 @@ GUI-сессия в стиле loopback не выпускается. | Статус | Тип или код | Значение | | --- | --- | --- | -| 401 | `opencodex admin token required` | Admin-token или GUI-session отсутствуют, неверны, просрочены, не совпадают по origin или не содержат CSRF-подтверждение | +| 401 | `codexcommander admin token required` | Admin-token или GUI-session отсутствуют, неверны, просрочены, не совпадают по origin или не содержат CSRF-подтверждение | | 403 | `cross-origin request blocked` | Origin запроса вне allowlist management API | | 404 | `not_found` | Ни один management-route не совпал по method и path | | 413 | `request body too large` | Тело POST, PUT или PATCH превысило лимит management API в 2 MiB | @@ -80,7 +80,7 @@ GUI-сессия в стиле loopback не выпускается. | `PUT /api/grok/selection` | Сохранить список исключённых моделей Grok | 400 invalid or oversized selection | | `POST /api/grok/apply` | Применить сохранённую конфигурацию Grok через managed sync | 409 `grok_apply_busy`; 400/500 apply failure | | `GET, PUT /api/claude-desktop` | Прочитать или сохранить routed/native-профиль Claude Desktop | 400 invalid or unavailable assignment | -| `POST /api/claude-desktop/apply` | Записать сохранённый профиль в managed config Claude Desktop | 400/500 write failure | +| `POST /api/claude-desktop/apply` | Записать сохранённый профиль в managed config Claude Desktop. Нужен JSON-объект с явным `mode`: `static`, `hybrid` или `discovery` | 400 invalid body/mode; 500 write failure | | `GET /api/claude-desktop/status` | Проверить согласованность saved-vs-applied profile и здоровье Desktop | 400 status read failure | | `GET, PUT /api/claude-code` | Прочитать или обновить настройки gateway, auth-mode, model-map, context, agent и sidecar для Claude Code | 400 invalid field or shape | @@ -109,9 +109,6 @@ GUI-сессия в стиле loopback не выпускается. | `GET, POST /api/windows-tray` | Прочитать состояние Windows tray или установить/запустить/остановить/удалить её | 400 unsupported platform/action; 500 operation failure | | `GET /api/diagnostics/project-config` | Прочитать кэшированные предупреждения project config | — | | `POST /api/sync` | Синхронизировать каталог моделей в Codex; возвращает `catalogQuality`, `rehydrated`, `catalogState` app-server и подсказку о перезапуске | 409 отказ в праве записи; 500 ошибка синхронизации | -| `GET /api/update/check` | Проверить канал обновлений `latest` или `preview` | 400 invalid tag | -| `POST /api/update/run` | Запустить update job, при желании с последующим restart | 400 invalid body; job-specific conflict/error status | -| `GET /api/update/status` | Опрашивать update job по id | 404 unknown job | | `GET, PUT /api/sidecar-settings` | Прочитать или обновить model/backend-settings web-search и vision sidecar'ов | 400 invalid shape, backend or limit | | `GET, PUT /api/shadow-call-settings` | Прочитать или обновить настройки shadow-call interception | 400 invalid shape or value | @@ -195,12 +192,6 @@ Endpoint'ы storage cleanup могут перемещать или навсег `provider_has_dependent_combos` — это safety-барьер: сначала удалите или отредактируйте зависящие combo, и лишь потом удаляйте их провайдера. -### Sidebar - -| Метод и путь | Назначение | Особые ошибки | -| --- | --- | --- | -| `GET /api/update/badge` | Прочитать дешёвое состояние update-badge в sidebar | — | - ### Жизненный цикл системы | Метод и путь | Назначение | Особые ошибки | @@ -221,7 +212,7 @@ Endpoint'ы storage cleanup могут перемещать или навсег | `PUT /api/codex-auth/accounts/pause` | Поставить один аккаунт на паузу или снять её | 400 invalid account/state; 404 missing account | | `PUT /api/codex-auth/accounts/pause-exhausted` | Поставить на паузу аккаунты с исчерпанной квотой | Сбои mutation-lock превращаются в 503 | | `POST /api/codex-auth/accounts/clear-cooldown` | Очистить runtime cooldown для одного аккаунта или для всех | 400 invalid id | -| `GET, PUT /api/codex-auth/active` | Прочитать или выбрать активный аккаунт | 400 invalid or missing account; 409 paused/legacy-row conflict | +| `GET, PUT /api/codex-auth/active` | Прочитать или выбрать активный аккаунт | 400 invalid or missing account; 409 paused account | | `PUT /api/codex-auth/auto-switch` | Задать порог квоты для автоматического переключения аккаунтов | 400 invalid threshold | | `PUT, PATCH /api/codex-auth/pool-strategy` | Обновить стратегию выбора в пуле аккаунтов Codex | 400 invalid strategy/config | | `PUT /api/codex-auth/failover` | Задать порог failover аккаунтов | 400 invalid threshold | @@ -241,6 +232,6 @@ Endpoint'ы storage cleanup могут перемещать или навсег Для обычного администрирования самый безопасный guided-workflow даёт [Веб-дашборд](/guides/web-dashboard/). Для headless-host'ов и automation используйте -соответствующие команды `ocx`: они обращаются к тому же живому API и возвращают ненулевой код, +соответствующие команды `ccx`: они обращаются к тому же живому API и возвращают ненулевой код, если прокси недоступен или операция завершилась неудачей. Прямой HTTP полезнее всего там, где интеграции нужен точный контракт endpoint'ов, описанный выше. diff --git a/docs-site/src/content/docs/ru/reference/proxy-formats.md b/docs-site/src/content/docs/ru/reference/proxy-formats.md index 8b7dc537d6..a413b5a61d 100644 --- a/docs-site/src/content/docs/ru/reference/proxy-formats.md +++ b/docs-site/src/content/docs/ru/reference/proxy-formats.md @@ -3,7 +3,7 @@ title: Форматы API прокси description: Справочник протокольного уровня для Responses, Chat Completions, Anthropic Messages, каталога моделей, WebSocket, Realtime и компактизации. --- -opencodex предоставляет один локальный прокси сразу в нескольких клиентских диалектах. Клиент +CodexCommander предоставляет один локальный прокси сразу в нескольких клиентских диалектах. Клиент Codex может говорить на Responses API, OpenAI-совместимое приложение — на Chat Completions, а Claude Code — на Anthropic Messages, при этом от каждого upstream-провайдера не требуется реализовывать все эти форматы. @@ -35,7 +35,7 @@ control и safety ответа всё равно происходят на гр ## `POST /v1/responses` -Это нативная форма data plane для opencodex. Тело запроса должно быть JSON-объектом с непустым +Это нативная форма data plane для CodexCommander. Тело запроса должно быть JSON-объектом с непустым `model`. Поле `input` может быть строкой или массивом Responses item'ов. ### Разрешённые поля запроса @@ -191,7 +191,7 @@ passthrough. Native-eligible-запрос пересылается в count-endp ## `POST /v1/live` и Realtime sideband `POST /v1/live` принимает surface Frameless call-creation из ChatGPT/Codex App. -`POST /v1/realtime/calls` принимает surface call-creation OpenAI Realtime. opencodex выбирает +`POST /v1/realtime/calls` принимает surface call-creation OpenAI Realtime. CodexCommander выбирает подходящий маршрут семейства OpenAI, нормализует запрос call-creation под нужный режим upstream-аутентификации и ретранслирует ограниченный ответ. @@ -213,7 +213,7 @@ conversation. | Тип маршрута | Поведение | | --- | --- | | Canonical ChatGPT или официальный маршрут OpenAI | Пересылает запрос в нативный endpoint `/responses/compact` с разрешённым аккаунтом и model-authentication | -| Любая другая routed-модель | Запускает внутренний, не-streaming, без-tool'овый compaction-turn с `compaction_trigger`; требует ровно один синтетический item `compaction`, чей `encrypted_content` — это envelope `ocx1:`; затем декодирует это summary обратно в replacement history v1 | +| Любая другая routed-модель | Запускает внутренний, не-streaming, без-tool'овый compaction-turn с `compaction_trigger`; требует ровно один синтетический item `compaction`, чей `encrypted_content` — это envelope `ccx1:`; затем декодирует это summary обратно в replacement history v1 | Нативные compact-ответы буферизуются с максимумом 32 MiB, включая ответы, у которых один только заявленный `Content-Length` уже превышает лимит. Для compaction есть такие специфические ошибки: @@ -225,12 +225,12 @@ conversation. | 499 | `client_cancelled` | Клиент отменил запрос во время forwarding или buffering | | 502 | `compact_response_too_large` | Нативный compact-output превысил 32 MiB | | 502 | `upstream_error` | Сбой соединения, чтения или synthetic compaction-turn | -| 502 | `invalid_response_error` | Synthetic-turn не создал ровно один корректный непустой item compaction `ocx1:` | +| 502 | `invalid_response_error` | Synthetic-turn не создал ровно один корректный непустой item compaction `ccx1:` | ## Матрица аутентификации На bind'е только для loopback data-plane admission не требует настроенного ключа. На удалённой -привязке используйте матрицу ниже. «Dedicated» означает `X-OpenCodex-API-Key`; остальные столбцы — +привязке используйте матрицу ниже. «Dedicated» означает `X-CodexCommander-API-Key`; остальные столбцы — это `Authorization: Bearer ...` и `x-api-key`. | Поверхность | Выделенный | Bearer | `x-api-key` | @@ -271,14 +271,14 @@ origin превращается в 403 `permission_error`, а не в OpenAI-sty ## Гигиена `encrypted_content` Proxy относится к подлинному ciphertext backend'а как к непрозрачным данным. Структурно валидный -ciphertext сохраняется байт в байт: opencodex его не расшифровывает, не переводит содержимое и не +ciphertext сохраняется байт в байт: CodexCommander его не расшифровывает, не переводит содержимое и не перешифровывает для другого провайдера. -Исторически некоторые agent hook'и клали plaintext control text в слот `encrypted_content`. Ради -совместимости proxy отделяет такой plaintext в текстовые части, сохраняя нетронутыми все +Некоторые agent hook'и кладут plaintext control text в слот `encrypted_content`. Proxy отделяет +такой plaintext в текстовые части, сохраняя нетронутыми все структурно валидные фрагменты Fernet. Если после такой починки у `agent_message` не остаётся ни одной шифрованной части, сообщение становится обычным user-message. Если текущая задача v2 остаётся по-настоящему зашифрованной, а выбранная routed-цель не умеет читать ciphertext нативного -ChatGPT, opencodex завершит запрос ошибкой `unreadable_encrypted_agent_task`, вместо того чтобы +ChatGPT, CodexCommander завершит запрос ошибкой `unreadable_encrypted_agent_task`, вместо того чтобы отправить нечитаемые байты этому провайдеру. О поведении клиента вокруг worker-task'ов см. [Поверхность подагентов](/guides/sub-agent-surface/). diff --git a/docs-site/src/content/docs/ru/troubleshooting/windows-memory.md b/docs-site/src/content/docs/ru/troubleshooting/windows-memory.md index e818b1a5c9..31cf4d2442 100644 --- a/docs-site/src/content/docs/ru/troubleshooting/windows-memory.md +++ b/docs-site/src/content/docs/ru/troubleshooting/windows-memory.md @@ -1,16 +1,16 @@ --- title: Рост памяти на Windows -description: Почему процесс bun может разрастаться до многих гигабайт RAM на Windows, что opencodex делает с этим сегодня и какие у вас есть варианты до выхода исправлений в upstream Bun. +description: Почему процесс bun может разрастаться до многих гигабайт RAM на Windows, что CodexCommander делает с этим сегодня и какие у вас есть варианты до выхода исправлений в upstream Bun. --- -Некоторые пользователи Windows наблюдают, как процесс `bun`, на котором работает opencodex, +Некоторые пользователи Windows наблюдают, как процесс `bun`, на котором работает CodexCommander, разрастается до многих гигабайт RSS во время долгих streaming-сессий (issue -[#314](https://github.com/lidge-jun/opencodex/issues/314)). Эта страница честно объясняет, что +[#314](https://github.com/pavelhov/CodexCommander/issues/314)). Эта страница честно объясняет, что именно происходит и что вы можете сделать сейчас. ## Корневая причина: проблемы в upstream-рантайме Bun -opencodex поставляет рантайм Bun (сейчас это **1.3.14**). Рост памяти вызван известными +CodexCommander поставляет рантайм Bun (сейчас это **1.3.14**). Рост памяти вызван известными проблемами upstream Bun, а не JavaScript-утечками внутри прокси: | Проблема Bun | Состояние (проверено 2026-07-23) | @@ -19,12 +19,12 @@ opencodex поставляет рантайм Bun (сейчас это **1.3.14* | [#32111](https://github.com/oven-sh/bun/issues/32111) — crash при отмене async-pull stream клиентом | Исправление [PR #32120](https://github.com/oven-sh/bun/pull/32120) смёржено 2026-06-21; не предполагается, что оно уже есть в 1.3.14. Важно: этот crash **не специфичен для Windows** (он воспроизводился и на macOS/Linux) | | [PR #31654](https://github.com/oven-sh/bun/pull/31654) — утечка socket handle в `node:net` | Всё ещё **open** в upstream | -На Windows opencodex вынужден оставлять streaming-ответы на более консервативном пути кода, +На Windows CodexCommander вынужден оставлять streaming-ответы на более консервативном пути кода, чтобы избежать crash из #32111, а именно этот путь сильнее всего подвержен проблеме backpressure: медленный или зависший клиент может оставить рантайм буферизовать upstream-данные в нативной памяти, которую JavaScript уже не может ограничить. -## Что opencodex делает сегодня +## Что CodexCommander делает сегодня Есть ограниченные меры и наблюдаемость — **не исправление**. На комплектном рантайме 1.3.14 сама утечка остаётся проблемой upstream: @@ -33,7 +33,7 @@ opencodex поставляет рантайм Bun (сейчас это **1.3.14* предупреждение, когда наблюдаемая память пересекает 4 GiB. Наблюдаемая память — это максимум из RSS, `external` и `arrayBuffers` (а не их сумма), потому что счётчики working set/RSS на Windows могут занижать коммит удерживаемой external-памяти. -- **`ocx doctor`** — раздел "Memory / runtime" показывает версию Bun у *service*-процесса, RSS, +- **`ccx doctor`** — раздел "Memory / runtime" показывает версию Bun у *service*-процесса, RSS, счётчики external/ArrayBuffers, контекст JS-heap и выбранный stream mode. На комплектном Bun 1.3.14 одних только `heapUsed` / `jscHeap` недостаточно, чтобы отличить утечку; сравнивайте наблюдаемую память с `responseState` и повторными сэмплами, прежде чем записывать это на @@ -49,7 +49,7 @@ opencodex поставляет рантайм Bun (сейчас это **1.3.14* prune'ится и не evict'ится. Карточка **Memory observability** в дашборде показывает те же поля и даёт confirm-gated действие **Drain & restart**: она показывает текущее число активных ходов, ждёт до 60 секунд, пока они закончатся (используя уже существующий drain через 503 + - `Retry-After`), затем прерывает оставшиеся ходы и перезапускает прокси через `ocx start` на + `Retry-After`), затем прерывает оставшиеся ходы и перезапускает прокси через `ccx start` на текущем порту (или через respawn service supervisor только при аварии), не снимая внедрение в Codex. Это более длинный и осознанный recycle, чем короткий drain у `POST /api/stop`. - **Альтернативный stream path под флагом** — bounded single-reader relay, убирающий цепочку @@ -57,7 +57,7 @@ opencodex поставляет рантайм Bun (сейчас это **1.3.14* трафик по-прежнему проходит runtime gate. На macOS режим `auto` выбирает точный relay с синхронным `pull()` только когда opt-in plaintext V2 collaboration действительно активировал client rewrite и процесс работает на проверенном bundled Bun 1.3.14. Это узкое исправление - terminal-delivery hang из [#1127](https://github.com/lidge-jun/opencodex/issues/1127), а не + terminal-delivery hang из [#1127](https://github.com/pavelhov/CodexCommander/issues/1127), а не заявление о наличии общего исправления #32111 в Bun 1.3.14. Остальные macOS rewrite остаются explicit-only. Memory endpoint публикует только скалярные счётчики in-flight, cancel, abort, error и queue watermark — без body и request identity. @@ -71,14 +71,14 @@ opencodex поставляет рантайм Bun (сейчас это **1.3.14* ## Что вы можете сделать 1. **Подождать обновления комплектного рантайма.** Когда релиз Bun подтверждённо будет содержать - эти исправления, opencodex обновит bundled runtime, и no-rewrite stream path автоматически + эти исправления, CodexCommander обновит bundled runtime, и no-rewrite stream path автоматически включится на Windows. Описанное выше macOS-исключение plaintext-V2 `auto` независимо привязано к конкретной проверенной версии Bun. -2. **Запустить Bun, которому вы доверяете, через `OPENCODEX_BUN_PATH`.** Это непроверенная - территория — вы запускаете opencodex на рантайме, который мы не тестировали, на свой риск. +2. **Запустить Bun, которому вы доверяете, через `CCX_BUN_PATH`.** Это непроверенная + территория — вы запускаете CodexCommander на рантайме, который мы не тестировали, на свой риск. Важно для service-установок: override считывается **при генерации артефакта службы**, а не при - её старте. Задайте переменную окружения и заново выполните `ocx service repair` из той же + её старте. Задайте переменную окружения и заново выполните `ccx service repair` из той же оболочки, чтобы путь оказался зашит в долговременное определение службы. Одной только переменной для уже установленной службы недостаточно. @@ -88,12 +88,12 @@ opencodex поставляет рантайм Bun (сейчас это **1.3.14* перезапуска. **Предупреждение о риске crash:** общие async-pull streams на Bun 1.3.14 всё ещё затронуты #32111, поэтому принудительный eager relay для непроверенных форм может уронить процесс на любой ОС. Service manager перезапустит его, но запросы в полёте потерпят неудачу. - `"legacy-tee"` фиксирует tee и отключает macOS plaintext-V2 auto-исключение. На Windows + `"safe-tee"` фиксирует tee и отключает macOS plaintext-V2 auto-исключение. На Windows `"auto"` (по умолчанию) следует runtime gate. На macOS `"auto"` остаётся на tee, кроме точного проверенного plaintext-V2 collaboration rewrite; явный `"eager-relay"` включает другие подходящие SSE-ходы. Если вы попробуете любой из этих вариантов на реальной Windows-нагрузке, пожалуйста, пришлите -разделы памяти из `ocx doctor` до и после в -[#314](https://github.com/lidge-jun/opencodex/issues/314) — именно такой верификации эта мера и +разделы памяти из `ccx doctor` до и после в +[#314](https://github.com/pavelhov/CodexCommander/issues/314) — именно такой верификации эта мера и ждёт. diff --git a/docs-site/src/content/docs/troubleshooting/windows-memory.md b/docs-site/src/content/docs/troubleshooting/windows-memory.md index 6f29dd91e2..9017b847fd 100644 --- a/docs-site/src/content/docs/troubleshooting/windows-memory.md +++ b/docs-site/src/content/docs/troubleshooting/windows-memory.md @@ -1,16 +1,16 @@ --- title: Windows Memory Growth -description: Why the bun process can grow to many gigabytes of RAM on Windows, what opencodex does about it today, and your options until the upstream Bun fixes ship. +description: Why the bun process can grow to many gigabytes of RAM on Windows, what CodexCommander does about it today, and your options until the upstream Bun fixes ship. --- -Some Windows users see the `bun` process behind opencodex grow to many +Some Windows users see the `bun` process behind CodexCommander grow to many gigabytes of RSS during long streaming sessions (reported as issue -[#314](https://github.com/lidge-jun/opencodex/issues/314)). This page explains +[#314](https://github.com/pavelhov/CodexCommander/issues/314)). This page explains what is actually happening and what you can do about it, honestly. ## Root cause: upstream Bun runtime issues -opencodex bundles the Bun runtime (currently **1.3.14**). The memory growth is +CodexCommander bundles the Bun runtime (currently **1.3.14**). The memory growth is driven by known upstream Bun issues, not by JavaScript-level leaks in the proxy: @@ -20,12 +20,12 @@ proxy: | [#32111](https://github.com/oven-sh/bun/issues/32111) — crash when a client aborts an async-pull stream | Fix [PR #32120](https://github.com/oven-sh/bun/pull/32120) merged 2026-06-21; not assumed present in 1.3.14. Note: this crash is **not Windows-specific** (it also reproduced on macOS/Linux) | | [PR #31654](https://github.com/oven-sh/bun/pull/31654) — `node:net` socket handle leak | Still **open** upstream | -On Windows, opencodex must keep streaming responses on a conservative code +On Windows, CodexCommander must keep streaming responses on a conservative code path to avoid the #32111 crash, and that path is the one most exposed to the backpressure issue: a slow or stalled client can leave the runtime buffering upstream data in native memory that JavaScript cannot bound. -## What opencodex does today +## What CodexCommander does today Bounded mitigation and visibility — **not a fix**. On the bundled 1.3.14 runtime the leak itself remains an upstream problem: @@ -35,7 +35,7 @@ runtime the leak itself remains an upstream problem: the largest of RSS, `external`, and `arrayBuffers` (not their sum), because Windows working-set/RSS counters can under-report committed external retention. -- **`ocx doctor`** — a "Memory / runtime" section shows the *service* +- **`ccx doctor`** — a "Memory / runtime" section shows the *service* process's Bun version, RSS, external/ArrayBuffers counters, JS-heap context, and stream-mode decision. On the bundled Bun 1.3.14 runtime, `heapUsed` / `jscHeap` alone are not a leak discriminator; compare observed memory with @@ -54,7 +54,7 @@ runtime the leak itself remains an upstream problem: same fields and offers a confirm-gated **Drain & restart** action: it shows the current active-turn count, waits up to 60s for active turns (reusing the existing 503 + `Retry-After` drain), then aborts any remaining turns and - restarts the proxy via `ocx start` on the live port (or a failure-only + restarts the proxy via `ccx start` on the live port (or a failure-only service supervisor respawn) without tearing down Codex injection. That is a longer, informed recycle than the short drain on `POST /api/stop`. - **A gated alternative stream path** — a bounded single-reader relay that @@ -64,7 +64,7 @@ runtime the leak itself remains an upstream problem: collaboration actually activates its client rewrite and the process runs the specifically validated bundled Bun 1.3.14. That narrow path fixes the terminal-delivery hang tracked in - [#1127](https://github.com/lidge-jun/opencodex/issues/1127) without claiming + [#1127](https://github.com/pavelhov/CodexCommander/issues/1127) without claiming that Bun 1.3.14 contains the generic #32111 fix. Other macOS rewrites remain explicit-only. The memory endpoint includes scalar eager-relay in-flight, cancel, abort, error, and queue-watermark counters; it never includes bodies @@ -80,15 +80,15 @@ restart it. ## Your options 1. **Wait for a bundled runtime update.** Once a Bun release verifiably - carries the fixes, opencodex will bump the bundled runtime and the safer + carries the fixes, CodexCommander will bump the bundled runtime and the safer no-rewrite stream path turns on automatically on Windows. The narrow macOS plaintext-V2 `auto` exception described above is independently version-pinned. -2. **Run a Bun runtime you trust with `OPENCODEX_BUN_PATH`.** This is - unvalidated territory — you are running opencodex on a runtime we have not +2. **Run a Bun runtime you trust with `CCX_BUN_PATH`.** This is + unvalidated territory — you are running CodexCommander on a runtime we have not tested; at your own risk. Important for service installs: the override is read **when the service artifact is generated**, not at service start. Set - the environment variable, then re-run `ocx service repair` from that same + the environment variable, then re-run `ccx service repair` from that same shell so the path is baked into the durable service definition. Setting the env alone does nothing for an already-installed service. @@ -98,13 +98,13 @@ restart it. applies to new turns without a restart. **Crash risk warning:** generic async-pull streams on Bun 1.3.14 remain affected by #32111, so forcing eager relay for unvalidated shapes can still crash the process on any OS. The - service manager will restart it, but in-flight requests fail. `"legacy-tee"` + service manager will restart it, but in-flight requests fail. `"safe-tee"` pins tee and also disables the macOS plaintext-V2 auto exception. On Windows, `"auto"` (default) lets the runtime gate decide. On macOS, `"auto"` stays on tee except for the exact validated plaintext-V2 collaboration rewrite; explicit `"eager-relay"` opts other eligible SSE turns in. If you try any of these on a real Windows workload, please report the before -and after `ocx doctor` memory sections on -[#314](https://github.com/lidge-jun/opencodex/issues/314) — that is exactly +and after `ccx doctor` memory sections on +[#314](https://github.com/pavelhov/CodexCommander/issues/314) — that is exactly the verification this mitigation is waiting on. diff --git a/docs-site/src/content/docs/zh-cn/benchmarks/index.mdx b/docs-site/src/content/docs/zh-cn/benchmarks/index.mdx index 479c971784..801ef192c7 100644 --- a/docs-site/src/content/docs/zh-cn/benchmarks/index.mdx +++ b/docs-site/src/content/docs/zh-cn/benchmarks/index.mdx @@ -3,7 +3,7 @@ title: 基准测试 description: 公开编程智能体基准快照 — 每任务成本与能力对比,附各榜单来源说明。 --- -这些是公开榜单的**静态快照**,手动更新 — 并非 OpenCodex 的实时计量。每个榜单都 +这些是公开榜单的**静态快照**,手动更新 — 并非 CodexCommander 的实时计量。每个榜单都 标注了来源、抓取日期和许可说明。只有当榜单中所有行都带有来源实测的每任务成本时, 才会显示得分/$ 排名。 diff --git a/docs-site/src/content/docs/zh-cn/contributing.md b/docs-site/src/content/docs/zh-cn/contributing.md index 48c98feeb4..5cf166adb4 100644 --- a/docs-site/src/content/docs/zh-cn/contributing.md +++ b/docs-site/src/content/docs/zh-cn/contributing.md @@ -1,13 +1,12 @@ --- title: 贡献指南 -description: opencodex 的开发环境、结构、约定,以及添加 provider 或 adapter 的方法。 +description: CodexCommander 的开发环境、结构、约定,以及添加 provider 或 adapter 的方法。 --- ## 环境搭建 ```bash -git clone https://github.com/pavelhov/opencodex.git -cd opencodex +cd /path/to/CodexCommander bun install bun run dev:proxy # 开发模式代理 API bun run dev:gui # 仪表盘 dev 服务器(另一个终端) @@ -42,11 +41,9 @@ bun run prepare:package # 刷新 package launcher/asset cd docs-site && bun install && bun dev ``` -## 文档发布 +## 文档站点 -公开文档发布到 GitHub Pages:<https://opencodex.me/zh-cn/>。 -`.github/workflows/deploy-docs.yml` 会在 `main` push 中 `docs-site/**` 或 workflow 本身发生变化时 -运行,构建 `docs-site` 并部署生成的网站。推送文档变更前请运行: +文档位于 `docs-site/`,目前没有已发布的托管地址。提交文档 pull request 前请本地构建: ```bash cd docs-site @@ -54,38 +51,29 @@ bun install --frozen-lockfile bun run build ``` -## CI 与发布 +本仓库不包含发布自动化。 -GitHub Actions 有意只保留必要步骤: +## 持续集成 -- **Cross-platform CI**(`.github/workflows/ci.yml`)会在改动 runtime、test、package、script、 - TypeScript 或 workflow 文件的 pull request 与 `main` push 上运行。Bun matrix 覆盖 Linux、 - Windows 和 macOS,执行 install、typecheck、test、privacy scan、release-helper build smoke、GUI - build 和 `ocx help`。另一个三系统 lane 使用 package 内置 runtime,验证无需单独安装 Bun 也能 - 完成 npm global install。 -- **Release**(`.github/workflows/release.yml`)只能手动运行。它不是第二套完整 CI;dry-run 或 - publish 前,精确的 release commit(`GITHUB_SHA`)必须已有成功的 Cross-platform CI run。 +每个 pull request 以及每次推送到 `main` 都只会运行 **一个**自动检查:**`ci`** +(`.github/workflows/ci.yml`)。普通贡献所需的自动化就是它。 -发布请使用 helper: +仓库管理员可在保护规则挡住有意的管理操作时,使用 GitHub ruleset **Always-allow** bypass。 +它用于管理员恢复与例外维护,不能替代贡献者变更的审查。 -```bash -bun run release <version> # commit/push 版本 bump;publish workflow 默认 dry-run -bun run release <version> --publish # 确认 CI-gated dry-run 后真正 publish -bun run release:watch # 观察最新的 Release workflow run -``` - -## 分支 +## 分支与 pull request -- `dev` — 唯一的集成目标。请把所有 PR 提到这里。 -- `main` — 仅用于发布。只有维护者从 `dev` 提升时才会变动,请勿直接提功能 PR。 -- `preview` — 预发布通道。 +- **`main` 是唯一的 default / 集成 / PR 目标。** 功能与修复 PR 请提到 `main`。 +- 从当前 **`main` tip** 拉分支。 +- 描述中写清改了什么、为什么,以及如何验证(具体命令与结果)。空描述或仅占位符不算 + review-ready。 +- 若改动仪表盘 UI,请在描述中附截图。 +- 行为变更需要在对应子系统现有测试附近加入聚焦回归测试;共享 routing、adapter、config + 或 server 变更需要完整 suite 通过。 -承载 Go 原生移植的 `dev2-go` 已经退役,同时维护两条集成线的政策也一并结束。其历史以只读 -形式保存在 -[lidge-jun/opencodex-go-archive](https://github.com/lidge-jun/opencodex-go-archive)。 -现在 `dev` 上的 Bun 原生 TypeScript 是唯一的运行时线。 +`main` 上的 Bun 原生 TypeScript 是唯一 runtime 线。 -欢迎变基 PR。把陈旧分支变基到当前 head 是正常的贡献而非噪音。请在描述中注明来源提交。 +欢迎 rebase PR。把陈旧分支接到当前 head 是常规维护;请在描述中注明来源提交。 ## 约定 @@ -95,7 +83,7 @@ bun run release:watch # 观察最新的 Release workflow run 小而专注的 module 位于单一 `index.ts` 之后。 - **在边界处理异步错误** —— sidecar 不会把异常抛进请求路径,而会降级成合适的 marker。 - **Structure SOT** —— 当前维护者不变量放在 `structure/`;公开用户流程放在 `docs-site/`; - 历史调查/诊断记录放在 `docs/`。 + 持续维护的工程与实现笔记放在 `docs/`。 - **保留 export** —— 其他 module 可能依赖它们。 ## 向目录中添加 provider @@ -116,7 +104,7 @@ bun run release:watch # 观察最新的 Release workflow run }, ``` -`src/providers/derive.ts` 会把该条目提供给 `ocx init`、`ocx provider`、仪表盘 preset、API-key +`src/providers/derive.ts` 会把该条目提供给 `ccx init`、`ccx provider`、仪表盘 preset、API-key 登录和 OAuth config seed。`enrichProviderFromCatalog()` 会把模型 metadata 与 capability 分类复制到 保存的 provider 配置。OAuth protocol 实现仍位于 `src/oauth/`;只有 registry metadata 并不会 自动形成 OAuth flow。 @@ -134,4 +122,4 @@ package API,还要从 `src/index.ts` export。 先运行能证明改动的最小命令:类型检查用 `bun run typecheck`,行为检查用聚焦的 `bun test tests/<name>.test.ts` 或 runtime probe,然后再执行适合影响范围的更宽 gate。 -opencodex 倾向于小而可验证的 commit,而不是大批量改动。 +CodexCommander 倾向于小而可验证的 commit,而不是大批量改动。 diff --git a/docs-site/src/content/docs/zh-cn/getting-started/for-agents.md b/docs-site/src/content/docs/zh-cn/getting-started/for-agents.md index 0ea1720640..5ef61150ac 100644 --- a/docs-site/src/content/docs/zh-cn/getting-started/for-agents.md +++ b/docs-site/src/content/docs/zh-cn/getting-started/for-agents.md @@ -1,67 +1,70 @@ --- title: Agent 快速上手 -description: 为受代理驱动或脚本控制的终端安装并操作 opencodex,同时不跨越用户同意边界。 +description: 为受代理驱动或脚本控制的终端安装并操作 CodexCommander,同时不跨越用户同意边界。 --- 本页面面向在终端中工作的 AI agent 或脚本用户。重点说明命令、退出状态,以及安全的无头操作。面向人工引导的流程,请使用 [Quickstart](/getting-started/quickstart/)。仪表板仍可用于交互式配置;参见 [Web Dashboard](/guides/web-dashboard/)。 -## 安装 opencodex +## 安装 CodexCommander -安装已发布的包,并确认 `ocx` 已在 `PATH` 中: +使用现有的源码检出目录。注册表包目前尚未发布: ```bash -npm install -g @bitkyc08/opencodex -ocx --version +bun install +bun run build:gui +bun run src/cli/index.ts --version ``` 选择一种方式运行代理: ```bash # Foreground: blocks this terminal until stopped. -ocx start +bun run src/cli/index.ts start # Background: installs or updates the service, then starts it. -ocx service +bun run src/cli/index.ts service ``` -在交互式终端中运行 `ocx init`。如果 `ocx start` 正占用前台,请使用第二个终端: +在交互式终端中运行 `ccx init`。如果 `ccx start` 正占用前台,请使用第二个终端: ```bash -ocx init +bun run src/cli/index.ts init ``` -该向导会写入 `$OPENCODEX_HOME/config.json`(通常是 `~/.opencodex/config.json`)。它还可以把代理地址注入 Codex 的 `config.toml`,并安装可选的 Codex 自动启动 shim。`ocx init` 从不启动代理。若要完全非交互式地完成设置,请改用下面所示的 `ocx provider add` 来配置提供方,而不是运行向导。 +下文的 `ccx <args>` 在此检出目录中可以写成 `bun run src/cli/index.ts <args>`。 + +该向导会写入 `$CODEXCOMMANDER_HOME/config.json`(通常是 `~/.codexcommander/config.json`)。它还可以把代理地址注入 Codex 的 `config.toml`,并安装可选的 Codex 自动启动 shim。`ccx init` 从不启动代理。若要完全非交互式地完成设置,请改用下面所示的 `ccx provider add` 来配置提供方,而不是运行向导。 ## 检查无头安装 在脚本和 agent 运行中使用这些只读检查: ```bash -ocx status -ocx doctor -ocx health --json +ccx status +ccx doctor +ccx health --json ``` -`ocx status` 会报告代理和服务状态。`ocx doctor` 会诊断本地环境、网络、Codex runtime 和账户健康问题。`ocx health` 在代理健康时退出 `0`,否则退出 `1`;`--json` 会返回结构化输出。 +`ccx status` 会报告代理和服务状态。`ccx doctor` 会诊断本地环境、网络、Codex runtime 和账户健康问题。`ccx health` 在代理健康时退出 `0`,否则退出 `1`;`--json` 会返回结构化输出。 -由管理 API 支持的命令,例如 `ocx combo set`,会联系正在运行的代理。如果找不到正在运行的代理,或者 API 不可达,CLI 会将其视为 `503` 失败并以非零状态退出。请先启动前台代理或后台服务,再重试。完整的命令和端点表面请参见 [CLI reference](/reference/cli/) 和 [Management API](/reference/management-api/)。 +由管理 API 支持的命令,例如 `ccx combo set`,会联系正在运行的代理。如果找不到正在运行的代理,或者 API 不可达,CLI 会将其视为 `503` 失败并以非零状态退出。请先启动前台代理或后台服务,再重试。完整的命令和端点表面请参见 [CLI reference](/reference/cli/) 和 [Management API](/reference/management-api/)。 ## 无需仪表板添加提供方和组合 可以按名称添加注册表中的提供方。例如,下面的命令会添加 Anthropic API key 预设并将其设为默认提供方: ```bash -ocx provider add anthropic-apikey \ +ccx provider add anthropic-apikey \ --api-key "$ANTHROPIC_API_KEY" \ --set-default ``` -`ocx provider add` 会写入本地配置。如果已经有正在运行的代理,并且你希望立刻把模型同步到 Codex,请加上 `--sync`;否则之后再运行 `ocx sync`。不在注册表中的自定义提供方同时需要 `--adapter` 和 `--base-url`。 +`ccx provider add` 会写入本地配置。如果已经有正在运行的代理,并且你希望立刻把模型同步到 Codex,请加上 `--sync`;否则之后再运行 `ccx sync`。不在注册表中的自定义提供方同时需要 `--adapter` 和 `--base-url`。 在所有目标提供方都配置好且代理正在运行后,创建一个故障转移 combo: ```bash -ocx combo set main \ +ccx combo set main \ --targets anthropic/claude-opus-4-8,openai/gpt-5.6-sol \ --strategy failover ``` @@ -70,11 +73,11 @@ ocx combo set main \ ## 远程和 LAN 绑定 -默认的回环绑定不需要 API token。非回环绑定,例如 `0.0.0.0`,则需要 `OPENCODEX_API_AUTH_TOKEN`;没有它,代理会拒绝启动。请在 `ocx start` 之前设置该变量,或者在 `ocx service install` 之前设置,这样服务就能接收到它: +默认的回环绑定不需要 API token。非回环绑定,例如 `0.0.0.0`,则需要 `CODEXCOMMANDER_API_AUTH_TOKEN`;没有它,代理会拒绝启动。请在 `ccx start` 之前设置该变量,或者在 `ccx service install` 之前设置,这样服务就能接收到它: ```bash -export OPENCODEX_API_AUTH_TOKEN="your-secret-token" -ocx service install +export CODEXCOMMANDER_API_AUTH_TOKEN="your-secret-token" +ccx service install ``` -之后,客户端必须对其管理请求和模型请求进行身份验证。在把 opencodex 暴露到本机之外之前,请先阅读 [Configuration](/reference/configuration/) 中的远程访问规则。 +之后,客户端必须对其管理请求和模型请求进行身份验证。在把 CodexCommander 暴露到本机之外之前,请先阅读 [Configuration](/reference/configuration/) 中的远程访问规则。 diff --git a/docs-site/src/content/docs/zh-cn/getting-started/how-it-works.mdx b/docs-site/src/content/docs/zh-cn/getting-started/how-it-works.mdx index 4cf7301a14..6eb782fa9d 100644 --- a/docs-site/src/content/docs/zh-cn/getting-started/how-it-works.mdx +++ b/docs-site/src/content/docs/zh-cn/getting-started/how-it-works.mdx @@ -1,20 +1,20 @@ --- title: 工作原理 -description: opencodex 的完整请求生命周期 —— 解析、路由、适配、桥接与 streaming。 +description: CodexCommander 的完整请求生命周期 —— 解析、路由、适配、桥接与 streaming。 --- import { Steps } from '@astrojs/starlight/components'; -Codex 使用 OpenAI **Responses API**。opencodex 接收通过 HTTP 与 Server-Sent Events 发送的 +Codex 使用 OpenAI **Responses API**。CodexCommander 接收通过 HTTP 与 Server-Sent Events 发送的 `POST /v1/responses`,也可选择在同一路径上启用 WebSocket 升级。它会把请求转换为 provider 的 wire 格式,再把响应转换回 Responses 事件,因此 Codex 无需知道自己正在与非 OpenAI 模型通信。 ``` - ┌──────────────────────────── opencodex ────────────────────────────┐ + ┌──────────────────────────── CodexCommander ────────────────────────────┐ │ │ Codex ──▶ │ parser ──▶ router ──▶ [vision] ──▶ adapter ──▶ provider │ ──▶ Codex (/v1/ │ │ │ │ │ │ │ (SSE / WS) - responses)│ OcxParsed provider describe buildRequest parseStream │ + responses)│ CodexCommanderParsed provider describe buildRequest parseStream │ │ Request +adapter images + fetch AdapterEvent[] │ │ │ │ │ │ [web-search loop] bridge ─▶ SSE │ @@ -33,7 +33,7 @@ Sol/Terra/Luna 三个模型和 `gpt-5.4-mini`。仪表盘可以从原生或已 <Steps> 1. **解析** —— `responses/parser.ts` 使用 Zod schema(`responses/schema.ts`)校验请求, - 并将其降级为内部的 `OcxParsedRequest`:系统提示词、一份规范化的消息列表 + 并将其降级为内部的 `CodexCommanderParsedRequest`:系统提示词、一份规范化的消息列表 (文本、图像、工具调用、工具结果)、工具定义、生成选项,以及诸如 `_webSearch`(请求了托管的网络搜索) 和 `_structuredOutput`(设置了 JSON schema / JSON 对象的 `text.format`)等特性标志。图像会被保留为真正的内容部分 —— 绝不会被内联为 @@ -44,21 +44,21 @@ Sol/Terra/Luna 三个模型和 `gpt-5.4-mini`。仪表盘可以从原生或已 (`claude-`、`gpt-`、`o1-`/`o3-`/`o4-`、`llama-`/`mixtral-`/`gemma-`) → provider 的 `models[]` → `defaultProvider` 回退。参见 [模型路由](/zh-cn/guides/model-routing/)。 -3. **认证** —— 对于 `oauth` 类型的 provider,opencodex 会把当前 access token 解析为 bearer - key,并遵循凭据所有权:OpenCodex 自有凭据会自动刷新;已链接的 Grok/Kimi 原生 CLI 代际会被 +3. **认证** —— 对于 `oauth` 类型的 provider,CodexCommander 会把当前 access token 解析为 bearer + key,并遵循凭据所有权:CodexCommander 自有凭据会自动刷新;已链接的 Grok/Kimi 原生 CLI 代际会被 重新读取,并以只读方式使用。 4. **Vision sidecar(可选)** —— 如果已路由的模型被列在 `provider.noVisionModels` 中,且 - 请求携带了图像,opencodex 会通过你的 ChatGPT 登录凭据,使用已配置的 vision sidecar 描述 + 请求携带了图像,CodexCommander 会通过你的 ChatGPT 登录凭据,使用已配置的 vision sidecar 描述 每张图像并将其替换为文本,让纯文本模型仍可对图像进行推理。 参见 [Sidecar](/zh-cn/guides/sidecars/)。 5. **直通快速路径** —— 对于 Responses 直通 adapter(`openai-responses` 或 `azure-openai`), - opencodex 会保留 Responses body,只执行必要的路由与兼容性改写,然后直接转发 provider 响应, + CodexCommander 会保留 Responses body,只执行必要的路由与兼容性改写,然后直接转发 provider 响应, 不再转换为 `AdapterEvent`。 6. **网络搜索 sidecar(可选)** —— 如果 Codex 启用了托管的 `web_search`,但已路由的模型 - 并非 OpenAI,opencodex 会暴露一个合成的 `web_search` 函数工具,并在一个小型 + 并非 OpenAI,CodexCommander 会暴露一个合成的 `web_search` 函数工具,并在一个小型 agentic 循环中运行该模型,默认通过你的 ChatGPT 登录凭据调用 `gpt-5.6-luna` 执行真实搜索, 再将结果作为工具结果注入回去。 @@ -67,7 +67,7 @@ Sol/Terra/Luna 三个模型和 `gpt-5.4-mini`。仪表盘可以从原生或已 情况下执行摘要,并返回 Codex 所需的替代历史记录格式。 8. **适配** —— 否则,所选 adapter 的 `buildRequest()` 会以 provider 的原生格式生成上游 HTTP 请求 - (URL、headers、body),由 opencodex 对其执行 `fetch`。 + (URL、headers、body),由 CodexCommander 对其执行 `fetch`。 9. **桥接** —— adapter 的 `parseStream()`(或 `parseResponse()`)会产出内部的 `AdapterEvent` (text、reasoning、tool-call start/delta/end、done、error)。`bridge.ts` 会将该流转换回 @@ -77,9 +77,9 @@ Sol/Terra/Luna 三个模型和 `gpt-5.4-mini`。仪表盘可以从原生或已 </Steps> -## 为什么是代理而不是 fork 一份 Codex? +## 为什么使用协议代理? -Codex 把 Responses API 硬编码在内部。通过在协议边界处进行翻译,opencodex 可以与 +Codex 把 Responses API 硬编码在内部。通过在协议边界处进行翻译,CodexCommander 可以与 Codex 的 **CLI、App 和 SDK** 无改动地协作,能在 Codex 更新后继续工作,并让你能够按请求切换 provider 而无需改动 Codex 本身。这种翻译是双向且忠于 streaming 的: 推理摘要、MCP 工具命名空间、freeform(`apply_patch`)工具,以及 `tool_search` 发现 diff --git a/docs-site/src/content/docs/zh-cn/getting-started/installation.md b/docs-site/src/content/docs/zh-cn/getting-started/installation.md index 721491f03d..0786cb1be0 100644 --- a/docs-site/src/content/docs/zh-cn/getting-started/installation.md +++ b/docs-site/src/content/docs/zh-cn/getting-started/installation.md @@ -1,9 +1,9 @@ --- title: 安装 -description: 安装 opencodex(ocx)代理及其前置条件,并验证它能够运行。 +description: 安装 CodexCommander(ccx)代理及其前置条件,并验证它能够运行。 --- -安装 opencodex 后会得到 `ocx` 和 `opencodex` 两个等价命令,它们都指向同一个基于 Bun 的 +打包或本地链接的构建会提供 `ccx` 和 `codexcommander` 两个等价命令,它们都指向同一个基于 Bun 的 小型本地 HTTP 服务器。模型请求会发往路由所选的 provider;当已路由模型需要时,可选的 vision 和网络搜索 sidecar 也可以使用你的 ChatGPT 登录凭据。 @@ -11,83 +11,57 @@ vision 和网络搜索 sidecar 也可以使用你的 ChatGPT 登录凭据。 | 要求 | 原因 | | --- | --- | -| **[Node](https://nodejs.org) ≥ 18** | `ocx` 运行在 Bun 运行时上,但运行时会在 `npm install` 时自动打包,你**无需**自己安装 Bun。 | -| **[OpenAI Codex](https://openai.com/codex)**(CLI、App 或 SDK) | opencodex 所代理的客户端。opencodex 会写入 `$CODEX_HOME/config.toml`(默认 `~/.codex/config.toml`)。 | +| **[Bun](https://bun.sh)** | 源码运行时和仓库脚本直接通过 Bun 执行。 | +| **[OpenAI Codex](https://openai.com/codex)**(CLI、App 或 SDK) | CodexCommander 所代理的客户端。CodexCommander 会写入 `$CODEX_HOME/config.toml`(默认 `~/.codex/config.toml`)。 | | 一个 provider 账号或 API key | Anthropic、xAI、Kimi、Ollama Cloud、OpenRouter、OpenAI API key、一个 OpenAI 兼容端点,或你的 ChatGPT 登录凭据。 | -## 安装 +## 运行源码检出目录 ```bash -npm install -g @bitkyc08/opencodex -``` - -:::note[npm 拦截了 bun postinstall?] -较新的 npm 可能会拦截 bun 的 postinstall 脚本(`npm warn install-scripts ... -blocked because they are not covered by allowScripts`),导致捆绑的 Bun -运行时未能就绪。请允许 bun 脚本后重新安装。注意 npm 警告给出的缩写命令 -缺少包名,会把当前目录重新安装进去,请始终显式写上包名: - -```bash -npm install -g --allow-scripts=bun @bitkyc08/opencodex - -# 如果最初是用 sudo 安装的,请继续使用 sudo: -sudo npm install -g --allow-scripts=bun @bitkyc08/opencodex -``` -::: - -确认两个命令都已加入 `PATH`: - -```bash -ocx --version -opencodex --version +bun install +bun run build:gui +bun run src/cli/index.ts start ``` -### 发布渠道 - -稳定的 `latest` 渠道已经包含 ChatGPT、OpenAI API key、OpenRouter 以及实验性 Cursor 路由所需的 -GPT-5.6 Sol/Terra/Luna 目录信息,但这些条目本身不会授予上游模型权限。只有在测试尚未正式发布的 -opencodex 构建时,才需要使用 preview 渠道: +注册表包目前尚未发布。在此检出目录中,请将 `ccx <args>` 替换为 +`bun run src/cli/index.ts <args>`。在另一个终端中验证运行时: ```bash -npm install -g @bitkyc08/opencodex@preview -ocx update --tag preview +bun run src/cli/index.ts --version ``` -## 从源码运行 +## 开发模式 -若要对 opencodex 本身进行开发: +编辑 UI 时,请分别运行代理和仪表盘: ```bash -git clone https://github.com/pavelhov/opencodex.git -cd opencodex -bun install bun run dev:proxy # 以开发模式启动代理 API (src/cli/index.ts start) bun run dev:gui # 启动仪表盘 dev 服务器 (另一个终端) ``` -`bun run dev` 作为 `bun run dev:proxy` 的别名保留。代理 API 暴露 `/healthz`、`/v1/responses`、 +`bun run dev` 是 `bun run dev:proxy` 的别名。代理 API 暴露 `/healthz`、`/v1/responses`、 `/api/*`;只有在 `bun run build:gui` 生成 `gui/dist` 之后,`GET /` 才会提供打包后的仪表盘。 -开发仪表盘时,请用 `bun run dev:gui` 单独运行前端。 +开发仪表盘时,请用 `bun run dev:gui` 单独运行前端。macOS 配套应用可在同一检出目录中通过 `bun run test:macos && bun run build:macos` 构建,源码构建位于 `dist/macos/CodexCommander.app`。 ## 会创建哪些内容 -opencodex 状态文件位于 `$OPENCODEX_HOME`(默认 `~/.opencodex`),Codex 集成文件位于 +CodexCommander 状态文件位于 `$CODEXCOMMANDER_HOME`(默认 `~/.codexcommander`),Codex 集成文件位于 `$CODEX_HOME`(默认 `~/.codex`)。 | 路径 | 用途 | | --- | --- | -| `$OPENCODEX_HOME/config.json` | 你的 provider、默认 provider、端口及选项。 | -| `$OPENCODEX_HOME/ocx.pid` | 正在运行的代理的 PID(单实例保护)。 | -| `$OPENCODEX_HOME/runtime-port.json` | 当前 PID、主机名和端口,包括自动选择的备用端口。 | -| `$OPENCODEX_HOME/auth.json` | 执行 `ocx login` 后保存的 OAuth 凭据。 | -| `$OPENCODEX_HOME/catalog-backup*.json` | opencodex 修改 Codex 模型目录前创建的备份。 | -| `$CODEX_HOME/config.toml` | 仅监听回环地址时,opencodex 会添加由自身标记管理的根级 `openai_base_url`;监听非回环地址时,则使用 `model_provider = "opencodex"` 和 `[model_providers.opencodex]`,以便 Codex 发送 API 认证 header。 | -| `$CODEX_HOME/opencodex.config.toml` | 与 Codex 主配置一同写入的备用/参考 profile。 | -| `$CODEX_HOME/opencodex-catalog.json` | 供 Codex 使用的原生与已路由模型目录。 | +| `$CODEXCOMMANDER_HOME/config.json` | 你的 provider、默认 provider、端口及选项。 | +| `$CODEXCOMMANDER_HOME/codexcommander.pid` | 正在运行的代理的 PID(单实例保护)。 | +| `$CODEXCOMMANDER_HOME/runtime-port.json` | 当前 PID、主机名和端口,包括自动选择的备用端口。 | +| `$CODEXCOMMANDER_HOME/auth.json` | 执行 `ccx login` 后保存的 OAuth 凭据。 | +| `$CODEXCOMMANDER_HOME/catalog-backup-<catalog-id>.json` | CodexCommander 修改 Codex 模型目录前创建的备份。 | +| `$CODEX_HOME/config.toml` | 仅监听回环地址时,CodexCommander 会添加由自身标记管理的根级 `openai_base_url`;监听非回环地址时,则使用 `model_provider = "codexcommander"` 和 `[model_providers.codexcommander]`,以便 Codex 发送 API 认证 header。 | +| `$CODEX_HOME/codexcommander.config.toml` | 与 Codex 主配置一同写入的备用/参考 profile。 | +| `$CODEX_HOME/codexcommander-catalog.json` | 供 Codex 使用的原生与已路由模型目录。 | :::note -opencodex 绝不会删除你的 Codex 配置。每次注入都是可逆的 —— `ocx stop`、`ocx restore` -或 `ocx eject` 会精确剥离 opencodex 所添加的那些行,并恢复原生 Codex。 +CodexCommander 绝不会删除你的 Codex 配置。每次注入都是可逆的 —— `ccx stop`、`ccx restore` +或 `ccx eject` 会精确剥离 CodexCommander 所添加的那些行,并恢复原生 Codex。 ::: ## 下一步 diff --git a/docs-site/src/content/docs/zh-cn/getting-started/quickstart.md b/docs-site/src/content/docs/zh-cn/getting-started/quickstart.md index e65ca9835c..5319fad80b 100644 --- a/docs-site/src/content/docs/zh-cn/getting-started/quickstart.md +++ b/docs-site/src/content/docs/zh-cn/getting-started/quickstart.md @@ -1,6 +1,6 @@ --- title: 快速开始 -description: 配置你的第一个 provider,并在三条命令内让 OpenAI Codex 通过 opencodex 路由。 +description: 配置你的第一个 provider,并在三条命令内让 OpenAI Codex 通过 CodexCommander 路由。 --- 本指南将带你从全新安装,一路走到用一个非 OpenAI 模型运行 Codex。 @@ -8,49 +8,49 @@ description: 配置你的第一个 provider,并在三条命令内让 OpenAI Co ## 1. 运行设置向导 ```bash -ocx init +ccx init ``` -`ocx init` 会引导你完成: +`ccx init` 会引导你完成: 1. **选择 provider** — 从内置 registry 的 76 个预设中选择一个,或选择 `custom` 手动输入 base URL 和 adapter。 2. **API key** — 粘贴一个 key,或引用一个环境变量,例如 `${ANTHROPIC_API_KEY}`。 3. **默认模型** — 对于 key、本地和 custom provider,接受预设值或输入模型 id。 4. **代理端口** — 默认为 `10100`。 -5. **注入到 Codex?** — 在常规 loopback 配置下,opencodex 会在 `$CODEX_HOME/config.toml`(默认 `~/.codex/config.toml`)根级添加 `openai_base_url`,让 Codex 内置的 `openai` provider 指向代理。远程/LAN 绑定则改用带 API 认证 header 的专用 provider 条目。 -6. **安装自启动 shim?** — 启用后,启动 `codex` 会先运行 `ocx ensure`。 +5. **注入到 Codex?** — 在常规 loopback 配置下,CodexCommander 会在 `$CODEX_HOME/config.toml`(默认 `~/.codex/config.toml`)根级添加 `openai_base_url`,让 Codex 内置的 `openai` provider 指向代理。远程/LAN 绑定则改用带 API 认证 header 的专用 provider 条目。 +6. **安装自启动 shim?** — 启用后,启动 `codex` 会先运行 `ccx ensure`。 -结果会保存到 `$OPENCODEX_HOME/config.json`(默认 `~/.opencodex/config.json`)。 +结果会保存到 `$CODEXCOMMANDER_HOME/config.json`(默认 `~/.codexcommander/config.json`)。 :::note[GPT-5.6 灰度发布条目] -当前稳定版会为 ChatGPT 透传、OpenAI API key、OpenRouter,以及实验性的 Cursor adapter 预置 GPT-5.6 Sol/Terra/Luna。只有当上游账号具备访问权限时它们才可用。OpenAI API key 和 OpenRouter 预设声明的可用上下文窗口为 372,000 token;Cursor 则保留自己的 adapter 元数据。 +当前源码树会为 ChatGPT 透传、OpenAI API key、OpenRouter,以及实验性的 Cursor adapter 预置 GPT-5.6 Sol/Terra/Luna。只有当上游账号具备访问权限时它们才可用。OpenAI API key 和 OpenRouter 预设声明的可用上下文窗口为 372,000 token;Cursor 则保留自己的 adapter 元数据。 ::: ## 2. 启动代理 ```bash -ocx start # defaults to port 10100 -ocx start --port 8080 +ccx start # defaults to port 10100 +ccx start --port 8080 ``` -启动时,opencodex 会: +启动时,CodexCommander 会: -- 将其 PID 写入 `~/.opencodex/ocx.pid`(并拒绝重复启动); +- 将其 PID 写入 `~/.codexcommander/codexcommander.pid`(并拒绝重复启动); - 在 provider 支持时发现实时模型,并**把原生与已路由条目同步进 Codex 的模型目录**; - 监听 `http://localhost:<port>/v1`。 -如果请求的端口已被占用,`ocx start` 会选择一个空闲端口,将其记录到 `runtime-port.json`,并更新 Codex 以使用这个实际监听地址。 +如果请求的端口已被占用,`ccx start` 会选择一个空闲端口,将其记录到 `runtime-port.json`,并更新 Codex 以使用这个实际监听地址。 检查它: ```bash -ocx status -ocx gui # open the dashboard on the live port +ccx status +ccx gui # open the dashboard on the live port ``` ## 3. 使用 Codex -Codex 现在会透明地通过 opencodex 通信: +Codex 现在会透明地通过 CodexCommander 通信: ```bash codex "Refactor this function for readability" @@ -65,16 +65,16 @@ codex -m "ollama-cloud/glm-5.2" "Write a SQL migration" ## 选择 sub-agent 模型(可选) -全新配置会在 Codex 的 sub-agent 选择器中提供五个原生模型:`gpt-5.5`、`gpt-5.6-sol`、`gpt-5.6-terra`、`gpt-5.6-luna` 和 `gpt-5.4-mini`。打开 `ocx gui`,可以替换或重新排序最多五个原生或已路由模型。仪表盘还可以设置一个首选 sub-agent 模型和 reasoning effort。参见 [Sub-agent Surface](/guides/sub-agent-surface/) 以选择 v1/base/v2,并了解何时适用 guidance、原生默认值和 fallback。 +全新配置会在 Codex 的 sub-agent 选择器中提供五个原生模型:`gpt-5.5`、`gpt-5.6-sol`、`gpt-5.6-terra`、`gpt-5.6-luna` 和 `gpt-5.4-mini`。打开 `ccx gui`,可以替换或重新排序最多五个原生或已路由模型。仪表盘还可以设置一个首选 sub-agent 模型和 reasoning effort。参见 [Sub-agent Surface](/guides/sub-agent-surface/) 以选择 v1/base/v2,并了解何时适用 guidance、原生默认值和 fallback。 ## 登录而非粘贴 key -部分 provider 支持真正的账号登录。OpenCodex 自有 OAuth 凭据会自动刷新;已链接的 +部分 provider 支持真正的账号登录。CodexCommander 自有 OAuth 凭据会自动刷新;已链接的 Grok/Kimi 原生 CLI 会话仍由 CLI 所有: ```bash -ocx login xai # or: anthropic, kimi, kiro, google-antigravity, cursor -ocx logout xai +ccx login xai # or: anthropic, kimi, kiro, google-antigravity, cursor +ccx logout xai ``` OpenAI 本身不需要 key——默认 provider 会直接透传你现有的 `codex login` 凭据(参见 [Providers](/guides/providers/))。 @@ -82,9 +82,9 @@ OpenAI 本身不需要 key——默认 provider 会直接透传你现有的 `cod ## 停止与恢复 ```bash -ocx stop # stop the proxy and restore native Codex -ocx restore # restore native Codex without stopping (alias: ocx eject) -ocx restore back # route Codex through the still-running proxy again +ccx stop # stop the proxy and restore native Codex +ccx restore # restore native Codex without stopping (alias: ccx eject) +ccx restore back # route Codex through the still-running proxy again ``` ## 下一步 diff --git a/docs-site/src/content/docs/zh-cn/guides/claude-code.md b/docs-site/src/content/docs/zh-cn/guides/claude-code.md index 31410c9214..5c514cdd5b 100644 --- a/docs-site/src/content/docs/zh-cn/guides/claude-code.md +++ b/docs-site/src/content/docs/zh-cn/guides/claude-code.md @@ -1,19 +1,19 @@ --- title: Claude Code 指南 -description: 在 Claude Code 中使用任意已路由模型——opencodex 在同一端口提供 Anthropic Messages API 和网关模型发现功能。 +description: 在 Claude Code 中使用任意已路由模型——CodexCommander 在同一端口提供 Anthropic Messages API 和网关模型发现功能。 --- -opencodex 在 `/v1/responses` 之外还提供 `POST /v1/messages`(以及 `count_tokens`),因此 Claude +CodexCommander 在 `/v1/responses` 之外还提供 `POST /v1/messages`(以及 `count_tokens`),因此 Claude Code 可以使用每一个已路由的提供商——包括 OAuth 登录、账户池、密钥故障转移和 sidecar—— 而无需进行任何额外的身份验证配置。 ## 快速开始 ```bash -ocx claude +ccx claude ``` -`ocx claude` 会确保代理正在运行,然后在接好环境变量的情况下启动 Claude Code: +`ccx claude` 会确保代理正在运行,然后在接好环境变量的情况下启动 Claude Code: | 变量 | 值 | | --- | --- | @@ -21,26 +21,23 @@ ocx claude | `ANTHROPIC_AUTH_TOKEN` | 仅在代理要求 API 密钥时设置——否则不会设置,因此你的 claude.ai 登录(订阅 + 连接器)会保持有效 | | `CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY` | `1`(原生 `/model` 选择器发现) | | `CLAUDE_CODE_AUTO_COMPACT_WINDOW` | 自动上下文压缩阈值(默认 `350000`);仅在启用自动上下文时注入 | -| `ANTHROPIC_MODEL` | `claudeCode.model`(可选) | -| `ANTHROPIC_DEFAULT_HAIKU_MODEL` | `claudeCode.tierModels.haiku ?? claudeCode.smallFastModel`(可选,也包括旧版 `ANTHROPIC_SMALL_FAST_MODEL`) | -| `ANTHROPIC_DEFAULT_{OPUS,SONNET,FABLE}_MODEL` | `claudeCode.tierModels.*`(可选) | -| `CLAUDE_CODE_ALWAYS_ENABLE_EFFORT` | 启用 `alwaysEnableEffort` 时设为 `1`(条件注入) | -| `CLAUDE_CODE_MAX_CONTEXT_TOKENS` / `DISABLE_COMPACT` | 设置 `maxContextTokens` 时使用的旧版上下文覆盖项(条件注入) | -你自行导出的变量始终优先。额外参数会直接透传:`ocx claude -p "hello"`。 +| `ANTHROPIC_DEFAULT_HAIKU_MODEL` / `ANTHROPIC_SMALL_FAST_MODEL` | 配置后使用 `claudeCode.smallFastModel` | + +你自行导出的变量始终优先。额外参数会直接透传:`ccx claude -p "hello"`。 ## 系统环境集成(macOS) -当 `claudeCode.systemEnv` 设置为 `true`(默认:**关闭**)时,`ocx start` 会使用 `launchctl setenv` +当 `claudeCode.systemEnv` 设置为 `true`(默认:**关闭**)时,`ccx start` 会使用 `launchctl setenv` 在系统范围内注入 `ANTHROPIC_BASE_URL` 和相关的 Claude Code 环境变量。因此,新打开的终端窗口和 -标签页可以直接通过代理路由普通的 `claude` 命令,无需使用 `ocx claude` 包装器。已经打开的 +标签页可以直接通过代理路由普通的 `claude` 命令,无需使用 `ccx claude` 包装器。已经打开的 shell 不受影响,必须重新打开。 -`ocx stop` 和代理关闭操作会**取消设置已注入的键**(不会恢复之前的值——只会移除 opencodex -注入的键)。代理还会写入 `~/.opencodex/claude-env.sh`;`ocx start` 会安装一个 `.zshrc` +`ccx stop` 和代理关闭操作会**取消设置已注入的键**(不会恢复之前的值——只会移除 CodexCommander +注入的键)。代理还会写入 `~/.codexcommander/claude-env.sh`;`ccx start` 会安装一个 `.zshrc` source hook,以自动加载该文件。 可以在配置中设置 `claudeCode.systemEnv: false`,或使用 GUI 开关来禁用。此功能仅适用于 -macOS;在其他平台上,请使用 `ocx claude`。 +macOS;在其他平台上,请使用 `ccx claude`。 ## 原生 Claude 透传(订阅直通) @@ -50,49 +47,38 @@ macOS;在其他平台上,请使用 `ocx claude`。 而已路由模型仍可在同一会话中通过选择器别名使用。 **请求头处理:**转发前会移除逐跳请求头以及 `host`、`content-length`、`accept-encoding`、 -`x-opencodex-api-key` 和 `origin`。其他所有请求头(包括 `anthropic-beta` 和 +`x-codexcommander-api-key` 和 `origin`。其他所有请求头(包括 `anthropic-beta` 和 `anthropic-version`)都会透传。 只有同时满足以下**四个**条件时才会触发透传:`nativePassthrough` 不为 `false`;模型以 `claude` 或 `anthropic` 开头;bearer 或 `x-api-key` 以 `sk-ant-` 开头;并且别名/模型映射 -解析后返回的模型保持不变。这也意味着使用 `ocx claude` 时不再出现 +解析后返回的模型保持不变。这也意味着使用 `ccx claude` 时不再出现 “claude.ai connectors are disabled”警告。 可以设置 `claudeCode.nativePassthrough: false` 来禁用;也可以通过 `claudeCode.anthropicBaseUrl` 指向其他位置。 ## /model 选择器(“From gateway”) -每个条目带有诚实的显示名(如 `gemini-3-pro (gemini)`),并以官方 ModelInfo 形态附带模型能力 -信息(推理强度梯度、thinking 类型),使 Claude Desktop 的第三方网关模式能够启用推理强度选择 -UI。真实 Anthropic 模型保留其原始 id。合成的 2026 日期是内部槽位,不是发布日期。旧版哈希 -别名和 `claude-ocx-<provider>--<model>` 别名仍可解析。拥有 1M 上下文的模型会多出一行 `…[1m]`: -选中后 Claude Code 会按 1M 计算该模型的上下文(自动压缩保留,代理在路由前去掉该标记)。 -选中后会保存到 Claude Code 的 `settings.json` `model` 字段;入站请求会将别名解析回路由 -模型。旧版 Claude Code 中选择器保持原生 — 通过 `ANTHROPIC_MODEL` 设置槽位,或直接在 `/model` -中输入任意路由 id(Claude Code 会原样传递字符串)。 - Claude Code 2.1.129+ 通过 `GET /v1/models?limit=1000` 发现网关模型,并在原生 `/model` 选择器中以“From gateway”标签列出。由于选择器只接受以 `claude` 或 `anthropic` 开头的 ID, -opencodex 会将已路由模型公开为稳定且可逆的别名: +CodexCommander 会将已路由模型公开为稳定且可逆的别名: | 界面 | 格式 | 示例 | | --- | --- | --- | -| Claude Code CLI | `claude-ocx-<provider>--<model>`(plain)或 `claude-ocx2-…`(escaped) | `claude-ocx-native--gpt-5.6-sol` | +| Claude Code CLI | `claude-ccx2-<provider>--<model>`(plain)或 `claude-ccx2-…`(escaped) | `claude-ccx2-native--gpt-5.6-sol` | | Claude Desktop 3P | `claude-opus-4-8-<code>`(3 字符 base36 哈希) | `claude-opus-4-8-ncb` | 代理会按请求选择别名族:`?ids=cli` 或 `?ids=desktop` 优先;否则,`claude-code/*` -user-agent 会获得易读的 CLI 形式,其他客户端会获得 Desktop 哈希形式。两种别名族都会永久 -保持可解码——以任一形式保存在 `settings.json` 中的模型都能继续工作。 +user-agent 会获得易读的 CLI 形式,其他客户端会获得 Desktop 哈希形式。当前两种别名族都由 +运行中的别名注册表解析。 如果 Claude Desktop 底部的选择器没有切换已运行 3P 对话的模型,请在该对话中使用 -`/model <id>`。OpenCodex 无法读取选择器状态,只会路由每个请求实际携带的模型 ID;可在 +`/model <id>`。CodexCommander 无法读取选择器状态,只会路由每个请求实际携带的模型 ID;可在 **Logs → requestedModel** 中确认结果。 -**别名语法规则:**provider 不得包含 `/` 或 `--`,也不得等于 `native`。 -不含 `/` 或 `~` 的普通 model ID 继续使用 v1 前缀 `claude-ocx-…`。包含 `/` 或 `~` 的 model ID -会使用 v2 前缀 `claude-ocx2-…` 并转义(`/` → `~s`,`~` → `~t`),例如 -`openrouter/anthropic/claude-opus-4-8` → `claude-ocx2-openrouter--anthropic~sclaude-opus-4-8`。 -v1 别名按字面解码(历史上 model ID 中包含的两字符序列 `~s` / `~t` 会被保留);v2 别名会展开转义。 +**别名语法规则:**provider 不得包含 `/` 或 `--`,也不得等于 `native`。当前 +`claude-ccx2-…` 编码把 `/` 转义为 `~s`、把 `~` 转义为 `~t`,例如 +`openrouter/anthropic/claude-opus-4-8` → `claude-ccx2-openrouter--anthropic~sclaude-opus-4-8`。 易读形式无法表达的路由会回退到哈希别名。模型 ID **可以**包含 `--`(解析时只按第一个 `--` 分割); 含 `--` 的原生 slug 会回退到哈希形式。 @@ -118,11 +104,10 @@ v1 别名按字面解码(历史上 model ID 中包含的两字符序列 `~s` / 2. 系统会注入 `CLAUDE_CODE_AUTO_COMPACT_WINDOW`(默认 `350000`,范围 `100000`–`1000000`), 使对话在该位置自动进行摘要。 -配置有三种状态: +配置有两种状态: - **缺省 / `true`:**启用(默认) - **`false`:**禁用——不添加标记,也不注入压缩窗口 -- **设置了旧版 `maxContextTokens`:**隐式禁用自动上下文 可以在 Claude 页面调整压缩值。**警告:**如果将其提高到超过模型的实际窗口,该模型将无法正常 工作——聊天会在触发摘要之前报错。 @@ -132,36 +117,34 @@ v1 别名按字面解码(历史上 model ID 中包含的两字符序列 `~s` / ### 有效模型环境变量 -`effectiveModelEnv` 会计算由 `ocx claude` / 系统环境 / shell 文件注入的六个槽位: -`ANTHROPIC_MODEL`、四个 `ANTHROPIC_DEFAULT_{OPUS,SONNET,HAIKU,FABLE}_MODEL`,以及旧版 -`ANTHROPIC_SMALL_FAST_MODEL`。有效 Haiku 值为 `tierModels.haiku ?? smallFastModel`,并会 -提供给两个 Haiku 变量。 +`effectiveModelEnv` 会计算由 `ccx claude`、系统环境和 shell 文件注入的两个辅助槽位: +`ANTHROPIC_DEFAULT_HAIKU_MODEL` 与 `ANTHROPIC_SMALL_FAST_MODEL`。两者都使用 +`claudeCode.smallFastModel`。 -当 `tierModels.haiku` 和 `smallFastModel` 均未设置时,OpenCodex 会让两个辅助模型变量保持未设置;随后 Claude Code 会选择其原生辅助模型(目前为 Sonnet),并可能产生原生提供方费用。 +当 `smallFastModel` 未设置时,CodexCommander 会让两个辅助模型变量保持未设置;随后 Claude Code 会选择其原生辅助模型,并可能产生原生提供方费用。 ## 名册代理(injectAgents) -`ocx claude`(以及系统环境守护进程)会把你的精选子代理名册(Subagents 标签页,最多 5 个模型) -和 `ocx-self` 同步到 `~/.claude/agents/ocx-*.md`。 +`ccx claude`(以及系统环境守护进程)会把你的精选子代理名册(Subagents 标签页,最多 5 个模型) +和 `ccx-self` 同步到 `~/.claude/agents/ccx-*.md`。 -- **`ocx-self`** 固定你在 `/model` 选择器中的默认模型(回退到 `claudeCode.model`);两者均 - 不存在时省略。它**不**使用模型继承。 -- 每个代理正文都包含一条 `<!-- ocx-route: <model> -->` 指令——代理使用该指令固定实际路由。 +- **`ccx-self`** 固定你在 `/model` 选择器中的默认模型;没有选择器默认值时省略。它**不**使用模型继承。 +- 每个代理正文都包含一条 `<!-- ccx-route: <model> -->` 指令——代理使用该指令固定实际路由。 因此 Agent 工具的 `model` 参数不起作用;请传入 `"haiku"` 作为占位符。 - Frontmatter 携带别名;路由由指令驱动。 -- 只有包含 `generated-by: opencodex` 且通过标记验证的 `ocx-*.md` 文件才会被覆盖或清理; +- 只有包含 `generated-by: codexcommander` 且通过标记验证的 `ccx-*.md` 文件才会被覆盖或清理; 你自己的代理绝不会被改动。 - 文件按单个文件进行原子同步(写入 + 重命名)。 - `enabled: false` 或 `injectAgents: false` 会清理所有经验证归属的定义。 - GUI PUT 和名册变更会立即重新同步;启动器/系统环境会在启动时同步。 -派发方式:`subagent_type: "ocx-gpt-5-6-sol"`。支持 1M 的目标会自动携带 `[1m]`。 +派发方式:`subagent_type: "ccx-gpt-5-6-sol"`。支持 1M 的目标会自动携带 `[1m]`。 ## 内置技能省略(blockedSkills) Claude Code 内置的 `claude-api` 技能会注入约 840KB(约 136k token)的 Anthropic 文档, 并在提及 Claude 模型时自动触发。已路由模型并未针对该文档包进行训练,因此默认情况下, -opencodex 会在**已路由**请求中将该技能内容替换为一个短占位说明。原生 Anthropic 透传不受影响。 +CodexCommander 会在**已路由**请求中将该技能内容替换为一个短占位说明。原生 Anthropic 透传不受影响。 **会处理两种载体:** @@ -192,7 +175,7 @@ opencodex 会在**已路由**请求中将该技能内容替换为一个短占位 ## Sidecar 矩阵:Web Search 与图像理解 -不同路由模型拥有的托管工具和图像能力并不相同。opencodex 会在主模型回答前补齐这些能力: +不同路由模型拥有的托管工具和图像能力并不相同。CodexCommander 会在主模型回答前补齐这些能力: - **Web-search sidecar** 执行真实的托管搜索,再把答案和来源作为工具结果交给路由模型。 - **Vision sidecar** 在调用 `noVisionModels` 中的模型前描述附件图像,并用文字描述替换图像。 @@ -312,7 +295,7 @@ role;`tool_result` 缺少 `tool_use_id`;`tool_use` 缺少 id/name;指定 ## 调试捕获 -`ocx debug claude on|off|status|reset`、`OCX_CLAUDE_DEBUG=1` 或 +`ccx debug claude on|off|status|reset`、`CCX_CLAUDE_DEBUG=1` 或 `PUT /api/debug {"claude": true}` 控制入站捕获。`GET /api/claude/inbound-debug` 返回 `{enabled, entries}`(最新条目在前,环形缓冲区大小为 20)。 @@ -328,7 +311,7 @@ HMAC 等值标签。**不会存储提示文本、原始对象或跨运行稳定 (标签特意在所有语言中保持一致)。该页面显示: - 入站总开关(启用开关) -- 快速开始(`ocx claude`)和手动环境变量块 +- 快速开始(`ccx claude`)和手动环境变量块 - Fast Mode 选择器(Auto / ON / OFF) - 自动上下文开关和压缩阈值下拉菜单 - 子代理自动注册开关 @@ -343,31 +326,31 @@ context/blocklist/compact-window 值。 **Claude Code 显示“Did 0 searches”**——当前版本会把已完成的 Responses `web_search_call` 转换成配对的 Anthropic `server_tool_use` 和 `web_search_tool_result` block, -并写入 `usage.server_tool_use.web_search_requests`。如果旧版本已经完成搜索却仍计为 0,请更新 -opencodex。 +并写入 `usage.server_tool_use.web_search_requests`。如果搜索已经完成却仍计为 0,请确认当前运行的 +CodexCommander 进程是从当前 checkout 重新构建的。 **Sidecar 未启用**——使用 `backend: "openai"` 时,请确认已登录 ChatGPT,并存在已启用的 `authMode: "forward"` provider。使用 `backend: "anthropic"` 时,请确认已存储的 Anthropic OAuth 活动账户未标记 `needsReauth`。显式选择 Anthropic 却没有可用凭据时会按设计关闭失败。 **“claude.ai connectors are disabled”**——你的 shell 中设置了 `ANTHROPIC_API_KEY` 或 -`ANTHROPIC_AUTH_TOKEN`。`ocx claude` 特意**不会**设置 `ANTHROPIC_API_KEY`;如果你已将其 -导出,请取消设置。`ocx claude` 会注入 `ANTHROPIC_BASE_URL`、发现相关变量、自动上下文和已配置的模型槽位,但绝不会注入 `ANTHROPIC_API_KEY`。 +`ANTHROPIC_AUTH_TOKEN`。`ccx claude` 特意**不会**设置 `ANTHROPIC_API_KEY`;如果你已将其 +导出,请取消设置。`ccx claude` 会注入 `ANTHROPIC_BASE_URL`、发现相关变量、自动上下文和已配置的模型槽位,但绝不会注入 `ANTHROPIC_API_KEY`。 **模型未显示在 /model 选择器中**——确认已设置 -`CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1`(使用 `ocx claude` 时会自动设置)。运行 -`ocx claude` 以刷新 `~/.claude/cache/gateway-models.json` 中的网关模型缓存。检查 +`CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1`(使用 `ccx claude` 时会自动设置)。运行 +`ccx claude` 以刷新 `~/.claude/cache/gateway-models.json` 中的网关模型缓存。检查 `claudeCode.enabled` 不为 `false`。 **端口更改后环境变量过时**——如果代理端口发生变化,旧 shell 中的 -`ANTHROPIC_BASE_URL` 可能已经过时。请打开一个新终端,或重新运行 `ocx claude`。 +`ANTHROPIC_BASE_URL` 可能已经过时。请打开一个新终端,或重新运行 `ccx claude`。 **大模型仍受 200k 上下文上限限制**——在选择器中选择 `[1m]` 变体,或启用自动上下文 (默认开启)。如果选择器中没有 `[1m]` 条目,该模型的权威上下文窗口可能低于自动压缩阈值。 **技能加载导致 token 数量过高**——内置的 `claude-api` 技能(约 136k token)会在提及 -Claude 模型时自动加载。对于原生透传,这是正常现象;对于已路由模型,opencodex 默认会将其 +Claude 模型时自动加载。对于原生透传,这是正常现象;对于已路由模型,CodexCommander 默认会将其 替换为占位说明(`blockedSkills: ["claude-api"]`)。 -**子代理派发到错误模型**——名册代理(`ocx-*`)使用 `<!-- ocx-route: ... -->` 指令, +**子代理派发到错误模型**——名册代理(`ccx-*`)使用 `<!-- ccx-route: ... -->` 指令, 而不是 Agent 工具的 `model` 参数。请确保指令与预期路由一致。传入 `"haiku"` 作为模型占位符。 diff --git a/docs-site/src/content/docs/zh-cn/guides/codex-app-models.md b/docs-site/src/content/docs/zh-cn/guides/codex-app-models.md index 6e6acb4818..9d89126bb0 100644 --- a/docs-site/src/content/docs/zh-cn/guides/codex-app-models.md +++ b/docs-site/src/content/docs/zh-cn/guides/codex-app-models.md @@ -1,11 +1,11 @@ --- title: Codex App 模型选择器 -description: opencodex 中的模型如何通过共享 Codex 目录出现在 Codex App、Codex CLI 和 Codex TUI 中。 +description: CodexCommander 中的模型如何通过共享 Codex 目录出现在 Codex App、Codex CLI 和 Codex TUI 中。 --- -opencodex 不会修改 Codex App。它会写入 Codex CLI/TUI 已经使用的同一套 Codex 配置和模型目录。因为 Codex App 读取的是这份共享状态,路由模型可以像普通 Codex 目录条目一样出现在 App 的模型选择器中。 +CodexCommander 不会修改 Codex App。它会写入 Codex CLI/TUI 已经使用的同一套 Codex 配置和模型目录。因为 Codex App 读取的是这份共享状态,路由模型可以像普通 Codex 目录条目一样出现在 App 的模型选择器中。 -OpenAI 条目有两种凭据通道:原生 Codex 登录,以及命名空间化的 `openai-apikey/<model>` API key 通道。仅在 Pool 与 Direct 之间切换 `codexAccountMode` 不会改变选择器 id。但当 `codexAccountNamespaces` 中有目标账户存在的 selector 时,opencodex 会为映射账户添加独立的 `<selector>/<native-openai-model>` 行,并在选择器中隐藏裸原生行。Selector 名称是用户自定义的公开标签,没有内置的账户角色含义。选择带 `selector` 的行只会使用映射账户,不会更改当前 Pool 账户;目标不可用时,请求会直接失败,不会切换到其他账户。详情请参阅[精确 Codex 账户选择器](/reference/configuration/routing/#exact-codex-account-selectors)。API GPT-5.6 条目使用 1,050,000 context / 922,000 max input,而 `*-pro` 选择器 id 会解析到基础线协议模型,并在日志、用量和选择器状态中保留虚拟 id,同时带上 `reasoning.mode: "pro"`。API 目录固定为恰好八个 id:`gpt-5.5`、`gpt-5.6`、Sol/Terra/Luna,以及它们三个 Pro 虚拟 id;不存在通用的 `gpt-5.6-pro` 别名。Compact 请求会保留所选 tier,但发送基础模型且不带 reasoning 对象。 +OpenAI 条目有两种凭据通道:原生 Codex 登录,以及命名空间化的 `openai-apikey/<model>` API key 通道。仅在 Pool 与 Direct 之间切换 `codexAccountMode` 不会改变选择器 id。但当 `codexAccountNamespaces` 中有目标账户存在的 selector 时,CodexCommander 会为映射账户添加独立的 `<selector>/<native-openai-model>` 行,并在选择器中隐藏裸原生行。Selector 名称是用户自定义的公开标签,没有内置的账户角色含义。选择带 `selector` 的行只会使用映射账户,不会更改当前 Pool 账户;目标不可用时,请求会直接失败,不会切换到其他账户。详情请参阅[精确 Codex 账户选择器](/reference/configuration/routing/#exact-codex-account-selectors)。API GPT-5.6 条目使用 1,050,000 context / 922,000 max input,而 `*-pro` 选择器 id 会解析到基础线协议模型,并在日志、用量和选择器状态中保留虚拟 id,同时带上 `reasoning.mode: "pro"`。API 目录固定为恰好八个 id:`gpt-5.5`、`gpt-5.6`、Sol/Terra/Luna,以及它们三个 Pro 虚拟 id;不存在通用的 `gpt-5.6-pro` 别名。Compact 请求会保留所选 tier,但发送基础模型且不带 reasoning 对象。 请通过选择器 id 显式选择凭据路径。在 Providers 页面切换 Pool/Direct;下面的 `<selector>` 是 用户自定义、通过 `codexAccountNamespaces` 映射的公开标签: @@ -16,21 +16,15 @@ gpt-5.6-sol # 通过 Pool 或 Direct 使用 bare Codex openai-apikey/gpt-5.6-sol # API key ``` -全新安装和没有保存模式的配置默认使用 Pool。当前配置使用 marker 2,并保留随发行版提供的 v1 源文件 `~/.opencodex/config.json.pre-openai-tiers-v2.bak`;可用以下命令恢复: - -```sh -cp ~/.opencodex/config.json.pre-openai-tiers-v2.bak ~/.opencodex/config.json -``` - -更早的 v1 三 provider 配置会自动迁移到这个支持单一选项的行。 +全新安装和没有保存模式的配置默认使用 Pool。 ## 集成路径 -`ocx init`、`ocx start` 和 `ocx sync` 会把共享的 Codex 配置和目录接入代理;有关配置注入、目录同步、shim、WebSocket fallback 和恢复机制,请参见 [Codex Integration](/guides/codex-integration/)。 +`ccx init`、`ccx start` 和 `ccx sync` 会把共享的 Codex 配置和目录接入代理;有关配置注入、目录同步、shim、WebSocket fallback 和恢复机制,请参见 [Codex Integration](/guides/codex-integration/)。 ## 为什么路由模型会显示 -Codex 的模型选择器需要 Codex 形状的目录条目。opencodex 会克隆一个原生 Codex 模型模板,然后替换路由模型的身份: +Codex 的模型选择器需要 Codex 形状的目录条目。CodexCommander 会克隆一个原生 Codex 模型模板,然后替换路由模型的身份: ```text slug = "anthropic/claude-sonnet-..." @@ -38,11 +32,11 @@ display_name = "anthropic/claude-sonnet-..." visibility = "list" ``` -克隆会保留严格解析器字段,例如 reasoning 档位、shell 类型、API 支持标志和 base instructions。随后,opencodex 会移除该路由无法兑现的仅原生能力,包括 OpenAI service-tier 元数据。 +克隆会保留严格解析器字段,例如 reasoning 档位、shell 类型、API 支持标志和 base instructions。随后,CodexCommander 会移除该路由无法兑现的仅原生能力,包括 OpenAI service-tier 元数据。 ## 当前稳定模型覆盖 -原生回退集合包含 `gpt-5.5`、`gpt-5.4`、`gpt-5.4-mini`、`gpt-5.3-codex-spark` 以及 GPT-5.6 Sol/Terra/Luna。对于 GPT-5.5/5.4 家族,opencodex 会保留已安装 Codex 目录中更丰富的实时条目,只在缺失时才合成条目。内置的上游快照只用于 GPT-5.6,因为它提供的是每个模型真实的身份和元数据,而不是较旧模板的近似版本。 +原生回退集合包含 `gpt-5.5`、`gpt-5.4`、`gpt-5.4-mini`、`gpt-5.3-codex-spark` 以及 GPT-5.6 Sol/Terra/Luna。对于 GPT-5.5/5.4 家族,CodexCommander 会保留已安装 Codex 目录中更丰富的实时条目,只在缺失时才合成条目。内置的上游快照只用于 GPT-5.6,因为它提供的是每个模型真实的身份和元数据,而不是较旧模板的近似版本。 | 路由 | 选择器 id 与目录元数据 | | --- | --- | @@ -92,11 +86,11 @@ service_tier = "fast" fast_mode = true ``` -但模型目录和运行时请求里的 tier id 使用的是 `priority`。opencodex 保留了这个拆分。原生 OpenAI 透传模型保留 fast 支持;路由的提供商会按能力门控——只有当提供商声明 `supportsServiceTier: false` 时才会剥离 `service_tier`(注册表已将官方 OpenAI 分类为 `true`,DeepSeek 和 Volcengine Ark 分类为 `false`);未分类的自定义网关会原样保留调用方提供的值且绝不注入,因此无法兑现的 fast 选项不会被展示,自定义网关也可以用 `true` 显式启用。 +但模型目录和运行时请求里的 tier id 使用的是 `priority`。CodexCommander 保留了这个拆分。原生 OpenAI 透传模型保留 fast 支持;路由的提供商会按能力门控——只有当提供商声明 `supportsServiceTier: false` 时才会剥离 `service_tier`(注册表已将官方 OpenAI 分类为 `true`,DeepSeek 和 Volcengine Ark 分类为 `false`);未分类的自定义网关会原样保留调用方提供的值且绝不注入,因此无法兑现的 fast 选项不会被展示,自定义网关也可以用 `true` 显式启用。 ## 子代理选择 -Codex 会按 `priority` 升序对选择器可见的目录条目排序,并把前五个作为 `spawn_agent` 模型 override 暴露出来。仪表盘的 **Agent Command Center** 最多可以选择并保存五个裸原生 id 或路由 `provider/model` id,也会保留已配置的账户限定 `<selector>/<native-openai-model>` id,并报告每个保存项是否实际公开或被排除。opencodex 会按所选顺序分配较低的目录 priority;启用账户 selector 时,裸原生选择会展开为 selector-qualified 分组。其他模型仍然可以通过精确 id 调用。 +Codex 会按 `priority` 升序对选择器可见的目录条目排序,并把前五个作为 `spawn_agent` 模型 override 暴露出来。仪表盘的 **Agent Command Center** 最多可以选择并保存五个裸原生 id 或路由 `provider/model` id,也会保留已配置的账户限定 `<selector>/<native-openai-model>` id,并报告每个保存项是否实际公开或被排除。CodexCommander 会按所选顺序分配较低的目录 priority;启用账户 selector 时,裸原生选择会展开为 selector-qualified 分组。其他模型仍然可以通过精确 id 调用。 Active Roster 与 Dashboard 的 **Sub-agent delegation** 选择彼此独立。它只决定 Codex 先提供哪些 override;它不会自己选择模型,也不会触发委派。 @@ -105,7 +99,7 @@ Active Roster 与 Dashboard 的 **Sub-agent delegation** 选择彼此独立。 如果选择器里仍然显示旧条目,请刷新目录并重启目标 Codex 界面: ```bash -ocx sync +ccx sync ``` -每当目录可见性、priority 或元数据发生变化时,opencodex 都会用一个刻意标记为过期的缓存 wrapper 重写 `models_cache.json`,这样 Codex 下次刷新模型时就会读取新目录。 +每当目录可见性、priority 或元数据发生变化时,CodexCommander 都会用一个刻意标记为过期的缓存 wrapper 重写 `models_cache.json`,这样 Codex 下次刷新模型时就会读取新目录。 diff --git a/docs-site/src/content/docs/zh-cn/guides/codex-integration.md b/docs-site/src/content/docs/zh-cn/guides/codex-integration.md index f77683d1c8..15158cd42e 100644 --- a/docs-site/src/content/docs/zh-cn/guides/codex-integration.md +++ b/docs-site/src/content/docs/zh-cn/guides/codex-integration.md @@ -1,26 +1,25 @@ --- title: Codex 集成 -description: opencodex 如何将自身注入 Codex、同步模型目录、安装 shim,并干净地恢复。 +description: CodexCommander 如何将自身注入 Codex、同步模型目录、安装 shim,并干净地恢复。 --- -opencodex 通过修改 Codex 读取的两样东西,让 Codex 经由 proxy 路由:它的 config +CodexCommander 通过修改 Codex 读取的两样东西,让 Codex 经由 proxy 路由:它的 config (`$CODEX_HOME/config.toml`,默认 `~/.codex/config.toml`)和它的 model catalog。每一次修改都 是幂等且可逆的。 proxy 提供一条裸 `openai` Codex 登录路由,支持 Pool(默认)和 Direct 账号模式,另有 `openai-apikey/<model>` 对应已配置的 API key。Pool 包含主账户加已添加账户;Direct 只使用调用方/ -主 bearer。这些路由之间不会互相 fallback。已发布的 v1 config 会迁移到 marker 2,并保留 -`config.json.pre-openai-tiers-v2.bak` 供手动恢复。 +主 bearer。这些路由之间不会互相 fallback。 ## Config 注入 -`ocx init`、`ocx start` 和 `ocx sync` 都会调用注入器。在默认的 loopback 绑定下,它会保留 -Codex 内置的 `openai` provider id,并将该 provider 指向 opencodex: +`ccx init`、`ccx start` 和 `ccx sync` 都会调用注入器。在默认的 loopback 绑定下,它会保留 +Codex 内置的 `openai` provider id,并将该 provider 指向 CodexCommander: ```toml # root keys, before the first table -model_catalog_json = "/absolute/path/to/opencodex-catalog.json" -# Auto-injected by opencodex +model_catalog_json = "/absolute/path/to/codexcommander-catalog.json" +# Auto-injected by CodexCommander openai_base_url = "http://127.0.0.1:10100/v1" # 仅在设置了 fastMode 时写入;未设置则不会创建 [features] 表 @@ -39,7 +38,7 @@ proxy 默认监听 `10100` 端口,并提供 `POST /v1/responses`、`POST /v1/r Codex 内置的 `image_gen` 工具不会经过 `/v1/responses` —— codex-rs 扩展会直接 POST `{base_url}/images/generations`(附带参考图像时则为 `/images/edits`),并使用它在聊天时相同的 -ChatGPT bearer auth。由于注入的 `base_url` 指向 opencodex,proxy 会把这些调用中继到 OpenAI +ChatGPT bearer auth。由于注入的 `base_url` 指向 CodexCommander,proxy 会把这些调用中继到 OpenAI 上游。 这与 [Image Bridge](/guides/image-bridge/) 是分开的;后者只会在某个 **Responses** 回合列出 @@ -58,7 +57,7 @@ ChatGPT bearer auth。由于注入的 `base_url` 指向 opencodex,proxy 会把 provider 时,`/v1/images/generations`(不是 `/images/edits`)会 fallback 到 Antigravity **Cloud Code Assist** endpoint,并使用 `gemini-3.1-flash-image` 模型。该 fallback 也会在 OpenAI auth 解析失败后触发(例如 ChatGPT 凭据过期或缺失),而不只是没有配置任何 OpenAI 候选时才触发。 - 这需要 `ocx login google-antigravity`;OAuth token 只会发送到固定的 CCA registry host, + 这需要 `ccx login google-antigravity`;OAuth token 只会发送到固定的 CCA registry host, 不会发送到配置级别的 `baseUrl` override。响应会以 Codex 期望的同一 `{created, data:[{b64_json}]}` 形状返回。 - **两者都不是:** proxy 会返回清晰的错误,而不是泛化的 404。路由型 provider(Cursor、Gemini、 @@ -66,9 +65,9 @@ ChatGPT bearer auth。由于注入的 `base_url` 指向 opencodex,proxy 会把 用 `codex features disable image_generation` 关闭它(即 `config.toml` 中 `[features] image_generation = false`)。 -工具声明仍会随模型的 Responses 请求一同发送。对于 API-key Responses provider,opencodex 会把 +工具声明仍会随模型的 Responses 请求一同发送。对于 API-key Responses provider,CodexCommander 会把 Codex 私有的 `image_gen` namespace 降级为上游安全的 `image_gen__<inner-name>` alias(例如 -`image_gen__imagegen`)。当这个可用 alias 取代客户端声明时,opencodex 会移除重复的 hosted +`image_gen__imagegen`)。当这个可用 alias 取代客户端声明时,CodexCommander 会移除重复的 hosted `image_generation` 声明。它会在 Codex 看到之前把函数调用映射回显式的 `image_gen` namespace, 并在之后将历史记录重放到上游时再次编码原生调用。这样即可让客户端侧图像生成在那些保留该 namespace, 或拒绝带点号函数名的公有兼容上游上继续可调用。ChatGPT forward 模式保持不变,并维持其原生 @@ -105,21 +104,21 @@ OpenAI Images 响应形状。provider 配置的 key 会在上游请求前替换 ```toml # root keys -model_provider = "opencodex" -model_catalog_json = "/absolute/path/to/opencodex-catalog.json" +model_provider = "codexcommander" +model_catalog_json = "/absolute/path/to/codexcommander-catalog.json" # appended at the end of the file -# Auto-injected by opencodex -[model_providers.opencodex] -name = "OpenCodex Proxy" +# Auto-injected by CodexCommander +[model_providers.codexcommander] +name = "CodexCommander Proxy" base_url = "http://your-host:10100/v1" wire_api = "responses" requires_openai_auth = true -env_http_headers = { "x-opencodex-api-key" = "OPENCODEX_API_AUTH_TOKEN" } +env_http_headers = { "x-codexcommander-api-key" = "CODEXCOMMANDER_API_AUTH_TOKEN" } # supports_websockets = true # only when config.websockets is true ``` -当 OpenCodex 负责路由时,两种模式都会把 `$CODEX_HOME/opencodex.config.toml` 写成参考/回退配置。 +当 CodexCommander 负责路由时,两种模式都会把 `$CODEX_HOME/codexcommander.config.toml` 写成参考/回退配置。 在 loopback 情况下,它包含可在自动注入被移除后手动合并的 root keys;在非 loopback 情况下, 它包含专用 provider 形式。外部 provider 模式会保持这个 profile 不变。 @@ -131,44 +130,38 @@ env_http_headers = { "x-opencodex-api-key" = "OPENCODEX_API_AUTH_TOKEN" } ## 共享模型目录 -Codex CLI、TUI、App 和 SDK 都读取同一个 Codex home。opencodex 会从 `CODEX_HOME` 解析该目录, +Codex CLI、TUI、App 和 SDK 都读取同一个 Codex home。CodexCommander 会从 `CODEX_HOME` 解析该目录, 回退到 `~/.codex`,并管理: ```text $CODEX_HOME/config.toml -$CODEX_HOME/opencodex.config.toml -$CODEX_HOME/opencodex-catalog.json +$CODEX_HOME/codexcommander.config.toml +$CODEX_HOME/codexcommander-catalog.json $CODEX_HOME/models_cache.json ``` -在 WSL 中,如果未设置 `CODEX_HOME`,且 Linux 侧的 `~/.codex/config.toml` 不存在,opencodex 还会检查 +在 WSL 中,如果未设置 `CODEX_HOME`,且 Linux 侧的 `~/.codex/config.toml` 不存在,CodexCommander 还会检查 `/mnt/c/Users/*/.codex/config.toml` 下是否存在单一的 Windows Codex Desktop home。只要候选项恰好只有一个, 它就会使用那个目录,让 WSL app-server mode 和 Windows Codex Desktop 共享同一份 config 与 auth 文件。 如需覆盖这一检测,请显式设置 `CODEX_HOME`。 在 Windows 上,Orca shell 可能会把 `CODEX_HOME` 和 `ORCA_CODEX_HOME` 都设置为 Orca 打包的 runtime home, -而 ChatGPT/Codex app 仍然读取 `%USERPROFILE%\\.codex`。`ocx status` 和 `ocx doctor` 会提示这个确切的不一致, +而 ChatGPT/Codex app 仍然读取 `%USERPROFILE%\\.codex`。`ccx status` 和 `ccx doctor` 会提示这个确切的不一致, 并打印经过脱敏的目标路径。如果某个后台服务是在那个 Orca shell 中安装的,请先在原始 shell 中卸载它, 然后把 `CODEX_HOME` 设为 app home,取消 `ORCA_CODEX_HOME`,重新运行 sync/restore,再安装一次服务。 在专用 provider 模式下,`requires_openai_auth = true` 会让 Codex App/TUI 中受账号门控的界面与原生 Codex 保持一致。 -opencodex 也会通过 WebSocket 提供 `/v1/responses`。专用 provider 只有在 `"websockets": true` 时才会声明 +CodexCommander 也会通过 WebSocket 提供 `/v1/responses`。专用 provider 只有在 `"websockets": true` 时才会声明 `supports_websockets = true`;在 loopback 情况下,Codex 的内置 provider 可能会先尝试 WebSocket,而关闭的 proxy 会返回 `426`,从而让 Codex fallback 到 HTTP/SSE。 -## 线程标识与历史记录 - -默认的 loopback 形式会让新线程继续标记为 Codex 原生的 `openai` provider,因此正常的 resume history 不需要 -重映射。首次 sync 时,它还会把旧版 opencodex 标记过的线程迁回 `openai`。非 loopback 的专用 provider 模式 -在运行期间仍会把历史记录镜像到 `opencodex` provider 名下,并在退出时恢复已备份的 metadata。 -如需保持历史记录完全不变,请设置 `syncResumeHistory: false`。 - ## 模型目录同步 -Codex 显示的模型来自一个磁盘上的 catalog(默认是 `$CODEX_HOME/opencodex-catalog.json`)。在启动时以及执行 -`ocx sync` 时,opencodex 会: +Codex 显示的模型来自一个磁盘上的 catalog(默认是 `$CODEX_HOME/codexcommander-catalog.json`)。在启动时以及执行 +`ccx sync` 时,CodexCommander 会: -1. **备份**一次干净的 catalog 到 `~/.opencodex/catalog-backup.json`(这样 featuring 是可逆的)。 +1. **备份**一次干净的 catalog 到 `~/.codexcommander/catalog-backup-<catalog-id>.json` + (这样 featuring 是可逆的)。 2. **抓取**符合条件的 provider 的实时模型 catalog(缓存约 5 分钟;失败时先回退到上一个正常列表,再回退到 已配置的 `models[]`)。forward auth 没有模型 endpoint,而 Cursor 使用它自己的 `GetUsableModels` RPC, 不是 `/models`。 @@ -191,44 +184,44 @@ Codex 显示的模型来自一个磁盘上的 catalog(默认是 `$CODEX_HOME/o 可以通过 CLI 添加 display name(proxy 在线时会立即同步 catalog): ```bash -ocx models add deepseek deepseek-v4 --display-name "DeepSeek V4" --context-window 128000 +ccx models add deepseek deepseek-v4 --display-name "DeepSeek V4" --context-window 128000 ``` 远程 Codex 客户端也可以通过管理 API 拉取同一个生成好的 catalog(与其他 `/api/*` 路由使用相同的 admission token): ```bash -dest="${CODEX_HOME:-$HOME/.codex}/opencodex-catalog.json" +dest="${CODEX_HOME:-$HOME/.codex}/codexcommander-catalog.json" tmp="$(mktemp "${dest}.XXXXXX")" -curl -fsS -H "x-opencodex-api-key: $OPENCODEX_ADMIN_AUTH_TOKEN" \ +curl -fsS -H "x-codexcommander-api-key: $CODEXCOMMANDER_ADMIN_AUTH_TOKEN" \ "https://proxy.example.com/api/catalog" > "$tmp" \ && mv "$tmp" "$dest" -ocx sync-cache +ccx sync-cache ``` -响应就是原始的 `opencodex-catalog.json` 文档(不含 provider 凭据)。当可用时, -`x-opencodex-codex-version` header 会报告服务器上的 Codex runtime 版本,方便客户端发现版本偏移。 +响应就是原始的 `codexcommander-catalog.json` 文档(不含 provider 凭据)。当可用时, +`x-codexcommander-codex-version` header 会报告服务器上的 Codex runtime 版本,方便客户端发现版本偏移。 你也可以通过管理 API(`POST /api/custom-models`、带 `displayName` 字符串的 `PUT /api/custom-models/<id>`) 以及 web dashboard 来设置或编辑它。因为会与路由 slug 分隔符冲突,所以 `/` 会被拒绝。 -display name 是 **仅用于显示且在重新生成时保持稳定的**。每一次 `ocx sync` 和 catalog refresh 都会从 +display name 是 **仅用于显示且在重新生成时保持稳定的**。每一次 `ccx sync` 和 catalog refresh 都会从 `config.json`(包括 `customModels`)重新派生路由条目,因此配置过的名称会重新应用,而不是漂回路由 slug。 受管服务重启后也会在 proxy 绑定完成后不久尝试做这次 sync。如果这个尽力而为的启动 sync 失败了,比如在离线登录时, -之前持久化下来的 catalog 会保留,而下一次成功的 `ocx sync` 会重新应用已配置的名称。真实的上游原生名称 +之前持久化下来的 catalog 会保留,而下一次成功的 `ccx sync` 会重新应用已配置的名称。真实的上游原生名称 (例如 `gpt-5.6-sol` → "GPT-5.6-Sol")来自固定的上游快照,绝不会被自定义 display name 覆盖。 ### 外部 provider 管理器 -如果 `config.toml` 已经选择了 `openai` 或 `opencodex` 之外的 provider,OpenCodex 会保持文件不变, -并跳过 profile 写入、catalog/cache 刷新,以及立即和后台两种 Codex 历史迁移。管理自定义 provider 的工具 +如果 `config.toml` 已经选择了 `openai` 或 `codexcommander` 之外的 provider,CodexCommander 会保持文件不变, +并跳过 profile 写入、catalog/cache 刷新和 Codex 历史同步。管理自定义 provider 的工具 通常会把现有会话标记为那个 provider id;如果替换活动 id,Codex 历史视图里那些完整会话可能会消失。 -同样的保护也适用于由旧版 root profile 选择的外部 provider。 +只要外部 provider 处于活动状态,同样的保护就会生效。 -只保留一个工具作为 Codex provider 配置的 owner。若要在现有 provider 管理器之后使用 OpenCodex, +只保留一个工具作为 Codex provider 配置的 owner。若要在现有 provider 管理器之后使用 CodexCommander, 请把那个 provider 指向 `http://127.0.0.1:10100/v1`,并使用 Responses passthrough(Codex TOML 中的 `wire_api = "responses"`),而不是 Chat Completions translation。当启用 proxy API auth 时,也要像上面的非 loopback -provider 形式一样,从 `OPENCODEX_API_AUTH_TOKEN` 传入 `x-opencodex-api-key`。如果要让 OpenCodex 直接注入路由, -请先把 Codex 切回其内置的 `openai` provider,并移除任何用户拥有的 root `openai_base_url`,然后重新运行 `ocx start`。 +provider 形式一样,从 `CODEXCOMMANDER_API_AUTH_TOKEN` 传入 `x-codexcommander-api-key`。如果要让 CodexCommander 直接注入路由, +请先把 Codex 切回其内置的 `openai` provider,并移除任何用户拥有的 root `openai_base_url`,然后重新运行 `ccx start`。 ### 目录排障 @@ -238,38 +231,38 @@ provider 形式一样,从 `OPENCODEX_API_AUTH_TOKEN` 传入 `x-opencodex-api-k 所有发现到的模型。一个不在 allowlist 里的 id 永远不会进入 catalog。 2. **`disabledModels`**(顶层) - 会同时隐藏 catalog 和 `/v1/models` 中的模型,并把裸原生 GPT slug 切成 `visibility: "hide"`。 -3. **`liveModels: false` 且 `models` 为空** - 当 live discovery 关闭而 `models` 为空或省略时,opencodex +3. **`liveModels: false` 且 `models` 为空** - 当 live discovery 关闭而 `models` 为空或省略时,CodexCommander 不会为那个 provider 暴露任何路由模型。 4. **Cursor `GetUsableModels`** - Cursor adapter 通过它的 protobuf `GetUsableModels` RPC 发现模型,而不是 `/models`,所以 Cursor 侧的变动会独立于其他 provider 改变哪些 id 可见。 -5. **缓存和 `ocx sync`** - live catalog 的缓存时间大约是五分钟(`modelCacheTtlMs`,默认 `300000`)。 - 运行 `ocx sync` 可以强制立即重新抓取并重写 catalog。 +5. **缓存和 `ccx sync`** - live catalog 的缓存时间大约是五分钟(`modelCacheTtlMs`,默认 `300000`)。 + 运行 `ccx sync` 可以强制立即重新抓取并重写 catalog。 6. **正在运行的 Codex `app-server`** - 当长生命周期的 Codex `app-server`(Desktop / CLI 后台宿主)还在 - 内存中保留旧列表时,只重写磁盘上的 catalog 还不够。`ocx sync` 和 `ocx sync-cache` 会在检测到这些进程时给出 - 警告。请用 `ocx sync --restart-codex` 重新启动它们(或者你自己停掉匹配的 `app-server` 进程),然后让 Codex + 内存中保留旧列表时,只重写磁盘上的 catalog 还不够。`ccx sync` 和 `ccx sync-cache` 会在检测到这些进程时给出 + 警告。请用 `ccx sync --restart-codex` 重新启动它们(或者你自己停掉匹配的 `app-server` 进程),然后让 Codex 重新创建它们,这样新列表才会出现。 :::caution[其他本地写入者] -在 opencodex 内部,catalog 写入(`opencodex-catalog.json`、`config.toml`)是原子的,这只能防止两个 -opencodex 所有的 writer 竞争时写出半截文件。它**不能**阻止其他本地进程、文件 watcher 或同步 agent 在 -opencodex 写入之后再次改写 catalog 的可见性或顺序。Codex 还有自己独立的 `models_cache.json`,并且可以独立刷新它, -从而在不重写 `opencodex-catalog.json` 的情况下改变可见列表。如果 proxy 正在运行时模型突然翻转,请停掉或重新配置 -竞争中的写入者,然后运行 `ocx sync` —— 这是外部写入者风险,不是已确认的 opencodex 缺陷。 +在 CodexCommander 内部,catalog 写入(`codexcommander-catalog.json`、`config.toml`)是原子的,这只能防止两个 +CodexCommander 所有的 writer 竞争时写出半截文件。它**不能**阻止其他本地进程、文件 watcher 或同步 agent 在 +CodexCommander 写入之后再次改写 catalog 的可见性或顺序。Codex 还有自己独立的 `models_cache.json`,并且可以独立刷新它, +从而在不重写 `codexcommander-catalog.json` 的情况下改变可见列表。如果 proxy 正在运行时模型突然翻转,请停掉或重新配置 +竞争中的写入者,然后运行 `ccx sync` —— 这是外部写入者风险,不是已确认的 CodexCommander 缺陷。 ::: ## Proxy 连接错误 如果 Codex 重试后报出类似 `stream disconnected before completion: error sending request for url (http://127.0.0.1:10100/v1/responses)` -的错误——或者 Claude Code 报告类似的连接失败——说明 opencodex proxy 没有在运行: +的错误——或者 Claude Code 报告类似的连接失败——说明 CodexCommander proxy 没有在运行: 配置端口上没有任何监听,所以客户端只能自己渲染出那条原始连接错误。重启 proxy: ```bash -ocx start # foreground -ocx service install # persistent: auto-starts on login and respawns on crash +ccx start # foreground +ccx service install # persistent: auto-starts on login and respawns on crash ``` -`ocx status` 会显示 proxy 是否在运行,并在未运行时打印相同的重启提示;`ocx doctor` 会报告 +`ccx status` 会显示 proxy 是否在运行,并在未运行时打印相同的重启提示;`ccx doctor` 会报告 重启安全性(service/shim 覆盖情况)。 ## sub-agent 选择器 @@ -280,7 +273,7 @@ fallback 行为,参见 [Sub-agent Surface](/guides/sub-agent-surface/)。 ## Codex 账号预热 -当把一个 ChatGPT 账号加入 Codex 账号池时,opencodex 会在持久化前向 Codex Responses backend +当把一个 ChatGPT 账号加入 Codex 账号池时,CodexCommander 会在持久化前向 Codex Responses backend 发送一个小型 streaming 请求来验证它。该请求使用真正的 Responses item 数组 (`input: [{ type: "message", ... }]`),等待 `response.completed`,并默认使用 `gpt-5.4-mini`。 如果该模型返回 HTTP 400,则会改用 `gpt-5.5` 重试;结构化的上游错误详情会被展示给用户,但不会暴露 @@ -289,16 +282,16 @@ fallback 行为,参见 [Sub-agent Surface](/guides/sub-agent-surface/)。 ## 恢复原生 Codex -opencodex 绝不会把你困住。**`ocx stop` 是完全恢复原生 Codex 的单一命令** —— 它会停止 proxy、 -停止后台服务(如已安装),并剥除所有注入的行和路由的目录条目,使普通的 `codex` 完全像 opencodex +CodexCommander 绝不会把你困住。**`ccx stop` 是完全恢复原生 Codex 的单一命令** —— 它会停止 proxy、 +停止后台服务(如已安装),并剥除所有注入的行和路由的目录条目,使普通的 `codex` 完全像 CodexCommander 从未存在过一样工作: ```bash -ocx stop # stop the proxy + service, restore native Codex -ocx restore # restore without stopping (alias: ocx eject) -ocx restore back # point plain Codex at the running proxy again +ccx stop # stop the proxy + service, restore native Codex +ccx restore # restore without stopping (alias: ccx eject) +ccx restore back # point plain Codex at the running proxy again ``` -当 opencodex 作为受管的 [background service](/reference/cli/#ocx-service) 运行时,它会设置 -`OCX_SERVICE=1`,这样由服务驱动的重启**不会**反复改写 Codex config——只有显式的 -`ocx stop` / `ocx service stop` 才会恢复原生 Codex。 +当 CodexCommander 作为受管的 [background service](/reference/cli/#ccx-service) 运行时,它会设置 +`CCX_SERVICE=1`,这样由服务驱动的重启**不会**反复改写 Codex config——只有显式的 +`ccx stop` / `ccx service stop` 才会恢复原生 Codex。 diff --git a/docs-site/src/content/docs/zh-cn/guides/combos.md b/docs-site/src/content/docs/zh-cn/guides/combos.md index 44b161321d..ae46e84a10 100644 --- a/docs-site/src/content/docs/zh-cn/guides/combos.md +++ b/docs-site/src/content/docs/zh-cn/guides/combos.md @@ -3,7 +3,7 @@ title: "组合:故障切换与负载均衡" description: 将一个虚拟模型路由到多个 provider,用于故障切换或加权负载均衡。 --- -**combo** 是一个虚拟模型,它前置了一组按顺序排列的真实 provider/model 目标。你的客户端请求 `combo/<id>`;opencodex 会选择一个目标,将请求重写为那个具体的 `provider/model`,并且在第一个目标出现可重试失败时,可以改试另一个目标。 +**combo** 是一个虚拟模型,它前置了一组按顺序排列的真实 provider/model 目标。你的客户端请求 `combo/<id>`;CodexCommander 会选择一个目标,将请求重写为那个具体的 `provider/model`,并且在第一个目标出现可重试失败时,可以改试另一个目标。 这在以下场景很有用: @@ -17,10 +17,10 @@ combo 位于正常 provider 路由之前。如果你还不熟悉 `provider/model 这个示例创建 `combo/main`,Anthropic 在前,OpenAI 在后。两个 provider 都必须已经存在并启用。 ```bash -ocx combo set main --targets anthropic/claude-opus-4-8,openai/gpt-5.6-sol +ccx combo set main --targets anthropic/claude-opus-4-8,openai/gpt-5.6-sol ``` -默认策略是故障切换,所以正常请求会发往 `anthropic/claude-opus-4-8`。如果这次尝试出现可重试失败,opencodex 可以切换到 `openai/gpt-5.6-sol`。 +默认策略是故障切换,所以正常请求会发往 `anthropic/claude-opus-4-8`。如果这次尝试出现可重试失败,CodexCommander 可以切换到 `openai/gpt-5.6-sol`。 在任何你通常会提供模型 id 的地方,都可以使用这个虚拟模型: @@ -34,7 +34,7 @@ ocx combo set main --targets anthropic/claude-opus-4-8,openai/gpt-5.6-sol 确认已保存的定义: ```bash -ocx combo show main +ccx combo show main ``` :::tip @@ -43,7 +43,7 @@ ocx combo show main ## combo 名称的工作方式 -`ocx combo set <id>` 中的 combo id 必须以字母或数字开头。之后可以包含字母、数字、`.`、`_` 或 `-`,总长度最多 64 个字符。其规范模型 id 始终是 `combo/<id>`;例如,id `main` 会变成 `combo/main`。 +`ccx combo set <id>` 中的 combo id 必须以字母或数字开头。之后可以包含字母、数字、`.`、`_` 或 `-`,总长度最多 64 个字符。其规范模型 id 始终是 `combo/<id>`;例如,id `main` 会变成 `combo/main`。 在配置 combo 时,`combo/` 命名空间是保留的。名为 `combo` 的 provider 不能占用它,而 combo id 也不能与已配置的 provider 名称重复。 @@ -82,7 +82,7 @@ ocx combo show main 创建一个 2:1 的 combo,并让每批包含两个成功请求: ```bash -ocx combo set balanced \ +ccx combo set balanced \ --targets anthropic/claude-opus-4-8:2,openai/gpt-5.6-sol:1 \ --strategy round-robin \ --sticky 2 @@ -111,7 +111,7 @@ combo 失败分为 **跳转** 失败和 **终止** 失败。 | 客户端取消(499)、`origin_rejected`、cyber-policy 拒绝、上下文溢出,或无效请求 | 停止并返回错误;换其他目标也无法让请求变得有效。 | | 任何其他未分类错误 | 停止并返回错误。 | -被跳过的目标默认会进入 60 秒冷却。如果上游响应包含有效的 `Retry-After` 值,opencodex 会改用该值。数字秒数和 HTTP-date 值都可以接受,而且每次冷却最多只会封顶到 10 分钟。 +被跳过的目标默认会进入 60 秒冷却。如果上游响应包含有效的 `Retry-After` 值,CodexCommander 会改用该值。数字秒数和 HTTP-date 值都可以接受,而且每次冷却最多只会封顶到 10 分钟。 当前请求不会再次重试同一个已经尝试过的目标。后续请求会跳过它,直到冷却结束。如果没有任何合格目标可用,代理会返回 HTTP 503,并带上 `error.code = "combo_unavailable"`。 @@ -127,15 +127,15 @@ combo 失败分为 **跳转** 失败和 **终止** 失败。 2. 调用方没有设置 effort;并且 3. 选中的目标目录明确声明了该精确的 effort。 -如果请求没有 `reasoning` 对象,opencodex 会创建一个。如果 `reasoning` 存在但没有 `effort` 属性,它会保留其他字段并添加默认值。调用方提供的 effort 永远不会被覆盖。 +如果请求没有 `reasoning` 对象,CodexCommander 会创建一个。如果 `reasoning` 存在但没有 `effort` 属性,它会保留其他字段并添加默认值。调用方提供的 effort 永远不会被覆盖。 -当目标能力未知,或者不包含配置的 effort 时,opencodex 会省略默认值,并保持目标自身行为不变。支持的值是 `low`、`medium`、`high`、`xhigh`、`max` 和 `ultra`;省略该字段或将其设为 `null`,就会把 effort 完全交给调用方和目标。 +当目标能力未知,或者不包含配置的 effort 时,CodexCommander 会省略默认值,并保持目标自身行为不变。支持的值是 `low`、`medium`、`high`、`xhigh`、`max` 和 `ultra`;省略该字段或将其设为 `null`,就会把 effort 完全交给调用方和目标。 ## 加密的 v2 子代理任务 -对于 Codex v2 子代理,有一个重要限制([issue #92](https://github.com/lidge-jun/opencodex/issues/92))。原生父进程只能把新启动 worker 的任务,以为原生 ChatGPT 后端生成的密文形式发送出去。外部 provider 无法读取那段负载。 +对于 Codex v2 子代理,有一个重要限制([issue #92](https://github.com/pavelhov/CodexCommander/issues/92))。原生父进程只能把新启动 worker 的任务,以为原生 ChatGPT 后端生成的密文形式发送出去。外部 provider 无法读取那段负载。 -对于这类请求,combo 会把合格目标筛选为规范的原生 ChatGPT 路由,即使在一次可重试失败之后也是如此。如果 combo 没有任何具备解密能力的目标,opencodex 会在分发前停止,并返回 HTTP 400: +对于这类请求,combo 会把合格目标筛选为规范的原生 ChatGPT 路由,即使在一次可重试失败之后也是如此。如果 combo 没有任何具备解密能力的目标,CodexCommander 会在分发前停止,并返回 HTTP 400: ```json { @@ -168,13 +168,13 @@ combo 失败分为 **跳转** 失败和 **终止** 失败。 主要命令如下: ```bash -ocx combo list -ocx combo show <id> -ocx combo set <id> --targets provider/model[:weight],... -ocx combo remove <id> --yes +ccx combo list +ccx combo show <id> +ccx combo set <id> --targets provider/model[:weight],... +ccx combo remove <id> --yes ``` -`set` 也接受 `--strategy`、`--sticky`、`--effort`、`--alias` 和 `--rename-from`。将 `--effort` 或 `--alias` 的值设为 `-` 可清除该字段。`create` 和 `update` 是 `set` 的别名;`delete` 是 `remove` 的别名;同样的子命令也可通过 `ocx route combo` 使用。 +`set` 也接受 `--strategy`、`--sticky`、`--effort`、`--alias` 和 `--rename-from`。将 `--effort` 或 `--alias` 的值设为 `-` 可清除该字段。`create` 和 `update` 是 `set` 的别名;`delete` 是 `remove` 的别名;同样的子命令也可通过 `ccx route combo` 使用。 ### Management API @@ -216,7 +216,7 @@ combo 会存储在顶层的 `combos` 对象中,并以 combo id 作为键: ### 为什么 `combo/<id>` 会返回 404? -combo id 不存在。响应是 HTTP 404,类型为 `invalid_request_error`。运行 `ocx combo list`,检查拼写和大小写,并确认你的管理命令写入的是同一个正在运行、并接收模型请求的 opencodex 实例。 +combo id 不存在。响应是 HTTP 404,类型为 `invalid_request_error`。运行 `ccx combo list`,检查拼写和大小写,并确认你的管理命令写入的是同一个正在运行、并接收模型请求的 CodexCommander 实例。 ### 为什么会收到 `combo_unavailable`? diff --git a/docs-site/src/content/docs/zh-cn/guides/grok-build.md b/docs-site/src/content/docs/zh-cn/guides/grok-build.md index 5e014c851e..44d6618d36 100644 --- a/docs-site/src/content/docs/zh-cn/guides/grok-build.md +++ b/docs-site/src/content/docs/zh-cn/guides/grok-build.md @@ -1,69 +1,69 @@ --- title: Grok Build -description: 在 xAI 的 Grok Build CLI 中使用任何由 opencodex 路由的模型——在代理运行期间,模型会自动注册到 ~/.grok/config.toml。 +description: 在 xAI 的 Grok Build CLI 中使用任何由 CodexCommander 路由的模型——在代理运行期间,模型会自动注册到 ~/.grok/config.toml。 --- -opencodex 在本地端口提供一个与 OpenAI 兼容的 `POST /v1/chat/completions`(以及 `/v1/responses`),而 Grok Build 支持针对与 OpenAI 兼容的服务器使用自定义模型。从这次集成开始,opencodex 会将其全部可见目录自动注册到 Grok Build 中,无需手动编辑配置。 +CodexCommander 在本地端口提供一个与 OpenAI 兼容的 `POST /v1/chat/completions`(以及 `/v1/responses`),而 Grok Build 支持针对与 OpenAI 兼容的服务器使用自定义模型。从这次集成开始,CodexCommander 会将其全部可见目录自动注册到 Grok Build 中,无需手动编辑配置。 ## 自动注册 -当 `~/.grok` 存在时,`ocx start`(以及 `ocx ensure` / `ocx restart`)会向 `~/.grok/config.toml` 写入一个受管理的区块: +当 `~/.grok` 存在时,`ccx start`(以及 `ccx ensure` / `ccx restart`)会向 `~/.grok/config.toml` 写入一个受管理的区块: ```toml -# >>> opencodex managed block — do not edit (removed by `ocx stop`) >>> -[model.ocx-gpt-5-6-sol] +# >>> CodexCommander managed block — do not edit (removed by `ccx stop`) >>> +[model.ccx-gpt-5-6-sol] model = "gpt-5.6-sol" base_url = "http://127.0.0.1:10100/v1" api_backend = "chat_completions" -api_key = "opencodex-loopback" -name = "OCX gpt-5.6-sol" -# ... one [model.ocx-*] table per visible model ... -# <<< opencodex managed block <<< +api_key = "codexcommander-loopback" +name = "CodexCommander gpt-5.6-sol" +# ... one [model.ccx-*] table per visible model ... +# <<< CodexCommander managed block <<< ``` -- **增量式:** 受边界线之外的你自己的配置不会被触碰。首次向已存在文件注入之前,会先写入一次性备份到 `~/.grok/config.toml.bak-opencodex`。 -- **幂等:** 每次 `ocx start`(以及在启用自动启动时的 `ocx ensure`)都会用当前目录替换这段有边界线的区块。 -- **卸载时移除:** `ocx stop`、`ocx eject`、`ocx uninstall`,以及非服务模式下的守护进程正常关闭,都会删除这段有边界线的区块,并将你的文件逐字节恢复。若在服务管理器下运行,卸载流程会通过 `ocx stop`/`ocx uninstall` 进行(服务模式进程会刻意在重启后保留该区块)。 -- **冲突安全:** 你自己的 `[model.*]` 表中已经定义过的别名会被保留(opencodex 会为自己的条目追加后缀);受损的边界线(有起始标记但没有结束标记)会拒绝任何自动变更,并要求手动修复。 +- **增量式:** 受边界线之外的你自己的配置不会被触碰。首次向已存在文件注入之前,会先写入一次性备份到 `~/.grok/config.toml.bak-codexcommander`。 +- **幂等:** 每次 `ccx start`(以及在启用自动启动时的 `ccx ensure`)都会用当前目录替换这段有边界线的区块。 +- **卸载时移除:** `ccx stop`、`ccx eject`、`ccx uninstall`,以及非服务模式下的守护进程正常关闭,都会删除这段有边界线的区块,并将你的文件逐字节恢复。若在服务管理器下运行,卸载流程会通过 `ccx stop`/`ccx uninstall` 进行(服务模式进程会刻意在重启后保留该区块)。 +- **冲突安全:** 你自己的 `[model.*]` 表中已经定义过的别名会被保留(CodexCommander 会为自己的条目追加后缀);受损的边界线(有起始标记但没有结束标记)会拒绝任何自动变更,并要求手动修复。 然后在 Grok Build 中选择一个模型: ```bash -grok models # lists ocx-* entries alongside native grok models -grok -m ocx-anthropic-claude-opus-4-8 -p "hello" -# or in the TUI: /model ocx-anthropic-claude-opus-4-8 +grok models # lists ccx-* entries alongside native grok models +grok -m ccx-anthropic-claude-opus-4-8 -p "hello" +# or in the TUI: /model ccx-anthropic-claude-opus-4-8 ``` ## 认证说明 -即使在 loopback 上,Grok Build 对自定义模型也要求一个非空 API key。注入的条目携带的是占位符(`opencodex-loopback`)——opencodex 会忽略 loopback 连接的接入密钥,因此这里不涉及任何真实机密。 +即使在 loopback 上,Grok Build 对自定义模型也要求一个非空 API key。注入的条目携带的是占位符(`codexcommander-loopback`)——CodexCommander 会忽略 loopback 连接的接入密钥,因此这里不涉及任何真实机密。 -**自动注册仅限 loopback。** 当 opencodex 绑定到非 loopback 主机时——包括通配符 `0.0.0.0` 和 `::`,它们会暴露所有网卡——请求需要你的真实接入令牌,而受管理区块无法安全地携带它。把字面令牌写进去会把你的密钥放进 `~/.grok/config.toml`,并在下次 `ocx start`/`ensure`/`restart` 时覆盖你在那里设置的内容。所以在这种情况下,opencodex 根本不会写入任何内容(并且会移除早先 loopback 绑定留下的任何区块),然后你需要在受管理标记之外自己配置这些模型,因为 opencodex 在那里做的任何事都不会覆盖它们。精确表结构见[手动方案](#manual-recipe-without-auto-registration),并同时设置 `base_url`(从你运行 `grok` 的位置实际可达的主机)和 `api_key`(你的 `OPENCODEX_API_AUTH_TOKEN`)。 +**自动注册仅限 loopback。** 当 CodexCommander 绑定到非 loopback 主机时——包括通配符 `0.0.0.0` 和 `::`,它们会暴露所有网卡——请求需要你的真实接入令牌,而受管理区块无法安全地携带它。把字面令牌写进去会把你的密钥放进 `~/.grok/config.toml`,并在下次 `ccx start`/`ensure`/`restart` 时覆盖你在那里设置的内容。所以在这种情况下,CodexCommander 根本不会写入任何内容(并且会移除早先 loopback 绑定留下的任何区块),然后你需要在受管理标记之外自己配置这些模型,因为 CodexCommander 在那里做的任何事都不会覆盖它们。精确表结构见[手动方案](#manual-recipe-without-auto-registration),并同时设置 `base_url`(从你运行 `grok` 的位置实际可达的主机)和 `api_key`(你的 `CODEXCOMMANDER_API_AUTH_TOKEN`)。 不要在这里把 `api_key` 换成 `env_key`。在未设置 `model_provider` 的情况下,解析失败的 `env_key` 不会阻止请求——Grok 会回退到你的 xAI 会话令牌,并把它发送到该条目指定的 `base_url`,而对于局域网部署来说,这通常是一个并非 xAI 的明文 HTTP 端点。 -这些模型注入的逐模型 `api_key` 会在 Grok 的凭据链中排在首位,因此对接 opencodex 时不需要额外登录 Grok。原生 grok 模型以及任何会直接联系 xAI 的 harness 功能,仍然保留你正常的 `grok login` / `XAI_API_KEY` 配置。 +这些模型注入的逐模型 `api_key` 会在 Grok 的凭据链中排在首位,因此对接 CodexCommander 时不需要额外登录 Grok。原生 grok 模型以及任何会直接联系 xAI 的 harness 功能,仍然保留你正常的 `grok login` / `XAI_API_KEY` 配置。 ## 手动方案(不使用自动注册) -如果你自己管理 `~/.grok/config.toml`——或者 opencodex 绑定在非 loopback 地址上——请在 `# >>> opencodex managed block` 标记之外,添加带有**直接字段**的逐模型表: +如果你自己管理 `~/.grok/config.toml`——或者 CodexCommander 绑定在非 loopback 地址上——请在 `# >>> CodexCommander managed block` 标记之外,添加带有**直接字段**的逐模型表: ```toml -[model.ocx-opus] +[model.ccx-opus] model = "anthropic/claude-opus-4-8" base_url = "http://127.0.0.1:10100/v1" api_backend = "chat_completions" -api_key = "opencodex-loopback" +api_key = "codexcommander-loopback" ``` 如果代理可通过网络访问,请把 `base_url` 指向 `grok` 实际可以连接的地址,并使用你的接入令牌: ```toml -[model.ocx-opus] +[model.ccx-opus] model = "anthropic/claude-opus-4-8" base_url = "http://192.168.1.10:10100/v1" # the reachable host, not 127.0.0.1 api_backend = "chat_completions" -api_key = "your-OPENCODEX_API_AUTH_TOKEN" +api_key = "your-CODEXCOMMANDER_API_AUTH_TOKEN" ``` 不要依赖 `[model_providers.<id>]` 继承来提供端点:截至 Grok Build 0.2.101,继承下来的 `base_url` 不会应用到推理路由(请求会落回默认的 xAI 代理,并以 401 失败)。直接在逐模型字段中配置可以正确路由。 @@ -72,7 +72,7 @@ api_key = "your-OPENCODEX_API_AUTH_TOKEN" ## 已知限制 -- **Responses 后端与保活:** opencodex 在 `/v1/responses` 流上、上游静默期间会发送 `response.heartbeat` 保活事件。Grok Build 的 Responses 解码器会拒绝未知事件类型,因此手动配置为 `api_backend = "responses"` 的模型在上游较慢时可能会在对话中途失败。自动注册的条目会固定为 `api_backend = "chat_completions"`,这样就不会暴露原始的心跳帧。 -- **服务安装后的 `ocx restart`:** 当 opencodex 运行在服务管理器下时,`ocx restart` 目前会停止该服务,并将其替换为一个非受管进程——服务持久化能力(自动重启、登录时启动)会丢失,直到下一次 `ocx service` 设置完成;如果这个非受管进程退出,受管理区块可能会指向一个已失效的代理,直到下一次 `ocx start`/`ocx ensure` 刷新它。 -- **配置读取时机:** 先启动 opencodex,再启动 `grok`,结果最可预测。Grok Build 会监视 `~/.grok/config.toml`,并在 `[model]` 表实际发生变化时重新加载(大约一秒的防抖,按内容比较),因此刷新后的区块可以在无需重启的情况下进入已打开的会话。要确认 Grok 解析到了什么,可以运行 `grok inspect`:它会列出已加载的配置来源,并提示被拒绝的字段,但不会打印最终解析出的模型列表。注意,单个 TOML 错误会使*整个*用户配置层失效,这也是 opencodex 以原子方式写入文件的原因——Grok 不会看到半写入的配置。 -- **目录更新:** 有边界线的区块反映的是注入时的目录状态。添加提供方或模型后,运行 `ocx ensure`(或重启代理)以刷新它。 +- **Responses 后端与保活:** CodexCommander 在 `/v1/responses` 流上、上游静默期间会发送 `response.heartbeat` 保活事件。Grok Build 的 Responses 解码器会拒绝未知事件类型,因此手动配置为 `api_backend = "responses"` 的模型在上游较慢时可能会在对话中途失败。自动注册的条目会固定为 `api_backend = "chat_completions"`,这样就不会暴露原始的心跳帧。 +- **服务安装后的 `ccx restart`:** 当 CodexCommander 运行在服务管理器下时,`ccx restart` 目前会停止该服务,并将其替换为一个非受管进程——服务持久化能力(自动重启、登录时启动)会丢失,直到下一次 `ccx service` 设置完成;如果这个非受管进程退出,受管理区块可能会指向一个已失效的代理,直到下一次 `ccx start`/`ccx ensure` 刷新它。 +- **配置读取时机:** 先启动 CodexCommander,再启动 `grok`,结果最可预测。Grok Build 会监视 `~/.grok/config.toml`,并在 `[model]` 表实际发生变化时重新加载(大约一秒的防抖,按内容比较),因此刷新后的区块可以在无需重启的情况下进入已打开的会话。要确认 Grok 解析到了什么,可以运行 `grok inspect`:它会列出已加载的配置来源,并提示被拒绝的字段,但不会打印最终解析出的模型列表。注意,单个 TOML 错误会使*整个*用户配置层失效,这也是 CodexCommander 以原子方式写入文件的原因——Grok 不会看到半写入的配置。 +- **目录更新:** 有边界线的区块反映的是注入时的目录状态。添加提供方或模型后,运行 `ccx ensure`(或重启代理)以刷新它。 diff --git a/docs-site/src/content/docs/zh-cn/guides/image-bridge.md b/docs-site/src/content/docs/zh-cn/guides/image-bridge.md index 71a4d3d3dd..a4dcfd16f4 100644 --- a/docs-site/src/content/docs/zh-cn/guides/image-bridge.md +++ b/docs-site/src/content/docs/zh-cn/guides/image-bridge.md @@ -10,7 +10,7 @@ description: 在使用非 OpenAI 提供方时,将 image_generation 托管工 ## 前提条件 - **启用桥接**:在配置中设置 `images.bridgeEnabled: true`(默认关闭,以避免意外产生 xAI 费用 - 见下文的 [配置](#configuration))。 -- 配置一个带有 **API 密钥** 的 `xai` provider 条目。桥接会将执行固定到注册表中的 xAI Images 端点(`https://api.x.ai/v1`);任何已配置的 `baseUrl` 覆盖都会被图像调用忽略。仅有 OAuth / `ocx login xai` **不会** 让桥接生效(Grok CLI 的 OAuth 传输是面向聊天的,不用于 `/images/*`)。 +- 配置一个带有 **API 密钥** 的 `xai` provider 条目。桥接会将执行固定到注册表中的 xAI Images 端点(`https://api.x.ai/v1`);任何已配置的 `baseUrl` 覆盖都会被图像调用忽略。仅有 OAuth / `ccx login xai` **不会** 让桥接生效(Grok CLI 的 OAuth 传输是面向聊天的,不用于 `/images/*`)。 ```json { @@ -24,7 +24,7 @@ description: 在使用非 OpenAI 提供方时,将 image_generation 托管工 ## 配置 -Image Bridge 的选项位于 `~/.opencodex/config.json` 的 `images` 下。桥接是 **显式启用** 的 - 你必须设置 `bridgeEnabled: true` 才会启用付费的 xAI Grok Imagine 生成能力: +Image Bridge 的选项位于 `~/.codexcommander/config.json` 的 `images` 下。桥接是 **显式启用** 的 - 你必须设置 `bridgeEnabled: true` 才会启用付费的 xAI Grok Imagine 生成能力: ```json { @@ -47,16 +47,16 @@ Image Bridge 的选项位于 `~/.opencodex/config.json` 的 `images` 下。桥 ## 产物保留 -生成的图像会写入 `~/.opencodex/artifacts/`。为了避免长期运行的会话中磁盘无限增长,目录会在每次完成的图像调用之后自动清理(也就是该调用的整批文件都已落盘之后) - 当文件数超过配置的最大值时,会删除最旧的文件(按修改时间排序)(默认 200,可通过 `images.artifactsKeepCount` 配置)。只有在清理后仍然保留的路径才会返回给模型。 +生成的图像会写入 `~/.codexcommander/artifacts/`。为了避免长期运行的会话中磁盘无限增长,目录会在每次完成的图像调用之后自动清理(也就是该调用的整批文件都已落盘之后) - 当文件数超过配置的最大值时,会删除最旧的文件(按修改时间排序)(默认 200,可通过 `images.artifactsKeepCount` 配置)。只有在清理后仍然保留的路径才会返回给模型。 ## 工作原理 Image Bridge 只会在 **Responses** 回合中生效,且仅当 `/v1/responses` 的 `tools` 数组里包含托管的 `image_generation` 工具,并且当前选择的是 **非 OpenAI** 模型时才会激活。它**不会**拦截 Codex 内置的 `image_gen` 工具,因为后者会直接 POST 到 `/v1/images/generations`(或 `/images/edits`) - 这条路径在 [Codex 集成](/guides/codex-integration/#built-in-image-generation-image_gen) 中单独覆盖。 -1. 当某个 Responses 请求在 `tools` 中列出 `image_generation` 时,OpenCodex 会在请求预处理阶段检测到它。 +1. 当某个 Responses 请求在 `tools` 中列出 `image_generation` 时,CodexCommander 会在请求预处理阶段检测到它。 2. 托管工具会被替换为一个 **合成函数工具**,路由后的模型可以像正常工具一样调用它 - 模型看到的是一个可调用工具,而不是一个自己无法执行的、不可见的托管工具。 -3. 当模型调用该工具时,OpenCodex 会拦截这次调用,并将提示词发送到 xAI 的图像生成 API。 -4. 生成的图像会保存到 `~/.opencodex/artifacts/`,并将 **本地文件路径** 作为工具结果返回给模型。 +3. 当模型调用该工具时,CodexCommander 会拦截这次调用,并将提示词发送到 xAI 的图像生成 API。 +4. 生成的图像会保存到 `~/.codexcommander/artifacts/`,并将 **本地文件路径** 作为工具结果返回给模型。 5. 模型随后会在了解生成图像及其位置的情况下继续对话。 从模型视角看,一切都没有变化 - 它调用了一个工具并拿到了结果。从用户视角看,图像生成可以在任何被路由的 provider 上正常工作,而不会悄然失败。 diff --git a/docs-site/src/content/docs/zh-cn/guides/macos-menu-bar.md b/docs-site/src/content/docs/zh-cn/guides/macos-menu-bar.md index b9b2c1c16a..1101b48aab 100644 --- a/docs-site/src/content/docs/zh-cn/guides/macos-menu-bar.md +++ b/docs-site/src/content/docs/zh-cn/guides/macos-menu-bar.md @@ -1,50 +1,32 @@ --- title: macOS 菜单栏伴侣 -description: 安装并使用原生 OpenCodex 状态、智能体活动和提供商配额伴侣。 +description: 安装并使用原生 CodexCommander 状态、智能体活动和提供商配额伴侣。 --- -macOS 伴侣会在菜单栏中显示最有用的 OpenCodex 状态,同时不会取代代理或重复实现 Web -控制面板。它是一款原生 Swift/AppKit 应用程序,并且只与同一台 Mac 上运行的 OpenCodex +macOS 伴侣会在菜单栏中显示最有用的 CodexCommander 状态,同时不会取代代理或重复实现 Web +控制面板。它是一款原生 Swift/AppKit 应用程序,并且只与同一台 Mac 上运行的 CodexCommander 实例通信。 ## 安装 -1. 从对应的 GitHub 发行版下载 <code>OpenCodex-<version>-macos-universal.zip</code> 及其 - <code>.sha256</code> 文件。 -2. 验证归档文件: - - shasum -a 256 -c OpenCodex-<version>-macos-universal.zip.sha256 - -3. 解压,然后将 <code>OpenCodex.app</code> 移到**应用程序**。 -4. 打开该应用。应用已包含 Bun 运行时、代理、生产依赖和仪表板资源,因此无需另行安装 npm、Bun 或 - <code>ocx</code>。其图标会出现在菜单栏中;它不会添加 Dock 图标。从稳定位置首次启动时会启用 - **Launch at Login**。 - -内置运行时继续使用现有用户状态 <code>~/.opencodex</code> 和 <code>~/.codex</code>,不会将凭据复制到 -应用包或 Keychain。提供商 OAuth 和 API 密钥仍在本地仪表板中配置。 - -在发行版使用 Developer ID 签名并完成公证之前,macOS 可能会阻止首次启动下载的应用。按住 -Control 键点按该应用,选择**打开**,然后确认**打开**。本地构建不会带有下载文件的隔离属性。 - -内置运行时为只读。更新时应替换为最新签名的 <code>OpenCodex.app</code>;npm、Bun 或源码更新不会 -修改已签名的 <code>Contents/Resources</code>。 +目前没有已发布的 macOS 打包应用。请按照[从源代码构建](#从源代码构建)的步骤从现有检出目录运行。开发应用应保留在 `dist/macos/CodexCommander.app`,不要复制到 Application Support。 ## 启动模式 - **Desktop** — 登录时打开菜单栏应用,并连接或启动唯一一个服务器。 -- **Headless** — 不打开菜单栏应用,只启动另行安装的 `ocx service`。 -- **Off** — 不自动启动;手动打开应用或运行 `ocx start`。 +- **Headless** — 不打开菜单栏应用,只启动另行安装的 `ccx service`。 +- **Off** — 不自动启动;手动打开应用或运行 `ccx start`。 可在启动行切换 **Launch at Login**。如果需要批准,应用会直接打开 macOS Login Items 设置。 此开关不会安装、停止或删除后台服务。 -可见应用与后台代理相互独立。当 OpenCodex 面板处于活动状态时,**Quit Menu Bar**(`⌘Q`)只关闭伴侣 UI,并让路由继续运行。 -**Stop OpenCodex and Quit…**(`⌥⌘Q`)是明确的破坏性退出操作:确认后停止代理和服务、恢复 +可见应用与后台代理相互独立。当 CodexCommander 面板处于活动状态时,**Quit Menu Bar**(`⌘Q`)只关闭伴侣 UI,并让路由继续运行。 +**Stop CodexCommander and Quit…**(`⌥⌘Q`)是明确的破坏性退出操作:确认后停止代理和服务、恢复 原生 Codex 路由,并且只有在确认停止成功后才关闭伴侣。 ## 面板显示的内容 -- **智能体活动** — 当前活动数量以及实时模型/提供商行。只有当 OpenCodex 能够根据请求元数据 +- **智能体活动** — 当前活动数量以及实时模型/提供商行。只有当 CodexCommander 能够根据请求元数据 证明其活动父项时,派生的子项才会嵌套显示;否则,它会显示为独立的子智能体。伴侣绝不会 虚构排队中、审阅中、受速率限制或已完成的历史记录。 - **提供商配额** — 在可用时显示提供商报告的 5 小时、每周、每月或特定额度窗口及重置时间。 @@ -54,14 +36,14 @@ Control 键点按该应用,选择**打开**,然后确认**打开**。本地 - **管理** — 打开所选提供商的 Accounts 或 API Keys 标签页。OAuth、API 密钥输入、重新认证、 账户切换和提供商配置仍在控制面板中进行。 - **Agent catalog update ready** — 当正在运行的 Codex 后台工作进程仍持有旧模型列表时显示的 - 持久、非故障卡片。OpenCodex 代理会保持健康并继续运行。 + 持久、非故障卡片。CodexCommander 代理会保持健康并继续运行。 - **Apply agent catalog…** — 打开确认窗口,在可用时显示最新请求活动,警告应用更新可能中断 回答,并提供 **Apply Now** 和 **Later**。 - **Stop Proxy…** — 始终请求确认,会中断活动客户端和子智能体请求、恢复原生 Codex,并让菜单栏应用保持打开。 - **Restart Proxy…** — 请求确认,允许代理用最多 60 秒排空活动请求,然后重新连接到替代进程。接受重启 请求不会被显示为完成;应用会等待新进程通过身份检查。 - **Quit Menu Bar** — 只关闭伴侣 UI;不会停止代理、服务或客户端路由。面板处于活动状态时,这是安全的 `⌘Q` 操作。 -- **Stop OpenCodex and Quit…** — 确认中断后停止后台代理和服务、恢复原生 Codex 路由,并且只在 +- **Stop CodexCommander and Quit…** — 确认中断后停止后台代理和服务、恢复原生 Codex 路由,并且只在 确认停止成功后退出。若停止失败,伴侣会保持打开并显示错误。面板处于活动状态时,快捷键为 `⌥⌘Q`。 如果 ChatGPT 的配额报告可用,ChatGPT 会排在最前并默认展开。Kimi 和 Grok 显示为折叠摘要。 @@ -73,37 +55,37 @@ Control 键点按该应用,选择**打开**,然后确认**打开**。本地 ## 智能体目录更新 -打开应用时,它会自动将 Codex 模型目录与 OpenCodex 当前配置的提供商同步。如果没有 Codex 工作 -进程在运行,新列表会在下一个 Codex 任务中生效。如果长时间运行的工作进程载入了旧列表,OpenCodex +打开应用时,它会自动将 Codex 模型目录与 CodexCommander 当前配置的提供商同步。如果没有 Codex 工作 +进程在运行,新列表会在下一个 Codex 任务中生效。如果长时间运行的工作进程载入了旧列表,CodexCommander 仍会继续运行,面板会持续显示非故障的 **Agent catalog update ready** 卡片。 选择 **Apply agent catalog…** 可查看中断风险。确认前会尽可能获取最新的活动请求数量,但请求数为 零不会被描述为 Codex 已空闲的证明,因为操作执行前仍可能开始新请求。**Apply Now** 会再次同步, 仅向当前用户所有、精确匹配 `codex … app-server` 和 `codex-code-mode-host` 的进程发送 `SIGTERM`,并 -短暂验证旧进程 ID 已退出。它不会使用宽泛的 `pkill`,不会重启 OpenCodex 代理,也不会关闭菜单栏 +短暂验证旧进程 ID 已退出。它不会使用宽泛的 `pkill`,不会重启 CodexCommander 代理,也不会关闭菜单栏 应用。Codex 会在下一个任务中创建新的后台主机并载入当前列表。 -此发行版不包含 **Apply when idle**。如果回答仍在进行,请选择 **Later**,并在准备好后应用更新; +当前配套应用不包含 **Apply when idle**。如果回答仍在进行,请选择 **Later**,并在准备好后应用更新; 卡片会继续保留。高级 CLI 回退命令如下: ```bash -ocx sync --restart-codex +ccx sync --restart-codex ``` ## 身份验证与隐私 -伴侣不会创建另一套登录系统,也不会迁移到 macOS Keychain 或从中读取提供商凭据。 +伴侣不会创建另一套登录系统,不使用 macOS Keychain,也不会从中读取提供商凭据。 -当前 OpenCodex 版本会在 <code>~/.opencodex/admin-api-token</code>(或 -<code>$OPENCODEX_HOME/admin-api-token</code>)生成独立的管理凭据。伴侣通过经过验证且不跟随 +当前 CodexCommander 版本会在 <code>~/.codexcommander/admin-api-token</code>(或 +<code>$CODEXCOMMANDER_HOME/admin-api-token</code>)生成独立的管理凭据。伴侣通过经过验证且不跟随 符号链接的文件描述符读取这个现有文件,仅将其值保留在进程内存中,并且只发送给经过身份 -验证的回环 OpenCodex 进程。它绝不会显示、记录、复制或存储该令牌,也不会将其放入浏览器 +验证的回环 CodexCommander 进程。它绝不会显示、记录、复制或存储该令牌,也不会将其放入浏览器 URL。 -提供商凭据仍由 OpenCodex 管理。伴侣绝不会读取 ChatGPT、Kimi、Grok、Anthropic 或其他 +提供商凭据仍由 CodexCommander 管理。伴侣绝不会读取 ChatGPT、Kimi、Grok、Anthropic 或其他 提供商令牌,也绝不会直接调用提供商登录端点。 -仅配置 <code>OPENCODEX_ADMIN_AUTH_TOKEN</code> 的安装,在应用进程继承该变量时可以工作。 +仅配置 <code>CODEXCOMMANDER_ADMIN_AUTH_TOKEN</code> 的安装,在应用进程继承该变量时可以工作。 从 Finder 启动的应用通常不会继承 shell 变量;如果没有受保护的令牌文件,伴侣会报告管理 身份验证不可用,而不会显示令牌输入表单。 @@ -114,49 +96,47 @@ URL。 ## 轮询 面板打开时,应用会频繁刷新轻量级活动信息;面板关闭时则会降低频率。提供商配额按独立且 -更慢的节奏刷新,并使用 OpenCodex 报告的上游时间戳。重复失败会自动退避,重叠的刷新会被 +更慢的节奏刷新,并使用 CodexCommander 报告的上游时间戳。重复失败会自动退避,重叠的刷新会被 合并。 使用**刷新**可立即刷新活动信息并强制刷新配额。 ## 从源代码构建 -需要 macOS 13 或更高版本以及 Xcode Command Line Tools。构建 Intel + Apple silicon 通用 -发行版需要完整的 Xcode。 +需要 macOS 13 或更高版本以及 Xcode Command Line Tools。构建 Intel + Apple silicon 通用版本需要完整的 Xcode。 ```bash -git clone https://github.com/pavelhov/opencodex.git -cd opencodex +cd /path/to/CodexCommander bun install bun run test:macos bun run build:macos -open dist/macos/OpenCodex.app +open dist/macos/CodexCommander.app ``` -源码应用的唯一位置是 `dist/macos/OpenCodex.app`。它使用同一检出中的 Bun 和 CLI,因此需要先运行 +源码应用的唯一位置是 `dist/macos/CodexCommander.app`。它使用同一检出中的 Bun 和 CLI,因此需要先运行 `bun install`。开发期间请保留在此位置,不要复制到 Application Support。双击会尝试确保代理运行; 即使离线或启动失败,应用也不会关闭,面板和 **Start** 控件仍可使用。 -每次构建都会把准确的 Git 修订写入应用包 `Info.plist` 的 `OpenCodexSourceRevision`,并在构建结束时 -输出。未提交的源码会带有 `-dirty`,因此制作最终分发包前请先提交。 +每次构建都会把准确的 Git 修订写入应用包 `Info.plist` 的 `CodexCommanderSourceRevision`,并在构建结束时 +输出。未提交的源码会带有 `-dirty`,因此制作最终包前请先提交。 ## 故障排除 -- **代理不可用** — 使用 <code>ocx start</code> 启动,或使用 - <code>ocx service install</code> 安装后台服务。 -- **身份验证不可用** — 运行 <code>ocx doctor</code>;确认 OpenCodex 状态目录和 +- **代理不可用** — 使用 <code>ccx start</code> 启动,或使用 + <code>ccx service install</code> 安装后台服务。 +- **身份验证不可用** — 运行 <code>ccx doctor</code>;确认 CodexCommander 状态目录和 <code>admin-api-token</code> 归你的用户所有,并且组用户和其他用户无法访问。 - **配额不可用** — 打开该提供商的**管理**目标,然后连接或重新认证账户。部分提供商不公开 - 配额 API。如果 Grok 显示**登录需要刷新**,请运行 <code>grok</code> 完成登录,然后在 OpenCodex + 配额 API。如果 Grok 显示**登录需要刷新**,请运行 <code>grok</code> 完成登录,然后在 CodexCommander 中点击**刷新**;Kimi 的对应操作使用 <code>kimi</code>。 -- **重启后未恢复** — 打开 **Logs** 并运行 <code>ocx status</code>。伴侣绝不会将终止进程或重写 +- **重启后未恢复** — 打开 **Logs** 并运行 <code>ccx status</code>。伴侣绝不会将终止进程或重写 服务状态作为回退措施。 -- **停止、更新或冷启动后只显示原生模型** — 重新打开 OpenCodex。启动时会自动同步目录;即使 - 提供商发现暂时为空,OpenCodex 也会从受保护的最近正常目录中恢复仍在配置中的路由模型。如果 +- **停止、Codex 更新或冷启动后只显示原生模型** — 重新打开 CodexCommander。启动时会自动同步目录;即使 + 提供商发现暂时为空,CodexCommander 也会从受保护的最近正常目录中恢复仍在配置中的路由模型。如果 **Agent catalog update ready** 仍然显示,请选择 **Apply agent catalog…**,或使用 [智能体目录更新](#智能体目录更新)中的 CLI 回退命令。 ## 卸载 -关闭 **Launch at Login**,退出伴侣,然后将 <code>OpenCodex.app</code> 移到废纸篓。它不存储 -提供商凭据,也不创建 Keychain 条目。卸载伴侣不会停止或卸载 OpenCodex 代理;只有在也要删除 -无界面服务时,才需另行运行 <code>ocx service uninstall</code>。 +关闭 **Launch at Login**,退出伴侣,然后将 <code>CodexCommander.app</code> 移到废纸篓。它不存储 +提供商凭据,也不创建 Keychain 条目。卸载伴侣不会停止或卸载 CodexCommander 代理;只有在也要删除 +无界面服务时,才需另行运行 <code>ccx service uninstall</code>。 diff --git a/docs-site/src/content/docs/zh-cn/guides/model-ordering.md b/docs-site/src/content/docs/zh-cn/guides/model-ordering.md index a1b8afffab..f1259c793a 100644 --- a/docs-site/src/content/docs/zh-cn/guides/model-ordering.md +++ b/docs-site/src/content/docs/zh-cn/guides/model-ordering.md @@ -1,9 +1,9 @@ --- title: 模型排序 -description: opencodex 如何确定 Codex 模型选择器和 spawn_agent 模型 override 的顺序。 +description: CodexCommander 如何确定 Codex 模型选择器和 spawn_agent 模型 override 的顺序。 --- -Codex 模型选择器不会保留 opencodex 配置中 provider 的声明顺序或模型数组顺序。最终顺序由目录 +Codex 模型选择器不会保留 CodexCommander 配置中 provider 的声明顺序或模型数组顺序。最终顺序由目录 priority 决定;priority 相同的路由模型则使用确定性的字母顺序。 ## Codex 应用的规则 @@ -12,7 +12,7 @@ Codex 的 models-manager 按 `priority` 升序排列选择器中可见的目录 丢弃,因此在生成的 JSON 数组中把某个条目前移,并不会让它在选择器中前移。该约束直接记录在 `src/codex/catalog/sync.ts` 中。 -因此,opencodex 通过分配更低的 priority 控制置顶位置,而不依赖数组位置。本表中的固定值及下例适用于 +因此,CodexCommander 通过分配更低的 priority 控制置顶位置,而不依赖数组位置。本表中的固定值及下例适用于 没有有效账户 selector 的配置。存在 `N` 个 selector 时,配置 rank 为 `i` 的置顶裸原生模型会展开为 priority 为 `i * N + j` 的 selector 行,其中 `j` 是从 0 开始的 selector 位置。置顶的路由行使用 `i * N`,精确的账户限定原生 id 使用其 selector 对应的 `i * N + j`。Codex 仍只公布选择器中可见的 @@ -65,7 +65,7 @@ priority,因此 Codex 的 priority 排序会保留这个开头序列。 3. 在目录合并过程中被移到 featured 区块之后的未选中原生模型。 如果没有 `subagentModels`,路由模型保持 priority `5`,原生 GPT 条目使用正常 priority -(opencodex 创建的条目通常为 `9`),路由组内部仍按 provider/id 字母排序。 +(CodexCommander 创建的条目通常为 `9`),路由组内部仍按 provider/id 字母排序。 ## 示例 @@ -105,11 +105,11 @@ subagentModels = [ **Active Roster**。可搜索的 **Agent Library** 可能包含远超五个的目录模型;路由可用时条目仍可通过精确 id 指定,而五个槽位的限制仅适用于最先向 `spawn_agent` 公布的 override。 -使用 `ocx agent subagents set` 或编辑 opencodex 配置,添加实时库中没有的精确 +使用 `ccx agent subagents set` 或编辑 CodexCommander 配置,添加实时库中没有的精确 `<selector>/<native-openai-model>` 选项。即使其 provider 暂时不可用,命令中心也会保留已配置的精确 selector,并可对其重新排序。存在账户 selector 时,一个裸原生选项可能展开为多个 selector-qualified 行,因此已配置的选项与公布的行不一定一一对应。 -目前 `OcxConfig` 中没有通用的 `modelOrder`、`providerOrder` 或 priority map 设置。受支持的排序 +目前 `CodexCommanderConfig` 中没有通用的 `modelOrder`、`providerOrder` 或 priority map 设置。受支持的排序 字段是 `subagentModels`;`disabledModels` 和各 provider 的 `selectedModels` 都是可见性字段。 因此,要更改选择器其余部分的顺序,需要修改代码行为,而不是调整配置。 diff --git a/docs-site/src/content/docs/zh-cn/guides/model-routing.md b/docs-site/src/content/docs/zh-cn/guides/model-routing.md index b3105376ac..338bb7bdbb 100644 --- a/docs-site/src/content/docs/zh-cn/guides/model-routing.md +++ b/docs-site/src/content/docs/zh-cn/guides/model-routing.md @@ -1,6 +1,6 @@ --- title: 模型路由 -description: opencodex 如何决定由哪个提供商来服务给定的模型 id。 +description: CodexCommander 如何决定由哪个提供商来服务给定的模型 id。 --- 当 Codex 请求某个模型时,`router.ts` 会将其解析为唯一一个已配置的提供商。规则**按顺序**检查;第一个匹配者胜出。 @@ -23,7 +23,7 @@ transport;这些凭证路径互不 fallback。 ``` 2. **Combo id 或 alias** —— 配置了至少一个 combo 时,规范的 `combo/<id>` 或已配置 combo alias - 会先选择具体目标,然后才检查 provider 命名空间。没有配置 combo 时,名称恰好为 `combo` 的 legacy + 会先选择具体目标,然后才检查 provider 命名空间。没有配置 combo 时,名称恰好为 `combo` 的 physical provider 仍作为普通 provider 命名空间。目标选择与 failover 行为见 [Combos](/zh-cn/guides/combos/)。 diff --git a/docs-site/src/content/docs/zh-cn/guides/opencode.md b/docs-site/src/content/docs/zh-cn/guides/opencode.md index a29542b388..f5eb8a42f0 100644 --- a/docs-site/src/content/docs/zh-cn/guides/opencode.md +++ b/docs-site/src/content/docs/zh-cn/guides/opencode.md @@ -1,94 +1,94 @@ --- title: opencode -description: 在 opencode 中使用任意路由模型 - opencodex 会注入一个运行时 provider 块,并且不会改动你自己的 opencode 配置。 +description: 在 opencode 中使用任意路由模型 - CodexCommander 会注入一个运行时 provider 块,并且不会改动你自己的 opencode 配置。 --- -opencode 从合并后的 JSON 配置层读取 provider,而不是从环境变量读取,所以没有类似 `ANTHROPIC_BASE_URL` 这样的注入位置。`ocx opencode` 正是为此补桥:它会确保代理正在运行,根据可见目录构建 provider 块,并通过 OpenCode 的内联运行时层(`OPENCODE_CONFIG_CONTENT`)注入进去。 +opencode 从合并后的 JSON 配置层读取 provider,而不是从环境变量读取,所以没有类似 `ANTHROPIC_BASE_URL` 这样的注入位置。`ccx opencode` 正是为此补桥:它会确保代理正在运行,根据可见目录构建 provider 块,并通过 OpenCode 的内联运行时层(`OPENCODE_CONFIG_CONTENT`)注入进去。 ## 快速开始 ```bash -ocx opencode +ccx opencode ``` -这会确保代理正在运行,并只为该进程注入生成的 `provider.opencodex` block 来启动 opencode。额外参数会原样透传:`ocx opencode run "hello"`。 +这会确保代理正在运行,并只为该进程注入生成的 `provider.codexcommander` block 来启动 opencode。额外参数会原样透传:`ccx opencode run "hello"`。 -路由模型会在选择器里作为 `opencodex` provider 出现: +路由模型会在选择器里作为 `codexcommander` provider 出现: ```text -opencodex/kiro/glm-5 -opencodex/gpt-5.6-sol # native slugs stay unprefixed +codexcommander/kiro/glm-5 +codexcommander/gpt-5.6-sol # native slugs stay unprefixed ``` ## 你的配置绝不会被修改 -启动器不会复制或重写 `~/.config/opencode/opencode.json`、项目中的 `opencode.json` / `opencode.jsonc`,也不会处理任何其他磁盘上的配置层。它可能会读取全局或项目配置,以检测是否存在 `provider.opencodex` 覆盖;而你现有的 providers、agents、keybinds、MCP 条目以及相对路径的 `{file:…}` 引用,都会继续从它们原本的文件中解析。 +启动器不会复制或重写 `~/.config/opencode/opencode.json`、项目中的 `opencode.json` / `opencode.jsonc`,也不会处理任何其他磁盘上的配置层。它可能会读取全局或项目配置,以检测是否存在 `provider.codexcommander` 覆盖;而你现有的 providers、agents、keybinds、MCP 条目以及相对路径的 `{file:…}` 引用,都会继续从它们原本的文件中解析。 -仅在这次启动中,opencodex 会通过 OpenCode 的内联运行时层添加生成的 `provider.opencodex` block。该层会在全局/自定义/项目配置之后合并,并且只会对这个子进程覆盖冲突的键。 +仅在这次启动中,CodexCommander 会通过 OpenCode 的内联运行时层添加生成的 `provider.codexcommander` block。该层会在全局/自定义/项目配置之后合并,并且只会对这个子进程覆盖冲突的键。 -| Layer | `ocx opencode` 下的行为 | +| Layer | `ccx opencode` 下的行为 | | --- | --- | | Global / custom / project config | 原样保留在磁盘上,不做任何改动 | -| Inline runtime (`OPENCODE_CONFIG_CONTENT`) | 只接收生成的 `provider.opencodex` block | +| Inline runtime (`OPENCODE_CONFIG_CONTENT`) | 只接收生成的 `provider.codexcommander` block | | Relative `{file:…}` paths | 仍然按最初定义它们的配置文件来解析 | -如果全局或项目配置里也定义了 `provider.opencodex`,启动器会打印一条提示信息:`ocx opencode` 的运行时层会在这次启动中覆盖它。 +如果全局或项目配置里也定义了 `provider.codexcommander`,启动器会打印一条提示信息:`ccx opencode` 的运行时层会在这次启动中覆盖它。 ## 通过控制面板建立持久连接(可选) -若要让普通 OpenCode、编辑器集成或 Desktop 一键启动使用代理,请在 OpenCodex 控制面板的 -**Integrations** 中选择 **Apply connection**。这与 `ocx opencode` 是不同的路径: +若要让普通 OpenCode、编辑器集成或 Desktop 一键启动使用代理,请在 CodexCommander 控制面板的 +**Integrations** 中选择 **Apply connection**。这与 `ccx opencode` 是不同的路径: - 它会选择 `XDG_CONFIG_HOME` 下的活动 OpenCode 全局配置(通常是 `~/.config/opencode/`):已有的 `opencode.jsonc` 优先,否则是 `opencode.json`。 -- JSONC 编辑只会修改 `provider.opencodex`,并保留注释、格式、其他 provider、agent、MCP +- JSONC 编辑只会修改 `provider.codexcommander`,并保留注释、格式、其他 provider、agent、MCP 和无关键。 -- 代理准入令牌保留在 OpenCodex 的受保护状态中;OpenCode 配置只收到 +- 代理准入令牌保留在 CodexCommander 的受保护状态中;OpenCode 配置只收到 `{file:/absolute/path}` 引用,不会读取 OpenCode 的认证存储。 - **Always keep OpenCode connected** 默认关闭;只有明确开启后,才会在代理启动或可见目录变化 时刷新这一受管 block。 当 journal 确认精确恢复安全时,**Restore** 会精确恢复原始字节;否则控制面板只会外科式恢复或 -删除受管的 `provider.opencodex`,保留其他用户修改。**Open OpenCode** 可一键启动 OpenCode Desktop; -只有 CLI 时请使用仍然不改磁盘的 `ocx opencode`。 +删除受管的 `provider.codexcommander`,保留其他用户修改。**Open OpenCode** 可一键启动 OpenCode Desktop; +只有 CLI 时请使用仍然不改磁盘的 `ccx opencode`。 ## 把这个 block 放进你自己的配置里 -`ocx opencode` 只会在单次启动中注入 provider block。若未应用上面的控制面板持久连接,普通的 -`opencode` 仍然不知道代理的存在。若你希望在普通 `opencode` 中也能使用路由模型,或者希望编辑器扩展不经过启动器也能使用它们,`ocx export` 会打印同样的 provider block,供你合并到自己的配置中: +`ccx opencode` 只会在单次启动中注入 provider block。若未应用上面的控制面板持久连接,普通的 +`opencode` 仍然不知道代理的存在。若你希望在普通 `opencode` 中也能使用路由模型,或者希望编辑器扩展不经过启动器也能使用它们,`ccx export` 会打印同样的 provider block,供你合并到自己的配置中: ```bash -ocx export --client opencode +ccx export --client opencode ``` 代理必须正在运行。该命令会打印配置、规范目标路径(`~/.config/opencode/opencode.json`,如果设置了 `XDG_CONFIG_HOME` 则位于其下)、合并警告,以及环境变量导出行。它绝不会修改那个文件 - 上面的说明依然成立,而把这个 block 挪进你的配置是你明确做出的动作。 :::caution[合并,不要替换] -请把 `provider.opencodex` block 合并进你现有的配置。用导出的文件直接替换整个配置会破坏你其他的 providers、agents、keybinds 和 MCP 条目。`ocx export --out` 会明确拒绝覆盖已存在的文件,原因正是如此,因此请把 `--out` 指向一个临时路径,然后把 block 复制过去: +请把 `provider.codexcommander` block 合并进你现有的配置。用导出的文件直接替换整个配置会破坏你其他的 providers、agents、keybinds 和 MCP 条目。`ccx export --out` 会明确拒绝覆盖已存在的文件,原因正是如此,因此请把 `--out` 指向一个临时路径,然后把 block 复制过去: ```bash -ocx export --client opencode --out ~/opencodex-opencode.json +ccx export --client opencode --out ~/codexcommander-opencode.json ``` ::: -与启动器的运行时 block 不同,合并后的 block 是一个静态快照:它不会跟随你的目录变化。每当你新增 provider 或调整 model 可见性后,都要重新运行 `ocx export`。 +与启动器的运行时 block 不同,合并后的 block 是一个静态快照:它不会跟随你的目录变化。每当你新增 provider 或调整 model 可见性后,都要重新运行 `ccx export`。 合并完成后,在启动 opencode 之前导出 admission key - 除非代理绑定在 loopback 上,那种情况下不需要: ```bash -export OPENCODEX_OPENCODE_API_KEY=<your key> +export CODEXCOMMANDER_OPENCODE_API_KEY=<your key> ``` ## admission key 不会写入磁盘 -当代理需要 API key 时,内联运行时配置携带的是 opencode 的 `{env:…}` 引用,而不是 secret。loopback 绑定会把这个引用作为 `apiKey` 使用;非 loopback 绑定只会通过 `x-opencodex-api-key` 发送它,从而让代理的 admission 与任何上游 `Authorization` header 保持分离。 +当代理需要 API key 时,内联运行时配置携带的是 opencode 的 `{env:…}` 引用,而不是 secret。loopback 绑定会把这个引用作为 `apiKey` 使用;非 loopback 绑定只会通过 `x-codexcommander-api-key` 发送它,从而让代理的 admission 与任何上游 `Authorization` header 保持分离。 loopback 示例: ```json "options": { "baseURL": "http://127.0.0.1:10100/v1", - "apiKey": "{env:OPENCODEX_OPENCODE_API_KEY}" + "apiKey": "{env:CODEXCOMMANDER_OPENCODE_API_KEY}" } ``` @@ -98,18 +98,18 @@ loopback 示例: "options": { "baseURL": "http://192.168.1.10:10100/v1", "headers": { - "x-opencodex-api-key": "{env:OPENCODEX_OPENCODE_API_KEY}" + "x-codexcommander-api-key": "{env:CODEXCOMMANDER_OPENCODE_API_KEY}" } } ``` -真实值只会通过子进程环境传递。`OPENCODEX_API_AUTH_TOKEN` 优先,然后是加固后的服务 token 文件,最后才是配置的 API key - 而非 loopback 绑定正是需要这个 API key。 +真实值只会通过子进程环境传递。`CODEXCOMMANDER_API_AUTH_TOKEN` 优先,然后是加固后的服务 token 文件,最后才是配置的 API key - 而非 loopback 绑定正是需要这个 API key。 -loopback 绑定(`127.0.0.1`,默认值)不会进行任何认证,所以 `{env:…}` 引用是惰性的,你可以不设置该变量。它只在 `hostname` 超出 loopback 范围时才有意义;参见 [Remote access](/reference/configuration/#remote-access)。这个 admission key 是 opencodex 自己的,与在 [Providers](/guides/providers/) 下配置的上游 provider keys 无关。 +loopback 绑定(`127.0.0.1`,默认值)不会进行任何认证,所以 `{env:…}` 引用是惰性的,你可以不设置该变量。它只在 `hostname` 超出 loopback 范围时才有意义;参见 [Remote access](/reference/configuration/#remote-access)。这个 admission key 是 CodexCommander 自己的,与在 [Providers](/guides/providers/) 下配置的上游 provider keys 无关。 ## 回滚 -临时的 `ocx opencode` 无需撤销,因为它不会修改 OpenCode 配置。对于控制面板连接,请在 +临时的 `ccx opencode` 无需撤销,因为它不会修改 OpenCode 配置。对于控制面板连接,请在 **Integrations** 中选择 **Restore**:journal 允许时会精确恢复原始字节,否则只会外科式恢复受管 provider。 ## 模型限制 @@ -118,7 +118,7 @@ loopback 绑定(`127.0.0.1`,默认值)不会进行任何认证,所以 `{ opencode 的 schema 会拒绝一个包含 `context` 但不包含 `output` 的 `limit` block,而目录没有按模型粒度提供权威的 output 字段,因此会同时写入一个 `32000` 的 `output` budget,并将其钳制到 context window 以内,确保不会给小 context 模型分配 `output > context`。这个数值只是为了满足 schema - 它并不是对任何具体模型真实上限的声明。 -`opencodex` provider block 会在每次启动时重新生成,所以在其中做的逐模型调整不会保留。若要自定义条目,请把它们放到你自己的 provider key 下。 +`codexcommander` provider block 会在每次启动时重新生成,所以在其中做的逐模型调整不会保留。若要自定义条目,请把它们放到你自己的 provider key 下。 ## 要求 diff --git a/docs-site/src/content/docs/zh-cn/guides/pi.md b/docs-site/src/content/docs/zh-cn/guides/pi.md index ad868e3194..0ee07e1ca0 100644 --- a/docs-site/src/content/docs/zh-cn/guides/pi.md +++ b/docs-site/src/content/docs/zh-cn/guides/pi.md @@ -1,17 +1,17 @@ --- title: Pi -description: 在 Pi 中使用任意已路由模型 - `ocx export` 会为 Pi 的 `models.json` 写入一个自定义 provider 块,并连接到正在运行的代理。 +description: 在 Pi 中使用任意已路由模型 - `ccx export` 会为 Pi 的 `models.json` 写入一个自定义 provider 块,并连接到正在运行的代理。 --- -Pi 从一个全局 JSON 文件而不是环境变量中读取 providers,所以 opencodex 不会启动它。相反,`ocx export` 会序列化 `opencodex` provider 块 - 基础 URL、模型列表,以及 Pi 会插值的 env 引用 - 然后你把它合并到自己的配置中。 +Pi 从一个全局 JSON 文件而不是环境变量中读取 providers,所以 CodexCommander 不会启动它。相反,`ccx export` 会序列化 `codexcommander` provider 块 - 基础 URL、模型列表,以及 Pi 会插值的 env 引用 - 然后你把它合并到自己的配置中。 ## 快速开始 先启动代理,再打印配置: ```bash -ocx start -ocx export --client pi +ccx start +ccx export --client pi ``` 输出会先显示 JSON,然后打印目标路径、合并警告、env 导出行,以及有多少模型带有权威上下文窗口限制。 @@ -19,10 +19,10 @@ ocx export --client pi ```json { "providers": { - "opencodex": { + "codexcommander": { "baseUrl": "http://127.0.0.1:10100/v1", "api": "openai-completions", - "apiKey": "$OPENCODEX_API_KEY", + "apiKey": "$CODEXCOMMANDER_API_KEY", "models": [ { "id": "anthropic/claude-opus-5", @@ -48,15 +48,15 @@ Pi 的全局模型配置位于: ``` :::caution[只合并,不要替换] -`ocx export` 永远不会写入那个文件。请把 `providers.opencodex` 块合并进去 - 直接替换整个文件会破坏你已配置的其他 provider。`--out` 只用于临时路径,并且如果不加 `--force` 就不会覆盖已有文件: +`ccx export` 永远不会写入那个文件。请把 `providers.codexcommander` 块合并进去 - 直接替换整个文件会破坏你已配置的其他 provider。`--out` 只用于临时路径,并且如果不加 `--force` 就不会覆盖已有文件: ```bash -ocx export --client pi --out ~/opencodex-pi-models.json -ocx export --client pi --json > ~/opencodex-pi-models.json # or redirect the byte-exact JSON +ccx export --client pi --out ~/codexcommander-pi-models.json +ccx export --client pi --json > ~/codexcommander-pi-models.json # or redirect the byte-exact JSON ``` ::: -导出的块是静态快照,不是实时视图。新增 provider 或更改模型可见性后,请重新运行 `ocx export`,再用新的块覆盖旧块进行合并。 +导出的块是静态快照,不是实时视图。新增 provider 或更改模型可见性后,请重新运行 `ccx export`,再用新的块覆盖旧块进行合并。 ## 准入密钥 @@ -64,33 +64,33 @@ ocx export --client pi --json > ~/opencodex-pi-models.json # or redirect the b | Key | 它是什么 | 它存放在哪里 | | --- | --- | --- | -| 代理准入密钥 | opencodex 自己的凭据,在仪表盘的 **API** 选项卡中生成 | 通过 `apiKey` 以 `$OPENCODEX_API_KEY` 形式引用;实际值保存在你的环境中 | -| Provider key | 你的 Anthropic / OpenAI / OpenRouter key | opencodex 自己的配置中,见 [Providers](/guides/providers/) | +| 代理准入密钥 | CodexCommander 自己的凭据,在仪表盘的 **API** 选项卡中生成 | 通过 `apiKey` 以 `$CODEXCOMMANDER_API_KEY` 形式引用;实际值保存在你的环境中 | +| Provider key | 你的 Anthropic / OpenAI / OpenRouter key | CodexCommander 自己的配置中,见 [Providers](/guides/providers/) | 导出的配置只包含引用,从不包含 secret。Pi 会插值裸的 `$NAME`,所以变量是: ```bash -export OPENCODEX_API_KEY=<your key> +export CODEXCOMMANDER_API_KEY=<your key> ``` -这个名字只属于 Pi。opencode 使用不同的变量(`OPENCODEX_OPENCODE_API_KEY`,以 `{env:…}` 形式出现) - 见 [opencode 指南](/guides/opencode/)。 +这个名字只属于 Pi。opencode 使用不同的变量(`CODEXCOMMANDER_OPENCODE_API_KEY`,以 `{env:…}` 形式出现) - 见 [opencode 指南](/guides/opencode/)。 -**回环代理根本不需要 key。** opencodex 默认绑定 `127.0.0.1`,在那里不做任何认证,所以 `$OPENCODEX_API_KEY` 引用是无效的,你可以不设置这个变量。它只在 `hostname` 超出回环范围时才有意义,而这也是代理会在没有 token 的情况下拒绝启动的时候 - 见 [远程访问](/reference/configuration/#remote-access)。 +**回环代理根本不需要 key。** CodexCommander 默认绑定 `127.0.0.1`,在那里不做任何认证,所以 `$CODEXCOMMANDER_API_KEY` 引用是无效的,你可以不设置这个变量。它只在 `hostname` 超出回环范围时才有意义,而这也是代理会在没有 token 的情况下拒绝启动的时候 - 见 [远程访问](/reference/configuration/#remote-access)。 ## 模型元数据 -只有当目录报告了权威的上下文窗口时,`contextWindow` 和 `maxTokens` 才会被输出。如果没有报告,这两个字段就会在该模型上省略,Pi 会应用自己的默认值;`ocx export` 会打印有多少行落入了这种情况。 +只有当目录报告了权威的上下文窗口时,`contextWindow` 和 `maxTokens` 才会被输出。如果没有报告,这两个字段就会在该模型上省略,Pi 会应用自己的默认值;`ccx export` 会打印有多少行落入了这种情况。 `maxTokens` 是一个满足 schema 的 `32000` 预算,并会向下钳制到上下文窗口,因此不会给小上下文模型分配超过其上下文容量的输出。它并不声称某个具体模型的真实最大值。 -有两个字段是刻意省略的。`cost` 需要全部四个价格字段,而 opencodex 没有已路由模型的价格数据 - 如果输出 0,会等于断言所有模型都是免费的。`reasoning` 在 Pi 里是一个布尔值,而目录里是一个 effort 层级,把二者互相映射只能是猜测。 +有两个字段是刻意省略的。`cost` 需要全部四个价格字段,而 CodexCommander 没有已路由模型的价格数据 - 如果输出 0,会等于断言所有模型都是免费的。`reasoning` 在 Pi 里是一个布尔值,而目录里是一个 effort 层级,把二者互相映射只能是猜测。 ## Schema 状态 :::note[未在真实安装上验证] -上面的结构遵循了 Pi 已公开的自定义 provider 文档。它**尚未**在一台安装了 Pi 的机器上、针对真实的 `~/.pi/agent/models.json` 进行验证。如果 Pi 拒绝这个导出块,问题在我们这边 - 请带上 Pi 的报错信息[提交 issue](https://github.com/lidge-jun/opencodex/issues)。 +上面的结构遵循了 Pi 已公开的自定义 provider 文档。它**尚未**在一台安装了 Pi 的机器上、针对真实的 `~/.pi/agent/models.json` 进行验证。如果 Pi 拒绝这个导出块,问题在我们这边 - 请带上 Pi 的报错信息[提交 issue](https://github.com/pavelhov/CodexCommander/issues)。 ::: ## 需求 -需要一个正在运行的 opencodex 代理(`ocx start`)以及已安装的 Pi。`ocx export` 通过代理的 management API 读取实时目录,因此配置永远不会在模型列表为空时被导出。 +需要一个正在运行的 CodexCommander 代理(`ccx start`)以及已安装的 Pi。`ccx export` 通过代理的 management API 读取实时目录,因此配置永远不会在模型列表为空时被导出。 diff --git a/docs-site/src/content/docs/zh-cn/guides/providers.md b/docs-site/src/content/docs/zh-cn/guides/providers.md index 5d61c86a27..6294cb492a 100644 --- a/docs-site/src/content/docs/zh-cn/guides/providers.md +++ b/docs-site/src/content/docs/zh-cn/guides/providers.md @@ -1,9 +1,9 @@ --- title: 提供商 -description: opencodex 进行身份验证并与 LLM 提供商通信的所有方式——OAuth、API 密钥、ChatGPT 转发以及本地。 +description: CodexCommander 进行身份验证并与 LLM 提供商通信的所有方式——OAuth、API 密钥、ChatGPT 转发以及本地。 --- -**提供商(provider)** 是一个上游 LLM 端点,加上访问它的方式:一个 adapter、一个基础 URL、一种认证模式,以及一个可选的模型列表。提供商配置位于 `~/.opencodex/config.json` 的 `providers` 下。 +**提供商(provider)** 是一个上游 LLM 端点,加上访问它的方式:一个 adapter、一个基础 URL、一种认证模式,以及一个可选的模型列表。提供商配置位于 `~/.codexcommander/config.json` 的 `providers` 下。 ## OpenAI 账户模式 @@ -35,10 +35,6 @@ Codex 登录使用 Pool 模式时,Providers 概览显示整个账户池的已 各账户状态和路由控制请参阅 [Codex Auth 账户池](/zh-cn/guides/web-dashboard/#codex-auth-and-account-pools)。 -shipped v1 配置自动迁移到 marker 2 的单一选项行。原配置只保留一次到 -`~/.opencodex/config.json.pre-openai-tiers-v2.bak`;恢复命令: -`cp ~/.opencodex/config.json.pre-openai-tiers-v2.bak ~/.opencodex/config.json`。 - ## 认证模式 提供商配置支持三种 `authMode`,默认值为 `key`。内置注册表还会单独标记本地预设;这类预设通常会 @@ -48,7 +44,7 @@ shipped v1 配置自动迁移到 marker 2 的单一选项行。原配置只保 | --- | --- | --- | | `key` | 发送你的 API 密钥(`Authorization: Bearer …`,或按 adapter 使用 `x-api-key` / `api-key`)。密钥可以是字面值,也可以是 `${ENV_VAR}` 引用。 | 大多数提供商。 | | `forward` | 将**你传入的 Codex 认证请求头**原样转发给提供商——不存储任何密钥。这就是 ChatGPT 登录的透传方式。 | OpenAI(`openai-responses` adapter)。 | -| `oauth` | 读取已存储的 OAuth 访问令牌作为 bearer 密钥,并遵循凭据所有权。OpenCodex 自有凭据会在过期前刷新;已链接的 Grok/Kimi CLI 凭据以只读方式采用,并仍由原生 CLI 所有。 | xAI、Anthropic、Kimi、Kiro、Google Antigravity、Cursor。 | +| `oauth` | 读取已存储的 OAuth 访问令牌作为 bearer 密钥,并遵循凭据所有权。CodexCommander 自有凭据会在过期前刷新;已链接的 Grok/Kimi CLI 凭据以只读方式采用,并仍由原生 CLI 所有。 | xAI、Anthropic、Kimi、Kiro、Google Antigravity、Cursor。 | [`retryOn429`](/zh-cn/reference/configuration/)(同 key 的 429 重试)仅适用于 API-key 提供商 (`authMode: "key"`)。OAuth、forward 与本地预设均被排除——同一 token 绝不可重放,本地运行时 @@ -76,37 +72,37 @@ ChatGPT 透传目录也会加入 GPT-5.6 Sol/Terra/Luna 的裸 slug(`gpt-5.6-s ## 2. 账号登录(OAuth) 有七个提供商预设使用 OAuth 登录,另加通过实验性非官方设备流桥接的 GitHub Copilot。 -opencodex 会把凭据存入 `~/.opencodex/auth.json`。OpenCodex 自有凭据会自动刷新。链接已登录的 -Grok 或 Kimi CLI 会话时,opencodex 只读采用其当前访问代际,更新责任仍由原生 CLI 承担。 +CodexCommander 会把凭据存入 `~/.codexcommander/auth.json`。CodexCommander 自有凭据会自动刷新。链接已登录的 +Grok 或 Kimi CLI 会话时,CodexCommander 只读采用其当前访问代际,更新责任仍由原生 CLI 承担。 登录 CLI 也接受 `chatgpt`:它会获取一份 ChatGPT 凭据,并创建一个 `forward` 模式的提供商条目。 ```bash -ocx login xai # xAI Grok -ocx login anthropic # Anthropic Claude (Pro/Max) -ocx login kimi # Moonshot Kimi -ocx login kiro # 导入 kiro-cli 凭据(支持令牌回退) -ocx login google-antigravity -ocx login cursor # 独立的 Cursor PKCE 登录 -ocx login command-code # Command Code 浏览器 OAuth(或导入 ~/.commandcode/auth.json) -ocx login github-copilot # GitHub 设备流 → Copilot 令牌(Copilot Pro/Business) -ocx login chatgpt # 独立的 ChatGPT OAuth 登录 -ocx logout <provider> +ccx login xai # xAI Grok +ccx login anthropic # Anthropic Claude (Pro/Max) +ccx login kimi # Moonshot Kimi +ccx login kiro # 导入 kiro-cli 凭据(支持令牌回退) +ccx login google-antigravity +ccx login cursor # 独立的 Cursor PKCE 登录 +ccx login command-code # Command Code 浏览器 OAuth(或导入 ~/.commandcode/auth.json) +ccx login github-copilot # GitHub 设备流 → Copilot 令牌(Copilot Pro/Business) +ccx login chatgpt # 独立的 ChatGPT OAuth 登录 +ccx logout <provider> ``` | 提供商 | Adapter | 基础 URL | 备注 | | --- | --- | --- | --- | | `xai` | `openai-chat` | `https://api.x.ai/v1` | 优先使用实时 Grok 目录;回退默认模型为 `grok-4.5`。 | | `anthropic` | `anthropic` | `https://api.anthropic.com` | Claude 模型;实时模型列表从 `/v1/models` 获取。 | -| `kimi` | `openai-chat` | `https://api.kimi.com/coding/v1` | Kimi K3(`k3`,1M 上下文)、固定窗口 `k3-256k`、兼容别名 `k3[1m]`,以及旧版 K2.7/K2.6/K2.5 编程模型。 | -| `kiro` | `kiro` | `https://runtime.us-east-1.kiro.dev` | 首次登录会导入已安装并已登录的 Kiro CLI 会话(Unix 使用 `curl -fsSL https://cli.kiro.dev/install | bash`;Windows PowerShell 使用 `irm 'https://cli.kiro.dev/install.ps1' | iex`;然后运行 `kiro-cli login`)。**添加账户**会先退出 `kiro-cli`,再启动新的浏览器登录,从而切换 `kiro-cli` 自身使用的账户,并保存账户范围的配置文件元数据。现有 OpenCodex 账户会保留;如果取消或失败,则恢复之前的 `kiro-cli` 会话。 | +| `kimi` | `openai-chat` | `https://api.kimi.com/coding/v1` | Kimi K3(`k3`,1M 上下文)、固定窗口 `k3-256k`、兼容别名 `k3[1m]`,以及 K2.7/K2.6/K2.5 编程模型。 | +| `kiro` | `kiro` | `https://runtime.us-east-1.kiro.dev` | 首次登录会导入已安装并已登录的 Kiro CLI 会话(Unix 使用 `curl -fsSL https://cli.kiro.dev/install | bash`;Windows PowerShell 使用 `irm 'https://cli.kiro.dev/install.ps1' | iex`;然后运行 `kiro-cli login`)。**添加账户**会先退出 `kiro-cli`,再启动新的浏览器登录,从而切换 `kiro-cli` 自身使用的账户,并保存账户范围的配置文件元数据。现有 CodexCommander 账户会保留;如果取消或失败,则恢复之前的 `kiro-cli` 会话。 | | `google-antigravity` | `google` | `https://daily-cloudcode-pa.googleapis.com` | 通过 Cloud Code Assist 协议使用 Google OAuth。由于 CCA 不提供通用 `/models` 端点,因此使用维护中的六模型静态目录。 | | `cursor` | `cursor` | `https://api2.cursor.sh` | 实验性 PKCE 登录、HTTP/2 传输和按账号筛选的模型发现。 | | `github-copilot` | `openai-chat` | `https://api.githubcopilot.com` | 实验性。GitHub 设备流 + `copilot_internal` 交换(VS Code OAuth 客户端)。需要有效的 Copilot 订阅;不是官方第三方 API。 | -对于规范的 Kimi Coding Plan 预设(`kimi` 账号登录和 `kimi-code` API key),opencodex +对于规范的 Kimi Coding Plan 预设(`kimi` 账号登录和 `kimi-code` API key),CodexCommander 只会把调用方提供的稳定 `prompt_cache_key` 转发到 Chat Completions 请求,绝不自行生成。Kimi 文档要求使用稳定的会话/任务 key 来提高 Code Plan 缓存命中率;没有 key 的请求仍保持不带 key。 -若已 opt-in 的上游拒绝该字段,opencodex 不会删除字段后重试,也不会改动已保存配置;其他 +若已 opt-in 的上游拒绝该字段,CodexCommander 不会删除字段后重试,也不会改动已保存配置;其他 provider 仍保持 deny-by-default。 你也可以从 [web 仪表盘](/zh-cn/guides/web-dashboard/) 启动 OAuth。 @@ -116,33 +112,33 @@ provider 仍保持 deny-by-default。 OAuth 凭据中带有稳定账号 id 或邮箱的提供商可以保存多个登录。Providers 页面会在下拉列表中显示这些 账号,允许继续添加,并在不登出其他账号的情况下切换当前账号。只有没有身份信息的 Kimi 凭据会替换 当前 active slot;Kiro 账户以配置文件 ARN 为键。`chatgpt` 始终只有一个 slot,因为 Codex 账号池使用独立存储。令牌仍保存在 -`~/.opencodex/auth.json` 中;`/api/oauth/accounts` 只返回脱敏后的 metadata。 +`~/.codexcommander/auth.json` 中;`/api/oauth/accounts` 只返回脱敏后的 metadata。 ### Kiro 凭据导入 -Kiro 登录需要 Kiro CLI:Unix 使用 `curl -fsSL https://cli.kiro.dev/install | bash` 安装;Windows PowerShell 使用 `irm 'https://cli.kiro.dev/install.ps1' | iex`;然后先运行 `kiro-cli login`。如果没有 `kiro-cli` 会话,`ocx login kiro` 会回退到粘贴的访问令牌或 `KIRO_ACCESS_TOKEN` 环境变量。 +Kiro 登录需要 Kiro CLI:Unix 使用 `curl -fsSL https://cli.kiro.dev/install | bash` 安装;Windows PowerShell 使用 `irm 'https://cli.kiro.dev/install.ps1' | iex`;然后先运行 `kiro-cli login`。如果没有 `kiro-cli` 会话,`ccx login kiro` 会回退到粘贴的访问令牌或 `KIRO_ACCESS_TOKEN` 环境变量。 -普通的 `ocx login kiro` 导入会以只读方式打开 CLI SQLite 数据库,不修改数据库、WAL 或 SHM。 +普通的 `ccx login kiro` 导入会以只读方式打开 CLI SQLite 数据库,不修改数据库、WAL 或 SHM。 - `KIROCLI_DB_PATH` 用于选择非标准位置的 Kiro CLI SQLite 数据库;指定的数据库必须已经存在。 - `KIROCLI_TOKEN_KEY` 在存在多个含糊的令牌行时选择确切的 `auth_kv` 行键。缺少选择值时,登录会失败而不会猜测。 -导入的凭据会保存到 `~/.opencodex/auth.json`。**添加账户**的回滚是独立流程:恢复之前的快照时会替换数据库,并删除当前的 WAL、SHM 和 journal 边车文件。 +导入的凭据会保存到 `~/.codexcommander/auth.json`。**添加账户**的回滚是独立流程:恢复之前的快照时会替换数据库,并删除当前的 WAL、SHM 和 journal 边车文件。 由于回滚依赖快照,当会话存储已存在但无法捕获时(文件不可读、架构不匹配、令牌选择有歧义),当 `KIROCLI_DB_PATH` / `KIRO_CLI_DB_FILE` 将导入路径指向与活动 CLI 存储不同的位置时,或当主 CLI 数据库没有可识别的令牌行时,**添加账户**会拒绝将 `kiro-cli` 登出。请修复或删除常规 `kiro-cli` 数据路径下的损坏数据库,并取消仅用于导入的选择器后重试。对于完全没有现有 `kiro-cli` 会话的机器,不受影响。 ## 3. API 密钥目录 -opencodex 内置 76 个预设:64 个密钥预设、8 个 OAuth 预设、3 个本地预设,以及 1 个默认的 +CodexCommander 内置 76 个预设:64 个密钥预设、8 个 OAuth 预设、3 个本地预设,以及 1 个默认的 ChatGPT 转发预设。仪表盘的 **Add provider** 选择器会打开密钥提供商的控制台,验证并保存密钥。 验证因提供商而异。主要条目包括: **ClinePass** 使用 Cline API 密钥连接[官方订阅目录](https://docs.cline.bot/getting-started/clinepass)和 [Chat Completions 端点](https://docs.cline.bot/api/chat-completions)。运营主体是 [Cline 条款](https://cline.bot/tos)所列的 Cline Bot Inc.。 -`cline-pass/cline-pass/kimi-k3` 这样的路由 ID 是预期格式:第一段选择 opencodex 提供商, +`cline-pass/cline-pass/kimi-k3` 这样的路由 ID 是预期格式:第一段选择 CodexCommander 提供商, 其余的 `cline-pass/kimi-k3` 是发送到上游的完整模型 slug。用量由账户的滚动 5 小时、每周和 -每月限额共同管理。当前 opencodex 仅公开经过实测的 `low` reasoning 档位;在网关公布或验证更宽 +每月限额共同管理。当前 CodexCommander 仅公开经过实测的 `low` reasoning 档位;在网关公布或验证更宽 档位之前,更高请求会被限制为 `low`。 **Cline** 使用相同的 API 密钥和端点,按用量计费,可访问 100 多个模型 @@ -201,13 +197,13 @@ Cline IDE/CLI 中提供,不能通过 API 使用;`minimax/minimax-m2.5` 是 `opencode-go` 是位于 `https://opencode.ai/zen/go/v1` 的 OpenCode Go 订阅提供商,和 OpenCode Desktop/CLI 不同。请在 [OpenCode 控制台](https://opencode.ai/console) 创建密钥,然后在 控制面板的 **Providers** 页面添加 **OpenCode Go**,或用该密钥配置 `opencode-go` 预设。 -OpenCodex 不会读取 OpenCode 认证存储,也不会将此密钥迁移到 Keychain。 +CodexCommander 不会读取 OpenCode 认证存储,也不会将此密钥存入 Keychain。 公开模型目录不能证明密钥有效;保存的密钥只有在使用该活动密钥首次成功推理后才会显示为**已验证**。 公开上限只是参考值:**$12 / 5 小时**、**$30 / 7 天**、**$60 / 30 天**。这些窗口的本地观测是 使用量估计,不是实时剩余额度或账单。只有上游明确报告具体限制事件时,才显示权威的限制事件。 -内置预设使用 API 密钥,因此 Add Provider 将其归入 **Paid**,而不是账号登录;OpenCodex 不提供 +内置预设使用 API 密钥,因此 Add Provider 将其归入 **Paid**,而不是账号登录;CodexCommander 不提供 OpenCode Go OAuth 流程。它也不同于 Client Apps 下的 **OpenCode** 客户端和无需密钥的 **OpenCode Free** 提供商。Add Provider 搜索会同时覆盖 Accounts、Free 和 Paid,所以从任意标签 搜索 `opencode` 都会按类别显示所有匹配的预设。 @@ -239,7 +235,7 @@ inference key 可从 [Vultr Console](https://my.vultr.com) 的订阅概览复制 **Command Code 发现:**该预设从固定的 Provider API 主机读取 Command Code 的 `/provider/v1/models` 列表,保留含 `/` 的原生模型 id,并将实时发现限制为 256 KiB 和 256 条原始记录。 -`ocx login command-code` 支持通过浏览器进行 OAuth 登录(现有 Command Code CLI 用户还可选择从 +`ccx login command-code` 支持通过浏览器进行 OAuth 登录(现有 Command Code CLI 用户还可选择从 `~/.commandcode/auth.json` 导入本地 CLI 凭据);模型目录按账户隔离,并在登录后从经过认证的发现 端点获取。聊天请求使用已配置的 bearer 密钥。密钥可在 [Command Code Studio](https://commandcode.ai/studio/) 创建。 @@ -274,7 +270,7 @@ dedicated deployment 需要配置为 custom provider。API 密钥可在 ### A6API 信用额度 使用 `openai-chat`、`authMode: "key"` 以及规范地址 `https://api.a6api.com` 或 -`https://api.a6api.com/v1` 的自定义提供商,会在仪表板和 `ocx account refresh <provider>` +`https://api.a6api.com/v1` 的自定义提供商,会在仪表板和 `ccx account refresh <provider>` 中显示 A6API 信用使用情况;提供商名称可以自定义。系统依据账户的 hard credit limit 将令牌单位换算为 USD,并显示已用百分比和剩余额度。 令牌到期不代表额度补充,因此不会显示为配额重置。只有当前活动密钥会发送到规范主机,重定向会被拒绝;负数 或内部不一致的计费总数不会生成报告。 @@ -293,13 +289,13 @@ dedicated deployment 需要配置为 custom provider。API 密钥可在 ### 从终端切换账号 -无需打开仪表盘,即可使用 `ocx account list`、`ocx account current` 和 `ocx account use` 查看或 +无需打开仪表盘,即可使用 `ccx account list`、`ccx account current` 和 `ccx account use` 查看或 切换同一组 Codex、OAuth 和 API-key pool。完整命令、JSON 输出和新 session 生效规则请参阅 -[CLI 参考](/zh-cn/reference/cli/#ocx-account-subcommand)。 +[CLI 参考](/zh-cn/reference/cli/#ccx-account-subcommand)。 ### GPT-5.6 预览路径 -GPT-5.6 Sol/Terra/Luna 会预置在提供商的回退列表中,因此即使实时模型目录暂时滞后,`ocx sync` +GPT-5.6 Sol/Terra/Luna 会预置在提供商的回退列表中,因此即使实时模型目录暂时滞后,`ccx sync` 也能继续显示这些模型。 | Codex 路由 | 预置模型 id | Codex 中显示的上下文 | @@ -314,47 +310,47 @@ GPT-5.6 Sol/Terra/Luna 会预置在提供商的回退列表中,因此即使实 发现结果,仅保留当前账号可用的模型。 :::note[gateway 与订阅 proxy] -是否支持某个提供商,取决于 opencodex 是否有匹配的 wire adapter,而**不取决于**它是否属于 +是否支持某个提供商,取决于 CodexCommander 是否有匹配的 wire adapter,而**不取决于**它是否属于 “agent”产品。当前 adapter id 包括 `openai-chat`、`openai-responses`、`anthropic`、`google` -(AI Studio、Vertex、Antigravity/Cloud Code Assist 模式)、`azure` / `azure-openai`、`kiro` 和 +(AI Studio、Vertex、Antigravity/Cloud Code Assist 模式)、`azure-openai`、`kiro` 和 `cursor`。原生 Amazon Bedrock 这类无法匹配上述实现的专有 API 暂不直接支持。**GitHub Copilot** 和 **GitLab Duo** 是多模型 gateway,映射到各自的通用 OpenAI 兼容端点。Copilot 支持通过 -`ocx login github-copilot` 使用 GitHub 设备流 OAuth 登录(非官方桥接 — 使用 VS Code 公开客户端 id +`ccx login github-copilot` 使用 GitHub 设备流 OAuth 登录(非官方桥接 — 使用 VS Code 公开客户端 id 登录后换取短期 Copilot API 令牌,需要有效的 Copilot 订阅,GitHub 政策收紧时可能失效);GitLab Duo 使用 Bearer **订阅令牌**(而非普通 API 密钥)进行认证。 **Cloudflare AI Gateway** 需要将 account 和 gateway id 填入 URL。 Copilot 提供混合 wire 目录:其 GPT-5 系列模型(`gpt-5.3-codex`、`gpt-5.4`、 `gpt-5.4-mini`、`gpt-5.5`、`gpt-5.6-luna`、`gpt-5.6-sol`、`gpt-5.6-terra`)会拒绝面向 -agent 流量的 `/chat/completions`,因此 opencodex 默认将这些模型路由到 Responses API,而其他 +agent 流量的 `/chat/completions`,因此 CodexCommander 默认将这些模型路由到 Responses API,而其他 Copilot 模型仍走 chat completions。优先级为:硬 wire 固定 → 显式 [`modelAdapters`](/zh-cn/reference/configuration/providers/) 条目 → 注册表默认值 → 提供商级 adapter。若要将没有内置默认值的模型(例如 `gpt-5.4-nano`)接入 Responses,请设置 `"modelAdapters": { "gpt-5.4-nano": "openai-responses" }`。 Cursor 作为单独的实验性 adapter 进行跟踪。`adapter: "cursor"` 会作为实验性本地配置出现在 -`ocx init` 和 dashboard Add Provider picker 中,并保存 Cursor 的静态回退模型目录 metadata。配置 -Cursor access token 后,opencodex 会使用 Cursor live HTTP/2 transport。内置回退列表包含上下文为 +`ccx init` 和 dashboard Add Provider picker 中,并保存 Cursor 的静态回退模型目录 metadata。配置 +Cursor access token 后,CodexCommander 会使用 Cursor live HTTP/2 transport。内置回退列表包含上下文为 1M 的 `gpt-5.6-sol` / `terra` / `luna`、上下文为 500K 的 `grok-4.5` / `grok-4.5-fast`,以及上下文为 262K 的 `kimi-k3`;最终显示哪些模型由账号的实时发现结果决定。Cursor 只以带 effort 后缀的 wire id 提供 Kimi K3,因此 `cursor/kimi-k3` 暴露 `low` / `high` / `max` 阶梯,默认值为 `max`,与该模型 文档中的 API 默认值一致。Cursor 服务器直接发起的 native read/write/delete/ls/grep/shell/fetch 执行默认禁用,因为它会绕过 Codex 的 approval 和 -sandbox 路径;只有在可信本地实验中,才应在 `~/.opencodex/config.json` 的 `providers.cursor` -对象上设置 `unsafeAllowNativeLocalExec: true`,也可以在仪表盘的 **Providers → Cursor → Edit JSON** +sandbox 路径;只有在可信本地实验中,才应在 `~/.codexcommander/config.json` 的 `providers.cursor` +对象上设置 `nativeLocalExec: "on"`,也可以在仪表盘的 **Providers → Cursor → Edit JSON** 中设置。完整示例参见 [配置参考](/zh-cn/reference/configuration/#cursor-provider-adapter-cursor)。MCP、屏幕录制和 computer-use -通过 executor hook 暴露;没有配置本地 executor 时,opencodex 会返回 typed no-executor 结果。 +通过 executor hook 暴露;没有配置本地 executor 时,CodexCommander 会返回 typed no-executor 结果。 Cursor OAuth 和 live model discovery 已在这个实验性 adapter 中启用;Cursor 仍不会出现在 key-login 列表中。 ::: ### Ollama Cloud -Ollama Cloud 是托管(而非本地)的 Ollama,在 `https://ollama.com/v1` 上兼容 OpenAI,密钥来自 [ollama.com/settings/keys](https://ollama.com/settings/keys)。opencodex 按视觉能力对其云端阵容进行分类,使 [vision sidecar](/zh-cn/guides/sidecars/) 仅对纯文本模型生效。纯文本模型(例如 `glm-5.2`、`deepseek-v4-pro`、`gpt-oss`、`qwen3-coder`、`minimax-m2.x`、`nemotron-3-*`)列在 `noVisionModels` 中;原生支持视觉的模型(例如 `kimi-k2.6`、`minimax-m3`、`gemma4`、`qwen3.5`、`gemini-3-flash-preview`)则不在其中。匹配能容忍 Ollama 的 `:size` 标签,因此 `gpt-oss` 涵盖 `gpt-oss:120b` 和 `gpt-oss:20b`。 +Ollama Cloud 是托管(而非本地)的 Ollama,在 `https://ollama.com/v1` 上兼容 OpenAI,密钥来自 [ollama.com/settings/keys](https://ollama.com/settings/keys)。CodexCommander 按视觉能力对其云端阵容进行分类,使 [vision sidecar](/zh-cn/guides/sidecars/) 仅对纯文本模型生效。纯文本模型(例如 `glm-5.2`、`deepseek-v4-pro`、`gpt-oss`、`qwen3-coder`、`minimax-m2.x`、`nemotron-3-*`)列在 `noVisionModels` 中;原生支持视觉的模型(例如 `kimi-k2.6`、`minimax-m3`、`gemma4`、`qwen3.5`、`gemini-3-flash-preview`)则不在其中。匹配能容忍 Ollama 的 `:size` 标签,因此 `gpt-oss` 涵盖 `gpt-oss:120b` 和 `gpt-oss:20b`。 ## 4. 本地提供商 -让 opencodex 指向本地的 OpenAI 兼容服务器——通常使用空密钥: +让 CodexCommander 指向本地的 OpenAI 兼容服务器——通常使用空密钥: | 提供商 | 基础 URL | | --- | --- | @@ -364,4 +360,4 @@ Ollama Cloud 是托管(而非本地)的 Ollama,在 `https://ollama.com/v1` ## 任意 OpenAI 兼容端点 -如果某个提供商使用 Chat Completions,`openai-chat` adapter 即可处理它——在仪表盘中选择 **Custom**,或在 `ocx init` 中选择 `custom` 并输入基础 URL。每个提供商字段(`headers`、`noReasoningModels`、`noVisionModels`、`models`……)请参见 [配置参考](/zh-cn/reference/configuration/)。 +如果某个提供商使用 Chat Completions,`openai-chat` adapter 即可处理它——在仪表盘中选择 **Custom**,或在 `ccx init` 中选择 `custom` 并输入基础 URL。每个提供商字段(`headers`、`noReasoningModels`、`noVisionModels`、`models`……)请参见 [配置参考](/zh-cn/reference/configuration/)。 diff --git a/docs-site/src/content/docs/zh-cn/guides/sidecars.md b/docs-site/src/content/docs/zh-cn/guides/sidecars.md index 1b49584b1a..2cb5f7cffb 100644 --- a/docs-site/src/content/docs/zh-cn/guides/sidecars.md +++ b/docs-site/src/content/docs/zh-cn/guides/sidecars.md @@ -3,7 +3,7 @@ title: "Sidecar:Web Search 与 Vision" description: 通过原生 ChatGPT sidecar,让路由模型获得真实 web search,并让纯文本模型理解图像。 --- -不同路由模型对托管 **Web Search** 和原生**图像输入**的支持并不相同。opencodex 通过两个 +不同路由模型对托管 **Web Search** 和原生**图像输入**的支持并不相同。CodexCommander 通过两个 sidecar 补齐这些能力;它们可以使用 ChatGPT 登录(`forward`)provider,也可以使用已存储的 Anthropic OAuth provider。Sidecar 错误会转换成长度受限的工具结果或图像提示,不会让整个 turn 失败。 @@ -16,18 +16,18 @@ Anthropic OAuth provider。Sidecar 错误会转换成长度受限的工具结果 ## Web-search sidecar -当 Codex 为非透传的路由模型请求托管 `web_search` 时,opencodex 会: +当 Codex 为非透传的路由模型请求托管 `web_search` 时,CodexCommander 会: 1. **移除**托管的 `web_search` 工具,改为向路由模型提供一个合成的 `web_search(query)` function 工具。原托管工具的选项会保留并用于 sidecar 调用。 -2. 让路由模型在一个小型 **agentic 循环**中运行。模型调用 `web_search` 时,opencodex 使用所选 +2. 让路由模型在一个小型 **agentic 循环**中运行。模型调用 `web_search` 时,CodexCommander 使用所选 后端:OpenAI 默认以 `gpt-5.6-luna` 运行托管 `web_search`;Anthropic 默认以 `claude-sonnet-5` 运行 `web_search_20250305`。Streaming 答案及引用会解析为工具结果。 3. **循环**直到模型回答,或真实查询总数达到 `maxSearchesPerTurn`(默认 3)。达到上限后会移除 search 工具并强制生成最终答案。如果模型调用 `apply_patch` 或 shell 等真实客户端工具,当前 turn 会结束,以便这些调用到达 Codex。 -路由模型的每次迭代都会向上游请求 `stream: true`,但 opencodex 会在决定搜索还是返回最终答案前, +路由模型的每次迭代都会向上游请求 `stream: true`,但 CodexCommander 会在决定搜索还是返回最终答案前, 在内部完整缓冲所有语义 event。只有第一次迭代的最终 header/status 和 429 key rotation 会被提前 取得。因此,合成搜索调用和中间输出不会作为模型输出暴露给客户端。 @@ -63,10 +63,10 @@ Anthropic OAuth provider。Sidecar 错误会转换成长度受限的工具结果 ## Vision sidecar -当路由模型列在其 provider 的 `noVisionModels` 中,并且请求包含图像时,opencodex 会在主调用 +当路由模型列在其 provider 的 `noVisionModels` 中,并且请求包含图像时,CodexCommander 会在主调用 **之前**描述每张图像,并用文字替换图像。Dashboard 和管理 API 当前显示的默认值是 -`gpt-5.6-luna`,启动时也会把明确保存的旧 `gpt-5.4-mini` 值迁移到 Luna。只有在 -`visionSidecar.model` 字段完全不存在时,vision 执行路径才会使用代码中的 `gpt-5.4-mini` 回退值。 +`gpt-5.6-luna`。只有在 `visionSidecar.model` 字段完全不存在时,vision 执行路径才会使用代码中的 +`gpt-5.4-mini` 回退值。 - 图像可以来自 user、developer 和 tool-result message,也包括 Codex 的 `view_image` 结果。 - 每张图像会以 `reasoning.effort: "low"` 发送给配置的原生 vision 模型,描述结果会就地替换 diff --git a/docs-site/src/content/docs/zh-cn/guides/sub-agent-surface.md b/docs-site/src/content/docs/zh-cn/guides/sub-agent-surface.md index f650e337ea..c2d64bbb09 100644 --- a/docs-site/src/content/docs/zh-cn/guides/sub-agent-surface.md +++ b/docs-site/src/content/docs/zh-cn/guides/sub-agent-surface.md @@ -5,7 +5,7 @@ description: 控制 Codex 如何在所有模型上生成和管理子代理。 ## 什么是子代理 -子代理是一个独立的 Codex 工作器,主代理可以为专注任务创建它。它有自己的上下文和工具,因此多个独立任务可以并行运行。opencodex 负责控制 Codex 的哪种协作界面会暴露这些工作器、Codex 会为它们提供哪些模型,以及失败模型如何回退。它不会决定主代理何时必须委派。 +子代理是一个独立的 Codex 工作器,主代理可以为专注任务创建它。它有自己的上下文和工具,因此多个独立任务可以并行运行。CodexCommander 负责控制 Codex 的哪种协作界面会暴露这些工作器、Codex 会为它们提供哪些模型,以及失败模型如何回退。它不会决定主代理何时必须委派。 ## 模式 @@ -29,7 +29,7 @@ description: 控制 Codex 如何在所有模型上生成和管理子代理。 - **base** 会恢复上游固定值。未固定的条目会遵循原生 `multi_agent_v2` 功能开关。 - **v2** 会把所有模型的 `multi_agent_version` 设为 `"v2"`。 -opencodex 会把这一点作为最后一步同时应用到实时的 `/v1/models` 目录和同步到磁盘的目录。因此,模式更改会一致影响新建的 App、CLI 和 TUI 会话。 +CodexCommander 会把这一点作为最后一步同时应用到实时的 `/v1/models` 目录和同步到磁盘的目录。因此,模式更改会一致影响新建的 App、CLI 和 TUI 会话。 对于 v2 roster,资格有三种状态:标记为 `"v2"` 的条目、显式设为 `null` 的条目,或者没有 `multi_agent_version` 字段的条目。真正的 `"v1"` 固定值会被排除,因为它说明该模型属于另一种协作界面。 @@ -37,11 +37,11 @@ opencodex 会把这一点作为最后一步同时应用到实时的 `/v1/models` Dashboard 上的 **Sub-agent delegation** 控件管理三个相关设置: -- `injectionModel` 是 opencodex 指引中指定的首选工作器模型。 +- `injectionModel` 是 CodexCommander 指引中指定的首选工作器模型。 - `injectionEffort` 是可选的 `reasoning_effort`,用于请求该模型。 - `injectionPrompt` 会替换内置的 v2 指引文本。 -`multiAgentGuidanceEnabled` 默认开启,是 opencodex 编写的指引在两个界面上的总开关。关闭它会同时抑制 v2 的 designation block 和 v1 的 proactive 文本。 +`multiAgentGuidanceEnabled` 默认开启,是 CodexCommander 编写的指引在两个界面上的总开关。关闭它会同时抑制 v2 的 designation block 和 v1 的 proactive 文本。 这些是发给主代理的指令,不是 proxy 侧的 spawn 路由器。对于 v2,全历史 fork 会继承父模型,并拒绝模型或 effort 覆盖。因此,指引会要求 Codex 在传递 `model` 或 `reasoning_effort` 时使用 `fork_turns: "none"`(或者像 `"3"` 这样正向的部分 turn 数),并让任务消息保持自包含。 @@ -54,31 +54,31 @@ Dashboard 上的 **Sub-agent delegation** 控件管理三个相关设置: | `{{roster}}` | 解析后的、对 picker 可见且与界面兼容的 roster | | `{{fallback}}` | 配置的全局 fallback 指引 | -内置的 v2 指引有 700 字符预算。如果会超出预算,opencodex 会优先删除 roster,而不是截断核心 spawn 指令。内置指引仅在首选模型、可用 roster 或 fallback chain 解析成功时触发。只要配置了 `injectionModel`,自定义提示词就会触发;如果未限定的值无法唯一解析,`{{model}}` 会替换为空字符串。 +内置的 v2 指引有 700 字符预算。如果会超出预算,CodexCommander 会优先删除 roster,而不是截断核心 spawn 指令。内置指引仅在首选模型、可用 roster 或 fallback chain 解析成功时触发。只要配置了 `injectionModel`,自定义提示词就会触发;如果未限定的值无法唯一解析,`{{model}}` 会替换为空字符串。 -在 v1 上,opencodex 只会在 `max` 或 `ultra` effort 下注入上游风格的主动委派指引。它不会在 v1 上额外添加首选模型、roster、fallback list 或自定义提示词。 +在 v1 上,CodexCommander 只会在 `max` 或 `ultra` effort 下注入上游风格的主动委派指引。它不会在 v1 上额外添加首选模型、roster、fallback list 或自定义提示词。 -默认关闭的 `syncCodexSubagentDefaults` 选项与指引是分开的。当 opencodex 拥有活跃的 Codex 路由时,同步或重启可以把所选值写入 Codex TOML 中带标记的 `[agents] default_subagent_model` 和 `default_subagent_reasoning_effort` 条目。opencodex 只会更新或移除带有其标记的字段。如果任一目标字段属于用户,整对值会保持不变,而不会部分写入;含糊不清的 TOML 会在不写入的情况下被拒绝。外部 provider 管理器和用户拥有的根路由也仍然具有最终权威。 +默认关闭的 `syncCodexSubagentDefaults` 选项与指引是分开的。当 CodexCommander 拥有活跃的 Codex 路由时,同步或重启可以把所选值写入 Codex TOML 中带标记的 `[agents] default_subagent_model` 和 `default_subagent_reasoning_effort` 条目。CodexCommander 只会更新或移除带有其标记的字段。如果任一目标字段属于用户,整对值会保持不变,而不会部分写入;含糊不清的 TOML 会在不写入的情况下被拒绝。外部 provider 管理器和用户拥有的根路由也仍然具有最终权威。 ## Fallback chains -对于生成出的工作器,opencodex 会按以下优先级构建顺序: +对于生成出的工作器,CodexCommander 会按以下优先级构建顺序: 1. 请求的主模型。 2. 该角色在其 `$CODEX_HOME/agents/*.toml` 定义中的 `model_fallback` 列表。 -3. opencodex 配置中的全局 `subagentModelFallback` 列表。 +3. CodexCommander 配置中的全局 `subagentModelFallback` 列表。 -重复的模型 id 会在保留第一次出现的前提下移除。在选择过程中,opencodex 会跳过已禁用、不可路由、由已禁用 provider 支撑、标记为 unhealthy、处于 cooldown、没有可用 pooled Codex 账户,或者超出配置配额阈值的候选项。可用性探测会缓存 `subagentModelFallbackPollMs` 的时长,默认 60 秒。 +重复的模型 id 会在保留第一次出现的前提下移除。在选择过程中,CodexCommander 会跳过已禁用、不可路由、由已禁用 provider 支撑、标记为 unhealthy、处于 cooldown、没有可用 pooled Codex 账户,或者超出配置配额阈值的候选项。可用性探测会缓存 `subagentModelFallbackPollMs` 的时长,默认 60 秒。 fallback 不会让不兼容的加密任务变得可读。当子任务为 ChatGPT 加密时,即使链中更靠前出现了外部模型,选择也只会限制在规范的原生 ChatGPT 目标上。 ## 加密的 v2 任务传递 -Codex 只能把 v2 原生到路由的子任务作为后端加密的 `encrypted_content` 发送。这个载荷可以被原生 ChatGPT 后端读取,但外部 provider 不能读取。这就是已知的 [#92](https://github.com/lidge-jun/opencodex/issues/92) 限制。 +Codex 只能把 v2 原生到路由的子任务作为后端加密的 `encrypted_content` 发送。这个载荷可以被原生 ChatGPT 后端读取,但外部 provider 不能读取。这就是已知的 [#92](https://github.com/pavelhov/CodexCommander/issues/92) 限制。 -这是默认 `multiAgentV2MessageDelivery: "encrypted"` 的行为。选择实验性的 `"plaintext"` 后,OpenCodex 只会把完整且已识别的 V2 协议转换到非保留命名空间,并在返回 Codex 前恢复为 `collaboration`。这样 Sol 等原生父级可以在保留 V2 生命周期的同时委派给 Kimi、Grok 和 DeepSeek。代价是该父级的所有 V2 消息都会成为明文,包括发给原生子级的消息。保存后必须启动新会话;未知或不完整的协议不会被猜测转换,而是继续安全失败。 +这是默认 `multiAgentV2MessageDelivery: "encrypted"` 的行为。选择实验性的 `"plaintext"` 后,CodexCommander 只会把完整且已识别的 V2 协议转换到非保留命名空间,并在返回 Codex 前恢复为 `collaboration`。这样 Sol 等原生父级可以在保留 V2 生命周期的同时委派给 Kimi、Grok 和 DeepSeek。代价是该父级的所有 V2 消息都会成为明文,包括发给原生子级的消息。保存后必须启动新会话;未知或不完整的协议不会被猜测转换,而是继续安全失败。 -opencodex 会安全失败,而不是转发空任务或不可读任务: +CodexCommander 会安全失败,而不是转发空任务或不可读任务: - 直接的非原生路由会返回 HTTP 400,并且 `error.code = "unreadable_encrypted_agent_task"`,不会回显密文。 - 对于该任务,combo 只会考虑规范的原生 ChatGPT 目标,包括重试。如果没有可用目标,则返回相同的 400 错误。 @@ -101,27 +101,27 @@ opencodex 会安全失败,而不是转发空任务或不可读任务: ### CLI -使用 `ocx v2` 管理协作界面和原生功能设置: +使用 `ccx v2` 管理协作界面和原生功能设置: ```bash -ocx v2 status -ocx v2 mode v1 -ocx v2 mode default -ocx v2 mode v2 -ocx v2 threads 8 +ccx v2 status +ccx v2 mode v1 +ccx v2 mode default +ccx v2 mode v2 +ccx v2 threads 8 ``` -使用 `ocx agent` 管理委派、roster、effort 上限和 fallback 设置: +使用 `ccx agent` 管理委派、roster、effort 上限和 fallback 设置: ```bash -ocx agent status -ocx agent injection set --model anthropic/claude-sonnet-5 --effort xhigh -ocx agent subagents set gpt-5.6-sol,anthropic/claude-sonnet-5 -ocx agent fallback set gpt-5.4-mini,xai/grok-4.5 --poll-ms 60000 -ocx agent effort set --subagent max +ccx agent status +ccx agent injection set --model anthropic/claude-sonnet-5 --effort xhigh +ccx agent subagents set gpt-5.6-sol,anthropic/claude-sonnet-5 +ccx agent fallback set gpt-5.4-mini,xai/grok-4.5 --poll-ms 60000 +ccx agent effort set --subagent max ``` -传入 `-` 可清除可空的 `ocx agent injection` 值,或者对 roster / fallback list 使用相应的 `clear` 操作。所有命令族请参见 [CLI reference](/reference/cli/)。 +传入 `-` 可清除可空的 `ccx agent injection` 值,或者对 roster / fallback list 使用相应的 `clear` 操作。所有命令族请参见 [CLI reference](/reference/cli/)。 ### API @@ -163,11 +163,11 @@ curl -X PUT http://localhost:10100/api/injection-model \ ### 模式更改会影响正在运行的会话吗? -不会。更改模式后请启动一个新的 Codex 会话。如果长时间运行的 App host 仍然显示旧的目录状态,请运行 `ocx sync` 并重启那个 Codex 界面。 +不会。更改模式后请启动一个新的 Codex 会话。如果长时间运行的 App host 仍然显示旧的目录状态,请运行 `ccx sync` 并重启那个 Codex 界面。 ### 推理强度 -`injectionEffort` 只会影响委派工作器的指引,以及在显式启用时影响原生 Codex 子代理默认值。它不会改变父会话的 effort。`ultra` 是面向客户端的顶级档位,Codex 会把它转换成 `max`;随后 opencodex 会按所选 provider 对该值进行映射或限制。 +`injectionEffort` 只会影响委派工作器的指引,以及在显式启用时影响原生 Codex 子代理默认值。它不会改变父会话的 effort。`ultra` 是面向客户端的顶级档位,Codex 会把它转换成 `max`;随后 CodexCommander 会按所选 provider 对该值进行映射或限制。 ### 上下文上限 diff --git a/docs-site/src/content/docs/zh-cn/guides/video-bridge.md b/docs-site/src/content/docs/zh-cn/guides/video-bridge.md index 39eb79c50b..a2b199a4d8 100644 --- a/docs-site/src/content/docs/zh-cn/guides/video-bridge.md +++ b/docs-site/src/content/docs/zh-cn/guides/video-bridge.md @@ -5,13 +5,13 @@ description: 通过非 OpenAI 模型生成 Grok Imagine Video 视频。 ## 概述 -Video Bridge 允许你通过 opencodex 路由的任意非 OpenAI 模型使用 xAI 的 Grok Imagine Video 生成功能。启用后,系统会在对话中注入一个合成的 `video_gen` 工具。模型会像调用普通函数工具一样调用它;opencodex 拦截该调用,向 xAI 提交视频生成任务,轮询直到完成,然后下载结果。 +Video Bridge 允许你通过 CodexCommander 路由的任意非 OpenAI 模型使用 xAI 的 Grok Imagine Video 生成功能。启用后,系统会在对话中注入一个合成的 `video_gen` 工具。模型会像调用普通函数工具一样调用它;CodexCommander 拦截该调用,向 xAI 提交视频生成任务,轮询直到完成,然后下载结果。 ## 前提条件 -- 一个带有 **API key** 的 `xai` provider 条目(仅执行 `ocx login xai` 不够,视频桥接需要 key 认证,而不是 OAuth) +- 一个带有 **API key** 的 `xai` provider 条目(仅执行 `ccx login xai` 不够,视频桥接需要 key 认证,而不是 OAuth) - 作为路由目标的非 OpenAI 模型(例如 Anthropic Claude、Google Gemini) -- 已配置 opencodex 通过该非 OpenAI provider 路由 +- 已配置 CodexCommander 通过该非 OpenAI provider 路由 > **⚠ 需要 provider key:** 只有当 `xai` provider 使用 API key 认证时,视频桥接才会生效。请在配置中加入以下内容: > @@ -23,7 +23,7 @@ Video Bridge 允许你通过 opencodex 路由的任意非 OpenAI 模型使用 xA > } > ``` > -> 如果你是通过 `ocx login xai` 接入的(OAuth),provider 会保持在 `authMode: "oauth"`,桥接就会静默不启用。请在环境中设置 `XAI_API_KEY`,或者像上面那样直接硬编码密钥。 +> 如果你是通过 `ccx login xai` 接入的(OAuth),provider 会保持在 `authMode: "oauth"`,桥接就会静默不启用。请在环境中设置 `XAI_API_KEY`,或者像上面那样直接硬编码密钥。 ## 配置 @@ -50,9 +50,9 @@ Video Bridge 允许你通过 opencodex 路由的任意非 OpenAI 模型使用 xA ## 工作原理 -1. opencodex 检测到一个已路由的非 OpenAI 模型,并且 `videoBridgeEnabled: true` +1. CodexCommander 检测到一个已路由的非 OpenAI 模型,并且 `videoBridgeEnabled: true` 2. 系统会在对话中注入一个合成的 `video_gen` 函数工具 -3. 当模型调用 `video_gen` 时,opencodex 会向 xAI 的 `/videos/generations` 提交任务 +3. 当模型调用 `video_gen` 时,CodexCommander 会向 xAI 的 `/videos/generations` 提交任务 4. 桥接每隔 5-15 秒轮询一次任务状态,并发送心跳消息以保持流持续存活 5. 视频准备就绪后,会下载到 artifacts 目录 6. 本地文件路径会作为工具结果返回给模型 diff --git a/docs-site/src/content/docs/zh-cn/guides/web-dashboard.md b/docs-site/src/content/docs/zh-cn/guides/web-dashboard.md index b63604fbd4..c0b1b9e356 100644 --- a/docs-site/src/content/docs/zh-cn/guides/web-dashboard.md +++ b/docs-site/src/content/docs/zh-cn/guides/web-dashboard.md @@ -1,28 +1,28 @@ --- title: Web 仪表盘 -description: 用于管理代理健康状态、provider、模型、委派指引、认证池、usage 和日志的 opencodex GUI。 +description: 用于管理代理健康状态、provider、模型、委派指引、认证池、usage 和日志的 CodexCommander GUI。 --- -opencodex 内置了一个由代理提供服务的本地 web 仪表盘(`gui/` 下的 Vite/React 应用)。你可以在 +CodexCommander 内置了一个由代理提供服务的本地 web 仪表盘(`gui/` 下的 Vite/React 应用)。你可以在 这里快速管理 provider、Codex/ChatGPT 账号、目录模型、sidecar、子代理设置和请求流量。 ## 打开仪表盘 ```bash -ocx gui +ccx gui ``` 该命令会在浏览器中打开 `http://localhost:<port>`;如果代理尚未运行,会先自动启动。开发时也可 让 GUI dev server 单独连接到正在运行的代理: ```bash -ocx start +ccx start bun run dev:gui ``` ## 登录 -通过 `localhost`、`127.0.0.1` 等 loopback 地址打开仪表盘时,它会自动获得一个短期 GUI session,因此通常无需输入 token。在非 loopback 主机上公开仪表盘时,必须使用 `OPENCODEX_ADMIN_AUTH_TOKEN` 或自动生成的 `~/.opencodex/admin-api-token` 文件中的管理员 token。 +通过 `localhost`、`127.0.0.1` 等 loopback 地址打开仪表盘时,它会自动获得一个短期 GUI session,因此通常无需输入 token。在非 loopback 主机上公开仪表盘时,必须使用 `CODEXCOMMANDER_ADMIN_AUTH_TOKEN` 或自动生成的 `~/.codexcommander/admin-api-token` 文件中的管理员 token。 远程仪表盘会显示标准密码表单,浏览器密码管理器可以提示保存并自动填充 token。仪表盘本身只在内存中保存 token,不会写入 `localStorage` 或 `sessionStorage`;是否持久保存完全由浏览器或密码管理器决定。 @@ -31,19 +31,19 @@ bun run dev:gui | 区域 | 作用 | | --- | --- | | **Dashboard 摘要** | 显示 multi-agent 模式、在线状态、版本、运行时间、provider 数量、30 天 token 总量、活动 provider 和可用的原生/路由模型。 | -| **Sub-agent delegation** | 选择供 OpenCodex 委派指引与可选的 Codex 原生子代理默认值共用的原生/路由模型和可选 reasoning 强度。它不是逐次生成的路由器,详见下文。 | +| **Sub-agent delegation** | 选择供 CodexCommander 委派指引与可选的 Codex 原生子代理默认值共用的原生/路由模型和可选 reasoning 强度。它不是逐次生成的路由器,详见下文。 | | **Sidecar** | 选择 web-search 模型及强度,以及图像描述模型;更改从下一次请求开始生效。 | -| **Maintenance** | 重新同步 Codex 模型目录,查看项目级配置绕过警告,检查 latest/preview 版本,并可在更新后重启代理。 | +| **Maintenance** | 重新同步 Codex 模型目录并查看项目级配置绕过警告。 | | **启动安全** | 显示注入的 Codex 路由能否在重启后继续工作,并分别显示服务、launcher shim 状态和准确的修复命令。 | | **Windows 托盘** | 安装用户登录托盘,一键控制代理启动、停止、重启、面板和状态。托盘不是代理重启服务。 | -| **Codex 自动启动** | 允许已安装的 Codex launcher shim 运行 `ocx ensure`。此开关不会安装 shim 或后台服务。 | +| **Codex 自动启动** | 允许已安装的 Codex launcher shim 运行 `ccx ensure`。此开关不会安装 shim 或后台服务。 | | **Providers** | 添加、编辑、设为默认(仅已启用)、启用/禁用、删除 provider,并在支持时管理 OAuth 账号池和 API key 池。删除当前默认时,会切换到剩余的第一个已启用 provider(若存在);否则拒绝删除并保留当前默认。Claude(Anthropic)OAuth 池中,每个已登录账号显示各自的 5 小时与周限额条(用量按凭证计);探测失败时保留上次已知数值并标记为暂时不可用。 | | **Add provider** | 搜索 registry preset,选择账号登录、API key 服务、本地服务器或自定义 endpoint。输入搜索词时会同时搜索 Accounts、Free 和 Paid;标签仍可用于浏览。 | | **Codex Auth** | 添加 ChatGPT/Codex 池账号,选择下一 session 的账号,刷新 5h / 每周 / 30d 配额,启用或停用配额自动切换,设置其 1–100% 阈值和临时故障 failover。 | | **Subagents** | 在 **Agent Command Center** 中选择并排序向 `spawn_agent` 公开的五个模型、搜索当前目录,并配置协议、V2 传递、引导、回退和线程上限等 Run Policy。已保存但未公开的条目会被明确报告。 | | **Models** | 开关原生 GPT 与路由模型,配置 provider allowlist 和上下文上限,选择 **Classic v1**、**Follow Codex defaults** 或 **Concurrent v2**,并设置 v2 thread 数量。Current behavior 卡片会将上下文显示为 **Uncapped**、**Limited** 或 **Mixed limits**。每个路由 provider 都会显示 **自动发现已开启** 或 **仅静态目录**,并链接到对应的 provider 设置。 | | **Client Apps** | 查看已配置和可连接的本地客户端;在支持时应用或移除托管配置并检查备份;集中访问 Codex、Claude Code/Desktop、Grok Build、OpenCode 及文件托管客户端,同时避免把客户端与提供商混为一谈。 | -| **API Access** | 签发和管理其他应用连接 OpenCodex 代理时使用的认证密钥。上游提供商凭据仍归 Providers 管理。 | +| **API Access** | 签发和管理其他应用连接 CodexCommander 代理时使用的认证密钥。上游提供商凭据仍归 Providers 管理。 | | **Logs** | 自动刷新近期请求,显示 token、请求强度以及(可用时)实际发送强度、实际模型、provider、状态、request id、耗时和错误详情。适配器发送 reasoning 参数时,详情中还会显示准确的 wire field。可按不透明会话/对话 ID(客户端提供时)筛选,并对当前已加载的 Logs 环形缓冲合计 token 与估算标价成本。 | | **Usage / Debug** | 查看 token usage 覆盖率与趋势,或启用可选的 provider transport 和 usage 提取诊断。 | | **Storage** | 只读查看 CODEX_HOME 磁盘占用(会话、归档、数据库、附件)。可选归档清理:预览最旧 N%,默认隔离到 `CODEX_HOME/.trash`,或勾选后永久删除。**自动清理策略**为可选且**默认关闭**(`storageCleanupPolicy.enabled`);可在 Storage 页配置阈值/目标/计划/模式,或点「立即运行」。可在 Storage 页从隔离区恢复(JSONL + 线程)。活动会话保持只读。Codex 锁定最新/活动的 `state_*.sqlite` 时拒绝清理与恢复。 | @@ -51,7 +51,7 @@ bun run dev:gui ### 链接到某个部分 -布局只有一种,无需切换。Dashboard 的各个部分都有自己的地址:`#dashboard` 打开 Overview,`#dashboard/providers` 与 `#dashboard/models` 打开另外两个。刷新、收藏和后退都会保留当前所在的部分。**Logs** 同理,使用 `#logs` 与 `#logs/debug`。旧的 `#providers/workspace` 书签现在会跳转到 `#providers`。 +布局只有一种,无需切换。Dashboard 的各个部分都有自己的地址:`#dashboard` 打开 Overview,`#dashboard/providers` 与 `#dashboard/models` 打开另外两个。刷新、收藏和后退都会保留当前所在的部分。**Logs** 同理,使用 `#logs` 与 `#logs/debug`。 **Logs** 和 **Usage** 中的费用是根据已报告 token 计算的 API 标价折算值,不是账单,也不能证明 实际发生了扣费;实际可能计入订阅用量或消耗服务商额度。 @@ -65,15 +65,15 @@ bun run dev:gui ## 委派选择器与生成路由的区别 Dashboard 的 **Sub-agent delegation** 选择器会保存 `injectionModel`,以及可选的 -`injectionEffort`。所选值会用于由 OpenCodex 编写的委派指引,而该指引由 +`injectionEffort`。所选值会用于由 CodexCommander 编写的委派指引,而该指引由 `multiAgentGuidanceEnabled` 单独控制。清除模型时也会清除已保存的强度,并关闭原生默认值同步。 -启用 **用作原生 Codex 子代理默认值** 后,当 OpenCodex 管理当前 Codex 路由时,下一次同步或重启会 +启用 **用作原生 Codex 子代理默认值** 后,当 CodexCommander 管理当前 Codex 路由时,下一次同步或重启会 把所选模型和强度应用为原生 `[agents]` 默认值;外部用户管理的 provider 配置不会被修改。这些默认值只影响新建的 Codex 任务,该选项本身不会触发委派。已有的用户自有 `[agents]` 默认值会保留而不会被覆盖,因此请求的默认值可能与 Codex 实际使用的默认值不同。 :::caution -两个开关相互独立:关闭 OpenCodex 委派指引不会关闭原生默认值同步;启用原生默认值同步也不会 +两个开关相互独立:关闭 CodexCommander 委派指引不会关闭原生默认值同步;启用原生默认值同步也不会 启用委派指引或触发委派。两者都不是代理侧的逐次跨模型路由器。v1/base/v2 的 权威说明见 [子代理界面](/zh-cn/guides/sub-agent-surface/)。 ::: @@ -95,7 +95,7 @@ Pool 模式会在主账号和已添加的 Codex 账号之间选择;Direct 只 - 每张账号卡片都带有 **选择顺序** 控件(最先 / 较先 / 默认 / 较后 / 最后)。顺序靠前的账号先被使用, 只有当它上面的账号全部耗尽或不可用时才会降到更靠后的顺序。改动顺序会从**下一个未绑定请求**起生效, 且不会移动已经绑定的 thread。Codex Desktop(主)账号同样参与排序,可以设为 **最后** 留作备用。 - 用 `ocx account priority` 设置的非预设值也会保留在卡片上,仍可选择。 + 用 `ccx account priority` 设置的非预设值也会保留在卡片上,仍可选择。 - Thread affinity 可避免每个请求都来回切换账号。启用配额自动切换后,长时间运行的 thread 会被 定期重新评估;当相关 usage 达到阈值,并且存在使用率确实更低的可用账号时,该 thread 可能会 重新绑定。 @@ -118,7 +118,6 @@ GUI 是代理 JSON 管理 API 之上的轻量客户端。常用 endpoint 包括 | `GET /api/startup-health` | 读取不含秘密信息的路由、服务、shim 和重启安全诊断。 | | `GET` / `POST /api/windows-tray` | 读取或更改 Windows 托盘安装和显示状态;POST 支持 `install`、`start`、`stop`、`uninstall`。 | | `POST /api/sync` | 重建共享模型目录,并把 Codex 模型缓存标记为过期。 | -| `GET /api/update/check` · `POST /api/update/run` · `GET /api/update/status` | 检查、运行和监控自更新任务。 | | `GET` / `PUT /api/sidecar-settings` | 读取或设置 search/vision sidecar 模型。 | | `GET` / `PUT /api/injection-model` | 读取或设置委派指引模型/强度、指引开关及 Codex 原生子代理默认值同步开关。 | | `GET` / `PUT /api/v2` | 读取或设置界面模式、Codex feature flag 和 v2 thread 上限。 | diff --git a/docs-site/src/content/docs/zh-cn/index.mdx b/docs-site/src/content/docs/zh-cn/index.mdx index 49f2e95c6b..197eb60488 100644 --- a/docs-site/src/content/docs/zh-cn/index.mdx +++ b/docs-site/src/content/docs/zh-cn/index.mdx @@ -1,10 +1,10 @@ --- -title: "opencodex — 让 Codex 跑在任意 LLM 上" +title: "CodexCommander — 让 Codex 跑在任意 LLM 上" description: 面向 OpenAI Codex 与 Claude Code 的通用 provider 代理 —— 在 Codex CLI、App、SDK 和 Claude Code 中使用任意 LLM。 template: splash head: - tag: title - content: "opencodex — 让 Codex 跑在任意 LLM 上" + content: "CodexCommander — 让 Codex 跑在任意 LLM 上" - tag: meta attrs: property: og:locale diff --git a/docs-site/src/content/docs/zh-cn/reference/adapters.md b/docs-site/src/content/docs/zh-cn/reference/adapters.md index 032df88068..a6b5cb55bd 100644 --- a/docs-site/src/content/docs/zh-cn/reference/adapters.md +++ b/docs-site/src/content/docs/zh-cn/reference/adapters.md @@ -3,7 +3,7 @@ title: Adapters description: 七个 provider adapter 的目标、请求构建方式与各自特性。 --- -**adapter** 负责在 opencodex 的内部请求/响应模型与某个 provider 的 wire 格式之间转换。每个 +**adapter** 负责在 CodexCommander 的内部请求/响应模型与某个 provider 的 wire 格式之间转换。每个 adapter 都实现 `ProviderAdapter` 接口(`src/adapters/base.ts`): ```ts @@ -17,7 +17,7 @@ interface ProviderAdapter { } ``` -`buildRequest` 把 `OcxParsedRequest` 转成上游 HTTP 请求;`parseStream` / `parseResponse` 把 provider +`buildRequest` 把 `CodexCommanderParsedRequest` 转成上游 HTTP 请求;`parseStream` / `parseResponse` 把 provider 回复转回内部 `AdapterEvent`。`fetchResponse` 允许 adapter 自己负责重试和 timeout;`runTurn` 支持 无法表示成一次 HTTP fetch 加一条响应流的 transport。随后 [`bridge.ts`](/zh-cn/reference/architecture/#桥接器) 把 event 转成 Responses SSE。 @@ -54,7 +54,7 @@ interface ProviderAdapter { 会等待并先于其他处理或故障转移,在相同 key 上重放完全相同请求,与翻译后的 `openai-chat`/Anthropic 请求路径一致。自定义 `runTurn` 传输不在 HTTP 重试循环之内。 -- `forward` URL → `{baseUrl}/responses`。`key` provider 默认保留原有的 `{baseUrl}/v1/responses` 构造。 +- `forward` URL → `{baseUrl}/responses`。`key` provider 的默认 URL 是 `{baseUrl}/v1/responses`。 - `key` provider 可设置经过验证的相对 `responsesPath`;adapter 会移除 `baseUrl` 末尾的一个 `/`,并向 `{trimmedBaseUrl}{responsesPath}` 发送请求。Ark Agent Plan 使用 `baseUrl: "https://ark.cn-beijing.volces.com/api/plan/v3"` 和 `responsesPath: "/responses"`。 - `forward` 模式只会转发安全的 header allowlist(`FORWARD_HEADERS`):authorization、ChatGPT account id 和 OpenAI beta/originator/session header。这条 ChatGPT 登录路径也为 @@ -106,7 +106,7 @@ Kiro 的 assistant 文本本身没有可靠的回合结束标记,但终止的 错误,内容过滤或 guardrail 停止表现为 filtered incomplete。没有真实工具调用却出现的 `TOOL_USE` 被视为 矛盾而非进展。 -启用工具时,opencodex 会添加私有 `codex_kiro_final_answer`。重试不会制造空的 assistant/user 回合, +启用工具时,CodexCommander 会添加私有 `codex_kiro_final_answer`。重试不会制造空的 assistant/user 回合, 而会保留原始 user/tool-result,并在发送前校验角色交替、非空结构消息以及 tool use/result 配对。 完成工具的回答即使与先前 commentary 完全相同,也会作为 `final_answer` 发出。 @@ -131,10 +131,10 @@ Kiro 的 assistant 文本本身没有可靠的回合结束标记,但终止的 - 保留 `cursor/grok-4.5-fast` 作为可选模型,但向 Cursor 发送规范的 `grok-4.5` 模型,并将独立的 `effort` 和 `fast=true` 值放入 `requested_model.parameters`。 - Cursor 原生本地 filesystem/shell/network 执行默认被拒绝。显式 `mcpServers` 与 - `desktopExecutor` 集成分别需要 opt-in;`unsafeAllowNativeLocalExec` 会启用更广泛的内置 + `desktopExecutor` 集成分别需要 opt-in;`nativeLocalExec: "on"` 会启用更广泛的内置 executor,并绕过 Codex 审批和 sandbox 语义。 -## `azure-openai`(别名:`azure`) +## `azure-openai` **目标:** **Azure OpenAI**。封装 `openai-responses`,因此同样是 `passthrough: true`。 **认证:** 用 `api-key` header 进行 `key` 认证,而非 Bearer。 diff --git a/docs-site/src/content/docs/zh-cn/reference/architecture.md b/docs-site/src/content/docs/zh-cn/reference/architecture.md index 806631086f..0b7ea27d11 100644 --- a/docs-site/src/content/docs/zh-cn/reference/architecture.md +++ b/docs-site/src/content/docs/zh-cn/reference/architecture.md @@ -1,9 +1,9 @@ --- title: 架构 -description: opencodex 内部机制 —— 模块图、请求解析器、AdapterEvent 桥接与缓存。 +description: CodexCommander 内部机制 —— 模块图、请求解析器、AdapterEvent 桥接与缓存。 --- -opencodex 运行在单个 Bun 进程中。请求以 OpenAI Responses 格式进入,规范化为内部模型后完成 +CodexCommander 运行在单个 Bun 进程中。请求以 OpenAI Responses 格式进入,规范化为内部模型后完成 路由,再由 adapter 发送到 provider,最后桥接回 Responses SSE。端到端流程参见 [工作原理](/zh-cn/getting-started/how-it-works/)。 @@ -11,7 +11,7 @@ opencodex 运行在单个 Bun 进程中。请求以 OpenAI Responses 格式进 ``` src/ -├── cli/ # ocx command dispatch, init, status, provider commands +├── cli/ # ccx command dispatch, init, status, provider commands ├── server/ # Bun.serve, /v1/* proxy, /api/* management API, WS bridge ├── codex/ # Codex config injection, catalog sync, auth/account integration ├── providers/ # provider metadata, API-key pool, quota and labels @@ -21,12 +21,12 @@ src/ ├── lib/ # runtime, process, retry, privacy, token estimate helpers ├── web-search/ # web-search sidecar (synthetic tool, loop, executor, parser) ├── vision/ # vision sidecar (describe + plan) -├── config.ts # ~/.opencodex/config.json, defaults, PID, env resolution +├── config.ts # ~/.codexcommander/config.json, defaults, PID, env resolution ├── router.ts # model id → provider + adapter ├── bridge.ts # AdapterEvent stream → Responses SSE / JSON ├── reasoning-effort.ts # reasoning-effort translation, clamping, and catalog levels ├── responses/ -│ ├── parser.ts # Responses request → OcxParsedRequest +│ ├── parser.ts # Responses request → CodexCommanderParsedRequest │ ├── schema.ts # Zod validation │ └── compaction.ts # remote compaction prompts, envelopes, compact history ├── service.ts # launchd / systemd / Task Scheduler background service @@ -34,14 +34,13 @@ src/ └── index.ts # public entry ``` -原先的三个大型入口文件现在是兼容性 facade:`codex/catalog.ts` 导出 7 个 -`codex/catalog/*.ts` 模块,`server/management-api.ts` 分派到 9 个 +`codex/catalog.ts` 导出 7 个 `codex/catalog/*.ts` 模块,`server/management-api.ts` 分派到 9 个 `server/management/*.ts` 模块,而 `server/responses.ts` 导出 5 个 `server/responses/*.ts` 模块。 ## 请求流程 -`server/index.ts` 负责 HTTP 边界,并把 Responses data plane 交给 `server/responses.ts` facade +`server/index.ts` 负责 HTTP 边界,并把 Responses data plane 交给 `server/responses.ts` 及其 `server/responses/*.ts` 模块: 1. `server/index.ts` 应用 CORS 和 API 认证,在 drain 期间拒绝新请求,并记录请求生命周期 @@ -68,9 +67,9 @@ src/ ## 解析器 `responses/parser.ts` 使用 `responses/schema.ts`(Zod)校验传入请求,然后构建 -`OcxParsedRequest`: +`CodexCommanderParsedRequest`: -- **消息(Messages)** —— `input` 条目会变成规范化的 `OcxMessage[]`:user / developer / +- **消息(Messages)** —— `input` 条目会变成规范化的 `CodexCommanderMessage[]`:user / developer / assistant / toolResult。`reasoning` 条目变成 thinking block;`function_call`、 `custom_tool_call`、`tool_search_call` 条目变成工具调用;对应的 `*_output` 条目变成工具结果。 - **工具(Tools)** —— function 工具直接透传;**带命名空间的(MCP)工具会被扁平化**为 @@ -117,18 +116,18 @@ item,因此 MCP 命名空间、`apply_patch` 风格的 freeform 工具和客 CRUD 与 key pool、模型选择/context cap/v2 控制、catalog sync、诊断与 debug log、usage 与 quota、sidecar 设置、更新、生成客户端 API key、OAuth 登录/状态/登出与账号选择、Codex 账号 管理,以及 graceful stop。proxy 绑定到 loopback 之外时,`server/auth-cors.ts` 会要求 -`/api/*` 和 `/v1/*` 都提供 `OPENCODEX_API_AUTH_TOKEN`;配置的 `corsAllowOrigins` 会扩展本地 +`/api/*` 和 `/v1/*` 都提供 `CODEXCOMMANDER_API_AUTH_TOKEN`;配置的 `corsAllowOrigins` 会扩展本地 origin allowlist。 OAuth 实现在 `oauth/` 中;每次路由调用前都会即时加载或刷新 access token,而 `oauth/token-guardian.ts` 只会主动刷新策略允许的 provider。Codex/ChatGPT pool credential 与 -thread affinity 位于 `codex/` 下,不会出现在管理 API 响应中。请求用量会规范化为 `OcxUsage`, +thread affinity 位于 `codex/` 下,不会出现在管理 API 响应中。请求用量会规范化为 `CodexCommanderUsage`, 显示在 Responses 终止 event 中,并由 `usage/` 汇总,供仪表盘和可选的 JSONL 诊断使用。 ## 传输与 compaction `server/index.ts` 默认在 `/v1/responses` 上提供 HTTP/SSE。当 `websockets` 为 `false` 而 Codex -尝试 Responses WebSocket upgrade 时,opencodex 会返回 `426 upgrade_required`,Codex 随后在该 +尝试 Responses WebSocket upgrade 时,CodexCommander 会返回 `426 upgrade_required`,Codex 随后在该 session 中回退到 HTTP。设置 `"websockets": true` 后,同一 endpoint 会接受 upgrade 并使用 WebSocket bridge。 @@ -141,7 +140,7 @@ Codex context compaction 同样适用于路由模型。`server/responses/compact - `codex/model-cache.ts` 为每个 provider 维护实时 `/models` 结果的内存 TTL 缓存(默认 5 分钟, 与 Codex 自身缓存一致),获取失败时会回退到旧数据。 -- `codex/catalog.ts` facade 导出的 `codex/catalog/sync.ts` 把路由模型作为带命名空间的条目 +- `codex/catalog.ts` 导出的 `codex/catalog/sync.ts` 把路由模型作为带命名空间的条目 合并进 Codex 目录,优先排列精选的 [subagent 模型](/zh-cn/guides/codex-integration/#subagent-选择器),过滤 `disabledModels`,并可从一次性备份中完整恢复原始目录。 @@ -159,7 +158,7 @@ Codex context compaction 同样适用于路由模型。`server/responses/compact ## 核心类型 -内部模型位于 `types.ts`:`OcxParsedRequest`、`OcxContext`、`OcxMessage` 联合类型、 -`OcxContentPart`(text / image)、`OcxToolCall`、`OcxTool`、`AdapterEvent`,以及配置类型 -(`OcxConfig`、`OcxProviderConfig`)。两个常用 helper 是 `namespacedToolName()` 和 +内部模型位于 `types.ts`:`CodexCommanderParsedRequest`、`CodexCommanderContext`、`CodexCommanderMessage` 联合类型、 +`CodexCommanderContentPart`(text / image)、`CodexCommanderToolCall`、`CodexCommanderTool`、`AdapterEvent`,以及配置类型 +(`CodexCommanderConfig`、`CodexCommanderProviderConfig`)。两个常用 helper 是 `namespacedToolName()` 和 `modelInList()`;后者会在匹配 `noVisionModels` / `noReasoningModels` 时容忍 `:size` 标签。 diff --git a/docs-site/src/content/docs/zh-cn/reference/cli.md b/docs-site/src/content/docs/zh-cn/reference/cli.md index 30a946ffb8..d43c6c9e07 100644 --- a/docs-site/src/content/docs/zh-cn/reference/cli.md +++ b/docs-site/src/content/docs/zh-cn/reference/cli.md @@ -1,15 +1,15 @@ --- title: CLI 参考 -description: 命令分发、退出码,以及指向每个 ocx 命令族的链接。 +description: 命令分发、退出码,以及指向每个 ccx 命令族的链接。 --- -opencodex 的 CLI 是 `ocx`。它会根据第一个命令名进行分发;文档中列出的别名,例如 `setup`/`init`、`restore`/`eject` 以及 `models`/`model`,都会到达同一操作。未知命令和无效的命令形状都视为错误。 +CodexCommander 的 CLI 是 `ccx`。它会根据第一个命令名进行分发;文档中列出的别名,例如 `setup`/`init`、`restore`/`eject` 以及 `models`/`model`,都会到达同一操作。未知命令和无效的命令形状都视为错误。 -运行 `ocx help`(或 `ocx --help` / `ocx -h`)查看顶层用法。运行 `ocx help <command>`、`ocx <command> --help` 或 `ocx <command> -h`,可查看在帮助表中注册的命令。帮助和版本命令都是只读的:它们不会启动、停止、安装、卸载或改写 Codex 或 opencodex 状态。 +运行 `ccx help`(或 `ccx --help` / `ccx -h`)查看顶层用法。运行 `ccx help <command>`、`ccx <command> --help` 或 `ccx <command> -h`,可查看在帮助表中注册的命令。帮助和版本命令都是只读的:它们不会启动、停止、安装、卸载或改写 Codex 或 CodexCommander 状态。 ## 命令族 -- [生命周期](/reference/cli/lifecycle/) —— 设置、代理和服务生命周期、健康检查、诊断、目录同步、仪表盘和更新。 +- [生命周期](/reference/cli/lifecycle/) —— 设置、代理和服务生命周期、健康检查、诊断、目录同步和仪表盘。 - [提供商、账号与模型](/reference/cli/providers-accounts/) —— 提供商配置、认证、凭据池、配额、自定义模型、可见性、已选模型和上下文上限。 - [代理、路由与集成](/reference/cli/agents/) —— 多代理控制、组合、可观测性、准入密钥、客户端集成、运行时设置和已验证配置。 @@ -17,16 +17,14 @@ opencodex 的 CLI 是 `ocx`。它会根据第一个命令名进行分发;文 管理命令会通过实时代理的管理 API 往返调用,使用记录下来的运行时端口和身份检查,而不是维护第二条配置路径。已停止或不可达的代理会被表示为 HTTP 503,并导致 CLI 以非零状态退出。明确标注为离线配置操作的命令,则可以在没有实时代理的情况下验证并编辑配置文件。 -在语义明确时,默认操作是 `list` 或 `status`。使用 `--json` 获取结构化快照,使用 `ocx observe logs --follow --jsonl` 获取流式请求日志。主题、语言、导航以及其他纯视觉浏览器状态都没有 CLI 对应项;Cloudflare Tunnel 的设置不在这组命令之内。 +在语义明确时,默认操作是 `list` 或 `status`。使用 `--json` 获取结构化快照,使用 `ccx observe logs --follow --jsonl` 获取流式请求日志。主题、语言、导航以及其他纯视觉浏览器状态都没有 CLI 对应项;Cloudflare Tunnel 的设置不在这组命令之内。 ## 退出码与确认 -成功的命令退出码为 0。无效用法、未知命令或资源、API 操作失败,以及必需服务不可用时,退出码都非零。`ocx health` 只有在代理健康时才以 0 退出,否则以 1 退出,因此可作为服务探针。脚本应检查退出码,而不是解析人类可读输出。 +成功的命令退出码为 0。无效用法、未知命令或资源、API 操作失败,以及必需服务不可用时,退出码都非零。`ccx health` 只有在代理健康时才以 0 退出,否则以 1 退出,因此可作为服务探针。脚本应检查退出码,而不是解析人类可读输出。 -声明需要确认的破坏性删除、导入、额度消耗和更新操作,在非交互用法中都要求 `--yes`。该标志是显式选择加入;省略它时,绝不能在静默情况下确认该操作。 +声明需要确认的破坏性删除、导入和额度消耗操作,在非交互用法中都要求 `--yes`。该标志是显式选择加入;省略它时,绝不能在静默情况下确认该操作。 -## 版本与内部分发目标 +## 版本 -`ocx --version`、`ocx -v` 和 `ocx version` 会打印一行适合脚本读取的版本信息并退出。 - -有两个分发目标会刻意不出现在普通帮助中:`__refresh-version [preview]` 会在分离进程中刷新更新通知缓存,而 `__gui-update-worker <job-id> [latest|preview] [restart]` 会运行一个仪表盘更新任务。它们是实现细节,不是稳定的面向用户命令。仪表盘会记录 worker PID,恢复 worker 已死亡但仍处于活动状态的任务,把更早的、没有 PID 的活动记录在十分钟后视为过期,并保护存活的 worker 不受并发更新影响。 +`ccx --version`、`ccx -v` 和 `ccx version` 会打印一行适合脚本读取的版本信息并退出。 diff --git a/docs-site/src/content/docs/zh-cn/reference/cli/agents.md b/docs-site/src/content/docs/zh-cn/reference/cli/agents.md index b8eac2e307..ce7c113abf 100644 --- a/docs-site/src/content/docs/zh-cn/reference/cli/agents.md +++ b/docs-site/src/content/docs/zh-cn/reference/cli/agents.md @@ -3,19 +3,19 @@ title: CLI 代理、路由与集成 description: 多代理、combo、可观测性、访问、集成、系统和配置命令。 --- -这些命令用于控制代理策略和路由,检查实时代理,并将受支持的客户端连接到 opencodex。 +这些命令用于控制代理策略和路由,检查实时代理,并将受支持的客户端连接到 CodexCommander。 ## Agent policy -### `ocx agent <status|injection|effort|subagents|fallback|sidecar> ...` +### `ccx agent <status|injection|effort|subagents|fallback|sidecar> ...` 管理无头多代理列表、effort 上限、提示注入、回退和 sidecar 设置。使用 `status` 查看当前策略。有关 surface 模式、委派、effort 和回退行为如何协同工作,请参见 [子代理 surface](/guides/sub-agent-surface/)。 ```bash -ocx agent subagents set ark/model-a,openai/gpt-5.5 +ccx agent subagents set ark/model-a,openai/gpt-5.5 ``` -### `ocx v2 <status|on|off|mode <v1|default|v2>|threads <n>>` +### `ccx v2 <status|on|off|mode <v1|default|v2>|threads <n>>` 管理 Codex 的 `multi_agent_v2` 功能标志和三态多代理 surface 模式。 @@ -30,105 +30,105 @@ ocx agent subagents set ark/model-a,openai/gpt-5.5 | `threads <n>` | 将当前 v1/v2 线程上限设为一个至少为 1 的整数。 | ```bash -ocx v2 status -ocx v2 mode v1 -ocx v2 mode default -ocx v2 on -ocx v2 threads 16 +ccx v2 status +ccx v2 mode v1 +ccx v2 mode default +ccx v2 on +ccx v2 threads 16 ``` -`mode` 子命令会将 `multiAgentMode` 写入 opencodex 配置,并重新同步 Codex 目录。模式和标志的切换会在有效的 v1/v2 Codex 键之间迁移当前的数值线程上限;如果切换失败,会恢复原始的 `config.toml`。更改只会应用于新的 Codex 会话,正在运行的会话会保持其已固定的 surface。 +`mode` 子命令会将 `multiAgentMode` 写入 CodexCommander 配置,并重新同步 Codex 目录。模式和标志的切换会在有效的 v1/v2 Codex 键之间迁移当前的数值线程上限;如果切换失败,会恢复原始的 `config.toml`。更改只会应用于新的 Codex 会话,正在运行的会话会保持其已固定的 surface。 ## Combo routing -### `ocx combo <list|show|set|remove> ...` · `ocx route combo ...` +### `ccx combo <list|show|set|remove> ...` · `ccx route combo ...` -管理 combo 的故障转移和轮询虚拟模型。`ocx route combo` 是层级别名;combo 目前是受支持的路由资源。目标使用 `provider/model[:weight],provider/model[:weight]`。 +管理 combo 的故障转移和轮询虚拟模型。`ccx route combo` 是层级别名;combo 目前是受支持的路由资源。目标使用 `provider/model[:weight],provider/model[:weight]`。 ```bash -ocx combo list -ocx route combo set reliable --targets ark/model-a:2,openai/gpt-5.5 +ccx combo list +ccx route combo set reliable --targets ark/model-a:2,openai/gpt-5.5 ``` 有关路由行为和配置指导,请参见 [Combos](/guides/combos/)。 ## Observability and debug -### `ocx observe <logs|usage|storage|memory|debug|claude-inbound|injection> ...` +### `ccx observe <logs|usage|storage|memory|debug|claude-inbound|injection> ...` 检查代理请求、用量、存储、内存和调试数据。直接别名如下: | 别名 | 对应资源 | | --- | --- | -| `ocx logs [filters] [--follow] [--json|--jsonl]` | `ocx observe logs` | -| `ocx usage [--range <7d|30d|all>] [--surface <all|codex|claude|grok>] [--json]` | `ocx observe usage` | -| `ocx storage [--json]` | `ocx observe storage` | -| `ocx memory [--json]` | `ocx observe memory` | +| `ccx logs [filters] [--follow] [--json|--jsonl]` | `ccx observe logs` | +| `ccx usage [--range <7d|30d|all>] [--surface <all|codex|claude|grok>] [--json]` | `ccx observe usage` | +| `ccx storage [--json]` | `ccx observe storage` | +| `ccx memory [--json]` | `ccx observe memory` | ```bash -ocx observe usage --range 30d --json +ccx observe usage --range 30d --json ``` -### `ocx debug <provider|usage|injection|claude> <on|off|status|reset|logs [-f]>` +### `ccx debug <provider|usage|injection|claude> <on|off|status|reset|logs [-f]>` 通过正在运行的代理的管理 API 读取或更改运行时调试覆盖项。 ```bash -ocx debug provider on|off|status|reset -ocx debug provider logs [-f|--follow] -ocx debug usage on|off|status|reset -ocx debug usage logs [-f|--follow] +ccx debug provider on|off|status|reset +ccx debug provider logs [-f|--follow] +ccx debug usage on|off|status|reset +ccx debug usage logs [-f|--follow] ``` -没有指定作用域时,`ocx debug` 会输出用法;如果代理已停止,还会输出下次启动时的环境默认值。提供方调试默认来自 `OCX_DEBUG=1`(旧版 `OCX_DEBUG_FRAMES=1` 也可用);用量调试默认来自 `OPENCODEX_USAGE_DEBUG=1`。 +没有指定作用域时,`ccx debug` 会输出用法;如果代理已停止,还会输出下次启动时的环境默认值。提供方调试默认来自 `CCX_DEBUG=1`;用量调试默认来自 `CODEXCOMMANDER_USAGE_DEBUG=1`。 ## API access -### `ocx access <key|endpoints|models|test> ...` +### `ccx access <key|endpoints|models|test> ...` -管理 OpenCodex 准入 API 密钥,并检查外部端点和模型。`ocx api-key -<list|create|remove> ...` 是 `ocx access key` 的别名。 +管理 CodexCommander 准入 API 密钥,并检查外部端点和模型。`ccx api-key +<list|create|remove> ...` 是 `ccx access key` 的别名。 ```bash -ocx access key create deployment +ccx access key create deployment ``` ## Client integrations -### `ocx integration <claude|grok> ...` +### `ccx integration <claude|grok> ...` 管理受支持的 Claude 和 Grok 集成。下面的直接命令族会暴露各自客户端专属的控制项。 -### `ocx claude [claude args...]` +### `ccx claude [claude args...]` -确保代理正在运行,然后使用 `ANTHROPIC_BASE_URL`、`ANTHROPIC_AUTH_TOKEN`、`CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1` 以及来自 `config.claudeCode` 的模型槽位启动 Claude Code。对于 Claude Code 2.1.129 或更新版本,路由后的模型会通过稳定的槽位别名出现在原生 `/model` 选择器中。在较旧版本中,请使用 `ANTHROPIC_MODEL` 或 `/model <id>` 选择。用户自行导出的 `ANTHROPIC_*` 变量始终优先生效。 +确保代理正在运行,然后使用 `ANTHROPIC_BASE_URL`、`ANTHROPIC_AUTH_TOKEN`、`CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1` 以及 `config.claudeCode` 中当前的认证/辅助设置启动 Claude Code。对于 Claude Code 2.1.129 或更新版本,路由后的模型会通过稳定别名出现在原生 `/model` 选择器中。在较旧版本中,请使用 `ANTHROPIC_MODEL` 或 `/model <id>` 选择。用户自行导出的 `ANTHROPIC_*` 变量始终优先生效。 Claude Desktop 配置档案命令如下: ```text -ocx claude desktop [apply] Save and apply the four-family profile -ocx claude desktop show [--json] Show routes, families, and defaults -ocx claude desktop move <route> <family> [--default] -ocx claude desktop default <family> <route|none> -ocx claude desktop export <path|-> Export versioned JSON (`-` = stdout) -ocx claude desktop import <path> [--apply] Validate and import JSON +ccx claude desktop apply Save and apply the four-family profile +ccx claude desktop show [--json] Show routes, families, and defaults +ccx claude desktop move <route> <family> [--default] +ccx claude desktop default <family> <route|none> +ccx claude desktop export <path|-> Export versioned JSON (`-` = stdout) +ccx claude desktop import <path> [--apply] Validate and import JSON ``` -这些 family 是 `opus`、`fable`、`sonnet` 和 `haiku`;新路由默认进入 `opus`。只有在该 family 为空时,`none` 才有效。旧版 apply 标志 `--static`、`--hybrid` 和 `--discovery-only` 仍受支持。Claude Code 设置请使用 `ocx claude config <status|set> ...`。 +这些 family 是 `opus`、`fable`、`sonnet` 和 `haiku`;新路由默认进入 `opus`。只有在该 family 为空时,`none` 才有效。Claude Code 设置请使用 `ccx claude config <status|set> ...`。 -### `ocx opencode [opencode args...]` +### `ccx opencode [opencode args...]` -确保代理正在运行,然后在 OpenCode 的内联运行时层(`OPENCODE_CONFIG_CONTENT`)中启动 opencode,并注入生成的 `provider.opencodex` 块。现有的内联配置会被保留,仅本次启动会替换 `provider.opencodex`。可能会读取全局或项目级 `opencode.json` 文件以警告已有覆盖,但不会修改磁盘上的文件。路由后的模型会显示为 `opencodex/<provider>/<model>`。此启动器不会改变之后普通 `opencode` 的启动;只有单独的 opt-in 控制面板集成才会持久化 `provider.opencodex`。 +确保代理正在运行,然后在 OpenCode 的内联运行时层(`OPENCODE_CONFIG_CONTENT`)中启动 opencode,并注入生成的 `provider.codexcommander` 块。现有的内联配置会被保留,仅本次启动会替换 `provider.codexcommander`。可能会读取全局或项目级 `opencode.json` 文件以警告已有覆盖,但不会修改磁盘上的文件。路由后的模型会显示为 `codexcommander/<provider>/<model>`。此启动器不会改变之后普通 `opencode` 的启动;只有单独的 opt-in 控制面板集成才会持久化 `provider.codexcommander`。 -### `ocx grok <status|exclude|include|set|clear|apply> ...` +### `ccx grok <status|exclude|include|set|clear|apply> ...` 管理并应用 Grok Build 模型边界。 ## Client config export -### `ocx export --client <opencode|pi>` +### `ccx export --client <opencode|pi>` -输出连接到正在运行代理的客户端配置。opencode 和 [Pi](/guides/pi/) 不是从环境变量,而是从各自的 JSON 配置中读取 providers,因此此命令会序列化 `opencodex` provider 块——基础 URL、模型列表以及客户端的环境引用——供你合并进那个文件。 +输出连接到正在运行代理的客户端配置。opencode 和 [Pi](/guides/pi/) 不是从环境变量,而是从各自的 JSON 配置中读取 providers,因此此命令会序列化 `codexcommander` provider 块——基础 URL、模型列表以及客户端的环境引用——供你合并进那个文件。 代理必须正在运行;该命令会解析其当前端口,读取 `/api/models`,并且只输出 Codex 当前可见的模型。 @@ -140,22 +140,22 @@ ocx claude desktop import <path> [--apply] Validate and import JSON | `--force` | 允许 `--out` 替换已存在的文件。 | ```bash -ocx export --client opencode # config plus destination, merge warning, and counts -ocx export --client pi --json > pi-models.json # byte-exact JSON for a pipe or a diff -ocx export --client opencode --out ~/opencodex-opencode.json +ccx export --client opencode # config plus destination, merge warning, and counts +ccx export --client pi --json > pi-models.json # byte-exact JSON for a pipe or a diff +ccx export --client opencode --out ~/codexcommander-opencode.json ``` 不使用 `--json` 时,JSON 会先输出,随后是规范目标路径、合并警告、环境变量导出行,以及一个模型计数,并标明有多少行省略了上下文限制(客户端会对这些项应用自己的默认值)。 | 客户端 | 规范目标路径 | 下载文件名 | 环境变量 | | --- | --- | --- | --- | -| `opencode` | `~/.config/opencode/opencode.json`(设置了 `XDG_CONFIG_HOME` 时以其为准) | `opencode.json` | `OPENCODEX_OPENCODE_API_KEY` | -| `pi` | `~/.pi/agent/models.json` | `pi-models.json` | `OPENCODEX_API_KEY` | +| `opencode` | `~/.config/opencode/opencode.json`(设置了 `XDG_CONFIG_HOME` 时以其为准) | `opencode.json` | `CODEXCOMMANDER_OPENCODE_API_KEY` | +| `pi` | `~/.pi/agent/models.json` | `pi-models.json` | `CODEXCOMMANDER_API_KEY` | -这两个环境变量名称不同,而且每个客户端只会插入自己的那个。opencode 读取 `{env:OPENCODEX_OPENCODE_API_KEY}`;Pi 读取 `$OPENCODEX_API_KEY`。 +这两个环境变量名称不同,而且每个客户端只会插入自己的那个。opencode 读取 `{env:CODEXCOMMANDER_OPENCODE_API_KEY}`;Pi 读取 `$CODEXCOMMANDER_API_KEY`。 :::caution[合并,不要替换] -`ocx export` 从不写入你的真实客户端配置。该命令只会打印目标路径供你手动合并,而 `--out` 在没有 `--force` 的情况下拒绝覆盖已有文件,因为替换配置会破坏其中已有的其他 providers、agents 和 MCP 条目。 +`ccx export` 从不写入你的真实客户端配置。该命令只会打印目标路径供你手动合并,而 `--out` 在没有 `--force` 的情况下拒绝覆盖已有文件,因为替换配置会破坏其中已有的其他 providers、agents 和 MCP 条目。 ::: 任何密钥都不会被序列化。配置里只包含客户端的环境引用,因此密钥仍保留在你的环境中。环回代理(`127.0.0.1`,默认值)根本不需要准入密钥——该引用只是不会被使用。只有当代理绑定到环回地址之外时才设置该变量;关于准入密钥如何签发,请参见 [远程访问](/reference/configuration/#remote-access)。上游 providers 自身的密钥则完全是另一回事,需要按 [Providers](/guides/providers/) 单独配置。 @@ -164,14 +164,14 @@ ocx export --client opencode --out ~/opencodex-opencode.json ## Runtime and configuration -### `ocx system <status|settings|startup|diagnostics|sync|update> ...` +### `ccx system <status|settings|startup|diagnostics|sync> ...` -管理无头运行时设置、启动、同步、诊断和更新。 +管理无头运行时设置、启动、同步和诊断。 ```bash -ocx system settings --stream-mode eager-relay +ccx system settings --stream-mode eager-relay ``` -### `ocx config <show|get|set|unset|validate|export|import> ...` +### `ccx config <show|get|set|unset|validate|export|import> ...` -检查并安全修改已验证的 OpenCodex 配置。`show` 和 `get` 会隐藏密钥。导入会先验证再写入,并且需要 `--yes`。 +检查并安全修改已验证的 CodexCommander 配置。`show` 和 `get` 会隐藏密钥。导入会先验证再写入,并且需要 `--yes`。 diff --git a/docs-site/src/content/docs/zh-cn/reference/cli/lifecycle.md b/docs-site/src/content/docs/zh-cn/reference/cli/lifecycle.md index 124a36c053..c997282453 100644 --- a/docs-site/src/content/docs/zh-cn/reference/cli/lifecycle.md +++ b/docs-site/src/content/docs/zh-cn/reference/cli/lifecycle.md @@ -1,69 +1,65 @@ --- title: CLI 生命周期 -description: 安装、启动、停止、服务、诊断、同步和更新命令。 +description: 安装、启动、停止、服务、诊断和同步命令。 --- -这些命令用于安装、运行、检查、修复并更新本地 opencodex 代理及其 Codex 集成。 +这些命令用于安装、运行、检查并修复本地 CodexCommander 代理及其 Codex 集成。 ## 初始化 -### `ocx init` · `ocx setup` +### `ccx init` · `ccx setup` -交互式初始化向导(`setup` 是 `init` 的别名)。会提示选择提供方(预设或自定义)、API key(字面量或 `${ENV}`)、默认模型和代理端口;将内容保存到 `~/.opencodex/config.json`;可选地把代理注入 `$CODEX_HOME/config.toml`(默认 `~/.codex/config.toml`);并可选安装 Codex 自启动 shim。 +交互式初始化向导(`setup` 是 `init` 的别名)。会提示选择提供方(预设或自定义)、API key(字面量或 `${ENV}`)、默认模型和代理端口;将内容保存到 `~/.codexcommander/config.json`;可选地把代理注入 `$CODEX_HOME/config.toml`(默认 `~/.codex/config.toml`);并可选安装 Codex 自启动 shim。 ## 代理生命周期 -### `ocx start [--port <port>]` +### `ccx start [--port <port>]` -启动代理服务器(首选端口 `10100`)。如果该端口已被占用,opencodex 会选择并记录另一个可用端口。它会写入 PID/运行时端口状态,并拒绝启动第二个存活实例。启动时,它会把每个提供方的模型同步到 Codex 的目录中。关闭时,它会恢复原生 Codex,除非它是作为受管服务启动的(`OCX_SERVICE=1`)。 +启动代理服务器(首选端口 `10100`)。如果该端口已被占用,CodexCommander 会选择并记录另一个可用端口。它会写入 PID/运行时端口状态,并拒绝启动第二个存活实例。启动时,它会把每个提供方的模型同步到 Codex 的目录中。关闭时,它会恢复原生 Codex,除非它是作为受管服务启动的(`CCX_SERVICE=1`)。 ```bash -ocx start -ocx start --port 8080 +ccx start +ccx start --port 8080 ``` -### `ocx stop` +### `ccx stop` -停止正在运行的代理(按 PID),移除 PID 文件,并恢复原生 Codex。如果安装了受管后台服务,`ocx stop` 还会先停止该服务,这样它就无法重新拉起代理。Web 仪表盘中的 **Stop** 按钮也提供同样的操作(`POST /api/stop`)。 +停止正在运行的代理(按 PID),移除 PID 文件,并恢复原生 Codex。如果安装了受管后台服务,`ccx stop` 还会先停止该服务,这样它就无法重新拉起代理。Web 仪表盘中的 **Stop** 按钮也提供同样的操作(`POST /api/stop`)。 -### `ocx restart` +### `ccx restart` 执行 `stop` 然后执行 `ensure`:停止代理/服务,恢复原生 Codex,在后台启动代理,并将当前端口重新同步回 Codex。 -### `ocx ensure` +### `ccx ensure` 以幂等方式确保后台代理正在运行,然后同步其当前模型目录。如果 `codexAutoStart` 为 `false`,它会打印自启动已禁用,并且不执行任何操作。 -### `ocx restore [back]` · `ocx eject [back]` +### `ccx restore [back]` · `ccx eject [back]` 在**不停止代理**的情况下恢复原生 Codex——移除注入的配置行和路由后的目录条目,让普通 `codex` 重新以原生方式工作。`eject` 是 `restore` 的别名。 在任一命令后附加 `back`,即可在不改变代理生命周期的前提下,把普通 `codex` 重新指向一个已经在运行的代理: ```bash -ocx restore back -ocx eject back +ccx restore back +ccx eject back ``` -### `ocx recover-history --legacy-openai` +### `ccx uninstall` · `ccx remove` -为更早期的开发构建提供显式恢复,这些构建在可逆备份支持存在之前就重映射了 Codex App 历史记录。如果其历史数据库已被锁定,请先关闭 Codex。 - -### `ocx uninstall` · `ocx remove` - -停止服务和代理,移除服务和 Codex shim,恢复原生 Codex,然后仅在所有恢复步骤都成功时才删除 opencodex 本地配置。`remove` 是 `uninstall` 的别名。配置清理需要由全新安装创建的所有权元数据;旧版或共享目录会保留原样。 +停止服务和代理,移除服务和 Codex shim,恢复原生 Codex,然后仅在所有恢复步骤都成功时才删除 CodexCommander 本地配置。`remove` 是 `uninstall` 的别名。配置清理需要规范的所有权元数据;无所有者或共享目录会保留原样。 ## 状态与健康 -### `ocx status [--json]` +### `ccx status [--json]` 输出只读诊断摘要:代理 PID、`/healthz` 可达性、仪表盘 URL、配置路径、默认提供方、Codex 自启动设置、服务状态、shim 状态,以及已脱敏的实际 Codex home。只有明确且高置信度的 Windows Orca 运行时 home 签名才会添加可执行的 App-home 不匹配警告;它绝不会自动更改 `CODEX_HOME`。 人类可读输出还会在 OAuth 登录摘要之后附加一个 **OAuth 健康** 区块:当所有已知账户都健康时显示 `OAuth health: ok`;否则显示 `OAuth health: warning`,并为每个不健康账户提供一行脱敏信息(提供方、打码后的账户 ID、状态,如需要重新认证、速率或配额受限、刷新冲突等),外加可选的 `Action:` 提示。账户 ID 会被脱敏;tokens 和邮箱绝不会打印。`--json` 协议目前不包含这个健康区块。 ```bash -ocx status -ocx status --json +ccx status +ccx status --json ``` 简化示例结构: @@ -84,8 +80,8 @@ ocx status --json "url": "http://localhost:10100/" }, "paths": { - "config": "/Users/example/.opencodex/config.json", - "pid": "/Users/example/.opencodex/ocx.pid", + "config": "/Users/example/.codexcommander/config.json", + "pid": "/Users/example/.codexcommander/codexcommander.pid", "runtime": "/path/to/bun" }, "runtime": { @@ -101,7 +97,7 @@ ocx status --json "codexAutostart": true, "defaultProvider": "openai", "service": { - "summary": "not installed (logs: /Users/example/.opencodex/service.log)" + "summary": "not installed (logs: /Users/example/.codexcommander/service.log)" }, "codexShim": { "summary": "Codex autostart shim: not installed" @@ -111,43 +107,43 @@ ocx status --json 真实对象还会包含 `listen`(端口、主机名、运行时/配置来源)、配置加载诊断,以及 bundled Codex 插件诊断。JSON schema 仅允许追加字段:未来版本可能新增字段,但现有字段应保持稳定。它刻意不包含 API keys、OAuth tokens、授权头、请求内容、邮箱和账户身份。 -### `ocx health [--json]` +### `ccx health [--json]` 对正在运行的代理做身份校验。人类可读输出报告 PID/端口;`--json` 输出 `{ok, pid, port}`。只有在健康时该命令才以 0 退出,否则以 1 退出,因此适合用作服务探针。 -### `ocx ready [--json] [--wait [--timeout <seconds>]]` +### `ccx ready [--json] [--wait [--timeout <seconds>]]` 通过无需认证的 `GET /readyz` 端点检查同步后的就绪状态。就绪时返回 `200`;状态为 `pending` 或 终态 `failed` 时返回 `503`,并带有 `Retry-After: 1`。HTTP 仅返回经脱敏的身份字段 -`{service, version, uptime, pid, port, status}`。不支持 `/readyz` 的旧代理会按 `unreachable` 失败关闭; -`/healthz` 是独立的存活检查,不是就绪检查。默认只探测一次;`--wait` 会轮询到就绪或超时,但遇到终态 +`{service, version, uptime, pid, port, status}`。`/healthz` 是独立的存活检查,不是就绪检查。 +默认只探测一次;`--wait` 会轮询到就绪或超时,但遇到终态 `failed` 会立即退出。默认超时为 45 秒;`--timeout <seconds>` 必须与 `--wait` 一起使用,取值范围为 1–300 秒的正整数。CLI JSON 输出 `{ready, status, pid, port}`,其中 `status` 为 `ready`、`pending`、`failed` 或 `unreachable`。退出码:就绪为 0;未就绪、pending、failed、超时或无法连接为 1;参数无效为 64。 -### `ocx doctor` +### `ccx doctor` -运行只读的环境与连通性诊断:状态路径和文件系统类型、WSL 双重安装、代理环境/配置、ChatGPT 可达性、Codex 插件和项目配置警告,以及待处理的历史迁移。Codex app-home 定位部分也会检测狭义的 Windows Orca 运行时 home 不匹配,并在适用时解释服务迁移。此诊断展示的路径会对操作系统用户名进行脱敏。Doctor 会输出修复提示,但不会自动应用。 +运行只读的环境与连通性诊断:状态路径和文件系统类型、WSL 双重安装、代理环境/配置、ChatGPT 可达性,以及 Codex 插件和项目配置警告。Codex app-home 定位部分也会检测狭义的 Windows Orca 运行时 home 不匹配,并在适用时显示手动卸载、环境设置和重新安装步骤。此诊断展示的路径会对操作系统用户名进行脱敏。Doctor 会输出修复提示,但不会自动应用。 -**OAuth 可靠性** 部分会报告凭据存储是否可写、是否能够在 `OPENCODEX_HOME` 下创建刷新 single-flight/锁文件、不健康的 OAuth 或 Codex 池账户(脱敏 ID)及其恢复 `Action:`,并给出一条静态 OK,说明 Codex 转发路径不会伪造官方客户端元数据。Doctor 绝不会修改凭据或执行修复。 +**OAuth 可靠性** 部分会报告凭据存储是否可写、是否能够在 `CODEXCOMMANDER_HOME` 下创建刷新 single-flight/锁文件、不健康的 OAuth 或 Codex 池账户(脱敏 ID)及其恢复 `Action:`,并给出一条静态 OK,说明 Codex 转发路径不会伪造官方客户端元数据。Doctor 绝不会修改凭据或执行修复。 ## 目录同步 -### `ocx sync [--restart-codex]` +### `ccx sync [--restart-codex]` 从每个已配置的提供方获取实时模型列表,并将合并后的目录重新注入 Codex。在添加提供方后运行,或用于刷新可用模型。 -如果仍有长期运行的 Codex `app-server` 进程,`ocx sync` 会警告它们可能继续提供旧的内存模型列表,即使 `opencodex-catalog.json` / `models_cache.json` 已更新。传入 `--restart-codex` 会仅向当前用户拥有、匹配 `codex … app-server` 和 `codex-code-mode-host` 的进程发送 `SIGTERM`(当前活跃会话可能会被打断)。故意避免使用宽泛的 `pkill -f codex` 匹配。 +如果仍有长期运行的 Codex `app-server` 进程,`ccx sync` 会警告它们可能继续提供旧的内存模型列表,即使 `codexcommander-catalog.json` / `models_cache.json` 已更新。传入 `--restart-codex` 会仅向当前用户拥有、匹配 `codex … app-server` 和 `codex-code-mode-host` 的进程发送 `SIGTERM`(当前活跃会话可能会被打断)。故意避免使用宽泛的 `pkill -f codex` 匹配。 -### `ocx sync-cache [--restart-codex]` +### `ccx sync-cache [--restart-codex]` -使 Codex 的本地模型选择器缓存失效,让它根据当前激活的 opencodex 目录重新生成。与 `ocx sync` 相同的陈旧 `app-server` 警告和可选 `--restart-codex` 行为同样适用。 +使 Codex 的本地模型选择器缓存失效,让它根据当前激活的 CodexCommander 目录重新生成。与 `ccx sync` 相同的陈旧 `app-server` 警告和可选 `--restart-codex` 行为同样适用。 ## 后台服务 -### `ocx service [install|repair|start|stop|status|uninstall|remove]` +### `ccx service [install|repair|start|stop|status|uninstall|remove]` -将 opencodex 作为登录管理的后台服务运行(macOS **launchd**、Linux **systemd user unit**、Windows **Task Scheduler**),在登录时自动启动,在崩溃时自动重启。服务运行会设置 `OCX_SERVICE=1`,因此重启时不会反复改动 Codex 配置。 +将 CodexCommander 作为登录管理的后台服务运行(macOS **launchd**、Linux **systemd user unit**、Windows **Task Scheduler**),在登录时自动启动,在崩溃时自动重启。服务运行会设置 `CCX_SERVICE=1`,因此重启时不会反复改动 Codex 配置。 | 子命令 | 操作 | | --- | --- | @@ -161,22 +157,22 @@ ocx status --json | `remove` | `uninstall` 的别名。 | ```bash -ocx service -ocx service install -ocx service repair -ocx service status -ocx service uninstall +ccx service +ccx service install +ccx service repair +ccx service status +ccx service uninstall ``` -在 Windows 上,`ocx service status` 会单独报告 Task Scheduler 注册状态和已身份验证的 OpenCodex 代理可达性。它不会打印本地化的 `schtasks` 表格,因此在不同 Windows 代码页下摘要仍然可读。 +在 Windows 上,`ccx service status` 会单独报告 Task Scheduler 注册状态和已身份验证的 CodexCommander 代理可达性。它不会打印本地化的 `schtasks` 表格,因此在不同 Windows 代码页下摘要仍然可读。 -在 Windows 上,创建 Task Scheduler 条目需要提升权限。识别到本地化的访问被拒绝文本时,会沿用现有的指导路径。如果该文本不可读,则回退要求命令形态为 `/create /tn opencodex-proxy /xml <non-empty-path> /f`,状态为 1,并且令牌明确为非提升权限;这时仪表盘的 Startup Safety 操作可以自动请求 UAC。如果该回退无法判断令牌状态,它会保留原始调度器错误。外部任务和操作绝不会发出自动提升标记。请批准仪表盘的 UAC 提示,或在提升权限的 PowerShell 窗口中重新运行 `ocx service install`。 +在 Windows 上,创建 Task Scheduler 条目需要提升权限。识别到本地化的访问被拒绝文本时,会沿用现有的指导路径。如果该文本不可读,则回退要求命令形态为 `/create /tn codexcommander-proxy /xml <non-empty-path> /f`,状态为 1,并且令牌明确为非提升权限;这时仪表盘的 Startup Safety 操作可以自动请求 UAC。如果该回退无法判断令牌状态,它会保留原始调度器错误。外部任务和操作绝不会发出自动提升标记。请批准仪表盘的 UAC 提示,或在提升权限的 PowerShell 窗口中重新运行 `ccx service install`。 -### `ocx codex-shim <install|status|uninstall|remove>` +### `ccx codex-shim <install|status|uninstall|remove>` 在 PATH 上把基于脚本的 `codex` 启动器包装为一个轻量自启动脚本。真实的 `codex.exe` 目标会保持不变,以避免破坏精确的可执行文件调用。 -如果已完成的外部 Codex 更新覆盖了已安装的 shim,下一次普通的 `ocx` 命令会先备份稳定的新启动器,再在分发前恢复 shim。仍在变动中的启动器会保持不动,并在稍后重试。修复失败只会警告,不会让所请求的命令失败;手动回退:`ocx codex-shim install`。将 `codexShimAutoRestore` 设为 `false`,或设置 `OPENCODEX_CODEX_SHIM_AUTO_RESTORE=0`,即可在进程级别关闭自动恢复。 +如果已完成的外部 Codex 更新覆盖了已安装的 shim,下一次普通的 `ccx` 命令会先备份稳定的新启动器,再在分发前恢复 shim。仍在变动中的启动器会保持不动,并在稍后重试。修复失败只会警告,不会让所请求的命令失败;手动回退:`ccx codex-shim install`。将 `codexShimAutoRestore` 设为 `false`,或设置 `CODEXCOMMANDER_CODEX_SHIM_AUTO_RESTORE=0`,即可在进程级别关闭自动恢复。 | 子命令 | 操作 | | --- | --- | @@ -186,34 +182,21 @@ ocx service uninstall | `status` | 报告 shim 状态(已安装、过期或缺失)。 | ```bash -ocx codex-shim install -ocx codex-shim status -ocx codex-shim uninstall +ccx codex-shim install +ccx codex-shim status +ccx codex-shim uninstall ``` :::tip[Service vs Shim] -将 `ocx service` 用于始终在线的后台代理(推荐)。将 `ocx codex-shim` 用于无需守护进程的轻量按需启动——代理只会在启动 `codex` 时运行。 +将 `ccx service` 用于始终在线的后台代理(推荐)。将 `ccx codex-shim` 用于无需守护进程的轻量按需启动——代理只会在启动 `codex` 时运行。 ::: -### `ocx tray <install|start|stop|status|uninstall|remove> [--json] [--no-start]` +### `ccx tray <install|start|stop|status|uninstall|remove> [--json] [--no-start]` 安装并控制 Windows 状态托盘图标。它会在 Windows 登录时启动,并提供一键代理控制。`start` 和 `stop` 只控制图标本身;要控制代理,请使用其菜单。`--no-start` 适用于 `install`,会安装托盘但不会立即启动。 ## 仪表盘 -### `ocx gui` +### `ccx gui` 在 `http://localhost:<port>` 打开 [web dashboard](/guides/web-dashboard/),如果代理未运行则会自动启动。 - -## 更新 - -### `ocx update [--tag latest|preview]` - -从 npm 自更新 opencodex。稳定版安装使用 `@latest`;预览版安装保持在 `@preview`,除非你传入 `--tag latest|preview`。它会检测源码检出,并提示你改为运行 `git pull && bun install`;如果你已经是该标签的最新版本,则不会执行任何操作。在替换文件之前会先停止正在运行的代理;已安装的服务会自动重建并启动,而前台安装则会打印 `ocx start` 作为下一步。 - -```bash -ocx update -ocx update --tag preview -``` - -当 [Release workflow](https://github.com/lidge-jun/opencodex/actions/workflows/release.yml) 将新版本发布到 npm 时,这些新版本就会变得可用。 diff --git a/docs-site/src/content/docs/zh-cn/reference/cli/providers-accounts.md b/docs-site/src/content/docs/zh-cn/reference/cli/providers-accounts.md index 911dbf72d2..f13d9aaafa 100644 --- a/docs-site/src/content/docs/zh-cn/reference/cli/providers-accounts.md +++ b/docs-site/src/content/docs/zh-cn/reference/cli/providers-accounts.md @@ -7,7 +7,7 @@ description: 提供方配置、凭据、配额,以及模型目录命令。 ## 提供方 -### `ocx provider <subcommand>` +### `ccx provider <subcommand>` 非交互式提供方管理。注册表条目按名称预置;自定义名称必须同时提供 `--adapter` 和 `--base-url`。 @@ -27,13 +27,13 @@ description: 提供方配置、凭据、配额,以及模型目录命令。 | `account-mode` | `pool`, `direct`, `--json` | 选择 Codex 账号的池化或直连路由。 | ```bash -ocx provider list --json -ocx provider test ark -ocx provider add anthropic --api-key sk-ant-... --set-default --sync -ocx provider add local-dev --adapter openai-chat --base-url http://localhost:11434/v1 -ocx provider show anthropic --json -ocx models --provider anthropic --json -ocx models live --provider ark --json +ccx provider list --json +ccx provider test ark +ccx provider add anthropic --api-key sk-ant-... --set-default --sync +ccx provider add local-dev --adapter openai-chat --base-url http://localhost:11434/v1 +ccx provider show anthropic --json +ccx models --provider anthropic --json +ccx models live --provider ark --json ``` :::caution[自定义请求头不是凭据通道] @@ -52,36 +52,36 @@ ocx models live --provider ark --json ## 认证 -### `ocx login <provider>` +### `ccx login <provider>` 启动该提供方已注册的登录流程。根据提供方不同,OAuth 登录会打开浏览器,或导入/链接 -已登录的原生 CLI 会话。存储在 `~/.opencodex/` 下且归 OpenCodex 所有的凭据会自动刷新; +已登录的原生 CLI 会话。存储在 `~/.codexcommander/` 下且归 CodexCommander 所有的凭据会自动刷新; 已链接的 Grok/Kimi CLI 访问代际以只读方式采用,更新责任仍由原生 CLI 承担。API 密钥登录 提供方会打开其密钥控制台,提示输入密钥,在可行时进行校验,并保存生成的提供方配置。 当名称缺失或未知时,命令会打印当前可接受的 OAuth 和 API 密钥提供方 id。 -在 `ocx status` / `ocx doctor` 报告需要重新认证或终端刷新失败后,也可用同一条 +在 `ccx status` / `ccx doctor` 报告需要重新认证或终端刷新失败后,也可用同一条 命令执行**重新认证**(或者在仪表盘中使用 Reauthenticate)。Codex 池账号不是一个 -公开的 `ocx login` 提供方 - 请通过仪表盘里的 Codex 账号池(Reauthenticate)或 -无头模式的 `ocx account reauth` 流程重新认证。 +公开的 `ccx login` 提供方 - 请通过仪表盘里的 Codex 账号池(Reauthenticate)或 +无头模式的 `ccx account reauth` 流程重新认证。 ```bash -ocx login xai -ocx login anthropic +ccx login xai +ccx login anthropic ``` -### `ocx logout <provider>` +### `ccx logout <provider>` 移除某个提供方已存储的 OAuth 凭据。 ## 账号与密钥池 -### `ocx account <subcommand>` +### `ccx account <subcommand>` 通过正在运行的代理列出并切换提供方账号和 API 密钥池。随附的帮助输出如下: ```text -Usage: ocx account <list|current|use|refresh|auto-switch|priority|login|reauth|code|cancel|remove|add-key|reset-credits> ... +Usage: ccx account <list|current|use|refresh|auto-switch|priority|login|reauth|code|cancel|remove|add-key|reset-credits> ... list [provider] Codex account pool, OAuth accounts and API keys (identifiers shown masked as the API returns them). current <provider> Show the active account or key. @@ -122,7 +122,7 @@ OAuth 账号会显示为 `Account N`,而 plan/label 列会在 plan、屏蔽后 } ``` -### `ocx account list [provider] [--json] [--all]` +### `ccx account list [provider] [--json] [--all]` 不指定提供方时,会列出 Codex 池、OAuth 账号和已配置的 API 密钥池。除非提供 `--all`,否则会跳过空的提供方。指定提供方时,只列出该凭据家族。人类可读输出 @@ -134,7 +134,7 @@ OAuth 账号会显示为 `Account N`,而 plan/label 列会在 plan、屏蔽后 { accounts: AccountRow[], notes: string[] } ``` -### `ocx account current <provider> [--json]` +### `ccx account current <provider> [--json]` 显示当前活动账号或密钥。没有手动固定的 Codex 池会报告自动选择最低使用量的结果; 没有活动凭据的其他家族会报告该状态,但仍然以 0 退出。`--json` 返回: @@ -143,10 +143,10 @@ OAuth 账号会显示为 `Account N`,而 plan/label 列会在 plan、屏蔽后 { provider, type, activeId: string | null, autoSwitchThreshold?: number, account: AccountRow | null } ``` -### `ocx account use <provider> <account-or-key-id|main> [--json]` +### `ccx account use <provider> <account-or-key-id|main> [--json]` 选择已有的 Codex 账号、OAuth 账号或 API key。对 `openai` 而言,`main` 选择 Codex App 登录。 -Codex Pool 选择会清除进程本地 affinity,并从下一次请求开始生效,包括已有可见任务的请求;代理重启或 affinity eviction 后,任务也可能变为未绑定,但进行中的请求保留已捕获账号。此选择只控制 Pool routing;Direct mode 继续使用 caller-owned/native main credential。基于用量的主动切换、401/403 重新认证、429/retry-after cooldown、排除,以及输出前 429/402 故障恢复之后仍可能选择其他合格 Pool 账号。这些恢复路径在关闭基于用量的切换时仍然有效。账号变化后 OpenCodex 会重放对话上下文,但 provider prompt cache 可能需要重新预热。未知 provider 或 id 返回退出码 1。`--json` 返回: +Codex Pool 选择会清除进程本地 affinity,并从下一次请求开始生效,包括已有可见任务的请求;代理重启或 affinity eviction 后,任务也可能变为未绑定,但进行中的请求保留已捕获账号。此选择只控制 Pool routing;Direct mode 继续使用 caller-owned/native main credential。基于用量的主动切换、401/403 重新认证、429/retry-after cooldown、排除,以及输出前 429/402 故障恢复之后仍可能选择其他合格 Pool 账号。这些恢复路径在关闭基于用量的切换时仍然有效。账号变化后 CodexCommander 会重放对话上下文,但 provider prompt cache 可能需要重新预热。未知 provider 或 id 返回退出码 1。`--json` 返回: 遇到 **401/403** 时,App 登录会清除该账户的进程内 affinity 并要求重新认证。 遇到 **429** 时,它会遵循 `Retry-After`、启动账户 cooldown、清除 affinity, 并可将请求切换到另一个符合条件的 Pool 账户。即使 `autoSwitchThreshold: 0`, @@ -156,9 +156,9 @@ Codex Pool 选择会清除进程本地 affinity,并从下一次请求开始生 { ok: true, provider, type, activeId } ``` -### `ocx account refresh <provider> [--json]` +### `ccx account refresh <provider> [--json]` -对于 Codex 池,请使用 `ocx account refresh openai [--json]`。它会强制刷新账号配额, +对于 Codex 池,请使用 `ccx account refresh openai [--json]`。它会强制刷新账号配额, 并打印可用的周/月百分比和重置时间;缺失的配额数据会报告为未知,而不是 0%。其 JSON 外壳是 `{ accounts: AccountRow[] }`,每个 Codex 行上都会带有 `quota`。 @@ -169,7 +169,7 @@ token,也不是简单重读账号列表。`--json` 返回 会以 1 退出;上游配额探测如果失败或超时,则会降级为 `null` 或陈旧报告(以 0 退出), 与仪表盘的配额条保持一致。 -### `ocx account auto-switch <provider> <on|off|status|threshold <0-100>> [--json]` +### `ccx account auto-switch <provider> <on|off|status|threshold <0-100>> [--json]` 只控制 `openai` 的 Codex 账号池。`on` 会设为 80%,`off` 会设为 0%,`status` 会读取 当前值,而 `threshold <n>` 接受 0 到 100 之间的整数。其他提供方和无效值都会以 1 @@ -179,11 +179,11 @@ token,也不是简单重读账号列表。`--json` 返回 { provider, autoSwitchThreshold: number, enabled: boolean } ``` -### `ocx account priority <provider> <account-id|main> [<-100..100|first|earlier|normal|later|last|reset>] [--json]` +### `ccx account priority <provider> <account-id|main> [<-100..100|first|earlier|normal|later|last|reset>] [--json]` 读取或设置某个 Codex pool 账号的选择顺序:**数值越大越先使用**,默认值为 `0`,范围是 `-100` 到 `100`。只有 `openai` 的 Codex pool 有选择顺序,其他 provider 返回退出码 1。`main` 指向 Codex Desktop -登录账号,它与其他 pool 账号一样参与排序:`ocx account priority openai main last` 就能把它留作备用。 +登录账号,它与其他 pool 账号一样参与排序:`ccx account priority openai main last` 就能把它留作备用。 预设词只是小整数的别名:`first` 为 `+2`,`earlier` 为 `+1`,`normal` 为 `0`,`later` 为 `-1`, `last` 为 `-2`。`reset` 恢复默认值并删除已保存的条目。**省略取值即为读取**,不会改写当前顺序。 @@ -199,12 +199,12 @@ token,也不是简单重读账号列表。`--json` 返回 ``` -### `ocx account login|reauth|code|cancel ...` +### `ccx account login|reauth|code|cancel ...` 在无头 shell 中运行基于浏览器或手动代码的账号认证。请使用 -`ocx account --help` 查看与提供方相关的命令形式。 +`ccx account --help` 查看与提供方相关的命令形式。 -### `ocx account remove <provider> <id|main> --yes [--json]` +### `ccx account remove <provider> <id|main> --yes [--json]` 这个受保护的非交互式删除需要 `--yes`。删除前,它会验证 id 是否存在;缺失的 id 会以 1 退出,而不会发送 DELETE。主 Codex App 登录不能被移除,因此会拒绝 @@ -217,35 +217,35 @@ token,也不是简单重读账号列表。`--json` 返回 { error: string } // stderr, exit 1 ``` -### `ocx account add-key <provider> [--label <label>] [--json]` +### `ccx account add-key <provider> [--label <label>] [--json]` 为 API 密钥提供方添加并激活一个密钥。该密钥只会从非 TTY 的管道/重定向 stdin 读取;交互式 TTY 输入、空输入、OAuth/Codex 提供方,以及 API 失败都会以 1 退出。 密钥永远不会回显,即使它出现在 label 里也是如此。建议使用秘密管理器或 here-string: ```bash -ocx account add-key openrouter --label personal <<< "$OPENROUTER_API_KEY" -security find-generic-password -w openrouter | ocx account add-key openrouter --json +ccx account add-key openrouter --label personal <<< "$OPENROUTER_API_KEY" +security find-generic-password -w openrouter | ccx account add-key openrouter --json ``` `--json` 返回 `{ ok: true, id: string | null, label?: string }`,并且绝不会包含该密钥。 -### `ocx account reset-credits <id|main> [--consume --yes]` +### `ccx account reset-credits <id|main> [--consume --yes]` 查看某个账号的 Codex 重置额度。消耗额度会造成破坏性影响,因此同时需要 `--consume` 和 `--yes`。 -### `ocx account main <subcommand>` +### `ccx account main <subcommand>` -管理命名的原生 Codex 主登录配置文件,而不更改 OpenCodex 账号池路由。 +管理命名的原生 Codex 主登录配置文件,而不更改 CodexCommander 账号池路由。 ```text -ocx account main doctor [--json] -ocx account main list [--json] -ocx account main register <label> [--json] -ocx account main add <label> -ocx account main switch <profile-id-or-label> --yes [--json] -ocx account main recover [--rollback --yes] [--json] +ccx account main doctor [--json] +ccx account main list [--json] +ccx account main register <label> [--json] +ccx account main add <label> +ccx account main switch <profile-id-or-label> --yes [--json] +ccx account main recover [--rollback --yes] [--json] ``` 每个变更命令都会显示运行中代理返回的规范化有效 `CODEX_HOME`。该路径可能与调用进程的 @@ -253,19 +253,17 @@ ocx account main recover [--rollback --yes] [--json] 版本 1 支持基于文件的 Codex 身份验证,使用 AES-256-GCM 加密保存的配置文件,并将加密密钥保存在操作系统凭据存储中。`add` 会先在受限暂存环境中启动官方 Codex 登录,再导入生成的凭据。切换配置文件前请关闭 Codex。切换成功后会保留本地任务和历史记录,但继续使用前必须重启 Codex。使用 `doctor` 检查配置文件状态,使用 `recover` 完成或回滚中断的切换。`switch` 可接受配置文件 ID 或标签。 -v1 恢复矩阵覆盖的是事务文件通过重命名发布后 OpenCodex 进程退出的情况。它不声明能够在操作系统或内核崩溃、突然断电后持久保存:`atomicWriteFileAsync()` 不会对文件或父目录执行 `fsync`。 +v1 恢复矩阵覆盖的是事务文件通过重命名发布后 CodexCommander 进程退出的情况。它不声明能够在操作系统或内核崩溃、突然断电后持久保存:`atomicWriteFileAsync()` 不会对文件或父目录执行 `fsync`。 -加密保管库、切换日志、恢复标记和日志隔离文件位于规范的 `<real CODEX_HOME>/.opencodex-native-main-profiles` 目录中。因此,共用该 Codex 主目录的所有 OpenCodex 实例都会看到同一个所有者和同一份恢复状态。明文登录暂存数据仍分别隔离在各自的 `<OPENCODEX_HOME>/native-main-profile-staging` 目录下。 +加密保管库、切换日志、恢复标记和日志隔离文件位于规范的 `<real CODEX_HOME>/.codexcommander-native-main-profiles` 目录中。因此,共用该 Codex 主目录的所有 CodexCommander 实例都会看到同一个所有者和同一份恢复状态。明文登录暂存数据仍分别隔离在各自的 `<CODEXCOMMANDER_HOME>/native-main-profile-staging` 目录下。 -在允许 native-main 流量或日志恢复之前,生命周期所有者会取得凭据的独占占用权,并且只删除名称与 `auth.json.ocx.<pid>.<sequence>.tmp` 完全匹配的崩溃残留文件。每个候选文件在整个过程中都必须位于未发生变化的规范 `CODEX_HOME` 下,并保持为硬链接计数为 1 的普通文件;系统会先将其截断,再刷新其内容,最后取消链接(unlink)。若发生链接或重解析点替换、文件标识发生变化或存在其他歧义,native-main 流量将继续保持关闭;名称仅近似匹配的文件绝不会被自动删除。这项防护针对正常协作的 OpenCodex 发生崩溃的情况,并不能抵御已经以同一操作系统用户身份运行的恶意进程。该用户以及承载 `CODEX_HOME` 的文件系统仍属于信任范围;截断文件也不保证从写时复制存储、快照或 SSD 残留数据中实现物理擦除。 - -预览版使用 `<OPENCODEX_HOME>/native-main-profiles`。该布局绝不会被静默导入。如果 `doctor` 报告旧版配置文件状态,请停止所有共用同一 `CODEX_HOME` 的 OpenCodex 代理。然后,请先备份,并在保留仅所有者可访问权限的情况下,将相应的 `*.vault.json`、`*.journal.json`、恢复标记以及任何被引用的日志隔离文件一起移动到规范目录中;或者删除旧的预览版文件集,再次运行 `ocx account main register`。只要仍有任何共用该 `CODEX_HOME` 的代理正在运行,就不要在多个旧根目录之间选择其一,也不要同时使用两种布局。在 Windows 上,按以前不区分大小写的主目录标识索引的预览状态必须重置,而不能直接移动,因为其加密 AAD 和操作系统密钥环标识被有意设计为不再复用。 +在允许 native-main 流量或日志恢复之前,生命周期所有者会取得凭据的独占占用权,并且只删除名称与 `auth.json.ccx.<pid>.<sequence>.tmp` 完全匹配的崩溃残留文件。每个候选文件在整个过程中都必须位于未发生变化的规范 `CODEX_HOME` 下,并保持为硬链接计数为 1 的普通文件;系统会先将其截断,再刷新其内容,最后取消链接(unlink)。若发生链接或重解析点替换、文件标识发生变化或存在其他歧义,native-main 流量将继续保持关闭;名称仅近似匹配的文件绝不会被自动删除。这项防护针对正常协作的 CodexCommander 发生崩溃的情况,并不能抵御已经以同一操作系统用户身份运行的恶意进程。该用户以及承载 `CODEX_HOME` 的文件系统仍属于信任范围;截断文件也不保证从写时复制存储、快照或 SSD 残留数据中实现物理擦除。 ## 模型 -### `ocx models [subcommand]` · `ocx model <subcommand>` +### `ccx models [subcommand]` · `ccx model <subcommand>` -`ocx model` 是 `ocx models` 的别名。没有子命令时,列出已配置提供方中静态预置的模型。 +`ccx model` 是 `ccx models` 的别名。没有子命令时,列出已配置提供方中静态预置的模型。 `--provider` 可过滤单个已配置提供方,而 `--json` 会返回模型元数据。`live` 读取运行中 的目录;`add`、`edit`、`remove` 和 `list-custom` 管理手动目录条目;`enable`、 `disable` 和 `provider` 控制可见性;`selected` 控制提供方允许列表;`context` 控制提供方 @@ -273,7 +271,7 @@ v1 恢复矩阵覆盖的是事务文件通过重命名发布后 OpenCodex 进程 这里提供仪表盘中所有逐模型操作,因此无头安装永远不需要 GUI 来管理目录。`add`、 `remove` 和 `list-custom` 针对配置文件工作,并通过目录同步应用到正在运行的代理; -其余命令会与在线管理 API 通信,并要求代理正在运行(`ocx start`,或已安装的服务)。 +其余命令会与在线管理 API 通信,并要求代理正在运行(`ccx start`,或已安装的服务)。 | 子命令 | 支持的标志 | 操作 | | --- | --- | --- | @@ -288,18 +286,18 @@ v1 恢复矩阵覆盖的是事务文件通过重命名发布后 OpenCodex 进程 | `provider <name> <on\|off>` | `--json` | 一次写入中启用或禁用某个提供方的全部模型。 | | `selected <provider>` | `--set <id,id...>`, `--clear`, `--json` | 读取或替换提供方模型允许列表。`--clear` 会移除允许列表,使所有模型都可提供。 | | `context <status\|value <tokens>\|provider <name> <on\|off>\|all <on\|off>>` | `--json` | 读取或设置上下文窗口上限,可全局设置或按提供方设置。 | -| `shadow <status\|set> [model\|-]` | `--enabled <on\|off>`, `--json` | 读取或设置 Codex 后台辅助调用所替换的模型。`-` 会清除该模型。`status` 还会报告 `sourceModels`,即代理拦截的辅助器 slug(默认值:`gpt-5.6-luna`;0.144.x 及更早客户端使用的 `gpt-5.4-mini` 可通过显式 `sourceModels` 覆盖恢复)。 | +| `shadow <status\|set> [model\|-]` | `--enabled <on\|off>`, `--json` | 读取或设置 Codex 后台辅助调用所替换的模型。`-` 会清除该模型。`status` 还会报告 `sourceModels`,即代理拦截的辅助器 slug(默认值:`gpt-5.6-luna`;显式覆盖仅用于当前自定义辅助器 ID)。 | ```bash -ocx models live --json # what Codex can actually see right now -ocx models disable anthropic/claude-haiku-4 # hide one routed model -ocx models enable gpt-5.6-sol # no slash, so it is treated as native -ocx models provider zenmux off # hide a noisy provider wholesale -ocx models selected anthropic --set claude-opus-5,claude-fable-5 -ocx models selected anthropic --clear # drop the allowlist again -ocx models add deepseek deepseek-v4 --display-name 'DeepSeek V4' --context-window 128000 --modalities text,image -ocx models list-custom --json # read the custom-id for edit/remove -ocx models remove deepseek/deepseek-v4 --yes +ccx models live --json # what Codex can actually see right now +ccx models disable anthropic/claude-haiku-4 # hide one routed model +ccx models enable gpt-5.6-sol # no slash, so it is treated as native +ccx models provider zenmux off # hide a noisy provider wholesale +ccx models selected anthropic --set claude-opus-5,claude-fable-5 +ccx models selected anthropic --clear # drop the allowlist again +ccx models add deepseek deepseek-v4 --display-name 'DeepSeek V4' --context-window 128000 --modalities text,image +ccx models list-custom --json # read the custom-id for edit/remove +ccx models remove deepseek/deepseek-v4 --yes ``` 带斜杠的模型选择器会按 routed 处理(`anthropic/claude-opus-5`);裸 id 会被视为 diff --git a/docs-site/src/content/docs/zh-cn/reference/configuration.md b/docs-site/src/content/docs/zh-cn/reference/configuration.md index 66327ddc41..c3dea61fcc 100644 --- a/docs-site/src/content/docs/zh-cn/reference/configuration.md +++ b/docs-site/src/content/docs/zh-cn/reference/configuration.md @@ -1,19 +1,19 @@ --- title: 配置参考 -description: opencodex 配置的存放位置、如何应用编辑,以及各配置域的链接。 +description: CodexCommander 配置的存放位置、如何应用编辑,以及各配置域的链接。 --- -opencodex 会把持久化配置存放在 `$OPENCODEX_HOME/config.json`,通常是 -`~/.opencodex/config.json`。在 Windows 上,默认路径是 -`%USERPROFILE%\.opencodex\config.json`。 +CodexCommander 会把持久化配置存放在 `$CODEXCOMMANDER_HOME/config.json`,通常是 +`~/.codexcommander/config.json`。在 Windows 上,默认路径是 +`%USERPROFILE%\.codexcommander\config.json`。 ## 配置编辑方式 按任务选择合适的编辑渠道: - **仪表盘:** 使用 Web UI 进行有引导的 provider、model、agent、access 和 storage 设置。 -- **CLI:** `ocx init` 会创建初始文件,而 `ocx provider`、`ocx models`、 - `ocx combo`、`ocx agent` 和 `ocx config` 等命令会更新或检查它们所负责的设置。 +- **CLI:** `ccx init` 会创建初始文件,而 `ccx provider`、`ccx models`、 + `ccx combo`、`ccx agent` 和 `ccx config` 等命令会更新或检查它们所负责的设置。 - **文件:** 对没有专门 UI 或 CLI 命令的字段,直接编辑 `config.json`。该文件必须保持为有效 JSON。 仪表盘、管理 API 和所有会修改配置的 CLI 命令都会把内容写回同一个文件。优先使用这些 @@ -21,14 +21,14 @@ opencodex 会把持久化配置存放在 `$OPENCODEX_HOME/config.json`,通常 可能会用快照覆盖你在磁盘上的手工修改。在线保存会在这些路径有明确冲突保护时,合并外部修改过的 `claudeCode` 和监听绑定字段,但这种保护并不覆盖所有子树。 -如果文件无法解析,opencodex 会将其备份为 +如果文件无法解析,CodexCommander 会将其备份为 `config.json.invalid-<timestamp>`,在控制台警告,并以默认值启动。文件缺失时也会使用新安装默认值: 一个 `openai` forward provider。 ## 优先级与默认值 `config.json` 中的有效值会覆盖内置默认值。缺失的可选字段使用各 domain 页面文档中说明的默认值。 -`OPENCODEX_HOME` 的优先级高于默认配置目录。支持环境引用的字段,例如 +`CODEXCOMMANDER_HOME` 的优先级高于默认配置目录。支持环境引用的字段,例如 `apiKey: "${PROVIDER_API_KEY}"`,会在请求时解析该变量。对于出站代理, 已经设置的 `HTTP_PROXY` 或 `HTTPS_PROXY` 会优先于顶层 `proxy` 字段。 @@ -49,6 +49,6 @@ API key 请优先使用 `${ENV_VAR}` 引用。字面量 `apiKey`、`apiKeyPool[] 在支持的地方请使用公开的 selector alias。 :::note[原子写入] -opencodex 会通过临时文件再重命名(`atomicWriteFile`)的方式写入托管的 `config.toml` 和 `opencodex-catalog.json` 文件。 -这可以避免在并发写入时留下半写入文件,例如 `ocx stop` 和代理 shutdown handler 同时恢复 Codex 的情况。 +CodexCommander 会通过临时文件再重命名(`atomicWriteFile`)的方式写入托管的 `config.toml` 和 `codexcommander-catalog.json` 文件。 +这可以避免在并发写入时留下半写入文件,例如 `ccx stop` 和代理 shutdown handler 同时恢复 Codex 的情况。 ::: diff --git a/docs-site/src/content/docs/zh-cn/reference/configuration/agents.md b/docs-site/src/content/docs/zh-cn/reference/configuration/agents.md index 14e0d03c9b..804f9ad80e 100644 --- a/docs-site/src/content/docs/zh-cn/reference/configuration/agents.md +++ b/docs-site/src/content/docs/zh-cn/reference/configuration/agents.md @@ -3,7 +3,7 @@ title: 代理配置 description: 多代理界面、委派引导、首选模型、回退链、原生默认值同步以及 effort 上限。 --- -代理设置控制会公开哪种 Codex 协作界面,以及 opencodex 如何引导、路由并限制委派工作。 +代理设置控制会公开哪种 Codex 协作界面,以及 CodexCommander 如何引导、路由并限制委派工作。 ## 代理字段 @@ -11,18 +11,18 @@ description: 多代理界面、委派引导、首选模型、回退链、原生 | --- | --- | --- | --- | | `multiAgentMode?` | `"v1" \| "default" \| "v2"` | `"default"` | `v1` 会把目录中的每个模型都标记为 v1;`v2` 会把每个模型都标记为 v2。`default` 会恢复上游固定值(Sol/Terra 为 v2,Luna 为 v1),否则遵循原生 `multi_agent_v2` 标志。适用于新会话。 | | `multiAgentV2MessageDelivery?` | `"encrypted" \| "plaintext"` | `"encrypted"` | V2 父级消息传递策略。`encrypted` 保留 ChatGPT 的预留加密协议;实验性的 `plaintext` 为后续 V2 父级请求启用跨提供方兼容,并使该父级的所有委派消息成为明文。路由父级的消息调用也会获得 Codex 明文标记。更改后请启动新会话。 | -| `subagentModels?` | `string[]` | `gpt-5.5`, `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna`, `gpt-5.4-mini` | 最多五个裸原生 id、账户限定的 `<selector>/<native-openai-model>` id 或路由 `provider/model` id 会优先公开在子代理选择器中。仪表盘会保留已配置的精确 selector(包括账户限定选项),并报告哪些已保存条目实际被公开或排除。对于当前目录中不存在的选项,请使用 `ocx agent subagents set` 或直接编辑配置。显式空列表会被保留。 | +| `subagentModels?` | `string[]` | `gpt-5.5`, `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna`, `gpt-5.4-mini` | 最多五个裸原生 id、账户限定的 `<selector>/<native-openai-model>` id 或路由 `provider/model` id 会优先公开在子代理选择器中。仪表盘会保留已配置的精确 selector(包括账户限定选项),并报告哪些已保存条目实际被公开或排除。对于当前目录中不存在的选项,请使用 `ccx agent subagents set` 或直接编辑配置。显式空列表会被保留。 | | `injectionModel?` | `string` | — | 在代理生成的 v2 委派引导中使用的首选原生或路由后的子代理模型。 | | `injectionEffort?` | `string` | — | 首选 effort(`low` 到 `ultra`),只有在 `injectionModel` 存在时才有意义。 | | `injectionPrompt?` | `string` | — | 替换内置 v2 指引正文。支持 `{{model}}`、`{{effort}}`、`{{roster}}` 和 `{{fallback}}`。只要配置了 `injectionModel`,自定义提示词就会触发。 | -| `multiAgentGuidanceEnabled?` | `boolean` | `true` | 只控制 opencodex 生成的 v1/v2 开发者引导;不会改变原生代理默认值、工具、路由、名单或 effort 上限。 | +| `multiAgentGuidanceEnabled` | `boolean` | `true` | 只控制 CodexCommander 生成的 v1/v2 开发者引导;不会改变原生代理默认值、工具、路由、名单或 effort 上限。 | | `syncCodexSubagentDefaults?` | `boolean` | `false` | 允许在同步或重启时,将 `injectionModel` 以及可选的 `injectionEffort` 写入为 Codex 的原生默认值。需要 `injectionModel`。 | | `subagentModelFallback?` | `string[]` | `[]` | 按优先级排序的全局回退模型,用于派生的子轮次。 | | `subagentModelFallbackPollMs?` | `number` | `60000` | 可用性探测缓存间隔。低于 1000 ms 的值会回退到默认值。 | | `effortCap?` | `string` | — | 对符合条件的 v2 主轮次和标记的派生子轮次设置硬上限。接受 `low` 到 `ultra`。 | | `subagentEffortCap?` | `string` | — | 仅针对派生子轮次的额外上限。两个上限同时适用时,较低者生效。 | -通过仪表板或 `ocx v2 status|on|off|mode <v1|default|v2>|threads <n>` 管理该界面。模式变更会应用于新会话。`maxConcurrentThreadsPerSession` 是 `PUT /api/v2` 字段,不是 `config.json` 键;`ocx v2 threads <n>` 会在启用 v2 后,将 `max_concurrent_threads_per_session` 写入 Codex 的 `$CODEX_HOME/config.toml` 中的 `[features.multi_agent_v2]` 下。 +通过仪表板或 `ccx v2 status|on|off|mode <v1|default|v2>|threads <n>` 管理该界面。模式变更会应用于新会话。`maxConcurrentThreadsPerSession` 是 `PUT /api/v2` 字段,不是 `config.json` 键;`ccx v2 threads <n>` 会在启用 v2 后,将 `max_concurrent_threads_per_session` 写入 Codex 的 `$CODEX_HOME/config.toml` 中的 `[features.multi_agent_v2]` 下。 管理 API 公开 `GET`/`PUT /api/v2`、`/api/injection-model`、`/api/effort-caps`、`/api/subagent-models` 和 `/api/subagent-model-fallback`。injection-model 更新是部分更新;自定义 prompt 是该 API 上的 `prompt` 字段。 @@ -48,7 +48,7 @@ V1 引导只会在 `max` 或 `ultra` 时以主动文本形式出现。V2 只有 2. 来自 `$CODEX_HOME/agents/*.toml` 的角色级 `model_fallback`;然后是 3. 全局 `subagentModelFallback` 条目。 -opencodex 会跳过已禁用、不可路由、不健康、处于冷却中,或已达到配额阈值的候选项。可用性快照会在 `subagentModelFallbackPollMs` 期间缓存。加密的子任务可以把链限制为规范的原生 ChatGPT 目标;如果没有任何目标能读取加密载荷,请求就会失败,而不是把不可读的密文路由到别处。 +CodexCommander 会跳过已禁用、不可路由、不健康、处于冷却中,或已达到配额阈值的候选项。可用性快照会在 `subagentModelFallbackPollMs` 期间缓存。加密的子任务可以把链限制为规范的原生 ChatGPT 目标;如果没有任何目标能读取加密载荷,请求就会失败,而不是把不可读的密文路由到别处。 ```json { @@ -68,6 +68,6 @@ opencodex 会跳过已禁用、不可路由、不健康、处于冷却中,或 上限只适用于 v2 协作功能:当主轮次的工具暴露 v2 时,它就符合条件;当子轮次在 `x-codex-turn-metadata` 中带有 codex-rs 的精确 `x-openai-subagent: collab_spawn` 或 `"subagent_kind": "thread_spawn"` 标记时,它也符合条件,即使叶子工具已经不再暴露协作。V1 主轮次、`multiAgentMode: "v1"`、压缩、审查以及记忆整合轮次都会绕过上限。 -上限只会降低 effort。它们会向下贴合到不高于上限、且模型公开的最高档位。如果模型没有 effort 控制,或者没有任何受支持的档位可用,opencodex 会移除 effort,让提供方默认值生效。`max` 和 `ultra` 都可接受,而仪表板提供 `low` 到 `xhigh`。 +上限只会降低 effort。它们会向下贴合到不高于上限、且模型公开的最高档位。如果模型没有 effort 控制,或者没有任何受支持的档位可用,CodexCommander 会移除 effort,让提供方默认值生效。`max` 和 `ultra` 都可接受,而仪表板提供 `low` 到 `xhigh`。 关于 v1、default 和 v2 行为的面向初学者说明,请参阅 [Sub-agent surfaces](/guides/sub-agent-surface/)。 diff --git a/docs-site/src/content/docs/zh-cn/reference/configuration/providers.md b/docs-site/src/content/docs/zh-cn/reference/configuration/providers.md index ba9e2f753d..7a66b90762 100644 --- a/docs-site/src/content/docs/zh-cn/reference/configuration/providers.md +++ b/docs-site/src/content/docs/zh-cn/reference/configuration/providers.md @@ -3,14 +3,13 @@ title: 提供方配置 description: 提供者条目、身份验证、端点、模型目录、配额、上下文上限以及提供者特定选项。 --- -提供者用于告诉 opencodex 模型位于哪里、使用哪种线协议适配器,以及请求如何进行身份验证。 +提供者用于告诉 CodexCommander 模型位于哪里、使用哪种线协议适配器,以及请求如何进行身份验证。 ## 提供者相关顶级字段 | 字段 | 类型 | 默认值 | 含义 | | --- | --- | --- | --- | -| `providers` | `Record<string, OcxProviderConfig>` | — | 提供者名称到提供者配置的映射。 | -| `openaiProviderTierVersion?` | `2` | 由迁移设置 | 标记单一、可感知选项的 OpenAI 投影已完成。 | +| `providers` | `Record<string, CodexCommanderProviderConfig>` | — | 提供者名称到提供者配置的映射。 | | `disabledModels?` | `string[]` | — | 从 Codex catalog 和 `/v1/models` 中隐藏、但不阻止直接 proxy 调用的 model。routed id 会从列表中移除。account-qualified native id 只隐藏对应 selector row;bare native GPT id 会隐藏 bare row 以及该 model 的所有 account-selector row。Models 页面只显示裸原生行和路由行;若只隐藏一个 selector-qualified 行,请直接设置此配置字段。 | | `providerContextCaps?` | `Record<string, number>` | `{}` | 按提供者设置、对 Codex 可见的上下文上限。上限只会降低已知的上下文窗口。 | | `contextCapValue?` | `number` | `350000` | 仪表板上下文上限控件使用的值;修改它会更新所有已启用的 `providerContextCaps` 条目。 | @@ -18,16 +17,16 @@ description: 提供者条目、身份验证、端点、模型目录、配额、 | `pausedCodexAccountIds?` | `string[]` | `[]` | 在恢复之前从 Pool 选择中排除的账户,包括被暂停时的主 `__main__` 账户。 | | `codexAccountNamespaces?` | `Record<string, string>` | — | 将任意公开 model selector 映射到已保存 Codex account target 的可选配置。target 存在的每个 selector 都会在 Codex picker 中添加独立的 `<selector>/<native-openai-model>` row,且每个 row 只使用对应账户。只要有 selector 生效,bare native row 就会在 picker 中隐藏;但除非显式禁用,其 id 仍可路由,并继续列在 raw `/v1/models` 中。 | | `activeCodexAccountId?` | `string` | — | 为下一次请求手动选定的 Pool 账户。选择会清除线程亲和性;进行中的请求会保留捕获到的凭据。 | -| `codexAccountPriorities?` | `Record<string,number>` | — | Codex pool 各账号的选择顺序:账号 ID → `-100` 到 `100` 的整数,**数值越大越先使用**,未设置即为 `0`。这是顺序边界而非资格边界:选择会把已经合格的账号收窄到仍有 quota 余量的最高 tier,再由 `accountPoolStrategy` 在该 tier 内挑选。只有当某个 tier 的所有成员都超过 `autoSwitchThreshold`、处于 cooldown、被 soft-avoid、已暂停或需要重新认证时,该 tier 才会被跳过;usage 未知不会让 tier 耗尽。顺序不会让不合格的账号变得可选,也不会重新绑定已经绑定账号的 thread。主账号 `__main__` 同样参与排序,因此可以让 Codex Desktop 登录账号最后才被用到。没有任何条目时,行为与以往完全一致。映射格式非法时会打印警告并关闭排序(不会触发 config 修复)。可通过 `ocx account priority` 和 Codex Auth 页面管理。 | +| `codexAccountPriorities?` | `Record<string,number>` | — | Codex pool 各账号的选择顺序:账号 ID → `-100` 到 `100` 的整数,**数值越大越先使用**,未设置即为 `0`。这是顺序边界而非资格边界:选择会把已经合格的账号收窄到仍有 quota 余量的最高 tier,再由 `accountPoolStrategy` 在该 tier 内挑选。只有当某个 tier 的所有成员都超过 `autoSwitchThreshold`、处于 cooldown、被 soft-avoid、已暂停或需要重新认证时,该 tier 才会被跳过;usage 未知不会让 tier 耗尽。顺序不会让不合格的账号变得可选,也不会重新绑定已经绑定账号的 thread。主账号 `__main__` 同样参与排序,因此可以让 Codex Desktop 登录账号最后才被用到。没有任何条目时,所有账号的优先级均为 `0`。映射格式非法时会打印警告并关闭排序(不会触发 config 修复)。可通过 `ccx account priority` 和 Codex Auth 页面管理。 | | `autoSwitchThreshold?` | `number` | `80` | 基于用量的主动切换阈值。`quota` 可在下一次请求中重新评估已绑定和未绑定任务;`fill-first` 仅把它用作未绑定分配的耗尽点;正常 `round-robin` 不使用它。分数取已知 5 小时、周或 30 天 quota window 的最高值。`0` 只关闭基于用量的主动切换,不关闭未绑定任务分配或故障恢复。 | | `accountPoolStrategy?` | `"quota" \| "round-robin" \| "fill-first"` | `"quota"` | 新建/未绑定 Codex 请求的分配策略。没有 live `(parent thread id, quota scope)` affinity 的请求属于未绑定;代理重启或 affinity 重置后,已有可见任务也可能未绑定。`quota` 在没有活跃账号时选择已知 usage 最低的合格账号;活跃账号合格且低于 `autoSwitchThreshold` 时继续使用;达到阈值后,可把未绑定请求或已绑定任务的下一次请求切换到 usage 更低的合格账号。`round-robin` 均匀分配未绑定请求;`fill-first` 在 cooldown、不可用或耗尽阈值前持续分配给活跃账号。 | | `accountPoolStickyLimit?` | `number` | `1` | 一次 round-robin 选择在推进前保留的新建/未绑定任务分配数。计数在任务绑定时增加,而不是在上游成功后增加。范围 1–100;仅当 `accountPoolStrategy` 为 `round-robin` 时生效。 | | `upstreamFailoverThreshold?` | `number` | `3` | 连续发生多少次瞬态故障后,后续新会话会切换到备用上游。设为 `0` 可禁用。已证明的连接前 DNS/TCP 不可达故障按 provider-host 粒度记录,不影响账户健康、冷却、线程/会话亲和性、活动账户选择或 Pool 路由,也不会计入此阈值;未确认的失败仍归属账户。 | | `modelCacheTtlMs?` | `number` | `300000` | 每个提供者 `/models` 缓存的新鲜度窗口。 | | `cacheRetention?` | `"none" \| "short" \| "long"` | `"short"` | Anthropic 提示缓存策略:禁用、5 分钟临时缓存,或 1 小时扩展缓存。 | -| `tokenGuardian?` | `OcxTokenGuardianConfig` | 关闭 | 可选的主动 OAuth 刷新与 Codex 账户预热策略。 | +| `tokenGuardian?` | `CodexCommanderTokenGuardianConfig` | 关闭 | 可选的主动 OAuth 刷新与 Codex 账户预热策略。 | -selector 名称是用户自定的公开 label;opencodex 不会为其赋予账户角色语义。 +selector 名称是用户自定的公开 label;CodexCommander 不会为其赋予账户角色语义。 `codexAccountNamespaces` 的 key 长度为 1–64 个字符,首尾必须是 ASCII 字母或数字, 中间可使用字母、数字、`.`、`_` 或 `-`;保留的 JavaScript object 名称会被拒绝。value 必须是有效的 pool account id(不能是内部 `__main__`),或用 `"@main"` 表示 Codex Desktop 账号。与 provider 及 @@ -40,17 +39,15 @@ pool account id(不能是内部 `__main__`),或用 `"@main"` 表示 Codex `openai` 和 `openai-apikey` 是固定的保留 id。`openai.codexAccountMode` 默认是 `"pool"`,会在主账户和新增账户之间选择;`"direct"` 只使用当前调用者/主登录态。API 只使用其配置的 API key 或 key 池。请使用裸模型名或 `openai-apikey/<model>`;不存在跨路由凭据回退。API 的 GPT-5.6 行携带 1,050,000 上下文 / 922,000 最大输入元数据,而 Pro 虚拟 id 会重写为基础线协议模型并带上 `reasoning.mode: "pro"`。 -`openaiProviderTierVersion: 2` 标记当前的单提供者投影。对已发布的 v1 配置进行迁移之前,opencodex 会创建 `config.json.pre-openai-tiers-v2.bak`,且不会覆盖不同的备份文件,并会把已知的旧式命名空间选择 id 重写为裸 id。 - -## 提供者条目(`OcxProviderConfig`) +## 提供者条目(`CodexCommanderProviderConfig`) | 字段 | 类型 | 含义 | | --- | --- | --- | -| `adapter` | `string` | `openai-chat`、`openai-responses`、`anthropic`、`google`、`kiro`、`cursor`、`azure-openai`(或别名 `azure`)之一。 | +| `adapter` | `string` | `openai-chat`、`openai-responses`、`anthropic`、`google`、`kiro`、`cursor`、`azure-openai` 之一。 | | `baseUrl` | `string` | 上游 API 基础 URL。大多数内置固定端点会忽略不匹配的值;具备冲突安全键的预设会保留一个更早、同名的自定义目标。 | | `responsesPath?` | `string` | 用于 key-auth `openai-responses` 请求的相对资源路径。必须以 `/` 开头,且不能包含 scheme、query 或 fragment。 | | `supportsServiceTier?` | `boolean` | `service_tier` 能力的三态。`true`:fast 模式可以注入,调用方提供的值也会被保留。`false`:剥离该字段且绝不注入(已明确不支持的上游不会收到它)。未设置:未分类——调用方提供的值原样保留,fast 模式绝不注入。注册表已对官方 OpenAI(`true`)、DeepSeek 和 Volcengine Ark(`false`)分类;仅对真正支持分层的自定义网关显式设置。 | -| `preserveResponsesReasoningContent?` | `boolean` | 在重放的 Responses reasoning 项中保留明文 reasoning 内容,而不是清空(清空是 ChatGPT 后端的规则)。对接受 reasoning 重放的上游(如 DeepSeek)启用。代理生成的 `ocxr1` 信封始终会被剥离。 | +| `preserveResponsesReasoningContent?` | `boolean` | 在重放的 Responses reasoning 项中保留明文 reasoning 内容,而不是清空(清空是 ChatGPT 后端的规则)。对接受 reasoning 重放的上游(如 DeepSeek)启用。代理生成的 `ccxr1` 信封始终会被剥离。 | | `disabled?` | `boolean` | 将提供者保留在磁盘上,但从路由和模型/目录列表中排除。 | | `apiKey?` | `string` | API key,或在请求时解析的 `${ENV_VAR}` / `$ENV_VAR` 引用。 | | `apiKeyTransport?` | `"x-api-key" \| "bearer"` | Anthropic key 头部样式。默认使用原生 `x-api-key`;仅对 key-auth `anthropic` 提供者有效。 | @@ -102,16 +99,15 @@ pool account id(不能是内部 `__main__`),或用 `"@main"` 表示 Codex | `location?` | `string` | Vertex 位置;环境变量回退为 `GOOGLE_CLOUD_LOCATION`。 | | `mcpServers?` | `Record<string, CursorMcpServerConfig>` | 仅 Cursor:stdio 或 Streamable HTTP MCP 服务器。 | | `desktopExecutor?` | `DesktopExecutorConfig` | 仅 Cursor:外部 computer-use 和录屏命令。 | -| `unsafeAllowNativeLocalExec?` | `boolean` | Cursor 旧布尔值;仅当更新字段未设置时,等同于 `nativeLocalExec: "on"`。 | -| `nativeLocalExec?` | `"off" \| "codex-sandbox" \| "on"` | Cursor 本地执行策略。`off` 是默认值;`codex-sandbox` 目前会像 `off` 一样失败关闭。 | +| `nativeLocalExec?` | `"off" \| "on"` | Cursor 本地执行策略。`off` 是默认值。 | -API key 提供者可以持有字面量 key,或环境引用。OAuth 提供者使用由 `ocx login` 填充的凭据存储;基于订阅的 Claude Code 启动行为在 [`claudeCode.authMode`](/reference/configuration/server/#claude-code) 下配置。 +API key 提供者可以持有字面量 key,或环境引用。OAuth 提供者使用由 `ccx login` 填充的凭据存储;基于订阅的 Claude Code 启动行为在 [`claudeCode.authMode`](/reference/configuration/server/#claude-code) 下配置。 ## 提供者诊断出站安全性 -仪表板连接测试和实时模型发现使用受限的、仅 GET 传输。没有出站代理时,opencodex 只会解析一次主机名,并仅连接到该已验证地址。HTTPS 仍会保留原始 Host、SNI 和证书验证;提供者配置不能关闭证书检查。 +仪表板连接测试和实时模型发现使用受限的、仅 GET 传输。没有出站代理时,CodexCommander 只会解析一次主机名,并仅连接到该已验证地址。HTTPS 仍会保留原始 Host、SNI 和证书验证;提供者配置不能关闭证书检查。 -当 `HTTP_PROXY`、`HTTPS_PROXY` 或 `ALL_PROXY` 生效时,这些操作会继续使用 Bun 的原生 fetch。URL 和字面量地址检查仍会执行,但最终路由、DNS 解析结果和对端由代理决定,因此 opencodex 无法固定或验证该对端。这是一个明确的安全限制。 +当 `HTTP_PROXY`、`HTTPS_PROXY` 或 `ALL_PROXY` 生效时,这些操作会继续使用 Bun 的原生 fetch。URL 和字面量地址检查仍会执行,但最终路由、DNS 解析结果和对端由代理决定,因此 CodexCommander 无法固定或验证该对端。这是一个明确的安全限制。 私有/本地目标需要 `allowPrivateNetwork: true`,并且在出站代理启用时,还需要匹配的 `NO_PROXY` 条目。回环地址会自动加入;每个 LAN 主机都必须显式列出,因为 CIDR 条目不会被解释。匹配器支持精确主机、域后缀、可选端口、带方括号的 IPv6 以及 `*`;例如,应显式列出 `192.168.1.50`。元数据和链路本地目标仍会被阻止。诊断请求会拒绝重定向,并报告一个已剥离凭据的目标。普通提供者请求的重定向审查仍然独立于这个诊断保护。 @@ -152,14 +148,14 @@ affinity。这些策略不能规避 provider enforcement。 启用后,429 会根据 `Retry-After` 记录有界冷却,或者使用默认退避,并且可能在同一请求内轮换。亲和性是进程本地的,并且有大小上限。凭据 401/403 会将账户标记为需要重新认证。如果所有合格账户都在冷却,客户端会在已知时收到带 `Retry-After` 的 429,而不是身份验证错误。 :::caution[Experimental] -除非你理解 Anthropic 账户策略风险,否则请保持关闭。若不确定,优先手动使用 `ocx account use anthropic <id>` 切换。 +除非你理解 Anthropic 账户策略风险,否则请保持关闭。若不确定,优先手动使用 `ccx account use anthropic <id>` 切换。 ::: ### 托管记录形状 `apiKeys[]` 条目包含 `id`、`name`、生成的 `key` 以及 ISO 格式的 `createdAt` 字符串。`codexAccounts[]` 条目要求有 `id`、`email` 和 `isMain`,并可选 `plan`、`chatgptAccountId` 和具备隐私安全性的 `logLabel`。这些记录通常由仪表板管理。 -### `tokenGuardian`(`OcxTokenGuardianConfig`) +### `tokenGuardian`(`CodexCommanderTokenGuardianConfig`) | 字段 | 类型 | 默认值 | 含义 | | --- | --- | --- | --- | @@ -185,7 +181,7 @@ affinity。这些策略不能规避 provider enforcement。 适配器之后可以再调整解析后的 URL。例如,Kiro 会依据导入凭据的 API 区域,遵循规范的 `runtime.{region}.kiro.dev`。参见[适配器](/reference/adapters/)。 -当路由丢弃 `baseUrl` 时,opencodex 会记录注册表端点以及仅有的已配置 origin;配置的路径本身也可能包含凭据。请移除未使用的 URL,或选择与预期区域相匹配的提供者条目。`alibaba-token-plan` 锁定在北京,而 `alibaba-token-plan-intl` 覆盖国际端点。 +当路由丢弃 `baseUrl` 时,CodexCommander 会记录注册表端点以及仅有的已配置 origin;配置的路径本身也可能包含凭据。请移除未使用的 URL,或选择与预期区域相匹配的提供者条目。`alibaba-token-plan` 锁定在北京,而 `alibaba-token-plan-intl` 覆盖国际端点。 对于损坏的 `openai-responses` 网关,修复应放在提供者对象上: @@ -210,7 +206,7 @@ affinity。这些策略不能规避 provider enforcement。 ## Cursor 提供者(`adapter: "cursor"`) -Cursor 桥接是实验性的。执行 `ocx login cursor` 之后,添加或编辑 `providers.cursor`。Cursor Router 的优化层级会作为独立的 Codex id 暴露,因为选择器无法渲染 Cursor 特定的模型参数: +Cursor 桥接是实验性的。执行 `ccx login cursor` 之后,添加或编辑 `providers.cursor`。Cursor Router 的优化层级会作为独立的 Codex id 暴露,因为选择器无法渲染 Cursor 特定的模型参数: | Codex model | Cursor Router mode | | --- | --- | @@ -225,8 +221,6 @@ Cursor 由服务端驱动的本地工具默认是禁用的。Codex 继续使用 - `"off"`(默认)会拒绝执行 Cursor 原生的 `read`、`write`、`delete`、`ls`、`grep`、`shell` 和 `fetch`。 - `"on"` 会启用受信任的本地执行,并绕过 Codex 的审批/沙箱语义。 -- `"codex-sandbox"` 为兼容性保留,但会像 `"off"` 一样失败关闭;请求文案并不是可信的沙箱证明。 - ```json { "providers": { @@ -241,7 +235,7 @@ Cursor 由服务端驱动的本地工具默认是禁用的。Codex 继续使用 } ``` -请将该字段设置在 `providers.cursor` 上,而不是顶层。在仪表板中,使用 **Providers → Cursor → Edit JSON**,保存,然后重启。旧的 `unsafeAllowNativeLocalExec: true` 仅在未设置 `nativeLocalExec` 时,才等同于 `nativeLocalExec: "on"`。MCP、屏幕录制和 computer use 由 `mcpServers` 和 `desktopExecutor` 单独控制。 +请将该字段设置在 `providers.cursor` 上,而不是顶层。在仪表板中,使用 **Providers → Cursor → Edit JSON**,保存,然后重启。MCP、屏幕录制和 computer use 由 `mcpServers` 和 `desktopExecutor` 单独控制。 每个 `mcpServers.<name>` 都可以接受 `command`(stdio)或 `url`(Streamable HTTP)。stdio 还接受 `args`、`env` 和 `cwd`;HTTP 接受 `headers`。两者都支持 `enabled`(默认 true)和 `toolPrefix`。`desktopExecutor` 接受 `computerUseCommand`、`recordScreenCommand`、`cwd`、`env` 和 `timeoutMs`(默认 `30000`)。命令通过 `sh -c` 执行,从 stdin 读取一个 JSON 请求,并且必须向 stdout 写入一个 JSON 结果。 @@ -277,7 +271,7 @@ OpenRouter 可以通过多个推理提供者来提供同一个模型。`openRout } ``` -模型键必须是精确的原生 OpenRouter id,不带外层的 opencodex 提供者前缀。选择 `openrouter/anthropic-claude-sonnet-5` 会在应用模型规则之前,还原为原生 `anthropic/claude-sonnet-5`。 +模型键必须是精确的原生 OpenRouter id,不带外层的 CodexCommander 提供者前缀。选择 `openrouter/anthropic-claude-sonnet-5` 会在应用模型规则之前,还原为原生 `anthropic/claude-sonnet-5`。 ## 静态模型允许列表 diff --git a/docs-site/src/content/docs/zh-cn/reference/configuration/routing.md b/docs-site/src/content/docs/zh-cn/reference/configuration/routing.md index b718ed4ed7..d5aad4ec6d 100644 --- a/docs-site/src/content/docs/zh-cn/reference/configuration/routing.md +++ b/docs-site/src/content/docs/zh-cn/reference/configuration/routing.md @@ -10,11 +10,11 @@ description: 默认提供方选择、模型解析顺序、组合别名、目标 | 字段 | 类型 | 默认值 | 含义 | | --- | --- | --- | --- | | `defaultProvider` | `string` | `"openai"` | 当没有更早的模型规则匹配时使用的最终提供方。它必须是一个已启用且已配置的提供方名称。 | -| `combos?` | `Record<string, OcxComboConfig>` | `{}` | 由有序的提供方/模型目标构建出来的虚拟 `combo/<id>` 模型。 | +| `combos?` | `Record<string, CodexCommanderComboConfig>` | `{}` | 由有序的提供方/模型目标构建出来的虚拟 `combo/<id>` 模型。 | ## 模型解析顺序 -opencodex 按以下顺序解析请求的模型: +CodexCommander 按以下顺序解析请求的模型: 1. 已配置的 `<account-selector>/<native-openai-model>` 命名空间,只会路由到映射的已存储 Codex 账户。无效或不可用的精确目标会以 fail closed 方式失败。 @@ -80,7 +80,7 @@ selector 校验、冲突规则和隐私说明见[提供方配置](/reference/con ### 目录可列出性 -即使某个 combo 不能被列出,它仍然可以直接路由。只有当所有目标都暴露出可以交集的能力时,`ocx sync`、`/v1/models` 和 Codex 选择器才会列出它: +即使某个 combo 不能被列出,它仍然可以直接路由。只有当所有目标都暴露出可以交集的能力时,`ccx sync`、`/v1/models` 和 Codex 选择器才会列出它: - 一个正的 `contextWindow`,来源可以是实时元数据、注册表提示,或提供方的 `modelContextWindows` / `contextWindow`;以及 @@ -94,7 +94,7 @@ selector 校验、冲突规则和隐私说明见[提供方配置](/reference/con 显式请求的 `policy/<id>`(或配置的别名)会在固定的候选白名单中,根据硬性能力要求与确定性、可解释的评分进行选择。现有模型 ID 永远不会隐式经过配置文件。支持 `candidates`(显式白名单)、可选 `alias`、`require`(`minContextWindow`、`minQuotaHeadroom`、`tools`、`imageInput`、`structuredOutput`、`localOnly`、`remoteAllowed`、`encryptedCodexTasks`、`reasoningEffort`、`serviceTier`)、`optimize`(latency/health/cost/quota 权重)、`limits.maxEstimatedCostUsd`、`unknownEvidence`(allow/penalize/exclude)。未知不会被当作零或免费。 -CLI:`ocx route policy list`、`ocx route policy show <id>`、`ocx route policy dry-run <id> --model-context <tokens> --tools`、`ocx route policy evaluate <id>`。 +CLI:`ccx route policy list`、`ccx route policy show <id>`、`ccx route policy dry-run <id> --model-context <tokens> --tools`、`ccx route policy evaluate <id>`。 组合是显式的有序/加权目标路由与故障转移;策略配置文件是基于证据在候选之间进行选择。 @@ -107,8 +107,8 @@ CLI:`ocx route policy list`、`ocx route policy show <id>`、`ocx route policy 返回的历史记录与路由决策负载仅暴露已脱敏的请求元数据(例如不透明的 `apiKeyId` 标签)。不包含凭证、原始提示正文或提供商密钥。 -CLI:`ocx logs explain <request-id>`、`ocx logs rebuild-index`、`ocx logs index-status`。 +CLI:`ccx logs explain <request-id>`、`ccx logs rebuild-index`、`ccx logs index-status`。 -## 迁移 +## 现有数据 -`routingProfiles` 是可选的增量配置:现有配置文件与旧 `usage.jsonl` 行均可原样加载。索引是一次性的——删除后会在下次查询时从 `usage.jsonl` 自动重建。系统不会自动调优。 +`routingProfiles` 是可选的增量配置:现有配置文件与不含 `routeDecision` 的 `usage.jsonl` 行均可加载。索引是一次性的——删除后会在下次查询时从 `usage.jsonl` 自动重建。系统不会自动调优。 diff --git a/docs-site/src/content/docs/zh-cn/reference/configuration/server.md b/docs-site/src/content/docs/zh-cn/reference/configuration/server.md index e3c530cc10..21367d5b64 100644 --- a/docs-site/src/content/docs/zh-cn/reference/configuration/server.md +++ b/docs-site/src/content/docs/zh-cn/reference/configuration/server.md @@ -11,26 +11,22 @@ description: 监听、远程访问、准入密钥、超时、存储、侧车、 | 字段 | 类型 | 默认值 | 含义 | | --- | --- | --- | --- | | `port` | `number` | `10100` | 代理监听端口。 | -| `hostname?` | `string` | `"127.0.0.1"` | 绑定地址。非回环绑定需要 `OPENCODEX_API_AUTH_TOKEN`。 | +| `hostname?` | `string` | `"127.0.0.1"` | 绑定地址。非回环绑定需要 `CODEXCOMMANDER_API_AUTH_TOKEN`。 | | `proxy?` | `string` | — | 出站 HTTP(S) 代理 URL,或 `${ENV_VAR}`。仅当 `HTTP_PROXY` / `HTTPS_PROXY` 未设置时才会应用;回环地址始终保留在 `NO_PROXY` 中。 | | `stallTimeoutSec?` | `number` | `300` | 在上游没有数据之前可等待的秒数,超过后返回 `response.incomplete`。最小值为 1。 | | `connectTimeoutMs?` | `number` | `200000` | 每次尝试的 DNS/TCP/TLS/最终响应头截止时间;它在正文生成之前结束。 | | `shutdownTimeoutMs?` | `number` | `5000` | 优雅停机截止时间,超过后会中止仍在进行中的请求。 | | `websockets?` | `boolean` | `false` | 为 Responses WebSocket 路径声明 `supports_websockets`。设为 false 会保留 HTTP/SSE。 | | `corsAllowOrigins?` | `string[]` | `[]` | CORS 额外允许的精确 origin。loopback origin 始终允许;支持 `chrome-extension://<扩展 ID>` 等基于 authority 的浏览器扩展 origin,`*` 不是通配符。Firefox 和 Safari 会(每次安装/启动浏览器时)重新生成扩展 UUID,origin 变化后请更新该条目。 | -| `apiKeys?` | `OcxApiKey[]` | `[]` | 管理平面和非回环绑定上的数据平面身份验证可接受的已生成 `ocx_…` 凭据。由仪表板管理。 | +| `apiKeys?` | `CodexCommanderApiKey[]` | `[]` | 非回环绑定上的数据平面身份验证可接受的已生成 `ccx_data_…` 凭据。由仪表板管理,不能用于验证 `/api/*`。 | | `storageCleanupPolicy?` | `StorageCleanupPolicy` | disabled | 可选启用的归档会话清理策略。不会被隐式启用。 | | `appOwnedMemoryBudgetMb?` | `number` | `256` | 可逐出应用自有日志、缓存、blob 和续传载荷的内存上限,单位 MiB。范围 64–4096;不是 RSS 上限。 | -| `codexAutoStart?` | `boolean` | `true` | 允许 Codex shim 在启动 Codex 之前运行 `ocx ensure`。设为 false 会让 ensure 变成无操作。 | -| `codexShimAutoRestore?` | `boolean` | `true` | 在完成外部 Codex 更新并覆盖安装的 shim 之后恢复该 shim。环境退出开关:`OPENCODEX_CODEX_SHIM_AUTO_RESTORE=0`。 | -| `syncResumeHistory?` | `boolean` | `true` | 可逆的 Codex App 历史兼容性。原始元数据会被备份,并由 `ocx stop` / `ocx restore` 恢复。 | -| `shadowCallIntercept?` | `{ enabled?: boolean; model?: string; sourceModels?: string[] }` | off | 将识别出的 Codex 辅助/影子调用以低努力级别重定向到选定模型。默认源前缀为 `gpt-5.6-luna`;0.144.x 及更早客户端使用 `gpt-5.4-mini`,可通过 `sourceModels` 恢复。 | -| `webSearchSidecar?` | `OcxWebSearchSidecarConfig` | 在可用时启用 | Web 搜索侧车选项。 | -| `visionSidecar?` | `OcxVisionSidecarConfig` | 在可用时启用 | 图像描述侧车选项。 | -| `images?` | `OcxImagesConfig` | 自动选择 OpenAI | 用于 Codex `image_gen` 的独立 Images 转发选项。 | - -如果较旧的开发版本在尚未提供备份支持之前修改过了 resume-history 元数据,请运行 -`ocx recover-history --legacy-openai` 强制使用原生提供方恢复。 +| `codexAutoStart?` | `boolean` | `true` | 允许 Codex shim 在启动 Codex 之前运行 `ccx ensure`。设为 false 会让 ensure 变成无操作。 | +| `codexShimAutoRestore?` | `boolean` | `true` | 在完成外部 Codex 更新并覆盖安装的 shim 之后恢复该 shim。环境退出开关:`CODEXCOMMANDER_CODEX_SHIM_AUTO_RESTORE=0`。 | +| `shadowCallIntercept?` | `{ enabled?: boolean; model?: string; sourceModels?: string[] }` | off | 将识别出的 Codex 辅助/影子调用以低努力级别重定向到选定模型。默认源前缀为 `gpt-5.6-luna`;`sourceModels` 是当前自定义源的显式覆盖。 | +| `webSearchSidecar?` | `CodexCommanderWebSearchSidecarConfig` | 在可用时启用 | Web 搜索侧车选项。 | +| `visionSidecar?` | `CodexCommanderVisionSidecarConfig` | 在可用时启用 | 图像描述侧车选项。 | +| `images?` | `CodexCommanderImagesConfig` | 自动选择 OpenAI | 用于 Codex `image_gen` 的独立 Images 转发选项。 | ## 远程访问 @@ -38,18 +34,18 @@ description: 监听、远程访问、准入密钥、超时、存储、侧车、 在 `/api/*` 和数据平面上都启用令牌认证。启动前先导出令牌: ```bash -export OPENCODEX_API_AUTH_TOKEN="your-secret-token" -ocx start +export CODEXCOMMANDER_API_AUTH_TOKEN="your-secret-token" +ccx start ``` 如果没有这个变量,代理会拒绝远程绑定。对于后台服务,请在运行 -`ocx service install` 之前导出它,这样 launchd、systemd 或 Task Scheduler 都能接收到。客户端应发送: +`ccx service install` 之前导出它,这样 launchd、systemd 或 Task Scheduler 都能接收到。客户端应发送: ```text -x-opencodex-api-key: your-secret-token +x-codexcommander-api-key: your-secret-token ``` -| 端点 | `Authorization: Bearer` | `x-opencodex-api-key` | `x-api-key` | +| 端点 | `Authorization: Bearer` | `x-codexcommander-api-key` | `x-api-key` | | --- | --- | --- | --- | | `/v1/responses` | 不接受 | **必需** | 不接受 | | `/v1/chat/completions` | 不接受 | **必需** | 不接受 | @@ -73,7 +69,7 @@ ssh -L 20100:localhost:10100 you@remote ``` 任意本地端口都可以。Host 解析为 `localhost`、`127.0.0.1` 或 `::1` 的请求无论端口是多少都仍然算回环,因此 `http://localhost:20100/v1` 可以正常工作。在客户端中把这个 base URL 设为目标地址; -`ocx` 只会把默认的本地 `127.0.0.1` 地址写入已管理的客户端配置。 +`ccx` 只会把默认的本地 `127.0.0.1` 地址写入已管理的客户端配置。 提供方 OAuth 回调监听在固定的远程端口上。请在远程机器上登录,或者也把那个端口转发出来: @@ -95,15 +91,14 @@ ssh -L 20100:localhost:10100 -L 1455:localhost:1455 you@remote ## Claude Code (`claudeCode`) -这些设置控制 `/v1/messages`、`ocx claude` 启动器,以及 Claude 仪表板页面。 +这些设置控制 `/v1/messages`、`ccx claude` 启动器,以及 Claude 仪表板页面。 | 键 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | `claudeCode.bodyStallSec?` | `number` | `90` | 在读取挂起期间,原生透传正文的不活动预算,单位秒,而不是总时长。最小值为 1;精确的 `0` 会禁用。 | | `claudeCode.bodyMaxBytes?` | `number` | `67108864` | 流式和缓冲响应的原生透传正文累计上限。精确的 `0` 会禁用。 | | `claudeCode.authMode?` | `"proxy" \| "subscription"` | auto | 启动流程如何处理 `ANTHROPIC_AUTH_TOKEN`。auto 会在每次启动时自动检测认证;显式值不会被覆盖。 | -| `claudeCode.authModeMigratedAt?` | `string` | unset | 内部的一次性升级标记。不要手动设置。 | -| `claudeCode.subagentEffort?` | `"low" \| "medium" \| "high" \| "xhigh" \| "max"` | inherit | 写入生成的 `~/.claude/agents/ocx-*.md` 的努力级别;与 Codex 指引和代理上限相互独立。需通过 `ocx claude` 重新启动以重新生成。 | +| `claudeCode.subagentEffort?` | `"low" \| "medium" \| "high" \| "xhigh" \| "max"` | inherit | 写入生成的 `~/.claude/agents/ccx-*.md` 的努力级别;与 Codex 指引和代理上限相互独立。需通过 `ccx claude` 重新启动以重新生成。 | 自动认证会在找到已保存的 Claude 认证时选择 subscription,在未找到时选择 proxy;如果检测结果不明确,则会选择 subscription 并给出警告。参见 [Claude Code 认证模式](/guides/claude-code/#auth-mode)。 @@ -111,7 +106,7 @@ ssh -L 20100:localhost:10100 -L 1455:localhost:1455 you@remote ## 影子调用 Codex 会为标题、提交信息等任务使用较小的辅助模型。启用 -`shadowCallIntercept` 后,可将识别出的源模型前缀重定向到另一个已配置模型。替换会以低努力级别运行。只有当客户端使用不同的辅助 ID 时,才设置 `sourceModels`。 +`shadowCallIntercept` 后,可将识别出的源模型前缀重定向到另一个已配置模型。替换会以低努力级别运行。仅在显式指定当前自定义源时设置 `sourceModels`。只有 `x-codex-turn-metadata` 中可识别的维护请求才会被拦截;普通轮次以及元数据缺失、损坏或无法识别的请求不会被拦截。 ```json { @@ -125,7 +120,7 @@ Codex 会为标题、提交信息等任务使用较小的辅助模型。启用 ## 侧车 -### `images` (`OcxImagesConfig`) +### `images` (`CodexCommanderImagesConfig`) | 字段 | 类型 | 默认值 | 含义 | | --- | --- | --- | --- | @@ -134,13 +129,13 @@ Codex 会为标题、提交信息等任务使用较小的辅助模型。启用 如果提供方缺失、被禁用、不兼容,或者没有可用密钥,显式选择就会失败并关闭;它绝不会回退到另一个付费上游。该端点必须实现 Codex 期望的 OpenAI Images API 路径和响应形状。 -### `webSearchSidecar` (`OcxWebSearchSidecarConfig`) +### `webSearchSidecar` (`CodexCommanderWebSearchSidecarConfig`) | 字段 | 类型 | 默认值 | 含义 | | --- | --- | --- | --- | | `enabled?` | `boolean` | 在可用时启用 | 总开关。 | | `backend?` | `"openai" \| "anthropic"` | auto | 显式优先;否则若可用的 Anthropic OAuth 存储凭据存在则选择 `anthropic`,否则选择 `openai`。 | -| `model?` | `string` | 依后端而定 | OpenAI 使用 `gpt-5.6-luna`,Anthropic 使用 `claude-sonnet-5`。旧的显式 `gpt-5.4-mini` 会在启动时迁移。 | +| `model?` | `string` | 依后端而定 | OpenAI 使用 `gpt-5.6-luna`,Anthropic 使用 `claude-sonnet-5`。 | | `reasoning?` | `string` | `low` | 侧车努力级别。`minimal` 与 web search 不兼容,会被拒绝。 | | `maxSearchesPerTurn?` | `number` | `3` | 每个主模型轮次允许的实际搜索次数。 | | `routedModelStallTimeoutMs?` | `number` | `200000` | 仅限配置文件的 routed-model 原始正文不活动截止时间。整数范围 1–2147483647;每个非空数据块都会重置它。 | @@ -152,7 +147,7 @@ routed 重放会把主 ChatGPT 认证注入内部请求。Anthropic 后端使用 搜索由四个时钟共同约束:基础 `stallTimeoutSec`、`connectTimeoutMs`、routed-model 不活动超时,以及 托管搜索超时。有效的桥接看门狗是最大值再加 30 秒。routed stall 是不活动保护,而不是总生成截止时间。 -### `visionSidecar` (`OcxVisionSidecarConfig`) +### `visionSidecar` (`CodexCommanderVisionSidecarConfig`) | 字段 | 类型 | 默认值 | 含义 | | --- | --- | --- | --- | @@ -164,4 +159,4 @@ routed 重放会把主 ChatGPT 认证注入内部请求。Anthropic 后端使用 Vision 只会对发送给其提供方 `noVisionModels` 中模型的图像生效。OpenAI 具有与 search 相同的登录/forward 要求;显式选择的 Anthropic 在没有可用凭据时会失败并关闭。成功的 `data:` 描述会使用一个受限缓存,其键由后端、模型、detail、图像字节以及规范化消息上下文组成。命中和同轮重复不会消耗限额。远程 `https:` 图像以及失败或空的描述不会被缓存。 -Anthropic OAuth 侧车会复用 opencodex 现有的 Claude Code OAuth 指纹。请对目标账户和负载进行 soak 测试。 +Anthropic OAuth 侧车会复用 CodexCommander 现有的 Claude Code OAuth 指纹。请对目标账户和负载进行 soak 测试。 diff --git a/docs-site/src/content/docs/zh-cn/reference/management-api.md b/docs-site/src/content/docs/zh-cn/reference/management-api.md index 9cde6c02e6..25faf80819 100644 --- a/docs-site/src/content/docs/zh-cn/reference/management-api.md +++ b/docs-site/src/content/docs/zh-cn/reference/management-api.md @@ -1,25 +1,25 @@ --- title: 管理 API -description: opencodex 控制平面的身份验证、错误和端点参考。 +description: CodexCommander 控制平面的身份验证、错误和端点参考。 --- -Management API 是 opencodex 的控制平面。`http://localhost:10100` 上的仪表板只是它的一个客户端;无头的 `ocx` provider、model、combo、account、settings、diagnostics 和 lifecycle 命令也是客户端。该 API 仅在代理运行时可用。 +Management API 是 CodexCommander 的控制平面。`http://localhost:10100` 上的仪表板只是它的一个客户端;无头的 `ccx` provider、model、combo、account、settings、diagnostics 和 lifecycle 命令也是客户端。该 API 仅在代理运行时可用。 请使用 [Web 仪表板](/guides/web-dashboard/) 作为交互式客户端,或者在构建自动化时参考本文档。持久化值最终遵循 [配置](/reference/configuration/)。 ## 身份验证模型 -Management API 有自己独立的管理员凭证,与数据平面 API 密钥无关。启动时,opencodex 会按以下顺序解析它: +Management API 有自己独立的管理员凭证,与数据平面 API 密钥无关。启动时,CodexCommander 会按以下顺序解析它: -1. `OPENCODEX_ADMIN_AUTH_TOKEN`,如果已设置。 -2. 在加固后的密钥文件中生成的 `ocx_admin_*` 令牌。 +1. `CODEXCOMMANDER_ADMIN_AUTH_TOKEN`,如果已设置。 +2. 在加固后的密钥文件中生成的 `ccx_admin_*` 令牌。 只有在其目录和文件权限或 ACL 已加固后,才会接受基于文件的令牌。如果无法保证这一点,管理身份验证将以拒绝式失败结束,API 会返回 503,直到提供环境变量令牌或修复文件状态为止。 管理员令牌可用以下任一形式发送: ```http -X-OpenCodex-API-Key: <admin-token> +X-CodexCommander-API-Key: <admin-token> ``` ```http @@ -32,7 +32,7 @@ Authorization: Bearer <admin-token> ### 回环仪表板会话 -在回环绑定上,仪表板引导可以接收一个短期的 `ocx_session_*` 凭证。每个会话持续五分钟,并绑定到精确的仪表板来源。安全请求必须匹配该来源。非安全方法还要求浏览器的 `Origin` 和该会话的 CSRF 令牌。 +在回环绑定上,仪表板引导可以接收一个短期的 `ccx_session_*` 凭证。每个会话持续五分钟,并绑定到精确的仪表板来源。安全请求必须匹配该来源。非安全方法还要求浏览器的 `Origin` 和该会话的 CSRF 令牌。 当需要数据平面身份验证时,会禁用会话签发,这也包括远程绑定。远程操作员必须使用原始管理员令牌进行身份验证;不会签发类似回环的 GUI 会话。 @@ -42,7 +42,7 @@ Authorization: Bearer <admin-token> | 状态 | 类型或代码 | 含义 | | --- | --- | --- | -| 401 | `opencodex admin token required` | 管理员令牌或 GUI 会话缺失、无效、过期、来源不匹配,或缺少 CSRF 证据 | +| 401 | `codexcommander admin token required` | 管理员令牌或 GUI 会话缺失、无效、过期、来源不匹配,或缺少 CSRF 证据 | | 403 | `cross-origin request blocked` | 请求来源不在管理允许列表中 | | 404 | `not_found` | 没有任何管理路由匹配该方法和路径 | | 413 | `request body too large` | POST、PUT 或 PATCH 请求体超过 2 MiB 的管理限制 | @@ -65,7 +65,7 @@ Authorization: Bearer <admin-token> | `PUT /api/grok/selection` | 持久化被排除的 Grok 模型 | 400 选择无效或超出大小限制 | | `POST /api/grok/apply` | 通过托管同步应用已持久化的 Grok 配置 | 409 `grok_apply_busy`;400/500 应用失败 | | `GET, PUT /api/claude-desktop` | 读取或持久化 Claude Desktop 的路由/原生配置文件 | 400 分配无效或不可用 | -| `POST /api/claude-desktop/apply` | 将已保存的配置文件写入 Claude Desktop 的托管配置 | 400/500 写入失败 | +| `POST /api/claude-desktop/apply` | 将已保存的配置文件写入 Claude Desktop 的托管配置。必须提供 JSON 对象及明确的 `mode`:`static`、`hybrid` 或 `discovery` | 400 请求体/mode 无效;500 写入失败 | | `GET /api/claude-desktop/status` | 检查已保存与已应用的配置文件以及 Desktop 健康状态 | 400 状态读取失败 | | `GET, PUT /api/claude-code` | 读取或更新 Claude Code 的网关、认证模式、模型映射、上下文、代理和 sidecar 设置 | 400 字段或结构无效 | @@ -93,9 +93,6 @@ Authorization: Bearer <admin-token> | `GET, POST /api/windows-tray` | 读取 Windows 托盘状态,或安装、启动、停止、卸载它 | 400 不支持的平台/动作;500 操作失败 | | `GET /api/diagnostics/project-config` | 读取缓存的项目配置警告 | — | | `POST /api/sync` | 将当前模型目录同步到 Codex,并返回 `catalogQuality`、`rehydrated`、Codex app-server `catalogState` 和所需的重启提示 | 409 写入权限被拒绝;500 同步失败 | -| `GET /api/update/check` | 检查 `latest` 或 `preview` 更新通道 | 400 无效标签 | -| `POST /api/update/run` | 启动更新任务,可选随后重启 | 400 无效请求体;任务特定的冲突/错误状态 | -| `GET /api/update/status` | 按 id 轮询更新任务 | 404 未知任务 | | `GET, PUT /api/sidecar-settings` | 读取或更新 web 搜索和 vision sidecar 的模型/后端设置 | 400 结构、后端或限制无效 | | `GET, PUT /api/shadow-call-settings` | 读取或更新 shadow-call 拦截设置 | 400 结构或值无效 | @@ -175,12 +172,6 @@ Authorization: Bearer <admin-token> `provider_has_dependent_combos` 是一个安全屏障:在删除 provider 之前,先移除或编辑依赖它的 combos。 -### 侧边栏 - -| 方法和路径 | 用途 | 典型错误 | -| --- | --- | --- | -| `GET /api/update/badge` | 读取便宜的侧边栏更新徽标状态 | — | - ### 系统生命周期 | 方法和路径 | 用途 | 典型错误 | @@ -200,7 +191,7 @@ Authorization: Bearer <admin-token> | `PUT /api/codex-auth/accounts/pause` | 暂停或恢复一个账户 | 400 账户/状态无效;404 缺少账户 | | `PUT /api/codex-auth/accounts/pause-exhausted` | 暂停配额已耗尽的账户 | 变更锁失败会变成 503 | | `POST /api/codex-auth/accounts/clear-cooldown` | 清除一个账户或所有账户的运行时冷却 | 400 id 无效 | -| `GET, PUT /api/codex-auth/active` | 读取或选择当前活跃账户 | 400 账户无效或缺失;409 暂停/旧行冲突 | +| `GET, PUT /api/codex-auth/active` | 读取或选择当前活跃账户 | 400 账户无效或缺失;409 账户已暂停 | | `PUT /api/codex-auth/auto-switch` | 设置自动切换账户的配额阈值 | 400 阈值无效 | | `PUT, PATCH /api/codex-auth/pool-strategy` | 更新 Codex 账户池选择策略 | 400 策略/配置无效 | | `PUT /api/codex-auth/failover` | 设置账户故障转移阈值 | 400 阈值无效 | @@ -216,4 +207,4 @@ Authorization: Bearer <admin-token> ## 如何选择客户端 -对于日常管理,[Web 仪表板](/guides/web-dashboard/)提供了最安全的引导式流程。对于无头主机和自动化,请使用相应的 `ocx` 命令:它们调用的是同一个实时 API,并在代理不可达或操作失败时返回非零结果。直接 HTTP 最适合需要上述精确端点契约的集成。 +对于日常管理,[Web 仪表板](/guides/web-dashboard/)提供了最安全的引导式流程。对于无头主机和自动化,请使用相应的 `ccx` 命令:它们调用的是同一个实时 API,并在代理不可达或操作失败时返回非零结果。直接 HTTP 最适合需要上述精确端点契约的集成。 diff --git a/docs-site/src/content/docs/zh-cn/reference/proxy-formats.md b/docs-site/src/content/docs/zh-cn/reference/proxy-formats.md index 1f3c2cfba8..4ee3fe326a 100644 --- a/docs-site/src/content/docs/zh-cn/reference/proxy-formats.md +++ b/docs-site/src/content/docs/zh-cn/reference/proxy-formats.md @@ -3,7 +3,7 @@ title: Proxy API 格式 description: 面向 Responses、Chat Completions、Anthropic Messages、模型目录、WebSocket、realtime 和 compaction 各表面的传输层参考。 --- -opencodex 以多种客户端方言提供一个本地代理。Codex 客户端可以使用 +CodexCommander 以多种客户端方言提供一个本地代理。Codex 客户端可以使用 Responses API,兼容 OpenAI 的应用可以使用 Chat Completions,而 Claude Code 可以使用 Anthropic Messages,而不需要每个上游提供方都实现每一种格式。 @@ -33,7 +33,7 @@ Responses 表示是这座桥的中心。原生兼容的路由可以跳过部分 ## `POST /v1/responses` -这是 opencodex 原生的数据平面形状。请求体必须是一个包含非空 `model` 的 JSON 对象。`input` 可以是字符串,也可以是 Responses 项目数组。 +这是 CodexCommander 原生的数据平面形状。请求体必须是一个包含非空 `model` 的 JSON 对象。`input` 可以是字符串,也可以是 Responses 项目数组。 ### 接受的请求字段 @@ -163,7 +163,7 @@ choice 增量、带 `finish_reason` 的终止 choice,以及 `data: [DONE]`。 ## `POST /v1/live` 和 Realtime sideband `POST /v1/live` 接受 ChatGPT/Codex App 的 Frameless call-creation 表面。 -`POST /v1/realtime/calls` 接受 OpenAI Realtime 的 call-creation 表面。opencodex 会选择 +`POST /v1/realtime/calls` 接受 OpenAI Realtime 的 call-creation 表面。CodexCommander 会选择 一个符合条件的 OpenAI 家族路由,将 call-creation 请求规范化为上游认证模式,并转发有界响应。 完成调用创建后,客户端可以使用任一受支持的入站形式加入 sideband WebSocket: @@ -181,7 +181,7 @@ Compaction 会为需要缩短长 Responses 会话的客户端返回替换历史 | 路由类型 | 行为 | | --- | --- | | Canonical ChatGPT 或官方 OpenAI 路由 | 将请求转发到原生 `/responses/compact` 端点,并使用已解析的账号和模型认证 | -| 其他路由模型 | 运行一次内部的、非流式、无工具的 compaction 轮次,并带 `compaction_trigger`;要求且只允许一个 synthetic `compaction` 项,其 `encrypted_content` 是一个 `ocx1:` 封装;把该摘要解码为 v1 替换历史 | +| 其他路由模型 | 运行一次内部的、非流式、无工具的 compaction 轮次,并带 `compaction_trigger`;要求且只允许一个 synthetic `compaction` 项,其 `encrypted_content` 是一个 `ccx1:` 封装;把该摘要解码为 v1 替换历史 | 原生 compact 响应会被缓冲,最大 32 MiB,即使其声明的 `Content-Length` 已经超过该限制也是如此。compact 专用失败包括: @@ -192,11 +192,11 @@ Compaction 会为需要缩短长 Responses 会话的客户端返回替换历史 | 499 | `client_cancelled` | 客户端在转发或缓冲期间取消了请求 | | 502 | `compact_response_too_large` | 原生 compact 输出超过 32 MiB | | 502 | `upstream_error` | 连接、读取,或合成 compaction 轮次失败 | -| 502 | `invalid_response_error` | 合成轮次没有产出恰好一个有效、非空的 `ocx1:` compaction 项 | +| 502 | `invalid_response_error` | 合成轮次没有产出恰好一个有效、非空的 `ccx1:` compaction 项 | ## 认证矩阵 -在仅绑定到 loopback 的情况下,数据平面准入不需要配置密钥。在远程绑定上,请使用下表。“Dedicated” 指 `X-OpenCodex-API-Key`;其他列指 `Authorization: Bearer ...` 和 `x-api-key`。 +在仅绑定到 loopback 的情况下,数据平面准入不需要配置密钥。在远程绑定上,请使用下表。“Dedicated” 指 `X-CodexCommander-API-Key`;其他列指 `Authorization: Bearer ...` 和 `x-api-key`。 | 表面 | Dedicated | Bearer | `x-api-key` | | --- | --- | --- | --- | @@ -232,7 +232,7 @@ Anthropic 来源的失败会以 Anthropic 的错误封装呈现,因此该方 ## 加密内容卫生 -代理把真正的后端密文视为不透明数据。结构有效的密文会逐字节保留:opencodex 不会对其解密、翻译其内容,或为另一个提供方重新加密。 +代理把真正的后端密文视为不透明数据。结构有效的密文会逐字节保留:CodexCommander 不会对其解密、翻译其内容,或为另一个提供方重新加密。 -某些 agent hook 历史上会把明文控制文本放进 `encrypted_content` 槽。为兼容起见,代理会把那部分明文拆分为文本片段,同时保持任何结构有效的 Fernet 片段不变。如果一个 `agent_message` 在该修复过程中失去了所有加密部分,它就会变成普通的 user message。如果当前的 v2 task 仍然真的是加密的,但所选路由目标无法读取原生 ChatGPT 密文,opencodex 会以 +某些 agent hook 会把明文控制文本放进 `encrypted_content` 槽。代理会把那部分明文拆分为文本片段,同时保持任何结构有效的 Fernet 片段不变。如果一个 `agent_message` 在该修复过程中失去了所有加密部分,它就会变成普通的 user message。如果当前的 v2 task 仍然真的是加密的,但所选路由目标无法读取原生 ChatGPT 密文,CodexCommander 会以 `unreadable_encrypted_agent_task` 失败,而不是把不可读字节发送给该提供方。有关 worker task 周边的客户端行为,请参见 [Sub-agent Surface](/guides/sub-agent-surface/)。 diff --git a/docs-site/src/content/docs/zh-cn/troubleshooting/windows-memory.md b/docs-site/src/content/docs/zh-cn/troubleshooting/windows-memory.md index 51d86bd125..ddba82e517 100644 --- a/docs-site/src/content/docs/zh-cn/troubleshooting/windows-memory.md +++ b/docs-site/src/content/docs/zh-cn/troubleshooting/windows-memory.md @@ -1,13 +1,13 @@ --- title: Windows 内存增长 -description: 为什么 bun 进程在 Windows 上会增长到数 GB 内存,opencodex 目前对此做了什么,以及在上游 Bun 修复发布前你可以怎么做。 +description: 为什么 bun 进程在 Windows 上会增长到数 GB 内存,CodexCommander 目前对此做了什么,以及在上游 Bun 修复发布前你可以怎么做。 --- -一些 Windows 用户会看到,opencodex 背后的 `bun` 进程在长时间流式会话期间增长到数 GB 的 RSS(已作为问题 [#314](https://github.com/lidge-jun/opencodex/issues/314) 报告)。本页会如实解释实际发生了什么,以及你可以采取什么措施。 +一些 Windows 用户会看到,CodexCommander 背后的 `bun` 进程在长时间流式会话期间增长到数 GB 的 RSS(已作为问题 [#314](https://github.com/pavelhov/CodexCommander/issues/314) 报告)。本页会如实解释实际发生了什么,以及你可以采取什么措施。 ## 根因:上游 Bun 运行时问题 -opencodex 打包了 Bun 运行时(当前为 **1.3.14**)。这类内存增长由已知的上游 Bun 问题驱动,而不是代理中的 JavaScript 级泄漏: +CodexCommander 打包了 Bun 运行时(当前为 **1.3.14**)。这类内存增长由已知的上游 Bun 问题驱动,而不是代理中的 JavaScript 级泄漏: | Bun issue | 状态(检查于 2026-07-23) | |---|---| @@ -15,16 +15,16 @@ opencodex 打包了 Bun 运行时(当前为 **1.3.14**)。这类内存增长 | [#32111](https://github.com/oven-sh/bun/issues/32111) — 当客户端中止一个 async-pull 流时发生崩溃 | 修复 [PR #32120](https://github.com/oven-sh/bun/pull/32120) 已于 2026-06-21 合并;不假定 1.3.14 已包含。注意:这个崩溃**不是 Windows 特有**的(在 macOS/Linux 上也可复现) | | [PR #31654](https://github.com/oven-sh/bun/pull/31654) — `node:net` socket 句柄泄漏 | 在上游仍然**开放** | -在 Windows 上,opencodex 必须把流式响应保持在一条保守代码路径上,以避免 #32111 崩溃,而这条路径也最容易暴露于背压问题:如果客户端缓慢或停滞,运行时就可能把上游数据缓存在原生内存中,而 JavaScript 无法对其设定上限。 +在 Windows 上,CodexCommander 必须把流式响应保持在一条保守代码路径上,以避免 #32111 崩溃,而这条路径也最容易暴露于背压问题:如果客户端缓慢或停滞,运行时就可能把上游数据缓存在原生内存中,而 JavaScript 无法对其设定上限。 -## opencodex 目前做了什么 +## CodexCommander 目前做了什么 这是有界缓解和可见性措施,不是修复。对于捆绑的 1.3.14 运行时,泄漏本身仍然是上游问题: - **内存监视器** — 代理每分钟采样一次自身内存,并在观测到的内存超过 4 GiB 时记录限频告警。观测到的内存取 RSS、`external` 和 `arrayBuffers` 三者中的最大值(不是它们的总和),因为 Windows 的工作集/RSS 计数可能低报已提交的外部保留。 -- **`ocx doctor`** — `"Memory / runtime"` 部分会显示*服务*进程的 Bun 版本、RSS、external/ArrayBuffers 计数、JS 堆上下文以及流模式决策。在捆绑的 Bun 1.3.14 运行时上,单看 `heapUsed` / `jscHeap` 不能作为泄漏判据;在认定为应用层泄漏之前,应把观测到的内存与 `responseState` 以及多次采样一起比较。 -- **`GET /api/system/memory`** — 通过已认证的管理 API 提供同样的数据,便于仪表板或脚本使用。除了 RSS/heap/external 计数之外,它还会报告一个标量的 `responseState` 块(条目数、序列化总字节数/最大字节数、最老条目的年龄),对应代理内存中的 `previous_response_id` 续接存储。这能进一步归因增长:在观测到的内存上升时,如果 `responseState.totalBytes` 也在上升,说明是对话保留在增长(较长的 `store:false` 链在每轮中重新扩张);而在观测到的内存上升时,如果 `responseState` 保持平稳,则更像不是这个存储造成的。返回值只包含标量,不包含请求正文、token、路径或账户标识,而且读取没有副作用(不会执行 prune,也不会 evict)。仪表板中的 **Memory observability** 卡片会渲染相同字段,并提供一个需要确认的 **Drain & restart** 操作:它会显示当前活动轮次数量,最多等待 60 秒让活动轮次结束(复用现有的 503 + `Retry-After` 排空机制),然后中止剩余轮次,并通过 `ocx start` 在当前端口重启代理(或者在仅故障时由服务监督程序重新拉起),同时不拆除 Codex 注入。这是一种比 `POST /api/stop` 的短排空更长、更知情的回收方式。 -- **有门控的替代流路径** — 一种有界的单读者中继,用来移除 tee + JavaScript rewrite 链。Windows 的 rewrite 流量已经使用它,普通 Windows 流量仍由运行时门控。macOS 上,只有当用户选择的 plaintext V2 collaboration 真正激活 client rewrite,且进程运行在经过验证的捆绑 Bun 1.3.14 上时,`auto` 才会选择精确的同步 `pull()` 中继。这是针对 [#1127](https://github.com/lidge-jun/opencodex/issues/1127) terminal delivery hang 的窄范围修复,并不表示 Bun 1.3.14 已包含通用的 #32111 修复。其他 macOS rewrite 仍需显式启用。memory endpoint 只公开 in-flight、cancel、abort、error 和 queue watermark 标量计数,不包含正文或请求身份。 +- **`ccx doctor`** — `"Memory / runtime"` 部分会显示*服务*进程的 Bun 版本、RSS、external/ArrayBuffers 计数、JS 堆上下文以及流模式决策。在捆绑的 Bun 1.3.14 运行时上,单看 `heapUsed` / `jscHeap` 不能作为泄漏判据;在认定为应用层泄漏之前,应把观测到的内存与 `responseState` 以及多次采样一起比较。 +- **`GET /api/system/memory`** — 通过已认证的管理 API 提供同样的数据,便于仪表板或脚本使用。除了 RSS/heap/external 计数之外,它还会报告一个标量的 `responseState` 块(条目数、序列化总字节数/最大字节数、最老条目的年龄),对应代理内存中的 `previous_response_id` 续接存储。这能进一步归因增长:在观测到的内存上升时,如果 `responseState.totalBytes` 也在上升,说明是对话保留在增长(较长的 `store:false` 链在每轮中重新扩张);而在观测到的内存上升时,如果 `responseState` 保持平稳,则更像不是这个存储造成的。返回值只包含标量,不包含请求正文、token、路径或账户标识,而且读取没有副作用(不会执行 prune,也不会 evict)。仪表板中的 **Memory observability** 卡片会渲染相同字段,并提供一个需要确认的 **Drain & restart** 操作:它会显示当前活动轮次数量,最多等待 60 秒让活动轮次结束(复用现有的 503 + `Retry-After` 排空机制),然后中止剩余轮次,并通过 `ccx start` 在当前端口重启代理(或者在仅故障时由服务监督程序重新拉起),同时不拆除 Codex 注入。这是一种比 `POST /api/stop` 的短排空更长、更知情的回收方式。 +- **有门控的替代流路径** — 一种有界的单读者中继,用来移除 tee + JavaScript rewrite 链。Windows 的 rewrite 流量已经使用它,普通 Windows 流量仍由运行时门控。macOS 上,只有当用户选择的 plaintext V2 collaboration 真正激活 client rewrite,且进程运行在经过验证的捆绑 Bun 1.3.14 上时,`auto` 才会选择精确的同步 `pull()` 中继。这是针对 [#1127](https://github.com/pavelhov/CodexCommander/issues/1127) terminal delivery hang 的窄范围修复,并不表示 Bun 1.3.14 已包含通用的 #32111 修复。其他 macOS rewrite 仍需显式启用。memory endpoint 只公开 in-flight、cancel、abort、error 和 queue watermark 标量计数,不包含正文或请求身份。 这些改动带来的真实世界 RSS 改善,仍在等待 Windows 用户验证,我们并不宣称泄漏已经修复。 @@ -32,10 +32,10 @@ opencodex 打包了 Bun 运行时(当前为 **1.3.14**)。这类内存增长 ## 你的选择 -1. **等待捆绑运行时更新。** 一旦某个 Bun 版本可验证地包含这些修复,opencodex 就会升级捆绑运行时,并在 Windows 上自动启用 no-rewrite 流路径。上面所述的 macOS plaintext-V2 `auto` 例外独立固定在特定的已验证 Bun 版本上。 +1. **等待捆绑运行时更新。** 一旦某个 Bun 版本可验证地包含这些修复,CodexCommander 就会升级捆绑运行时,并在 Windows 上自动启用 no-rewrite 流路径。上面所述的 macOS plaintext-V2 `auto` 例外独立固定在特定的已验证 Bun 版本上。 -2. **通过 `OPENCODEX_BUN_PATH` 运行你信任的 Bun 运行时。** 这属于未验证区域,你是在一个我们没有测试过的运行时上运行 opencodex,风险自负。对服务安装而言,这个覆盖值是在生成服务产物时读取的,而不是在服务启动时读取的。先设置环境变量,然后在同一个 shell 中重新运行 `ocx service repair`,这样路径才会被写入持久化的服务定义。只设置环境变量对已经安装好的服务没有任何作用。 +2. **通过 `CCX_BUN_PATH` 运行你信任的 Bun 运行时。** 这属于未验证区域,你是在一个我们没有测试过的运行时上运行 CodexCommander,风险自负。对服务安装而言,这个覆盖值是在生成服务产物时读取的,而不是在服务启动时读取的。先设置环境变量,然后在同一个 shell 中重新运行 `ccx service repair`,这样路径才会被写入持久化的服务定义。只设置环境变量对已经安装好的服务没有任何作用。 -3. **通过 `streamMode: "eager-relay"` 显式启用有界中继。** 有两种方式:编辑 `config.json`(添加 `"streamMode": "eager-relay"`),或调用管理 API - `PUT /api/settings` 携带 `{"streamMode":"eager-relay"}`,即可对新轮次生效,无需重启。**崩溃风险警告:** Bun 1.3.14 的通用 async-pull 流仍受 #32111 影响,因此对未经验证的形态强制使用 eager relay 仍可能在任何操作系统上使进程崩溃。服务管理器会重启进程,但正在进行的请求会失败。`"legacy-tee"` 会固定 tee,并关闭 macOS plaintext-V2 auto 例外。Windows 的 `"auto"`(默认值)遵循运行时门控。macOS 的 `"auto"` 除了精确、已验证的 plaintext-V2 collaboration rewrite 外都保持 tee;显式 `"eager-relay"` 可让其他符合条件的 SSE 轮次选择该路径。 +3. **通过 `streamMode: "eager-relay"` 显式启用有界中继。** 有两种方式:编辑 `config.json`(添加 `"streamMode": "eager-relay"`),或调用管理 API - `PUT /api/settings` 携带 `{"streamMode":"eager-relay"}`,即可对新轮次生效,无需重启。**崩溃风险警告:** Bun 1.3.14 的通用 async-pull 流仍受 #32111 影响,因此对未经验证的形态强制使用 eager relay 仍可能在任何操作系统上使进程崩溃。服务管理器会重启进程,但正在进行的请求会失败。`"safe-tee"` 会固定 tee,并关闭 macOS plaintext-V2 auto 例外。Windows 的 `"auto"`(默认值)遵循运行时门控。macOS 的 `"auto"` 除了精确、已验证的 plaintext-V2 collaboration rewrite 外都保持 tee;显式 `"eager-relay"` 可让其他符合条件的 SSE 轮次选择该路径。 -如果你在真实的 Windows 工作负载上尝试这些方案,请把变更前后 `ocx doctor` 的内存部分发到 [#314](https://github.com/lidge-jun/opencodex/issues/314)——这正是这个缓解措施在等待的验证。 +如果你在真实的 Windows 工作负载上尝试这些方案,请把变更前后 `ccx doctor` 的内存部分发到 [#314](https://github.com/pavelhov/CodexCommander/issues/314)——这正是这个缓解措施在等待的验证。 diff --git a/docs-site/src/data/README-frontier.md b/docs-site/src/data/README-frontier.md index 13bbd7c2a0..2b919c3ac2 100644 --- a/docs-site/src/data/README-frontier.md +++ b/docs-site/src/data/README-frontier.md @@ -5,7 +5,7 @@ Static leaderboard data for the docs-site **Benchmarks** page lives in `../components/FrontierBoards.astro`. Ported from PR #144 (GUI Frontier page proposal) — the GUI was not the right home for hand-maintained snapshots. -These numbers are **snapshots**, not live OpenCodex metering. Refresh them when +These numbers are **snapshots**, not live CodexCommander metering. Refresh them when upstream boards move, then bump `provenance.capturedAt` and (if needed) the catalog `version`. diff --git a/docs-site/src/data/frontier-benchmarks.json b/docs-site/src/data/frontier-benchmarks.json index baf16a2b8e..3aae6391a2 100644 --- a/docs-site/src/data/frontier-benchmarks.json +++ b/docs-site/src/data/frontier-benchmarks.json @@ -4,7 +4,7 @@ { "id": "deepswe", "title": "DeepSWE", - "sourceNote": "Illustrative snapshot from the public DeepSWE leaderboard (mini-swe-agent). Scores and costs are not live OpenCodex metering.", + "sourceNote": "Illustrative snapshot from the public DeepSWE leaderboard (mini-swe-agent). Scores and costs are not live CodexCommander metering.", "updated": "2026-07-16", "taskCount": 113, "axes": { @@ -261,7 +261,7 @@ { "id": "aa-coding-agent", "title": "AA Coding Agent", - "sourceNote": "Artificial Analysis Coding Agent Index snapshot (post GPT-5.6 GA, 2026-07-09). See provenance.url. Not live OpenCodex metering.", + "sourceNote": "Artificial Analysis Coding Agent Index snapshot (post GPT-5.6 GA, 2026-07-09). See provenance.url. Not live CodexCommander metering.", "updated": "2026-07-09", "axes": { "xKey": "avgCostUsd", @@ -413,7 +413,7 @@ { "id": "aa-intelligence-index", "title": "AA Intelligence Index", - "sourceNote": "Illustrative snapshot inspired by Artificial Analysis Intelligence Index cost-per-task (Answer / Reasoning / Cache write / Cache hit / Input). Totals match published headline figures where noted; segment splits are approximate for charting. Not live OpenCodex metering.", + "sourceNote": "Illustrative snapshot inspired by Artificial Analysis Intelligence Index cost-per-task (Answer / Reasoning / Cache write / Cache hit / Input). Totals match published headline figures where noted; segment splits are approximate for charting. Not live CodexCommander metering.", "updated": "2026-07-16", "axes": { "xKey": "avgCostUsd", @@ -673,7 +673,7 @@ { "id": "frontiercode", "title": "FrontierCode", - "sourceNote": "Illustrative snapshot from cognition.com/frontiercode (FrontierCode 1.1 Main, Jul 2026). Score = mergeability rubric; cost = mean USD per rollout. Best vs all reasoning modes match Cognition’s leaderboard toggle. Not live OpenCodex metering.", + "sourceNote": "Illustrative snapshot from cognition.com/frontiercode (FrontierCode 1.1 Main, Jul 2026). Score = mergeability rubric; cost = mean USD per rollout. Best vs all reasoning modes match Cognition’s leaderboard toggle. Not live CodexCommander metering.", "updated": "2026-07-16", "taskCount": 100, "axes": { @@ -1395,7 +1395,7 @@ { "id": "frontierswe", "title": "FrontierSWE", - "sourceNote": "Illustrative snapshot from frontierswe.com (Mean@5 dominance). X-axis uses blended public API $/MTok as a relative cost proxy — not measured $/task. Not live OpenCodex metering.", + "sourceNote": "Illustrative snapshot from frontierswe.com (Mean@5 dominance). X-axis uses blended public API $/MTok as a relative cost proxy — not measured $/task. Not live CodexCommander metering.", "updated": "2026-07-16", "axes": { "xKey": "avgCostUsd", @@ -1605,7 +1605,7 @@ { "id": "terminal-bench-2.1", "title": "Terminal Bench 2.1", - "sourceNote": "Illustrative mix of Snorkel-verified Terminal-Bench 2.1 rows + published GPT-5.6 figures. Costs are approximate proxies (DeepSWE overlap or API-tier estimates). Not live OpenCodex metering.", + "sourceNote": "Illustrative mix of Snorkel-verified Terminal-Bench 2.1 rows + published GPT-5.6 figures. Costs are approximate proxies (DeepSWE overlap or API-tier estimates). Not live CodexCommander metering.", "updated": "2026-07-11", "taskCount": 89, "axes": { @@ -1826,7 +1826,7 @@ { "id": "program-bench", "title": "Program Bench", - "sourceNote": "Snapshot from programbench.com extended leaderboard (mini-SWE-agent, 200 tasks). Score = almost-resolved (≥95% tests). Costs = published average API $/task. Not live OpenCodex metering.", + "sourceNote": "Snapshot from programbench.com extended leaderboard (mini-SWE-agent, 200 tasks). Score = almost-resolved (≥95% tests). Costs = published average API $/task. Not live CodexCommander metering.", "updated": "2026-06-23", "taskCount": 200, "axes": { @@ -2003,7 +2003,7 @@ { "id": "swe-marathon", "title": "SWE Marathon", - "sourceNote": "Illustrative snapshot from swe-marathon.org (pass@1 on 20 ultra-long-horizon tasks). Cost axis is an estimated relative run cost (long trajectories); not published $/task. Not live OpenCodex metering.", + "sourceNote": "Illustrative snapshot from swe-marathon.org (pass@1 on 20 ultra-long-horizon tasks). Cost axis is an estimated relative run cost (long trajectories); not published $/task. Not live CodexCommander metering.", "updated": "2026-07-09", "taskCount": 20, "axes": { @@ -2211,7 +2211,7 @@ { "id": "frontend-code-arena", "title": "Frontend Code Arena", - "sourceNote": "Illustrative snapshot from arena.ai Code Arena | WebDev (Elo from blind human votes on frontend tasks, Jul 16 2026). X-axis is blended public API $/MTok — preference Elo has no $/task. Not live OpenCodex metering.", + "sourceNote": "Illustrative snapshot from arena.ai Code Arena | WebDev (Elo from blind human votes on frontend tasks, Jul 16 2026). X-axis is blended public API $/MTok — preference Elo has no $/task. Not live CodexCommander metering.", "updated": "2026-07-16", "axes": { "xKey": "avgCostUsd", @@ -2466,7 +2466,7 @@ { "id": "cybench", "title": "Cybench", - "sourceNote": "Illustrative snapshot from cybench.github.io (unguided % solved on professional CTF tasks). Many rows are system-card / subset results, not one uniform full-suite run. Costs are relative agent-run estimates — Cybench does not publish $/task. Not live OpenCodex metering.", + "sourceNote": "Illustrative snapshot from cybench.github.io (unguided % solved on professional CTF tasks). Many rows are system-card / subset results, not one uniform full-suite run. Costs are relative agent-run estimates — Cybench does not publish $/task. Not live CodexCommander metering.", "updated": "2026-07-16", "taskCount": 40, "axes": { diff --git a/docs-site/src/data/frontier-i18n.ts b/docs-site/src/data/frontier-i18n.ts index 1e56f8e627..c3661563e8 100644 --- a/docs-site/src/data/frontier-i18n.ts +++ b/docs-site/src/data/frontier-i18n.ts @@ -2,7 +2,7 @@ // German strings from the PR are dropped: the docs-site ships en/ko/zh-CN/ru/ja. export const FRONTIER_STRINGS = { en: { - "frontier.subtitle": "Compare models on public coding-agent benchmarks: capability vs cost per task. Pick a domain, then a board; filter by model, effort, price, or use-case. Snapshot data — update with OpenCodex releases, not live metering.", + "frontier.subtitle": "Compare models on public coding-agent benchmarks: capability vs cost per task. Pick a domain, then a board; filter by model, effort, price, or use-case. Snapshot data — update with CodexCommander releases, not live metering.", "frontier.updated": "Snapshot {date}", "frontier.tasks": "{count} tasks", "frontier.domainsAria": "Task domains", @@ -69,46 +69,46 @@ export const FRONTIER_STRINGS = { "frontier.board.deepswe.title": "DeepSWE", "frontier.board.deepswe.xLabel": "Avg cost per task (USD)", "frontier.board.deepswe.yLabel": "Pass@1", - "frontier.board.deepswe.sourceNote": "Illustrative snapshot from the public DeepSWE leaderboard (mini-swe-agent). Scores and costs are not live OpenCodex metering.", + "frontier.board.deepswe.sourceNote": "Illustrative snapshot from the public DeepSWE leaderboard (mini-swe-agent). Scores and costs are not live CodexCommander metering.", "frontier.board.aa-coding-agent.title": "AA Coding Agent", "frontier.board.aa-coding-agent.xLabel": "Cost per task (USD)", "frontier.board.aa-coding-agent.yLabel": "Coding Agent Index", - "frontier.board.aa-coding-agent.sourceNote": "Artificial Analysis Coding Agent Index snapshot (post GPT-5.6 GA, 2026-07-09). See provenance.url. Not live OpenCodex metering.", + "frontier.board.aa-coding-agent.sourceNote": "Artificial Analysis Coding Agent Index snapshot (post GPT-5.6 GA, 2026-07-09). See provenance.url. Not live CodexCommander metering.", "frontier.board.aa-intelligence-index.title": "AA Intelligence Index", "frontier.board.aa-intelligence-index.xLabel": "Cost per Intelligence Index task (USD)", "frontier.board.aa-intelligence-index.yLabel": "Intelligence Index", - "frontier.board.aa-intelligence-index.sourceNote": "Illustrative snapshot inspired by Artificial Analysis Intelligence Index cost-per-task (Answer / Reasoning / Cache write / Cache hit / Input). Totals match published headline figures where noted; segment splits are approximate for charting. Not live OpenCodex metering.", + "frontier.board.aa-intelligence-index.sourceNote": "Illustrative snapshot inspired by Artificial Analysis Intelligence Index cost-per-task (Answer / Reasoning / Cache write / Cache hit / Input). Totals match published headline figures where noted; segment splits are approximate for charting. Not live CodexCommander metering.", "frontier.board.frontiercode.title": "FrontierCode", "frontier.board.frontiercode.xLabel": "Avg cost per rollout (USD)", "frontier.board.frontiercode.yLabel": "Mergeability score", - "frontier.board.frontiercode.sourceNote": "Illustrative snapshot from cognition.com/frontiercode (FrontierCode 1.1 Main, Jul 2026). Score = mergeability rubric; cost = mean USD per rollout. Best vs all reasoning modes match Cognition’s leaderboard toggle. Not live OpenCodex metering.", + "frontier.board.frontiercode.sourceNote": "Illustrative snapshot from cognition.com/frontiercode (FrontierCode 1.1 Main, Jul 2026). Score = mergeability rubric; cost = mean USD per rollout. Best vs all reasoning modes match Cognition’s leaderboard toggle. Not live CodexCommander metering.", "frontier.board.frontierswe.title": "FrontierSWE", "frontier.board.frontierswe.xLabel": "Relative API cost (blended $/MTok)", "frontier.board.frontierswe.yLabel": "Dominance", - "frontier.board.frontierswe.sourceNote": "Illustrative snapshot from frontierswe.com (Mean@5 dominance). X-axis uses blended public API $/MTok as a relative cost proxy — not measured $/task. Not live OpenCodex metering.", + "frontier.board.frontierswe.sourceNote": "Illustrative snapshot from frontierswe.com (Mean@5 dominance). X-axis uses blended public API $/MTok as a relative cost proxy — not measured $/task. Not live CodexCommander metering.", "frontier.board.terminal-bench-2.1.title": "Terminal Bench 2.1", "frontier.board.terminal-bench-2.1.xLabel": "Estimated cost (USD, illustrative)", "frontier.board.terminal-bench-2.1.yLabel": "Accuracy", - "frontier.board.terminal-bench-2.1.sourceNote": "Illustrative mix of Snorkel-verified Terminal-Bench 2.1 rows + published GPT-5.6 figures. Costs are approximate proxies (DeepSWE overlap or API-tier estimates). Not live OpenCodex metering.", + "frontier.board.terminal-bench-2.1.sourceNote": "Illustrative mix of Snorkel-verified Terminal-Bench 2.1 rows + published GPT-5.6 figures. Costs are approximate proxies (DeepSWE overlap or API-tier estimates). Not live CodexCommander metering.", "frontier.board.program-bench.title": "Program Bench", "frontier.board.program-bench.xLabel": "Avg cost per task (USD)", "frontier.board.program-bench.yLabel": "Almost resolved", - "frontier.board.program-bench.sourceNote": "Snapshot from programbench.com extended leaderboard (mini-SWE-agent, 200 tasks). Score = almost-resolved (≥95% tests). Costs = published average API $/task. Not live OpenCodex metering.", + "frontier.board.program-bench.sourceNote": "Snapshot from programbench.com extended leaderboard (mini-SWE-agent, 200 tasks). Score = almost-resolved (≥95% tests). Costs = published average API $/task. Not live CodexCommander metering.", "frontier.board.swe-marathon.title": "SWE Marathon", "frontier.board.swe-marathon.xLabel": "Est. relative run cost (USD)", "frontier.board.swe-marathon.yLabel": "Resolution rate", - "frontier.board.swe-marathon.sourceNote": "Illustrative snapshot from swe-marathon.org (pass@1 on 20 ultra-long-horizon tasks). Cost axis is an estimated relative run cost (long trajectories); not published $/task. Not live OpenCodex metering.", + "frontier.board.swe-marathon.sourceNote": "Illustrative snapshot from swe-marathon.org (pass@1 on 20 ultra-long-horizon tasks). Cost axis is an estimated relative run cost (long trajectories); not published $/task. Not live CodexCommander metering.", "frontier.board.frontend-code-arena.title": "Frontend Code Arena", "frontier.board.frontend-code-arena.xLabel": "Relative API cost (blended $/MTok)", "frontier.board.frontend-code-arena.yLabel": "Arena Elo", - "frontier.board.frontend-code-arena.sourceNote": "Illustrative snapshot from arena.ai Code Arena | WebDev (Elo from blind human votes on frontend tasks, Jul 16 2026). X-axis is blended public API $/MTok — preference Elo has no $/task. Not live OpenCodex metering.", + "frontier.board.frontend-code-arena.sourceNote": "Illustrative snapshot from arena.ai Code Arena | WebDev (Elo from blind human votes on frontend tasks, Jul 16 2026). X-axis is blended public API $/MTok — preference Elo has no $/task. Not live CodexCommander metering.", "frontier.board.cybench.title": "Cybench", "frontier.board.cybench.xLabel": "Est. relative run cost (USD)", "frontier.board.cybench.yLabel": "Unguided % solved", - "frontier.board.cybench.sourceNote": "Illustrative snapshot from cybench.github.io (unguided % solved on professional CTF tasks). Many rows are system-card / subset results, not one uniform full-suite run. Costs are relative agent-run estimates — Cybench does not publish $/task. Not live OpenCodex metering." + "frontier.board.cybench.sourceNote": "Illustrative snapshot from cybench.github.io (unguided % solved on professional CTF tasks). Many rows are system-card / subset results, not one uniform full-suite run. Costs are relative agent-run estimates — Cybench does not publish $/task. Not live CodexCommander metering." }, ko: { - "frontier.subtitle": "공개 코딩 에이전트 벤치마크에서 모델을 비교합니다: 능력 vs 작업당 비용. 도메인을 고른 뒤 보드를 선택하고 모델·노력·가격·용도로 필터하세요. 스냅샷 데이터이며 OpenCodex 릴리스 때 갱신합니다(실시간 계측 아님).", + "frontier.subtitle": "공개 코딩 에이전트 벤치마크에서 모델을 비교합니다: 능력 vs 작업당 비용. 도메인을 고른 뒤 보드를 선택하고 모델·노력·가격·용도로 필터하세요. 스냅샷 데이터이며 CodexCommander 릴리스 때 갱신합니다(실시간 계측 아님).", "frontier.updated": "스냅샷 {date}", "frontier.tasks": "작업 {count}개", "frontier.domainsAria": "작업 도메인", @@ -175,46 +175,46 @@ export const FRONTIER_STRINGS = { "frontier.board.deepswe.title": "DeepSWE", "frontier.board.deepswe.xLabel": "작업당 평균 비용 (USD)", "frontier.board.deepswe.yLabel": "Pass@1", - "frontier.board.deepswe.sourceNote": "공개 DeepSWE 리더보드(mini-swe-agent) 스냅샷입니다. 점수·비용은 OpenCodex 실시간 미터링이 아닙니다.", + "frontier.board.deepswe.sourceNote": "공개 DeepSWE 리더보드(mini-swe-agent) 스냅샷입니다. 점수·비용은 CodexCommander 실시간 미터링이 아닙니다.", "frontier.board.aa-coding-agent.title": "AA Coding Agent", "frontier.board.aa-coding-agent.xLabel": "작업당 비용 (USD)", "frontier.board.aa-coding-agent.yLabel": "Coding Agent Index", - "frontier.board.aa-coding-agent.sourceNote": "Artificial Analysis Coding Agent Index 스냅샷(GPT-5.6 GA 이후, 2026-07-09). provenance.url 참고. OpenCodex 실시간 미터링 아님.", + "frontier.board.aa-coding-agent.sourceNote": "Artificial Analysis Coding Agent Index 스냅샷(GPT-5.6 GA 이후, 2026-07-09). provenance.url 참고. CodexCommander 실시간 미터링 아님.", "frontier.board.aa-intelligence-index.title": "AA Intelligence Index", "frontier.board.aa-intelligence-index.xLabel": "Intelligence Index 작업당 비용 (USD)", "frontier.board.aa-intelligence-index.yLabel": "Intelligence Index", - "frontier.board.aa-intelligence-index.sourceNote": "Answer / Reasoning / Cache / Input 비용 분해가 포함된 Artificial Analysis Intelligence Index 스냅샷. OpenCodex 실시간 미터링 아님.", + "frontier.board.aa-intelligence-index.sourceNote": "Answer / Reasoning / Cache / Input 비용 분해가 포함된 Artificial Analysis Intelligence Index 스냅샷. CodexCommander 실시간 미터링 아님.", "frontier.board.frontiercode.title": "FrontierCode", "frontier.board.frontiercode.xLabel": "롤아웃당 평균 비용 (USD)", "frontier.board.frontiercode.yLabel": "Mergeability score", - "frontier.board.frontiercode.sourceNote": "Cognition FrontierCode 스냅샷. 인용 전 cognition.com에서 확인하세요. OpenCodex 실시간 미터링 아님.", + "frontier.board.frontiercode.sourceNote": "Cognition FrontierCode 스냅샷. 인용 전 cognition.com에서 확인하세요. CodexCommander 실시간 미터링 아님.", "frontier.board.frontierswe.title": "FrontierSWE", "frontier.board.frontierswe.xLabel": "상대 API 비용 (blended $/MTok)", "frontier.board.frontierswe.yLabel": "Dominance", - "frontier.board.frontierswe.sourceNote": "frontierswe.com 스냅샷(Mean@5 Dominance). X축은 공개 API $/MTok 상대 비용 — 측정된 $/task 아님. OpenCodex 실시간 미터링 아님.", + "frontier.board.frontierswe.sourceNote": "frontierswe.com 스냅샷(Mean@5 Dominance). X축은 공개 API $/MTok 상대 비용 — 측정된 $/task 아님. CodexCommander 실시간 미터링 아님.", "frontier.board.terminal-bench-2.1.title": "Terminal Bench 2.1", "frontier.board.terminal-bench-2.1.xLabel": "추정 비용 (USD, 예시)", "frontier.board.terminal-bench-2.1.yLabel": "정확도", - "frontier.board.terminal-bench-2.1.sourceNote": "Snorkel 검증 Terminal-Bench 2.1 행 + 공개 GPT-5.6 수치의 예시 혼합. 비용은 근사 프록시입니다. OpenCodex 실시간 미터링 아님.", + "frontier.board.terminal-bench-2.1.sourceNote": "Snorkel 검증 Terminal-Bench 2.1 행 + 공개 GPT-5.6 수치의 예시 혼합. 비용은 근사 프록시입니다. CodexCommander 실시간 미터링 아님.", "frontier.board.program-bench.title": "Program Bench", "frontier.board.program-bench.xLabel": "작업당 평균 비용 (USD)", "frontier.board.program-bench.yLabel": "Almost resolved", - "frontier.board.program-bench.sourceNote": "programbench.com 확장 리더보드 스냅샷(mini-SWE-agent, 200 과제). 점수 = almost-resolved(≥95% 테스트). 비용 = 게시된 평균 API $/task. OpenCodex 실시간 미터링 아님.", + "frontier.board.program-bench.sourceNote": "programbench.com 확장 리더보드 스냅샷(mini-SWE-agent, 200 과제). 점수 = almost-resolved(≥95% 테스트). 비용 = 게시된 평균 API $/task. CodexCommander 실시간 미터링 아님.", "frontier.board.swe-marathon.title": "SWE Marathon", "frontier.board.swe-marathon.xLabel": "추정 상대 실행 비용 (USD)", "frontier.board.swe-marathon.yLabel": "Resolution rate", - "frontier.board.swe-marathon.sourceNote": "swe-marathon.org 스냅샷(초장기 20과제 pass@1). 비용 축은 추정 상대 실행 비용이며 게시된 $/task가 아닙니다. OpenCodex 실시간 미터링 아님.", + "frontier.board.swe-marathon.sourceNote": "swe-marathon.org 스냅샷(초장기 20과제 pass@1). 비용 축은 추정 상대 실행 비용이며 게시된 $/task가 아닙니다. CodexCommander 실시간 미터링 아님.", "frontier.board.frontend-code-arena.title": "Frontend Code Arena", "frontier.board.frontend-code-arena.xLabel": "상대 API 비용 (blended $/MTok)", "frontier.board.frontend-code-arena.yLabel": "Arena Elo", - "frontier.board.frontend-code-arena.sourceNote": "Code Arena Elo 예시 스냅샷. 비용은 상대 API 블렌드이며 측정된 $/task가 아닙니다. OpenCodex 실시간 미터링 아님.", + "frontier.board.frontend-code-arena.sourceNote": "Code Arena Elo 예시 스냅샷. 비용은 상대 API 블렌드이며 측정된 $/task가 아닙니다. CodexCommander 실시간 미터링 아님.", "frontier.board.cybench.title": "Cybench", "frontier.board.cybench.xLabel": "추정 상대 실행 비용 (USD)", "frontier.board.cybench.yLabel": "Unguided % solved", - "frontier.board.cybench.sourceNote": "Cybench unguided 해결률 예시. 비용은 상대 추정입니다. 재게시 시 Cybench를 인용하세요. OpenCodex 실시간 미터링 아님." + "frontier.board.cybench.sourceNote": "Cybench unguided 해결률 예시. 비용은 상대 추정입니다. 재게시 시 Cybench를 인용하세요. CodexCommander 실시간 미터링 아님." }, "zh-cn": { - "frontier.subtitle": "在公开编程代理基准上比较模型:能力 vs 每任务成本。先选领域再选榜单,并按模型、推理力度、价格或用途筛选。为快照数据,随 OpenCodex 发版更新,非实时计量。", + "frontier.subtitle": "在公开编程代理基准上比较模型:能力 vs 每任务成本。先选领域再选榜单,并按模型、推理力度、价格或用途筛选。为快照数据,随 CodexCommander 发版更新,非实时计量。", "frontier.updated": "快照 {date}", "frontier.tasks": "{count} 项任务", "frontier.domainsAria": "任务领域", @@ -281,46 +281,46 @@ export const FRONTIER_STRINGS = { "frontier.board.deepswe.title": "DeepSWE", "frontier.board.deepswe.xLabel": "每任务平均成本 (USD)", "frontier.board.deepswe.yLabel": "Pass@1", - "frontier.board.deepswe.sourceNote": "来自公开 DeepSWE 排行榜(mini-swe-agent)的示意快照。分数与成本并非 OpenCodex 实时计量。", + "frontier.board.deepswe.sourceNote": "来自公开 DeepSWE 排行榜(mini-swe-agent)的示意快照。分数与成本并非 CodexCommander 实时计量。", "frontier.board.aa-coding-agent.title": "AA Coding Agent", "frontier.board.aa-coding-agent.xLabel": "每任务成本 (USD)", "frontier.board.aa-coding-agent.yLabel": "Coding Agent Index", - "frontier.board.aa-coding-agent.sourceNote": "Artificial Analysis Coding Agent Index 快照(GPT-5.6 GA 之后,2026-07-09)。见 provenance.url。非 OpenCodex 实时计量。", + "frontier.board.aa-coding-agent.sourceNote": "Artificial Analysis Coding Agent Index 快照(GPT-5.6 GA 之后,2026-07-09)。见 provenance.url。非 CodexCommander 实时计量。", "frontier.board.aa-intelligence-index.title": "AA Intelligence Index", "frontier.board.aa-intelligence-index.xLabel": "每 Intelligence Index 任务成本 (USD)", "frontier.board.aa-intelligence-index.yLabel": "Intelligence Index", - "frontier.board.aa-intelligence-index.sourceNote": "含 Answer / Reasoning / Cache / Input 成本拆分的 Artificial Analysis Intelligence Index 快照。非 OpenCodex 实时计量。", + "frontier.board.aa-intelligence-index.sourceNote": "含 Answer / Reasoning / Cache / Input 成本拆分的 Artificial Analysis Intelligence Index 快照。非 CodexCommander 实时计量。", "frontier.board.frontiercode.title": "FrontierCode", "frontier.board.frontiercode.xLabel": "每次 rollout 平均成本 (USD)", "frontier.board.frontiercode.yLabel": "Mergeability score", - "frontier.board.frontiercode.sourceNote": "Cognition FrontierCode 快照;引用前请在 cognition.com 核对。非 OpenCodex 实时计量。", + "frontier.board.frontiercode.sourceNote": "Cognition FrontierCode 快照;引用前请在 cognition.com 核对。非 CodexCommander 实时计量。", "frontier.board.frontierswe.title": "FrontierSWE", "frontier.board.frontierswe.xLabel": "相对 API 成本(混合 $/MTok)", "frontier.board.frontierswe.yLabel": "Dominance", - "frontier.board.frontierswe.sourceNote": "来自 frontierswe.com 的示意快照(Mean@5 Dominance)。X 轴为公开 API $/MTok 相对成本——非实测 $/task。非 OpenCodex 实时计量。", + "frontier.board.frontierswe.sourceNote": "来自 frontierswe.com 的示意快照(Mean@5 Dominance)。X 轴为公开 API $/MTok 相对成本——非实测 $/task。非 CodexCommander 实时计量。", "frontier.board.terminal-bench-2.1.title": "Terminal Bench 2.1", "frontier.board.terminal-bench-2.1.xLabel": "估计成本(USD,示意)", "frontier.board.terminal-bench-2.1.yLabel": "准确率", - "frontier.board.terminal-bench-2.1.sourceNote": "Snorkel 验证的 Terminal-Bench 2.1 行与已发布 GPT-5.6 数据的示意混合。成本为近似代理。非 OpenCodex 实时计量。", + "frontier.board.terminal-bench-2.1.sourceNote": "Snorkel 验证的 Terminal-Bench 2.1 行与已发布 GPT-5.6 数据的示意混合。成本为近似代理。非 CodexCommander 实时计量。", "frontier.board.program-bench.title": "Program Bench", "frontier.board.program-bench.xLabel": "每任务平均成本 (USD)", "frontier.board.program-bench.yLabel": "Almost resolved", - "frontier.board.program-bench.sourceNote": "来自 programbench.com 扩展排行榜的快照(mini-SWE-agent,200 题)。分数 = almost-resolved(≥95% 测试)。成本 = 已发布的平均 API $/task。非 OpenCodex 实时计量。", + "frontier.board.program-bench.sourceNote": "来自 programbench.com 扩展排行榜的快照(mini-SWE-agent,200 题)。分数 = almost-resolved(≥95% 测试)。成本 = 已发布的平均 API $/task。非 CodexCommander 实时计量。", "frontier.board.swe-marathon.title": "SWE Marathon", "frontier.board.swe-marathon.xLabel": "估计相对运行成本 (USD)", "frontier.board.swe-marathon.yLabel": "Resolution rate", - "frontier.board.swe-marathon.sourceNote": "来自 swe-marathon.org 的示意快照(20 个超长程任务的 pass@1)。成本轴为估计相对运行成本,非已发布 $/task。非 OpenCodex 实时计量。", + "frontier.board.swe-marathon.sourceNote": "来自 swe-marathon.org 的示意快照(20 个超长程任务的 pass@1)。成本轴为估计相对运行成本,非已发布 $/task。非 CodexCommander 实时计量。", "frontier.board.frontend-code-arena.title": "Frontend Code Arena", "frontier.board.frontend-code-arena.xLabel": "相对 API 成本(混合 $/MTok)", "frontier.board.frontend-code-arena.yLabel": "Arena Elo", - "frontier.board.frontend-code-arena.sourceNote": "Code Arena Elo 示意快照。成本为相对 API 混合,非实测 $/task。非 OpenCodex 实时计量。", + "frontier.board.frontend-code-arena.sourceNote": "Code Arena Elo 示意快照。成本为相对 API 混合,非实测 $/task。非 CodexCommander 实时计量。", "frontier.board.cybench.title": "Cybench", "frontier.board.cybench.xLabel": "估计相对运行成本 (USD)", "frontier.board.cybench.yLabel": "Unguided % solved", - "frontier.board.cybench.sourceNote": "Cybench unguided 解决率示意。成本为相对估计。转载请引用 Cybench。非 OpenCodex 实时计量。" + "frontier.board.cybench.sourceNote": "Cybench unguided 解决率示意。成本为相对估计。转载请引用 Cybench。非 CodexCommander 实时计量。" }, ru: { - "frontier.subtitle": "Сравнивайте модели на публичных бенчмарках кодинг-агентов: способности против стоимости задачи. Выберите область, затем доску; фильтруйте по модели, уровню рассуждений, цене или назначению. Данные — снапшот: обновляются с релизами OpenCodex, а не в реальном времени.", + "frontier.subtitle": "Сравнивайте модели на публичных бенчмарках кодинг-агентов: способности против стоимости задачи. Выберите область, затем доску; фильтруйте по модели, уровню рассуждений, цене или назначению. Данные — снапшот: обновляются с релизами CodexCommander, а не в реальном времени.", "frontier.updated": "Снапшот {date}", "frontier.tasks": "{count} задач", "frontier.domainsAria": "Области задач", @@ -387,46 +387,46 @@ export const FRONTIER_STRINGS = { "frontier.board.deepswe.title": "DeepSWE", "frontier.board.deepswe.xLabel": "Средняя стоимость задачи (USD)", "frontier.board.deepswe.yLabel": "Pass@1", - "frontier.board.deepswe.sourceNote": "Иллюстративный снапшот публичного лидерборда DeepSWE (mini-swe-agent). Баллы и стоимости — это не учёт OpenCodex в реальном времени.", + "frontier.board.deepswe.sourceNote": "Иллюстративный снапшот публичного лидерборда DeepSWE (mini-swe-agent). Баллы и стоимости — это не учёт CodexCommander в реальном времени.", "frontier.board.aa-coding-agent.title": "AA Coding Agent", "frontier.board.aa-coding-agent.xLabel": "Стоимость задачи (USD)", "frontier.board.aa-coding-agent.yLabel": "Coding Agent Index", - "frontier.board.aa-coding-agent.sourceNote": "Снапшот Artificial Analysis Coding Agent Index (после GA GPT-5.6, 2026-07-09). См. provenance.url. Это не учёт OpenCodex в реальном времени.", + "frontier.board.aa-coding-agent.sourceNote": "Снапшот Artificial Analysis Coding Agent Index (после GA GPT-5.6, 2026-07-09). См. provenance.url. Это не учёт CodexCommander в реальном времени.", "frontier.board.aa-intelligence-index.title": "AA Intelligence Index", "frontier.board.aa-intelligence-index.xLabel": "Стоимость задачи Intelligence Index (USD)", "frontier.board.aa-intelligence-index.yLabel": "Intelligence Index", - "frontier.board.aa-intelligence-index.sourceNote": "Иллюстративный снапшот по мотивам стоимости задачи Artificial Analysis Intelligence Index (Answer / Reasoning / Cache write / Cache hit / Input). Итоги совпадают с опубликованными заголовочными цифрами там, где это отмечено; разбивка на сегменты приблизительная — для наглядности графика. Это не учёт OpenCodex в реальном времени.", + "frontier.board.aa-intelligence-index.sourceNote": "Иллюстративный снапшот по мотивам стоимости задачи Artificial Analysis Intelligence Index (Answer / Reasoning / Cache write / Cache hit / Input). Итоги совпадают с опубликованными заголовочными цифрами там, где это отмечено; разбивка на сегменты приблизительная — для наглядности графика. Это не учёт CodexCommander в реальном времени.", "frontier.board.frontiercode.title": "FrontierCode", "frontier.board.frontiercode.xLabel": "Средняя стоимость роллаута (USD)", "frontier.board.frontiercode.yLabel": "Mergeability score", - "frontier.board.frontiercode.sourceNote": "Иллюстративный снапшот с cognition.com/frontiercode (FrontierCode 1.1 Main, июль 2026). Балл = рубрика mergeability; стоимость = средняя сумма в USD за роллаут. Режимы Best / All соответствуют переключателю на лидерборде Cognition. Это не учёт OpenCodex в реальном времени.", + "frontier.board.frontiercode.sourceNote": "Иллюстративный снапшот с cognition.com/frontiercode (FrontierCode 1.1 Main, июль 2026). Балл = рубрика mergeability; стоимость = средняя сумма в USD за роллаут. Режимы Best / All соответствуют переключателю на лидерборде Cognition. Это не учёт CodexCommander в реальном времени.", "frontier.board.frontierswe.title": "FrontierSWE", "frontier.board.frontierswe.xLabel": "Относительная стоимость API (смешанный $/MTok)", "frontier.board.frontierswe.yLabel": "Dominance", - "frontier.board.frontierswe.sourceNote": "Иллюстративный снапшот с frontierswe.com (доминирование Mean@5). Ось X использует смешанный публичный API-тариф $/MTok как относительный показатель стоимости — это не измеренные $/task. Это не учёт OpenCodex в реальном времени.", + "frontier.board.frontierswe.sourceNote": "Иллюстративный снапшот с frontierswe.com (доминирование Mean@5). Ось X использует смешанный публичный API-тариф $/MTok как относительный показатель стоимости — это не измеренные $/task. Это не учёт CodexCommander в реальном времени.", "frontier.board.terminal-bench-2.1.title": "Terminal Bench 2.1", "frontier.board.terminal-bench-2.1.xLabel": "Оценочная стоимость (USD, иллюстративно)", "frontier.board.terminal-bench-2.1.yLabel": "Точность", - "frontier.board.terminal-bench-2.1.sourceNote": "Иллюстративная смесь строк Terminal-Bench 2.1, проверенных Snorkel, и опубликованных показателей GPT-5.6. Стоимости — приблизительные прокси-значения (пересечение с DeepSWE или оценки по тарифам API). Это не учёт OpenCodex в реальном времени.", + "frontier.board.terminal-bench-2.1.sourceNote": "Иллюстративная смесь строк Terminal-Bench 2.1, проверенных Snorkel, и опубликованных показателей GPT-5.6. Стоимости — приблизительные прокси-значения (пересечение с DeepSWE или оценки по тарифам API). Это не учёт CodexCommander в реальном времени.", "frontier.board.program-bench.title": "Program Bench", "frontier.board.program-bench.xLabel": "Средняя стоимость задачи (USD)", "frontier.board.program-bench.yLabel": "Almost resolved", - "frontier.board.program-bench.sourceNote": "Снапшот расширенного лидерборда programbench.com (mini-SWE-agent, 200 задач). Балл = almost-resolved (≥95% тестов). Стоимости = опубликованные средние API $/task. Это не учёт OpenCodex в реальном времени.", + "frontier.board.program-bench.sourceNote": "Снапшот расширенного лидерборда programbench.com (mini-SWE-agent, 200 задач). Балл = almost-resolved (≥95% тестов). Стоимости = опубликованные средние API $/task. Это не учёт CodexCommander в реальном времени.", "frontier.board.swe-marathon.title": "SWE Marathon", "frontier.board.swe-marathon.xLabel": "Прибл. относительная стоимость прогона (USD)", "frontier.board.swe-marathon.yLabel": "Доля решённых", - "frontier.board.swe-marathon.sourceNote": "Иллюстративный снапшот с swe-marathon.org (pass@1 на 20 задачах со сверхдлинным горизонтом). Ось стоимости — оценочная относительная стоимость прогона (длинные траектории); это не опубликованные $/task. Это не учёт OpenCodex в реальном времени.", + "frontier.board.swe-marathon.sourceNote": "Иллюстративный снапшот с swe-marathon.org (pass@1 на 20 задачах со сверхдлинным горизонтом). Ось стоимости — оценочная относительная стоимость прогона (длинные траектории); это не опубликованные $/task. Это не учёт CodexCommander в реальном времени.", "frontier.board.frontend-code-arena.title": "Frontend Code Arena", "frontier.board.frontend-code-arena.xLabel": "Относительная стоимость API (смешанный $/MTok)", "frontier.board.frontend-code-arena.yLabel": "Arena Elo", - "frontier.board.frontend-code-arena.sourceNote": "Иллюстративный снапшот arena.ai Code Arena | WebDev (Elo по слепым голосам людей на фронтенд-задачах, 16 июля 2026). Ось X — смешанный публичный API-тариф $/MTok: у Elo предпочтений нет $/task. Это не учёт OpenCodex в реальном времени.", + "frontier.board.frontend-code-arena.sourceNote": "Иллюстративный снапшот arena.ai Code Arena | WebDev (Elo по слепым голосам людей на фронтенд-задачах, 16 июля 2026). Ось X — смешанный публичный API-тариф $/MTok: у Elo предпочтений нет $/task. Это не учёт CodexCommander в реальном времени.", "frontier.board.cybench.title": "Cybench", "frontier.board.cybench.xLabel": "Прибл. относительная стоимость прогона (USD)", "frontier.board.cybench.yLabel": "% решённых (unguided)", - "frontier.board.cybench.sourceNote": "Иллюстративный снапшот с cybench.github.io (% профессиональных CTF-задач, решённых без подсказок, unguided). Многие строки — результаты из system card или на подмножествах, а не один единый прогон полного набора. Стоимости — относительные оценки агентных прогонов: Cybench не публикует $/task. Это не учёт OpenCodex в реальном времени.", + "frontier.board.cybench.sourceNote": "Иллюстративный снапшот с cybench.github.io (% профессиональных CTF-задач, решённых без подсказок, unguided). Многие строки — результаты из system card или на подмножествах, а не один единый прогон полного набора. Стоимости — относительные оценки агентных прогонов: Cybench не публикует $/task. Это не учёт CodexCommander в реальном времени.", }, ja: { - "frontier.subtitle": "公開のコーディングエージェントベンチマークでモデルを比較します: 能力 vs タスクあたりコスト。ドメインを選び、次にボードを選択し、モデル・推論負荷・価格・用途でフィルタします。スナップショットデータで OpenCodex リリース時に更新されます(ライブ計測ではありません)。", + "frontier.subtitle": "公開のコーディングエージェントベンチマークでモデルを比較します: 能力 vs タスクあたりコスト。ドメインを選び、次にボードを選択し、モデル・推論負荷・価格・用途でフィルタします。スナップショットデータで CodexCommander リリース時に更新されます(ライブ計測ではありません)。", "frontier.updated": "スナップショット {date}", "frontier.tasks": "{count} タスク", "frontier.domainsAria": "タスクドメイン", @@ -493,43 +493,43 @@ export const FRONTIER_STRINGS = { "frontier.board.deepswe.title": "DeepSWE", "frontier.board.deepswe.xLabel": "タスクあたり平均コスト (USD)", "frontier.board.deepswe.yLabel": "Pass@1", - "frontier.board.deepswe.sourceNote": "公開 DeepSWE リーダーボード(mini-swe-agent)の参考スナップショット。スコアとコストは OpenCodex のライブ計測ではありません。", + "frontier.board.deepswe.sourceNote": "公開 DeepSWE リーダーボード(mini-swe-agent)の参考スナップショット。スコアとコストは CodexCommander のライブ計測ではありません。", "frontier.board.aa-coding-agent.title": "AA Coding Agent", "frontier.board.aa-coding-agent.xLabel": "タスクあたりコスト (USD)", "frontier.board.aa-coding-agent.yLabel": "Coding Agent Index", - "frontier.board.aa-coding-agent.sourceNote": "Artificial Analysis Coding Agent Index のスナップショット(GPT-5.6 GA 後、2026-07-09)。provenance.url を参照。OpenCodex のライブ計測ではありません。", + "frontier.board.aa-coding-agent.sourceNote": "Artificial Analysis Coding Agent Index のスナップショット(GPT-5.6 GA 後、2026-07-09)。provenance.url を参照。CodexCommander のライブ計測ではありません。", "frontier.board.aa-intelligence-index.title": "AA Intelligence Index", "frontier.board.aa-intelligence-index.xLabel": "Intelligence Index タスクあたりコスト (USD)", "frontier.board.aa-intelligence-index.yLabel": "Intelligence Index", - "frontier.board.aa-intelligence-index.sourceNote": "Artificial Analysis Intelligence Index のタスクあたりコスト(Answer / Reasoning / Cache write / Cache hit / Input)を参考にしたスナップショット。合計は注記がある箇所で公開の見出し数値と一致します; セグット分割はグラフ用のおおよその値です。OpenCodex のライブ計測ではありません。", + "frontier.board.aa-intelligence-index.sourceNote": "Artificial Analysis Intelligence Index のタスクあたりコスト(Answer / Reasoning / Cache write / Cache hit / Input)を参考にしたスナップショット。合計は注記がある箇所で公開の見出し数値と一致します; セグット分割はグラフ用のおおよその値です。CodexCommander のライブ計測ではありません。", "frontier.board.frontiercode.title": "FrontierCode", "frontier.board.frontiercode.xLabel": "rollout あたり平均コスト (USD)", "frontier.board.frontiercode.yLabel": "Mergeability score", - "frontier.board.frontiercode.sourceNote": "cognition.com/frontiercode の参考スナップショット(FrontierCode 1.1 Main、2026年7月)。スコア = mergeability ルーブリック; コスト = rollout あたり平均 USD。Best と all 推論モードは Cognition のリーダーボード切替に一致します。OpenCodex のライブ計測ではありません。", + "frontier.board.frontiercode.sourceNote": "cognition.com/frontiercode の参考スナップショット(FrontierCode 1.1 Main、2026年7月)。スコア = mergeability ルーブリック; コスト = rollout あたり平均 USD。Best と all 推論モードは Cognition のリーダーボード切替に一致します。CodexCommander のライブ計測ではありません。", "frontier.board.frontierswe.title": "FrontierSWE", "frontier.board.frontierswe.xLabel": "相対 API コスト(混合 $/MTok)", "frontier.board.frontierswe.yLabel": "Dominance", - "frontier.board.frontierswe.sourceNote": "frontierswe.com の参考スナップショット(Mean@5 Dominance)。X 軸は公開 API $/MTok を相対コスト指標として使用 — 実測 $/task ではありません。OpenCodex のライブ計測ではありません。", + "frontier.board.frontierswe.sourceNote": "frontierswe.com の参考スナップショット(Mean@5 Dominance)。X 軸は公開 API $/MTok を相対コスト指標として使用 — 実測 $/task ではありません。CodexCommander のライブ計測ではありません。", "frontier.board.terminal-bench-2.1.title": "Terminal Bench 2.1", "frontier.board.terminal-bench-2.1.xLabel": "推定コスト(USD、参考)", "frontier.board.terminal-bench-2.1.yLabel": "精度", - "frontier.board.terminal-bench-2.1.sourceNote": "Snorkel 検証済みの Terminal-Bench 2.1 行と公開 GPT-5.6 数値の参考混合。コストは近似プロキシ(DeepSWE との重複または API ティア推定)。OpenCodex のライブ計測ではありません。", + "frontier.board.terminal-bench-2.1.sourceNote": "Snorkel 検証済みの Terminal-Bench 2.1 行と公開 GPT-5.6 数値の参考混合。コストは近似プロキシ(DeepSWE との重複または API ティア推定)。CodexCommander のライブ計測ではありません。", "frontier.board.program-bench.title": "Program Bench", "frontier.board.program-bench.xLabel": "タスクあたり平均コスト (USD)", "frontier.board.program-bench.yLabel": "Almost resolved", - "frontier.board.program-bench.sourceNote": "programbench.com 拡張リーダーボードのスナップショット(mini-SWE-agent、200 タスク)。スコア = almost-resolved(≥95% テスト)。コスト = 公開の平均 API $/task。OpenCodex のライブ計測ではありません。", + "frontier.board.program-bench.sourceNote": "programbench.com 拡張リーダーボードのスナップショット(mini-SWE-agent、200 タスク)。スコア = almost-resolved(≥95% テスト)。コスト = 公開の平均 API $/task。CodexCommander のライブ計測ではありません。", "frontier.board.swe-marathon.title": "SWE Marathon", "frontier.board.swe-marathon.xLabel": "推定相対実行コスト (USD)", "frontier.board.swe-marathon.yLabel": "解決率", - "frontier.board.swe-marathon.sourceNote": "swe-marathon.org の参考スナップショット(20 の超長期タスクの pass@1)。コスト軸は推定相対実行コスト(長いトラジェクトリ)であり、公開 $/task ではありません。OpenCodex のライブ計測ではありません。", + "frontier.board.swe-marathon.sourceNote": "swe-marathon.org の参考スナップショット(20 の超長期タスクの pass@1)。コスト軸は推定相対実行コスト(長いトラジェクトリ)であり、公開 $/task ではありません。CodexCommander のライブ計測ではありません。", "frontier.board.frontend-code-arena.title": "Frontend Code Arena", "frontier.board.frontend-code-arena.xLabel": "相対 API コスト(混合 $/MTok)", "frontier.board.frontend-code-arena.yLabel": "Arena Elo", - "frontier.board.frontend-code-arena.sourceNote": "arena.ai Code Arena | WebDev の参考スナップショット(フロントエンドタスクでのブラインド人間投票による Elo、2026年7月16日)。X 軸は公開 API $/MTok の混合 — 選好 Elo に $/task はありません。OpenCodex のライブ計測ではありません。", + "frontier.board.frontend-code-arena.sourceNote": "arena.ai Code Arena | WebDev の参考スナップショット(フロントエンドタスクでのブラインド人間投票による Elo、2026年7月16日)。X 軸は公開 API $/MTok の混合 — 選好 Elo に $/task はありません。CodexCommander のライブ計測ではありません。", "frontier.board.cybench.title": "Cybench", "frontier.board.cybench.xLabel": "推定相対実行コスト (USD)", "frontier.board.cybench.yLabel": "Unguided % solved", - "frontier.board.cybench.sourceNote": "cybench.github.io の参考スナップショット(プロフェッショナル CTF タスクの unguided 解決率)。多くの行は system card の結果またはサブセットの結果であり、一つの統一フルスイート実行ではありません。コストはエージェント実行の相対推定です — Cybench は $/task を公開していません。OpenCodex のライブ計測ではありません。", + "frontier.board.cybench.sourceNote": "cybench.github.io の参考スナップショット(プロフェッショナル CTF タスクの unguided 解決率)。多くの行は system card の結果またはサブセットの結果であり、一つの統一フルスイート実行ではありません。コストはエージェント実行の相対推定です — Cybench は $/task を公開していません。CodexCommander のライブ計測ではありません。", }, } as const; diff --git a/docs-site/src/styles/custom.css b/docs-site/src/styles/custom.css index ddd7b5e4a4..19a37b33e6 100644 --- a/docs-site/src/styles/custom.css +++ b/docs-site/src/styles/custom.css @@ -1,6 +1,6 @@ /* ============================================================================ - opencodex docs — liquid-glass skin over Starlight - Same grammar as the ocx dashboard (gui/src/styles.css): white/near-black + codexcommander docs — liquid-glass skin over Starlight + Same grammar as the ccx dashboard (gui/src/styles.css): white/near-black monochrome, hairline borders, pill controls, glass ONLY on the chrome layers (header, sidebar rail, dropdowns, search modal). Content stays solid. One ambient tri-radial wash per viewport, refracted by the glass. @@ -33,17 +33,17 @@ --sl-color-backdrop-overlay: rgba(23, 23, 23, 0.55); /* glass material (chrome layers only) */ - --ocx-glass-rail: rgba(23, 23, 23, 0.55); - --ocx-glass-panel: rgba(38, 38, 38, 0.96); - --ocx-glass-blur: saturate(1.5) blur(40px); - --ocx-surface: #262626; - --ocx-raised: #303030; - --ocx-hover: rgba(255, 255, 255, 0.05); - --ocx-shadow: 0 1px 2px rgba(0, 0, 0, 0.5), 0 10px 28px rgba(0, 0, 0, 0.3); - - --ocx-radius: 12px; - --ocx-radius-sm: 8px; - --ocx-radius-pill: 999px; + --ccx-glass-rail: rgba(23, 23, 23, 0.55); + --ccx-glass-panel: rgba(38, 38, 38, 0.96); + --ccx-glass-blur: saturate(1.5) blur(40px); + --ccx-surface: #262626; + --ccx-raised: #303030; + --ccx-hover: rgba(255, 255, 255, 0.05); + --ccx-shadow: 0 1px 2px rgba(0, 0, 0, 0.5), 0 10px 28px rgba(0, 0, 0, 0.3); + + --ccx-radius: 12px; + --ccx-radius-sm: 8px; + --ccx-radius-pill: 999px; --sl-font: "Geist Variable", "Pretendard Variable", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, "Helvetica Neue", @@ -77,12 +77,12 @@ --sl-color-hairline: #f0f0f0; --sl-color-backdrop-overlay: rgba(249, 249, 249, 0.5); - --ocx-glass-rail: rgba(249, 249, 249, 0.55); - --ocx-glass-panel: rgba(255, 255, 255, 0.96); - --ocx-surface: #ffffff; - --ocx-raised: #f4f4f4; - --ocx-hover: rgba(13, 13, 13, 0.04); - --ocx-shadow: 0 1px 2px rgba(16, 24, 40, 0.06), 0 10px 28px rgba(16, 24, 40, 0.07); + --ccx-glass-rail: rgba(249, 249, 249, 0.55); + --ccx-glass-panel: rgba(255, 255, 255, 0.96); + --ccx-surface: #ffffff; + --ccx-raised: #f4f4f4; + --ccx-hover: rgba(13, 13, 13, 0.04); + --ccx-shadow: 0 1px 2px rgba(16, 24, 40, 0.06), 0 10px 28px rgba(16, 24, 40, 0.07); } /* ---- ambient wash (one per viewport; glass chrome refracts it) ---------- */ @@ -129,9 +129,9 @@ header.header > .header { /* ---- glass chrome: sidebar rail ----------------------------------------- */ #starlight__sidebar { - background-color: var(--ocx-glass-rail); - backdrop-filter: var(--ocx-glass-blur); - -webkit-backdrop-filter: var(--ocx-glass-blur); + background-color: var(--ccx-glass-rail); + backdrop-filter: var(--ccx-glass-blur); + -webkit-backdrop-filter: var(--ccx-glass-blur); border-inline-end: 1px solid var(--sl-color-hairline-light); } @@ -139,11 +139,11 @@ header.header > .header { .sidebar-content .top-level a, .sidebar-content summary, .sidebar-content a { - border-radius: var(--ocx-radius-sm); + border-radius: var(--ccx-radius-sm); } .sidebar-content a:hover, .sidebar-content a:focus-visible { - background-color: var(--ocx-hover); + background-color: var(--ccx-hover); color: var(--sl-color-white); } .sidebar-content a[aria-current='page'] { @@ -159,7 +159,7 @@ header.header > .header { /* ---- search: pill trigger + glass modal ---------------------------------- */ button[data-open-modal] { - border-radius: var(--ocx-radius-pill); + border-radius: var(--ccx-radius-pill); background-color: color-mix(in oklab, var(--sl-color-black) 55%, transparent); border: 1px solid var(--sl-color-gray-5); backdrop-filter: blur(12px) saturate(1.3); @@ -171,11 +171,11 @@ button[data-open-modal]:hover { } dialog[aria-label] { border: 1px solid var(--sl-color-gray-5); - border-radius: var(--ocx-radius); - background-color: var(--ocx-glass-panel); - backdrop-filter: var(--ocx-glass-blur); - -webkit-backdrop-filter: var(--ocx-glass-blur); - box-shadow: var(--ocx-shadow); + border-radius: var(--ccx-radius); + background-color: var(--ccx-glass-panel); + backdrop-filter: var(--ccx-glass-blur); + -webkit-backdrop-filter: var(--ccx-glass-blur); + box-shadow: var(--ccx-shadow); } dialog::backdrop { background-color: var(--sl-color-backdrop-overlay); @@ -198,27 +198,27 @@ article.card { /* kill Starlight's rotating orange/purple/green tints: monochrome surface */ --sl-card-border: var(--sl-color-gray-5) !important; --sl-card-bg: transparent !important; - background-color: var(--ocx-surface); + background-color: var(--ccx-surface); border: 1px solid var(--sl-color-gray-5); - border-radius: var(--ocx-radius); + border-radius: var(--ccx-radius); box-shadow: none; } article.card .title { color: var(--sl-color-white); } .sl-link-card { - background-color: var(--ocx-surface); + background-color: var(--ccx-surface); border: 1px solid var(--sl-color-gray-5); - border-radius: var(--ocx-radius); + border-radius: var(--ccx-radius); box-shadow: none; } .sl-link-card:hover { - background-color: var(--ocx-surface); + background-color: var(--ccx-surface); border-color: var(--sl-color-gray-4); } /* asides/callouts: quiet monochrome-tinted, keep semantic hue only on the bar */ .starlight-aside { - border-radius: var(--ocx-radius-sm); + border-radius: var(--ccx-radius-sm); border-inline-start-width: 2px; } @@ -227,7 +227,7 @@ code:not(:where(.expressive-code *)) { border-radius: 6px; } .expressive-code .frame { - --ec-brdRad: var(--ocx-radius); + --ec-brdRad: var(--ccx-radius); } /* tables: hairline, rounded wrap */ @@ -396,7 +396,7 @@ main:has(.lp) .content-panel:first-child { padding-block: 0; } align-items: center; gap: 0.5rem; padding: 0.7rem 1.4rem; - border-radius: var(--ocx-radius-pill); + border-radius: var(--ccx-radius-pill); background-color: #0d0d0d; color: #ffffff; font-weight: 500; @@ -408,7 +408,7 @@ main:has(.lp) .content-panel:first-child { padding-block: 0; } display: inline-flex; align-items: center; padding: 0.7rem 1.4rem; - border-radius: var(--ocx-radius-pill); + border-radius: var(--ccx-radius-pill); border: 0; background-color: #ffffff; color: #0d0d0d; @@ -459,7 +459,7 @@ main:has(.lp) .content-panel:first-child { padding-block: 0; } } .lp-chips li { padding: 0.35rem 0.9rem; - border-radius: var(--ocx-radius-pill); + border-radius: var(--ccx-radius-pill); border: 0; background-color: rgba(255, 255, 255, 0.95); color: #1a1a1a; @@ -489,7 +489,7 @@ main:has(.lp) .content-panel:first-child { padding-block: 0; } display: block; width: 100%; height: auto; - border-radius: var(--ocx-radius) var(--ocx-radius) 0 0; + border-radius: var(--ccx-radius) var(--ccx-radius) 0 0; border: 1px solid rgba(0, 0, 0, 0.18); border-bottom: 0; box-shadow: 0 -8px 40px rgba(0, 0, 0, 0.14); @@ -505,7 +505,7 @@ main:has(.lp) .content-panel:first-child { padding-block: 0; } /* opaque sheet surfaces so stacking reads as window transitions */ .lp-quick, .lp-rail { - background-color: var(--ocx-surface); + background-color: var(--ccx-surface); border: 1px solid var(--sl-color-hairline-light); border-radius: 24px; overflow: hidden; @@ -565,10 +565,10 @@ main:has(.lp) .content-panel:first-child { padding-block: 0; } .lp-inline-link:hover { text-decoration: underline; text-underline-offset: 3px; } .lp-terminal { border: 1px solid var(--sl-color-gray-5); - border-radius: var(--ocx-radius); + border-radius: var(--ccx-radius); background-color: light-dark(#1a1a1a, #171717); overflow: hidden; - box-shadow: var(--ocx-shadow); + box-shadow: var(--ccx-shadow); } :root[data-theme='light'] .lp-terminal { background-color: #1a1a1a; } .lp-terminal-bar { @@ -617,7 +617,7 @@ main:has(.lp) .content-panel:first-child { padding-block: 0; } max-width: min(58rem, 100%); width: 100%; height: auto; - border-radius: var(--ocx-radius); + border-radius: var(--ccx-radius); border: 1px solid var(--sl-color-hairline-light); } .lp-scrub-poster { @@ -625,7 +625,7 @@ main:has(.lp) .content-panel:first-child { padding-block: 0; } max-width: min(58rem, 100%); width: 100%; height: auto; - border-radius: var(--ocx-radius); + border-radius: var(--ccx-radius); border: 1px solid var(--sl-color-hairline-light); } .lp-scrub-caption { @@ -661,8 +661,8 @@ main:has(.lp) .content-panel:first-child { padding-block: 0; } gap: 0.5rem; padding: 1.25rem 1.375rem; border: 1px solid var(--sl-color-gray-5); - border-radius: var(--ocx-radius); - background-color: var(--ocx-surface); + border-radius: var(--ccx-radius); + background-color: var(--ccx-surface); min-width: 0; overflow: hidden; } @@ -686,7 +686,7 @@ main:has(.lp) .content-panel:first-child { padding-block: 0; } margin-top: auto; width: 100%; height: auto; - border-radius: var(--ocx-radius-sm); + border-radius: var(--ccx-radius-sm); border: 1px solid var(--sl-color-hairline-light); max-height: 15rem; object-fit: cover; @@ -751,8 +751,8 @@ main:has(.lp) .content-panel:first-child { padding-block: 0; } gap: 1.5rem; padding: 1.5rem 1.75rem; border: 1px solid var(--sl-color-gray-5); - border-radius: var(--ocx-radius); - background-color: var(--ocx-surface); + border-radius: var(--ccx-radius); + background-color: var(--ccx-surface); } @media (max-width: 64rem) { .lp-next-grid { grid-template-columns: repeat(2, 1fr); } } @media (max-width: 40rem) { .lp-next-grid { grid-template-columns: 1fr; } } @@ -790,7 +790,7 @@ footer.sl-flex .meta { color: var(--sl-color-gray-4); } /* ---- motion (all gated) ---------------------------------------------------- */ @media (prefers-reduced-motion: no-preference) { /* landing entrance choreography (the one signature moment) */ - @keyframes ocx-fade-up { + @keyframes ccx-fade-up { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: translateY(0); } } @@ -799,13 +799,13 @@ footer.sl-flex .meta { color: var(--sl-color-gray-4); } .lp-cta, .lp-chips, .lp-stage-in img { - animation: ocx-fade-up 0.7s cubic-bezier(0.16, 1, 0.3, 1) both; + animation: ccx-fade-up 0.7s cubic-bezier(0.16, 1, 0.3, 1) both; } .lp-sub { animation-delay: 0.07s; } .lp-cta { animation-delay: 0.14s; } .lp-chips { animation-delay: 0.21s; } /* per-chip stagger on top of the group entrance */ - .lp-chips li { animation: ocx-fade-up 0.5s cubic-bezier(0.16, 1, 0.3, 1) both; } + .lp-chips li { animation: ccx-fade-up 0.5s cubic-bezier(0.16, 1, 0.3, 1) both; } .lp-chips li:nth-child(1) { animation-delay: 0.22s; } .lp-chips li:nth-child(2) { animation-delay: 0.26s; } .lp-chips li:nth-child(3) { animation-delay: 0.3s; } @@ -828,7 +828,7 @@ footer.sl-flex .meta { color: var(--sl-color-gray-4); } .sl-link-card:hover, article.card:hover { transform: translateY(-2px); - box-shadow: var(--ocx-shadow); + box-shadow: var(--ccx-shadow); } .lp-btn-primary, .lp-btn-ghost { transition: transform 0.15s, opacity 0.15s, border-color 0.15s; } .lp-btn-primary:hover, .lp-btn-ghost:hover { transform: translateY(-1px); } @@ -839,7 +839,7 @@ footer.sl-flex .meta { color: var(--sl-color-gray-4); } .lp-next h2, .lp-next-grid, .lp-disclaimer { - animation: ocx-fade-up linear both; + animation: ccx-fade-up linear both; animation-timeline: view(); animation-range: entry 0% entry 45%; } @@ -861,7 +861,7 @@ footer.sl-flex .meta { color: var(--sl-color-gray-4); } overflow: hidden; transform-origin: 50% 15%; box-shadow: 0 -12px 48px rgba(0, 0, 0, 0.12); - animation: ocx-scene-sink linear both; + animation: ccx-scene-sink linear both; animation-timeline: --scene; animation-range: exit 5% exit 100%; } @@ -871,23 +871,23 @@ footer.sl-flex .meta { color: var(--sl-color-gray-4); } /* kinetic type wipes in line by line while the sheet settles */ .lp-kline { clip-path: inset(0 100% 0 0); - animation: ocx-text-wipe linear both; + animation: ccx-text-wipe linear both; animation-timeline: --scene; } .lp-kline:nth-child(1) { animation-range: cover 22% cover 38%; } .lp-kline:nth-child(2) { animation-range: cover 30% cover 46%; } .lp-kline:nth-child(3) { animation-range: cover 38% cover 54%; } - @keyframes ocx-text-wipe { to { clip-path: inset(0 0 0 0); } } - @keyframes ocx-scene-sink { + @keyframes ccx-text-wipe { to { clip-path: inset(0 0 0 0); } } + @keyframes ccx-scene-sink { to { opacity: 0.12; transform: scale(0.94) translateY(-1.5%); } } /* the field photo pushes in while the hero scene sinks */ .lp-field-bg img { - animation: ocx-field-push linear both; + animation: ccx-field-push linear both; animation-timeline: --scene; animation-range: exit 0% exit 100%; } - @keyframes ocx-field-push { to { transform: scale(1.08); } } + @keyframes ccx-field-push { to { transform: scale(1.08); } } /* scrub canvas fills the stage height without overflowing the sheet */ .lp-scene-inner.lp-scrub .lp-scrub-canvas, .lp-scene-inner.lp-scrub .lp-scrub-poster { diff --git a/docs/README.md b/docs/README.md index 6a72059024..d5c3c540bf 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,8 +1,9 @@ -# Historical Notes +# Engineering Notes -This folder contains investigations and diagnostic notes. It is not the primary user manual and it -is not the maintainer source of truth for current invariants. +This folder contains maintained architecture decisions, design-system references, and focused +implementation notes. It is not the primary user manual or the maintainer source of truth for +cross-system invariants. - Public user workflows live in [`../docs-site/`](../docs-site). - Current maintainer invariants live in [`../structure/`](../structure). -- Keep files here when the detail is useful for archaeology, debugging, or source research. +- Keep files here only while their implementation detail remains current and useful. diff --git a/docs/adr/0001-gui-update-worker.md b/docs/adr/0001-gui-update-worker.md deleted file mode 100644 index 056db8e8a8..0000000000 --- a/docs/adr/0001-gui-update-worker.md +++ /dev/null @@ -1,51 +0,0 @@ -# ADR 0001: GUI self-update runs through a worker job - -## Status - -Accepted - -## Context - -The dashboard needs buttons for `ocx sync` and opencodex self-update. `ocx sync` is safe to run in -the proxy process because it refreshes Codex config/catalog state. `ocx update` is different: npm -installs may replace the package files currently serving the GUI, and the existing CLI update path -can print to inherited stdio and exit the process. - -## Decision - -GUI self-update is not executed directly in the request handler. The dashboard calls management -API endpoints that create an update job in `OPENCODEX_HOME/update-job.json`. The proxy starts a -detached hidden CLI worker, and the worker performs the install command and optional restart. - -For npm installs, the worker runs the Node launcher path (`node bin/ocx.mjs update --tag <tag>`) so -the existing npm self-update guard is reused. For Bun global installs, it runs the existing Bun -global update command. Source checkouts remain manual-only and show `git pull && bun install && -bun run build:gui`. - -After an update requests a restart, the worker now waits for an identity-checked `/healthz` to -return and remain healthy for a short stability window before marking the job successful. This -keeps `update-job.json` honest on Windows cases where npm leaves the bundled Bun runtime in a bad -state and the restarted proxy dies a few seconds later. - -For npm installs specifically, `node ocx.mjs update` already stops the proxy and reinstalls / -starts the managed service (or falls back to a direct start). When a background service was -installed, the worker therefore confirms that self-update restart first — but only skips the -redundant second `service install` when /healthz shows update-correlated evidence (a new PID -vs the pre-update capture, and/or the job's target version). A bare healthy identity is not -enough: a surviving pre-update process would otherwise look like success. Direct (non-service) -npm installs skip the probe-first path entirely, because the launcher only prints `ocx start` -and never brings the proxy back on its own — waiting would always burn the full health timeout -before the worker's explicit restart. A second install would call `stopWindows()` on the healthy -listener and often fail elevation from the non-interactive worker, leaving the captured port -(default 10100) dead until a manual restart. Bun global installs still always take the explicit -restart path because `bun add -g` does not restart the proxy. - -## Consequences - -- The GUI request handler stays responsive and does not overwrite its own running module graph. -- Update status survives a proxy restart because it is stored in the opencodex config directory. -- Restart handling can branch between service-managed installs and direct detached proxy starts. -- A completed install can still finish with `status: "failed"` when the replacement proxy never - becomes healthy or flaps during the stability window; the job log then points the user at - `ocx start` and the Bun `--allow-scripts` reinstall path. -- The dashboard must poll both the job endpoint and `/healthz` while reconnecting. diff --git a/docs/adr/0002-doctor-proxy-env-diagnostics.md b/docs/adr/0002-doctor-proxy-env-diagnostics.md index b76b3bd370..8c3fbec20a 100644 --- a/docs/adr/0002-doctor-proxy-env-diagnostics.md +++ b/docs/adr/0002-doctor-proxy-env-diagnostics.md @@ -6,22 +6,22 @@ Accepted ## Context -`ocx doctor` used to show only the proxy variables visible to the `ocx doctor` +`ccx doctor` used to show only the proxy variables visible to the `ccx doctor` process. That is accurate for the current shell, but misleading when a user -started `ocx start` or a service from a different environment and then ran -`ocx doctor` in a new terminal. +started `ccx start` or a service from a different environment and then ran +`ccx doctor` in a new terminal. Environment variables are inherited by child processes, not shared globally between existing shells. A new terminal can therefore show `HTTP_PROXY` as unset -while the already-running opencodex proxy process still has it set. +while the already-running CodexCommander proxy process still has it set. ## Decision -`ocx doctor` reports three separate proxy surfaces: +`ccx doctor` reports three separate proxy surfaces: - the current doctor process environment - the effective `config.proxy` state, with the value hidden -- the running opencodex proxy process environment when a recorded PID is +- the running CodexCommander proxy process environment when a recorded PID is available and Linux `/proc/<pid>/environ` can be read The process environment diagnostic reports only presence/absence of known proxy diff --git a/docs/adr/0003-deepseek-v4-thinking-history.md b/docs/adr/0003-deepseek-v4-thinking-history.md index dc22c2d410..ad8853df77 100644 --- a/docs/adr/0003-deepseek-v4-thinking-history.md +++ b/docs/adr/0003-deepseek-v4-thinking-history.md @@ -11,7 +11,7 @@ field to be passed back in later multi-turn and tool-call requests. If the gateway drops that history, DeepSeek can reject the next request with a 400 that says the `reasoning_content` from thinking mode must be passed back. -opencodex already has a provider flag for OpenAI-compatible chat models that +CodexCommander has a provider flag for OpenAI-compatible chat models that require reasoning history replay: `preserveReasoningContentModels`. ## Decision @@ -22,7 +22,7 @@ DeepSeek V4 thinking models are marked in the provider registry with: - `xhigh` to upstream `max` reasoning effort mapping - `preserveReasoningContentModels` -This is not enabled for every OpenAI-compatible provider or for the legacy +This is not enabled for every OpenAI-compatible provider or for the `deepseek-reasoner` preset. ## Consequences diff --git a/docs/adr/0005-gui-design-token-system.md b/docs/adr/0005-gui-design-token-system.md index 93a43365a0..38a2cc1693 100644 --- a/docs/adr/0005-gui-design-token-system.md +++ b/docs/adr/0005-gui-design-token-system.md @@ -29,7 +29,7 @@ Keep component styling in the existing CSS and React primitives instead of addin Tailwind, a component framework, or a remote font. Document the contract under `docs/design-system/` and require new visual values to use tokens. -For local integrated visual QA, use Vite's opt-in `OPENCODEX_PROXY_TARGET` proxy so the development +For local integrated visual QA, use Vite's opt-in `CODEXCOMMANDER_PROXY_TARGET` proxy so the development GUI can call the running management API through the same origin without changing production output. ## Alternatives considered diff --git a/docs/adr/0006-provider-output-defaults-and-web-search-replay.md b/docs/adr/0006-provider-output-defaults-and-web-search-replay.md index 2cdd5642f9..b273a4dfec 100644 --- a/docs/adr/0006-provider-output-defaults-and-web-search-replay.md +++ b/docs/adr/0006-provider-output-defaults-and-web-search-replay.md @@ -11,7 +11,7 @@ providers then inherit their own default `max_tokens`, which can be much smaller than the model supports. This is especially visible on reasoning-heavy coding models where the default budget covers both thinking and visible output. -Routed providers also receive expanded Responses history. Historical +Routed providers also receive expanded Responses history. Replayed `web_search_call` output items are internal evidence that a prior hosted search cell was rendered, but they do not contain a paired result payload that a routed adapter can replay safely. @@ -20,11 +20,11 @@ adapter can replay safely. [Decision Log] - 목적과 의도: Allow operators to set honest provider/model output-token fallbacks without changing explicit caller requests, and prevent internal web-search replay markers from becoming model-visible text. -- 기존 구현 및 제약 조건: `openai-chat` only sent `max_tokens` from request `max_output_tokens`; provider config already had input/context metadata but no output fallback. Historical `web_search_call` replay was converted to `[web search performed: ...]` assistant text, which could be echoed when no sidecar plan was available. +- 기존 구현 및 제약 조건: `openai-chat` only sent `max_tokens` from request `max_output_tokens`; provider config already had input/context metadata but no output fallback. Replayed `web_search_call` items could become `[web search performed: ...]` assistant text and be echoed when no sidecar plan was available. - 검토한 주요 대안: Force a global `max_tokens`; add provider-only defaults; add provider plus model-specific defaults; filter the marker from final output; convert replayed hosted search cells into synthetic tool calls. - 선택한 방식: Resolve `max_tokens` in the `openai-chat` adapter with precedence explicit request, model-specific provider config, provider default, then omit. Validate both config fields as positive integers and thread them through registry/derive/router plumbing. Drop replayed hosted search cells from assistant-visible history instead of post-filtering output. - 다른 대안 대신 이 방식을 선택한 이유: Adapter-time resolution preserves passthrough behavior and keeps the field closest to the OpenAI Chat wire. Model-specific defaults cover providers with mixed ceilings. Hiding replay cells at parse time removes the leak source without claiming a current search ran or altering the active sidecar loop. -- 장점, 단점 및 영향: Long routed turns can opt into larger budgets while existing configs remain byte-for-byte compatible when unset. Historical search cells no longer create echoable sentinel text; the tradeoff is that routed models do not receive a separate text hint that a prior search cell existed when no actual search result payload is available. +- 장점, 단점 및 영향: Long routed turns can opt into larger budgets while existing configs remain byte-for-byte compatible when unset. Replayed search cells no longer create echoable sentinel text; the tradeoff is that routed models do not receive a separate text hint that a prior search cell existed when no actual search result payload is available. ## Consequences diff --git a/docs/adr/0007-headless-cli-parity.md b/docs/adr/0007-headless-cli-parity.md index 9562142aee..9d17a2199a 100644 --- a/docs/adr/0007-headless-cli-parity.md +++ b/docs/adr/0007-headless-cli-parity.md @@ -8,10 +8,9 @@ Accepted The dashboard exposes provider editing and tests, live model visibility, combo routing, subagent policy, request/usage observability, API admission keys, Claude Code settings, -Grok selection, and startup settings. Historically the CLI covered lifecycle operations -and a smaller provider/account/model subset. Headless servers therefore required either -the dashboard or direct `config.json` edits, and direct edits bypassed live validation, -catalog refreshes, and runtime side effects. +Grok selection, and startup settings. The CLI exposes the same non-visual management +capabilities so headless servers do not require dashboard access or direct `config.json` +edits that bypass live validation, catalog refreshes, and runtime side effects. ## Decision @@ -19,24 +18,24 @@ catalog refreshes, and runtime side effects. - 목적과 의도: Make every non-visual dashboard management capability usable from a discoverable headless CLI. - 기존 구현 및 제약 조건: The dashboard already used validated `/api/*` management routes; CLI commands mixed direct config writes and one-off HTTP clients. Runtime ports can move, and management auth must follow the same identity and token rules as the dashboard. - 검토한 주요 대안: Duplicate all route validation in CLI modules; expose a generic raw HTTP command; use a shared management client and resource-oriented commands. -- 선택한 방식: Add a shared identity-checked runtime API client and resource-oriented commands (`provider`, `account`, `models`, `combo`, `agent`, `observe`, `access`, `grok`, `system`, `config`). Existing commands and aliases remain compatible. +- 선택한 방식: Use a shared identity-checked runtime API client and resource-oriented commands (`provider`, `account`, `models`, `combo`, `agent`, `observe`, `access`, `grok`, `system`, `config`). - 다른 대안 대신 이 방식을 선택한 이유: Reusing management routes keeps GUI and CLI validation, persistence, cache refresh, and live side effects aligned. Resource commands remain easier to discover than arbitrary endpoint invocation. -- 장점, 단점 및 영향: Headless parity improves and future operations share consistent errors. Live management commands require a running proxy; offline config inspection/import remains available through a separately validated `ocx config` path. +- 장점, 단점 및 영향: Headless parity improves and future operations share consistent errors. Live management commands require a running proxy; offline config inspection/import remains available through a separately validated `ccx config` path. ## Command structure ```text -ocx setup interactive first-run flow (`init` remains an alias) -ocx provider ... provider config, test, quota, selected models -ocx account ... Codex/OAuth/key-pool login and lifecycle -ocx models ... live/custom models, visibility, context, shadow calls -ocx route combo ... failover and round-robin virtual models -ocx agent ... subagents, fallback, injection, effort, sidecars -ocx observe ... logs, usage, storage, memory, debug captures -ocx access ... external API keys, endpoints, model tests -ocx integration ... Claude and Grok client integrations -ocx system ... settings, startup, diagnostics, sync, update jobs -ocx config ... masked inspection and validated offline import/edit +ccx setup interactive first-run flow (`init` remains an alias) +ccx provider ... provider config, test, quota, selected models +ccx account ... Codex/OAuth/key-pool login and lifecycle +ccx models ... live/custom models, visibility, context, shadow calls +ccx route combo ... failover and round-robin virtual models +ccx agent ... subagents, fallback, injection, effort, sidecars +ccx observe ... logs, usage, storage, memory, debug captures +ccx access ... external API keys, endpoints, model tests +ccx integration ... Claude and Grok client integrations +ccx system ... settings, startup, diagnostics, sync +ccx config ... masked inspection and validated offline import/edit ``` Convenience aliases (`model`, `combo`, `logs`, `usage`, `storage`, `memory`, @@ -50,7 +49,7 @@ uses `--json`; streaming request logs use `--jsonl`. - Cloudflare Tunnel is intentionally outside this ADR and this implementation. - Secrets are masked in config/account/provider reads. API admission-key creation is the deliberate exception: the newly generated key is returned once so it can be stored. -- Live mutations go through the running management API. `ocx config import/set` validates +- Live mutations go through the running management API. `ccx config import/set` validates the complete candidate before an atomic write and never hot-reloads a stopped process. ## Consequences @@ -59,4 +58,3 @@ uses `--json`; streaming request logs use `--jsonl`. visual-only exemption in the same change. - Management route validation remains authoritative; CLI parsers provide early UX errors but must not become a second domain schema. -- Existing automation keeps working because old command names and semantics are preserved. diff --git a/docs/codex-app-model-catalog.md b/docs/codex-app-model-catalog.md deleted file mode 100644 index a6cd01da27..0000000000 --- a/docs/codex-app-model-catalog.md +++ /dev/null @@ -1,188 +0,0 @@ -# Codex App Model Catalog Integration - -Date: 2026-06-20 - -> **Archive note.** This is a dated design-rationale record, not current behavior -> documentation. For up-to-date behavior see the published docs at -> [opencodex.me](https://opencodex.me/) and the -> maintainer source-of-truth under [`structure/`](../structure). The current injected -> provider table name is `"OpenCodex Proxy"` (see `src/codex/inject.ts`). - -This document records why opencodex routed models can appear in Codex App's model picker without -patching Codex App itself. - -## Summary - -Codex CLI, TUI, and App share the Codex home configuration surface. opencodex integrates by writing -Codex-native config and catalog files under the resolved `CODEX_HOME`: - -- `$CODEX_HOME/config.toml` -- `$CODEX_HOME/opencodex.config.toml` -- `$CODEX_HOME/opencodex-catalog.json` -- `$CODEX_HOME/models_cache.json` - -When Codex App reads the same config/catalog state, routed opencodex models are visible because they -look like valid Codex catalog entries. - -## Required config shape - -The global provider must be a root TOML key: - -```toml -model_provider = "opencodex" -``` - -It must not be appended under whichever TOML table happened to be last. TOML root keys after a table -header become part of that table, which makes Codex ignore the provider as a global setting. - -The custom model catalog path must also be a root TOML key: - -```toml -model_catalog_json = "/absolute/path/to/opencodex-catalog.json" -``` - -The provider block must advertise a Responses-compatible provider: - -```toml -[model_providers.opencodex] -name = "OpenCodex Proxy" -base_url = "http://localhost:10100/v1" -wire_api = "responses" -requires_openai_auth = true -``` - -`requires_openai_auth = true` is important for Codex App/TUI account-gated behavior. Codex derives -ChatGPT-account capability from the active provider; without this flag, fast-related UI can stay -hidden even when the user has ChatGPT auth. - -## Catalog entry shape - -opencodex does not generate minimal JSON entries. It clones a native Codex model catalog entry and -then changes the routed fields: - -```text -slug = "<provider>/<model>" -display_name = "<provider>/<model>" -description = "Routed via opencodex -> <provider> ..." -priority = <picker priority> -visibility = "list" -``` - -Slash-containing native ids: some providers namespace their own model ids -(zenmux `moonshotai/kimi-k3-free`, openrouter `anthropic/...`, nvidia `moonshotai/...`). -Codex's models-manager metadata lookup tolerates exactly one "/", so opencodex aliases -inner slashes to "-" in the Codex-facing slug (`zenmux/moonshotai-kimi-k3-free`) and -decodes back to the native id in the proxy via an exact known-id lookup -(`src/providers/slug-codec.ts`). Raw full-slash selectors keep working; upstream -requests, logs, usage, and metadata always carry the native id. - -Cloning a native entry preserves fields Codex's strict parser expects, including: - -- `base_instructions` -- `supported_reasoning_levels` -- `default_reasoning_level` -- `shell_type` -- `supported_in_api` - -This is why routed entries can behave like normal picker-visible Codex models. - -### Reasoning effort ladder - -The recognized Codex effort ladder is `low < medium < high < xhigh < max < ultra` -(`src/reasoning-effort.ts` `CODEX_REASONING_LEVELS`), matching the upstream codex-rs -`ReasoningEffort` enum order. Semantics ported from upstream (df1199fdd, 80f54d126): - -- `ultra` is a client-facing selection: maximum reasoning plus proactive multi-agent delegation - (derived in codex-rs core, not by the proxy). Upstream converts it to `max` at the inference - boundary; ocx mirrors that in two places — the Responses parser normalizes `ultra -> max` at - ingest, and `mapReasoningEffort` converts any direct `ultra` caller to the `max` wire value. -- Routed models default to the `low..max` ladder. `ultra` is per-model opt-in via the - `reasoningEfforts` provider config; when opted in it renders its canonical description. -- Native `gpt-5.6-*` slugs are emitted from the pinned upstream models.json snapshot - (`src/codex/data/upstream-models.json`, openai/codex PR #31684): exact per-slug ladders - (`sol`/`terra` end at `ultra`, `luna` ends at `max` — no ultra), default efforts - (`sol` = `low`, `terra`/`luna` = `medium`), real display names/descriptions/NUX, and - `multi_agent_version` (`sol`/`terra` v2, `luna` v1). ocx adaptations: `minimal_client_version` - is stripped (it would hide the model from older installed clients) and - `prefer_websockets`/`supports_websockets` follow the central websocket gate. A future - `gpt-5.6-*` slug the snapshot predates falls back to template synthesis plus - `ensureGpt56ReasoningLevels` (appends `max`+`ultra`). -- Snapshot scope is deliberately gpt-5.6-only: the bundled upstream entries for - `gpt-5.5`/`gpt-5.4` are staler than the installed catalog's live entries (e.g. snapshot - gpt-5.5 carries `tool_mode: null`), so substituting them would downgrade real data. On-disk - sync also self-heals fallback-quality 5.6 entries (display_name stamped with the bare slug) - by upgrading them to the snapshot entry; genuine entries from a newer installed codex are - preserved untouched. -- Snapshot refresh: replace `src/codex/data/upstream-models.json` with the latest - `codex-rs/models-manager/models.json` from openai/codex (e.g. the periodic - "Update models.json" bot PR) and re-run the catalog test suite. - -## Fast tier handling - -Codex uses a split between config spelling and runtime/catalog spelling: - -| Surface | Value | -|---|---| -| `config.toml` persistence | `service_tier = "fast"` | -| catalog/request tier id | `priority` | -| feature gate | `[features].fast_mode = true` | -| provider/account gate | `requires_openai_auth = true` | - -Native OpenAI passthrough models can keep fast metadata. Routed non-OpenAI models must not inherit -that metadata from the native template: - -```text -delete additional_speed_tiers -delete service_tier -delete service_tiers -delete default_service_tier -``` - -This prevents fast from appearing for providers where Codex/OpenAI priority processing is not a valid -request option. - -## Cache invalidation - -Codex caches models in: - -```text -$CODEX_HOME/models_cache.json -``` - -After changing providers, hidden models, featured models, or service-tier metadata, opencodex should -delete that cache so the next Codex process or model refresh sees the updated catalog. - -## Native GPT enable/disable - -`disabledModels` is the single enable/disable choke point for BOTH model families: - -- Routed ids stay namespaced (`provider/model`) and are excluded from the catalog and - `/v1/models` entirely. -- Bare ids (no `/`) are native GPT passthrough slugs. Their catalog entries are NOT removed — - the on-disk sync and the `/v1/models?client_version` shape flip them to `visibility: "hide"` - (codex-rs keeps hidden entries out of the picker itself), so the template/backup/restore - paths survive and re-enabling restores the exact entry. Only the bare OpenAI list shape of - `/v1/models` omits disabled natives. -- The dashboard Models page lists natives from the static supported set - (`nativeModelRows`), independent of catalog visibility, so a disabled model stays visible - in the GUI for re-enabling. The visibility flip runs as the LAST sync pass - (`applyNativeVisibility`) so the gpt-5.6 snapshot-upgrade branch can never clobber it. - -## Verification - -Useful probes: - -```bash -codex doctor --json -codex debug models -ocx sync -ocx status -``` - -Expected high-level result: - -- active model provider is `opencodex` -- provider uses ChatGPT auth reachability semantics -- native `gpt-*` entries keep fast support -- routed `<provider>/<model>` entries are `visibility = "list"` -- routed entries have no fast/service-tier metadata diff --git a/docs/codex-path-investigation.md b/docs/codex-path-investigation.md deleted file mode 100644 index 6b3396c355..0000000000 --- a/docs/codex-path-investigation.md +++ /dev/null @@ -1,479 +0,0 @@ -# Codex Path Investigation - -Date: 2026-06-19 - -> **Archive note.** This is a dated investigation record, not current behavior -> documentation. Some details (e.g. the referenced Codex version) reflect the state -> at the time of writing. For current behavior see -> [opencodex.me](https://opencodex.me/) and the -> maintainer source-of-truth under [`structure/`](../structure). - -This note records the web/source investigation behind opencodex's Codex path -handling. The short version is that modern Codex resolves almost all durable -local state through `CODEX_HOME`, not a platform-specific opencodex guess. If -`CODEX_HOME` is unset, Codex falls back to `~/.codex`. - -## Primary conclusion - -opencodex should treat Codex's home directory exactly as Codex does: - -1. If `CODEX_HOME` is set and non-empty, it must already exist and be a - directory. -2. That directory is canonicalized. -3. If `CODEX_HOME` is not set, the default is `<user home>/.codex`. -4. All opencodex-managed Codex files should be written under that resolved root: - - `$CODEX_HOME/config.toml` - - `$CODEX_HOME/opencodex.config.toml` - - `$CODEX_HOME/opencodex-catalog.json` - - `$CODEX_HOME/models_cache.json` - -The old opencodex behavior assumed `homedir()/.codex` everywhere. That happened -to work on many macOS setups because Codex and opencodex both landed on the same -default. It breaks when Codex is launched with a different `CODEX_HOME`, when -the Desktop/App host injects one, or when a service manager starts opencodex -without the same shell environment. - -## Web findings - -### `CODEX_HOME` - -OpenAI's Codex environment variable reference says `CODEX_HOME` is used by the -CLI, IDE extension, app-server, and installers. It defaults to `~/.codex` and is -the root for config, auth, logs, sessions, skills, and standalone package -metadata. It also states that if the variable is set, the directory must already -exist. - -Source: -https://developers.openai.com/codex/environment-variables - -The open-source Codex implementation confirms the same behavior in -`codex-rs/utils/home-dir/src/lib.rs`: it reads `CODEX_HOME`, rejects missing or -non-directory paths, canonicalizes a valid directory, and otherwise appends -`.codex` to the user's home directory. - -Source: -https://github.com/openai/codex/blob/main/codex-rs/utils/home-dir/src/lib.rs - -Node/Bun's `os.homedir()` is not a Codex-compatible replacement for -`CODEX_HOME`. The Node docs say POSIX uses `$HOME` first, while Windows uses -`USERPROFILE` first. That explains why `homedir()/.codex` usually matched on -macOS/Linux terminals but was still the wrong abstraction for Codex. - -Source: -https://nodejs.org/api/os.html#oshomedir - -### User config and profiles - -Codex user configuration lives under the Codex home. The current docs commonly -show the default path as `~/.codex/config.toml`, but the same docs also state -that Codex local state is under `CODEX_HOME`. - -Sources: -https://developers.openai.com/codex/config-advanced -https://developers.openai.com/codex/config-reference - -The profile model changed in modern Codex. OpenAI's advanced configuration docs -say that `--profile profile-name` loads the base config and then overlays -`~/.codex/profile-name.config.toml`; profile files should use top-level config -keys and must not be nested under `[profiles.profile-name]`. - -The same page states that in Codex `0.134.0` and later, `--profile` no longer -reads `[profiles.profile-name]` from `config.toml`, and the top-level -`profile = "profile-name"` selector is no longer supported. - -Source: -https://developers.openai.com/codex/config-advanced - -For opencodex this means: - -```toml -# $CODEX_HOME/opencodex.config.toml -model_provider = "opencodex" -model_catalog_json = "/absolute/path/to/opencodex-catalog.json" -``` - -Do not write this as: - -```toml -[profiles.opencodex] -model_provider = "opencodex" -``` - -### `model_catalog_json` - -The Codex configuration reference lists `model_catalog_json` as a string path to -a JSON model catalog loaded on startup. It also says a selected -`$CODEX_HOME/profile-name.config.toml` profile file can override it per profile. - -Source: -https://developers.openai.com/codex/config-reference - -The open-source config types show the same key at both levels: - -- root `ConfigToml.model_catalog_json` -- profile `ConfigProfile.model_catalog_json` - -Sources: -https://github.com/openai/codex/blob/main/codex-rs/config/src/config_toml.rs -https://github.com/openai/codex/blob/main/codex-rs/config/src/profile_toml.rs - -The source comments say this catalog is applied on startup only. Practically, -opencodex must write or update the catalog before the target Codex process -starts or must ask the user/process to restart. Editing the catalog while Codex -is already running is not enough for all surfaces. - -### `models_cache.json` - -The Codex models manager source defines `MODEL_CACHE_FILE` as -`models_cache.json` and constructs the cache path as -`codex_home.join(MODEL_CACHE_FILE)`. It also defines the default model cache TTL -as 300 seconds. - -Source: -https://github.com/openai/codex/blob/main/codex-rs/models-manager/src/manager.rs - -For opencodex this means invalidation must target: - -```text -$CODEX_HOME/models_cache.json -``` - -not: - -```text -~/.codex/models_cache.json -``` - -GitHub issues in the official Codex repository also repeatedly mention -`models_cache.json` as the local model list/cache file, including Windows paths -such as `C:\Users\<user>\.codex\models_cache.json`. Issues are not the primary -source of truth, but they confirm the same practical behavior users observe. - -Examples: -https://github.com/openai/codex/issues/12542 -https://github.com/openai/codex/issues/23119 - -### Project `.codex/config.toml` - -Codex can also read project-scoped `.codex/config.toml` files inside a repo, but -only when the project is trusted. OpenAI's docs say project config cannot -override machine-local provider/auth/profile/telemetry keys such as -`model_provider`, `model_providers`, `profile`, and `profiles`. - -Source: -https://developers.openai.com/codex/config-advanced - -Therefore opencodex provider injection must remain user-level/profile-level. It -should not rely on a project-local `.codex/config.toml` to install -`model_provider` or `[model_providers.opencodex]`. - -### Global instructions under Codex home - -OpenAI's `AGENTS.md` guide says the global instruction scope is also under the -Codex home directory: Codex reads `AGENTS.override.md` or `AGENTS.md` there, -unless `CODEX_HOME` points elsewhere. - -Source: -https://developers.openai.com/codex/guides/agents-md - -This is another confirmation that `CODEX_HOME` is the root concept, not a -hardcoded `~/.codex` path. - -## Platform-specific path notes - -### macOS - -Default path when `CODEX_HOME` is unset: - -```text -/Users/<user>/.codex -``` - -Why the old code often worked on macOS: - -- Terminal-launched Codex usually had no `CODEX_HOME`. -- opencodex used `os.homedir()/.codex`. -- Codex also fell back to `~/.codex`. - -So both processes touched the same files by coincidence. The implementation was -still wrong because it ignored the official override. - -For launchd services, the plist must explicitly carry the same environment if -opencodex was installed under a custom `CODEX_HOME`. The `launchd.plist` man -page defines `ProgramArguments` and `EnvironmentVariables`; the latter sets -additional environment variables before running the job. - -Source: -https://www.manpagez.com/man/5/launchd.plist/ - -opencodex service plist should include: - -```xml -<key>EnvironmentVariables</key> -<dict> - <key>OCX_SERVICE</key><string>1</string> - <key>PATH</key><string>...</string> - <key>CODEX_HOME</key><string>/Users/me/.codex-custom</string> -</dict> -``` - -when `CODEX_HOME` was set during service installation. - -### Linux - -Default path when `CODEX_HOME` is unset: - -```text -/home/<user>/.codex -``` - -The direct `ocx start` path works if the shell environment matches the shell -that later launches Codex. The service path is different: `systemd --user` -starts opencodex from a unit file, not necessarily from the same interactive -shell environment. - -The systemd docs define `Environment=` for variables passed to executed -processes, and `StandardOutput=`/`StandardError=` support destinations such as -`append:path`. - -Sources: -https://www.man7.org/linux/man-pages/man5/systemd.exec.5.html -https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/ - -opencodex systemd units should pin the resolved install-time variables: - -```ini -[Service] -Environment="OCX_SERVICE=1" -Environment="PATH=/usr/local/bin:/usr/bin:/bin" -Environment="CODEX_HOME=/home/me/.codex-custom" -StandardOutput="append:/home/me/.opencodex/service.log" -StandardError="append:/home/me/.opencodex/service.log" -``` - -If `CODEX_HOME` is omitted from the unit, opencodex can inject one Codex home -while Codex reads another. That recreates the "model list only shows native -models" bug on Linux service installs. - -### Windows - -Default path when `CODEX_HOME` is unset: - -```text -C:\Users\<user>\.codex -``` - -This follows from Codex's `~/.codex` fallback plus Windows home-directory -resolution. Node's `os.homedir()` uses `USERPROFILE` first on Windows, but again -opencodex must prefer `CODEX_HOME` before touching `homedir()`. - -OpenAI's Windows Codex docs also refer to diagnostics under `CODEX_HOME`, for -example: - -```text -CODEX_HOME/.sandbox/sandbox.log -CODEX_HOME/.sandbox-secrets/ -``` - -Source: -https://developers.openai.com/codex/windows - -For Windows services, opencodex currently uses Task Scheduler. Microsoft's -`schtasks /create` documentation says `/tr` is the program or command to run -and `/sc onlogon` schedules a task whenever a user logs on. This means the -registered task should run the opencodex command with paths fully quoted. - -Source: -https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/schtasks-create - -Because Task Scheduler does not automatically encode opencodex-specific -environment overrides into the command the way a shell session does, opencodex -service install writes a small `.cmd` wrapper under `~/.opencodex/`. That wrapper -sets `OCX_SERVICE=1`, preserves `PATH`, preserves `CODEX_HOME` when present, and -then starts opencodex. - -## Required opencodex behavior - -### Resolve paths once, from Codex rules - -Use a shared helper equivalent to: - -```text -resolveCodexHome(): - if CODEX_HOME is non-empty: - require it to exist - require it to be a directory - return canonical path - else: - return homedir()/.codex -``` - -Then derive: - -```text -CODEX_CONFIG_PATH = $CODEX_HOME/config.toml -CODEX_PROFILE_PATH = $CODEX_HOME/opencodex.config.toml -DEFAULT_CATALOG_PATH = $CODEX_HOME/opencodex-catalog.json -CODEX_MODELS_CACHE_PATH = $CODEX_HOME/models_cache.json -``` - -### Inject root config - -Root `$CODEX_HOME/config.toml` should contain: - -```toml -model_provider = "opencodex" -model_catalog_json = "/absolute/path/to/opencodex-catalog.json" - -[model_providers.opencodex] -name = "OpenCodex Proxy" -base_url = "http://127.0.0.1:10100/v1" -wire_api = "responses" -requires_openai_auth = true -``` - -`model_provider` and `model_providers` must live in user-level config, not -project-local config. - -### Inject profile config - -`$CODEX_HOME/opencodex.config.toml` should use top-level keys: - -```toml -model_provider = "opencodex" -model_catalog_json = "/absolute/path/to/opencodex-catalog.json" -``` - -This is the supported shape for: - -```shell -codex --profile opencodex -``` - -### Remove legacy profile tables - -Remove old blocks from `$CODEX_HOME/config.toml`: - -```toml -[profiles.opencodex] -``` - -and avoid writing: - -```toml -profile = "opencodex" -``` - -for modern Codex. - -### Keep catalog startup behavior in mind - -`model_catalog_json` is startup-loaded. After catalog changes, opencodex should: - -- invalidate `$CODEX_HOME/models_cache.json` when appropriate; -- ensure the catalog exists before Codex starts; -- advise restart or trigger a fresh Codex process when a running UI does not - pick up the new catalog. - -### Service managers must preserve relevant environment - -If a user runs `CODEX_HOME=/some/path ocx service install`, the service -definition should preserve that value: - -- Linux: add `Environment="CODEX_HOME=/some/path"` to the systemd user unit. -- macOS: add `CODEX_HOME` under launchd `EnvironmentVariables`. -- Windows: run Task Scheduler through an explicit `.cmd` wrapper that sets - `OCX_SERVICE=1` and preserves `CODEX_HOME` when present. - -## Why macOS appeared fine - -The old code was not macOS-correct in principle; it was default-path-compatible. -On a typical macOS terminal: - -```text -Codex default -> /Users/<user>/.codex -opencodex old -> /Users/<user>/.codex -``` - -So model catalog/profile files landed where Codex read them. Windows exposed the -bug because the active Codex process and opencodex could disagree on the Codex -home, and because modern Codex requires the new profile file plus startup model -catalog path. - -## Regression checklist - -Run these cases before release: - -1. Windows default home: - - unset `CODEX_HOME` - - run `ocx sync` - - verify `$USERPROFILE\.codex\opencodex.config.toml` - - verify `$USERPROFILE\.codex\opencodex-catalog.json` - - verify `codex debug models` includes routed models - -2. Windows custom home: - - create a temp directory - - set `CODEX_HOME` to it - - run `ocx sync` - - verify no writes go to `$USERPROFILE\.codex` except unrelated existing - files - -3. macOS default home: - - unset `CODEX_HOME` - - run `ocx sync` - - verify `~/.codex/opencodex.config.toml` - -4. macOS custom home: - - set `CODEX_HOME` to an existing directory - - run `ocx service install` - - inspect `~/Library/LaunchAgents/com.opencodex.proxy.plist` - - verify `CODEX_HOME` appears in `EnvironmentVariables` - -5. Linux default home: - - unset `CODEX_HOME` - - run `ocx sync` - - verify `~/.codex/opencodex.config.toml` - -6. Linux custom home with service: - - set `CODEX_HOME` to an existing directory - - run `ocx service install` - - inspect `~/.config/systemd/user/opencodex-proxy.service` - - verify `Environment="CODEX_HOME=..."` - -7. Catalog refresh: - - add/remove routed models - - verify `$CODEX_HOME/models_cache.json` is invalidated - - restart Codex and confirm model picker/debug list includes routed models - -## Source index - -- OpenAI Codex environment variables: - https://developers.openai.com/codex/environment-variables -- OpenAI Codex advanced configuration: - https://developers.openai.com/codex/config-advanced -- OpenAI Codex configuration reference: - https://developers.openai.com/codex/config-reference -- OpenAI Codex CLI reference: - https://developers.openai.com/codex/cli/reference -- OpenAI Codex Windows docs: - https://developers.openai.com/codex/windows -- OpenAI Codex AGENTS.md guide: - https://developers.openai.com/codex/guides/agents-md -- Codex `CODEX_HOME` source: - https://github.com/openai/codex/blob/main/codex-rs/utils/home-dir/src/lib.rs -- Codex models manager/cache source: - https://github.com/openai/codex/blob/main/codex-rs/models-manager/src/manager.rs -- Codex root config TOML type: - https://github.com/openai/codex/blob/main/codex-rs/config/src/config_toml.rs -- Codex profile TOML type: - https://github.com/openai/codex/blob/main/codex-rs/config/src/profile_toml.rs -- Node/Bun home-directory semantics: - https://nodejs.org/api/os.html#oshomedir -- systemd execution environment: - https://www.man7.org/linux/man-pages/man5/systemd.exec.5.html -- systemd environment directive summary: - https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/ -- launchd plist keys: - https://www.manpagez.com/man/5/launchd.plist/ -- Microsoft Task Scheduler `schtasks /create`: - https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/schtasks-create diff --git a/docs/design-system/README.md b/docs/design-system/README.md index 78e02359aa..fc9a6b90df 100644 --- a/docs/design-system/README.md +++ b/docs/design-system/README.md @@ -1,6 +1,6 @@ -# OpenCodex GUI Design System +# CodexCommander GUI Design System -OpenCodex 관리 GUI의 시각 언어와 구현 규칙을 정의한다. 목표는 화면마다 새 스타일을 +CodexCommander 관리 GUI의 시각 언어와 구현 규칙을 정의한다. 목표는 화면마다 새 스타일을 만드는 것이 아니라, 같은 역할의 요소가 어떤 페이지에서도 같은 글꼴, 크기, 간격, 표면, 상태 표현을 사용하게 하는 것이다. diff --git a/docs/design-system/contributing.md b/docs/design-system/contributing.md index 8a60de8c1e..e95003f1d6 100644 --- a/docs/design-system/contributing.md +++ b/docs/design-system/contributing.md @@ -58,5 +58,5 @@ cd gui && bun run lint && bun run build ```bash cd gui -OPENCODEX_PROXY_TARGET=http://127.0.0.1:10101 bun run dev --host 127.0.0.1 +CODEXCOMMANDER_PROXY_TARGET=http://127.0.0.1:10101 bun run dev --host 127.0.0.1 ``` diff --git a/docs/github-copilot-app.md b/docs/github-copilot-app.md index 876f12454d..1563e46f96 100644 --- a/docs/github-copilot-app.md +++ b/docs/github-copilot-app.md @@ -1,19 +1,19 @@ # GitHub Copilot App -OpenCodex can act as an **OpenAI-compatible model provider** for the GitHub Copilot +CodexCommander can act as an **OpenAI-compatible model provider** for the GitHub Copilot desktop app (Settings → Model providers). This is a client integration: Copilot App -calls OpenCodex; it is separate from the experimental upstream `github-copilot` +calls CodexCommander; it is separate from the experimental upstream `github-copilot` provider that uses a Copilot subscription as a backend. ## Requirements -1. OpenCodex proxy running locally (`ocx start` / `ocx gui`). +1. CodexCommander proxy running locally (`ccx start` / `ccx gui`). 2. At least one configured provider with models (dashboard → Providers). 3. GitHub Copilot desktop app with **Model providers** support. ## Setup -1. Start OpenCodex and confirm health: +1. Start CodexCommander and confirm health: ```bash curl http://127.0.0.1:10100/healthz @@ -26,9 +26,9 @@ provider that uses a Copilot subscription as a backend. | Field | Value | | --- | --- | - | Name | `OpenCodex Gateway` (any label) | + | Name | `CodexCommander Gateway` (any label) | | Base URL | `http://127.0.0.1:10100/v1` | - | API key | leave blank on loopback; for non-loopback binds use `OPENCODEX_API_AUTH_TOKEN` | + | API key | leave blank on loopback; for non-loopback binds use `CODEXCOMMANDER_API_AUTH_TOKEN` | 4. Sync models from the endpoint, or add a model by id (`provider/model`, e.g. `anthropic/claude-sonnet-4-6`). @@ -42,7 +42,7 @@ provider that uses a Copilot subscription as a backend. | `GET` | `/v1/models` | Model discovery (OpenAI list shape) | | `POST` | `/v1/chat/completions` | Chat turns (stream + non-stream) | -OpenCodex translates Chat Completions into its internal Responses path, so all +CodexCommander translates Chat Completions into its internal Responses path, so all existing providers, routing, OAuth, and sidecars apply. ## Supported fields @@ -58,12 +58,12 @@ including penalties, `n`, and logprobs, are not currently supported. - **No models configured** — ensure the proxy is up, base URL ends with `/v1` (not `/v1/chat/completions`), and `GET /v1/models` returns a non-empty `data` - array. Add/enable providers in the OpenCodex dashboard, then sync again. -- **401** — remote (non-loopback) binds require the OpenCodex admission token in - `x-opencodex-api-key`. `Authorization` remains the upstream identity for native + array. Add/enable providers in the CodexCommander dashboard, then sync again. +- **401** — remote (non-loopback) binds require the CodexCommander admission token in + `x-codexcommander-api-key`. `Authorization` remains the upstream identity for native direct-account mode. -- **404 on chat** — older OpenCodex builds lacked `/v1/chat/completions`; upgrade - to a build that includes this surface. +- **404 on chat** — confirm the base URL ends with `/v1` and that the running package exposes + `/v1/chat/completions`. - **Model ids with `/`** — prefer the namespaced `provider/model` form returned by `/v1/models`. If a client rejects slashes, add the model by an alias id you control or open an issue for slash-safe aliases. diff --git a/docs/shadow-call-intercept.md b/docs/shadow-call-intercept.md index ff527c87df..39fd114565 100644 --- a/docs/shadow-call-intercept.md +++ b/docs/shadow-call-intercept.md @@ -10,12 +10,10 @@ Codex Desktop App makes background API calls with a hard-coded helper model for These calls happen independently of your selected main model and use `reasoningEffort: low`. -The helper model is not stable across client versions. Codex used `gpt-5.4-mini` up to 0.144.x and -moved to `gpt-5.6-luna` in 0.145.0, which silently disabled a single-literal intercept -([#311](https://github.com/lidge-jun/opencodex/issues/311)). The intercept therefore matches a -**set** of source-model prefixes — `gpt-5.4-mini` and `gpt-5.6-luna` by default — so a client bump -does not quietly turn the feature off. Routed ids (`provider/model`) are never matched: a shadow -call is always a bare native slug, and an explicit routed selection must not be hijacked. +`gpt-5.6-luna` is the default source prefix. Set `sourceModels` only as an explicit current +custom-source override when a client uses another helper id. Routed ids (`provider/model`) are +never matched: a shadow call is always a bare native slug, and an explicit routed selection must +not be hijacked. ## The problem @@ -29,7 +27,7 @@ Related GitHub issues: [#26288](https://github.com/openai/codex/issues/26288), [ ### Via Dashboard UI -1. Open the opencodex dashboard +1. Open the CodexCommander dashboard 2. Find the "Shadow Call Intercept" panel 3. Toggle the switch to enable 4. Enter a replacement model (e.g., `gpt-5.5`) @@ -65,16 +63,8 @@ the defaults rather than extending them: - Matching maintenance requests, including `prewarm`, `compaction`, and `memory`, are rewritten to the configured model -- Normal user turns identified by `x-codex-turn-metadata` with `request_kind: "turn"` are - never rewritten -- Headerless legacy clients retain the original prefix behavior: matching bare model ids are - rewritten -- Missing, malformed, or unrecognized turn metadata retains the legacy prefix behavior +- Normal user turns are never rewritten +- Missing, malformed, or unrecognized `x-codex-turn-metadata` is never intercepted - Reasoning effort is forced to `low` (matching the original behavior) - The original model ID is logged as `shadowCallRewrittenFrom` in request logs - When disabled (default), no interception occurs - -### Warning - -Headerless clients cannot distinguish foreground turns from background helper calls. If such a -client uses `gpt-5.6-luna` as its main model, narrow `sourceModels` or disable the intercept. diff --git a/docs/superpowers/plans/2026-07-26-oauth-reliability-integrity.md b/docs/superpowers/plans/2026-07-26-oauth-reliability-integrity.md deleted file mode 100644 index 798219e8ff..0000000000 --- a/docs/superpowers/plans/2026-07-26-oauth-reliability-integrity.md +++ /dev/null @@ -1,762 +0,0 @@ -# OAuth Reliability and Client Integrity Implementation Plan - -> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. - -**Goal:** Generalize cross-process OAuth refresh locking and generation CAS, expose a shared OAuth health projection through status/doctor/dashboard, and harden Codex client-metadata integrity tests — without changing Codex affinity policy A or adding impersonation/limit-bypass behaviour. - -**Architecture:** Reuse `createOAuthRefreshIntentLock` + `mergeAccountCredential` (already proven for xAI/Anthropic) for remaining OAuth providers behind the existing in-process `tokenRefreshes` map. Project existing `needsReauth` / Codex cooldown / conflict signals into one `OAuthAccountHealth` type consumed by CLI, management API, and GUI. Keep Codex pool 401/403 quarantine and 429 affinity-clear/rotate behaviour unchanged. - -**Tech Stack:** Bun, TypeScript, existing `src/oauth/*`, `src/codex/*`, `src/cli/*`, React GUI, Bun test runner, docs-site (Astro/Starlight). - -**Spec:** `docs/superpowers/specs/2026-07-26-oauth-reliability-integrity-design.md` - -## Global Constraints - -- Target branch: `feat/oauth-reliability-integrity` (worktree); PRs target `dev` -- TDD: write failing test → confirm fail → minimal implementation → confirm pass → commit -- No new dependencies -- Never log access tokens, refresh tokens, authorization headers, OAuth codes, or full account identifiers -- Redact account IDs in CLI/UI (`maskAccountId`) -- Do not claim ban protection; describe reliability, integrity, diagnostics only -- Affinity policy A: keep current Codex clear-on-401/403/429 behaviour -- Do not persist `threadAccountMap` to disk -- Do not fabricate official Codex client metadata -- Avoid unrelated refactors - -## File map - -| Path | Role | -|------|------| -| `src/lib/privacy.ts` | Add `maskAccountId` | -| `src/oauth/log.ts` | Structured redacted OAuth transition logs | -| `src/oauth/health.ts` | Shared health projection + aggregators | -| `src/oauth/index.ts` | Generalized locked refresh for non-xAI/Anthropic providers | -| `src/oauth/store.ts` | Only if tiny helpers needed for incomplete-credential detection | -| `src/cli/status.ts` / `src/cli/index.ts` | Status OAuth health block | -| `src/cli/doctor.ts` | Doctor OAuth checks | -| `src/server/management/oauth-account-routes.ts` | Expose health on account DTOs | -| `src/codex/auth-context.ts` / `src/adapters/openai-responses.ts` | Metadata integrity (tests; code only if gap found) | -| `gui/src/lib/privacy.ts` or shared import path | GUI redaction helper if GUI cannot import runtime privacy directly | -| `gui/src/components/provider-workspace/*` | Health badge + explanation | -| `docs-site/src/content/docs/**` | User-facing docs | -| `tests/*.test.ts` | Behaviour tests per task | - ---- - -### Task 1: Account ID redaction helper - -**Files:** -- Modify: `src/lib/privacy.ts` -- Test: `tests/privacy-mask-account.test.ts` -- Modify (if CLI already prints raw IDs in oauth summary paths later): none in this task beyond helper - -**Interfaces:** -- Consumes: none -- Produces: `maskAccountId(value: string | null | undefined): string | null` - -- [ ] **Step 1: Write the failing test** - -```ts -import { describe, expect, test } from "bun:test"; -import { maskAccountId } from "../src/lib/privacy"; - -describe("maskAccountId", () => { - test("redacts long account ids to account-…suffix", () => { - expect(maskAccountId("acct_abcdefghijklmnopqrstuvwxyz")).toBe("account-…wxyz"); - }); - - test("returns null for empty", () => { - expect(maskAccountId(null)).toBeNull(); - expect(maskAccountId("")).toBeNull(); - }); - - test("short ids still redact without leaking full value when length > 4", () => { - expect(maskAccountId("abcdef")).toBe("account-…cdef"); - }); -}); -``` - -- [ ] **Step 2: Run test to verify it fails** - -Run: `bun test tests/privacy-mask-account.test.ts` - -Expected: FAIL — `maskAccountId` is not exported - -- [ ] **Step 3: Write minimal implementation** - -In `src/lib/privacy.ts`: - -```ts -export function maskAccountId(value: string | null | undefined): string | null { - if (!value) return null; - const id = value.trim(); - if (!id) return null; - const suffix = id.length <= 4 ? id : id.slice(-4); - return `account-…${suffix}`; -} -``` - -- [ ] **Step 4: Run test to verify it passes** - -Run: `bun test tests/privacy-mask-account.test.ts` - -Expected: PASS - -- [ ] **Step 5: Commit** - -```bash -git add src/lib/privacy.ts tests/privacy-mask-account.test.ts -git commit -m "$(cat <<'EOF' -feat(privacy): add maskAccountId for OAuth diagnostics - -EOF -)" -``` - ---- - -### Task 2: Structured OAuth logger - -**Files:** -- Create: `src/oauth/log.ts` -- Test: `tests/oauth-log.test.ts` - -**Interfaces:** -- Consumes: `maskAccountId` from `src/lib/privacy.ts` -- Produces: - - `logOAuthEvent(event: string, fields: { provider: string; accountId?: string; [k: string]: unknown }): void` - - Events must never include keys: `access`, `refresh`, `authorization`, `code`, `token` - -- [ ] **Step 1: Write the failing test** - -```ts -import { describe, expect, test } from "bun:test"; -import { logOAuthEvent } from "../src/oauth/log"; - -describe("logOAuthEvent", () => { - test("emits redacted account and never prints a token-looking field value", () => { - const lines: string[] = []; - const original = console.info; - console.info = (msg?: unknown) => { lines.push(String(msg)); }; - try { - logOAuthEvent("OAuth refresh started", { - provider: "kiro", - accountId: "acct_abcdefghijklmnopqrstuvwxyz", - until: "2026-07-23T14:30:00.000Z", - }); - } finally { - console.info = original; - } - expect(lines.length).toBe(1); - expect(lines[0]).toContain("[opencodex]"); - expect(lines[0]).toContain("provider=kiro"); - expect(lines[0]).toContain("account=account-…wxyz"); - expect(lines[0]).not.toContain("acct_abcdefghijklmnopqrstuvwxyz"); - }); -}); -``` - -- [ ] **Step 2: Run test to verify it fails** - -Run: `bun test tests/oauth-log.test.ts` - -Expected: FAIL — module missing - -- [ ] **Step 3: Write minimal implementation** - -```ts -// src/oauth/log.ts -import { maskAccountId } from "../lib/privacy"; - -const FORBIDDEN = /^(access|refresh|authorization|code|token|accessToken|refreshToken)$/i; - -export function logOAuthEvent( - event: string, - fields: { provider: string; accountId?: string; [key: string]: unknown }, -): void { - const parts = [`[opencodex] ${event}`, `provider=${fields.provider}`]; - if (fields.accountId) parts.push(`account=${maskAccountId(fields.accountId)}`); - for (const [key, value] of Object.entries(fields)) { - if (key === "provider" || key === "accountId") continue; - if (FORBIDDEN.test(key)) continue; - if (value === undefined) continue; - parts.push(`${key}=${String(value)}`); - } - console.info(parts.join(" ")); -} -``` - -- [ ] **Step 4: Run test to verify it passes** - -Run: `bun test tests/oauth-log.test.ts` - -Expected: PASS - -- [ ] **Step 5: Commit** - -```bash -git add src/oauth/log.ts tests/oauth-log.test.ts -git commit -m "$(cat <<'EOF' -feat(oauth): add redacted structured OAuth event logger - -EOF -)" -``` - ---- - -### Task 3: Generalized locked refresh + CAS for generic OAuth providers - -**Files:** -- Modify: `src/oauth/index.ts` (`refreshAndPersistAccessToken` generic branch ~352–400) -- Test: `tests/oauth-refresh-generic-lock.test.ts` (new; mirror patterns from `tests/xai-refresh-lock.test.ts` / `tests/oauth-refresh.test.ts`) - -**Interfaces:** -- Consumes: `createOAuthRefreshIntentLock`, `mergeAccountCredential`, `credentialGeneration`, `markAccountNeedsReauthIfGeneration`, `getAccountCredential`, `logOAuthEvent` -- Produces: generic path behaviour equivalent to: - 1. lock → reload → skip if already fresh → refresh → CAS persist → unlock - 2. in-process `tokenRefreshes` still coalesces callers -- Keep xAI / Anthropic / Kiro special branches unchanged in behaviour - -- [ ] **Step 1: Write the failing tests** - -Create `tests/oauth-refresh-generic-lock.test.ts` covering at least: - -1. Ten concurrent `getValidAccessTokenForAccount("kimi", id)` (or another non-xAI/Anthropic provider with injectable `refresh`) trigger **one** IdP refresh; all get same access token -2. Failed refresh clears single-flight so a later call can retry -3. After lock acquire, a newer disk credential is adopted without a second IdP call -4. Older refresh result cannot overwrite newer stored token (`mergeAccountCredential` superseded path) -5. Rotated refresh token is persisted on disk - -Use the existing test helpers that point `OPENCODEX_HOME` at a temp dir and stub `OAUTH_PROVIDERS[provider].refresh` / fetch. Follow `tests/oauth-refresh.test.ts` setup patterns for auth store isolation. - -Sketch for concurrent refresh: - -```ts -test("ten concurrent generic refreshes share one IdP call and same credential", async () => { - let refreshCalls = 0; - // arrange expired kimi (or github-copilot) credential in temp auth store - // stub provider refresh to increment refreshCalls and return rotated tokens - const results = await Promise.all( - Array.from({ length: 10 }, () => getValidAccessTokenForAccount(provider, accountId)), - ); - expect(new Set(results).size).toBe(1); - expect(refreshCalls).toBe(1); - const stored = getAccountCredential(provider, accountId); - expect(stored?.refresh).toBe("rotated-refresh"); -}); -``` - -- [ ] **Step 2: Run test to verify it fails** - -Run: `bun test tests/oauth-refresh-generic-lock.test.ts` - -Expected: FAIL — generic path still uses unlocked `saveAccountCredential` / can double-refresh under injected dual locks or pre-persist races (assert the specific failure your test constructs) - -- [ ] **Step 3: Write minimal implementation** - -Replace the generic branch in `refreshAndPersistAccessToken` with a shared helper, e.g. `refreshGenericAccountWithLock`, modeled on xAI/Anthropic but without Grok/Claude local-cli logic: - -```ts -async function refreshGenericAccountWithLock( - provider: string, - accountId: string, - def: OAuthProviderDef, - callerCredential: OAuthCredentials, -): Promise<string> { - logOAuthEvent("OAuth refresh started", { provider, accountId }); - const guard = await createOAuthRefreshIntentLock(provider, accountId).acquire(); - try { - const stored = getAccountCredential(provider, accountId); - if (!stored) throw new OAuthLoginRequiredError(provider); - if ( - credentialGeneration(stored) !== credentialGeneration(callerCredential) - && stored.expires > Date.now() + REFRESH_SKEW_MS - ) { - logOAuthEvent("OAuth refresh joined existing operation", { provider, accountId }); - return stored.access; - } - const generation = credentialGeneration(stored); - try { - const fresh = merged(await def.refresh(stored.refresh), stored); - const outcome = await mergeAccountCredential(provider, accountId, fresh, { - expectedGeneration: generation, - }); - if (outcome.superseded) { - if (outcome.stored.expires > Date.now() + REFRESH_SKEW_MS) return outcome.stored.access; - throw new OAuthLoginRequiredError(provider); - } - logOAuthEvent("OAuth credentials rotated and persisted", { provider, accountId }); - return fresh.access; - } catch (error) { - if (!isTerminalRefreshError(error)) throw error; - await markAccountNeedsReauthIfGeneration(provider, accountId, generation); - throw new OAuthLoginRequiredError(provider); - } - } finally { - guard.release(); - } -} -``` - -Wire it from the generic branch (still after Kiro active-import and xAI/Anthropic special cases). Ensure `tokenRefreshes` finally-clear behaviour remains so failed refreshes allow retry. - -Also log `"OAuth refresh joined existing operation"` when `tokenRefreshes.get(key)` hits an existing promise. - -- [ ] **Step 4: Run tests to verify they pass** - -Run: - -```bash -bun test tests/oauth-refresh-generic-lock.test.ts tests/oauth-refresh.test.ts tests/xai-refresh-lock.test.ts -``` - -Expected: PASS (no regressions on xAI/Anthropic) - -- [ ] **Step 5: Commit** - -```bash -git add src/oauth/index.ts tests/oauth-refresh-generic-lock.test.ts -git commit -m "$(cat <<'EOF' -feat(oauth): lock and CAS generic provider token refresh - -EOF -)" -``` - ---- - -### Task 4: Shared OAuth health projection - -**Files:** -- Create: `src/oauth/health.ts` -- Test: `tests/oauth-health.test.ts` -- Modify: export from `src/oauth/index.ts` if that is the public surface used by CLI - -**Interfaces:** -- Consumes: - - OAuth store `needsReauth` / credential presence via existing getters - - Codex cooldown via exported read helpers — if none exist, add a **read-only** `getCodexAccountCooldown(accountId): { until: number; source: string } | null` in `src/codex/routing.ts` without changing write policy -- Produces: - -```ts -export type OAuthAccountHealth = - | { status: "healthy" } - | { status: "cooldown"; until: string; reason: "rate_limit" | "quota" } - | { status: "reauth_required"; reason: "unauthorized" | "forbidden" | "refresh_failed" } - | { status: "warning"; reason: "refresh_conflict" | "metadata_mismatch" | "stale_credentials" }; - -export type OAuthHealthEntry = { - provider: string; - accountId: string; - health: OAuthAccountHealth; - action?: string; -}; - -export function projectOAuthAccountHealth(input: { - needsReauth?: boolean; - reauthReason?: "unauthorized" | "forbidden" | "refresh_failed"; - cooldownUntilMs?: number; - cooldownReason?: "rate_limit" | "quota"; - warningReason?: "refresh_conflict" | "metadata_mismatch" | "stale_credentials"; - now?: number; -}): OAuthAccountHealth; - -export function collectOAuthHealthEntries(now?: number): OAuthHealthEntry[]; -``` - -Priority when multiple signals exist: `reauth_required` > `cooldown` > `warning` > `healthy`. - -- [ ] **Step 1: Write the failing tests** - -```ts -test("reauth beats cooldown", () => { - expect(projectOAuthAccountHealth({ - needsReauth: true, - reauthReason: "refresh_failed", - cooldownUntilMs: Date.now() + 60_000, - })).toEqual({ status: "reauth_required", reason: "refresh_failed" }); -}); - -test("active cooldown projects until ISO timestamp", () => { - const until = Date.parse("2026-07-23T14:30:00.000Z"); - expect(projectOAuthAccountHealth({ - cooldownUntilMs: until, - cooldownReason: "rate_limit", - now: until - 1000, - })).toEqual({ - status: "cooldown", - until: "2026-07-23T14:30:00.000Z", - reason: "rate_limit", - }); -}); -``` - -Also test `collectOAuthHealthEntries` with a temp auth store marking one account `needsReauth`. - -- [ ] **Step 2: Run test to verify it fails** - -Run: `bun test tests/oauth-health.test.ts` - -Expected: FAIL — module missing - -- [ ] **Step 3: Write minimal implementation** - -Implement `projectOAuthAccountHealth` and `collectOAuthHealthEntries`. For Codex pool accounts, read cooldown via a new thin getter in `src/codex/routing.ts`: - -```ts -export function getCodexAccountHealthSnapshot(accountId: string, now = Date.now()): { - cooldownUntil?: number; - cooldownSource?: "retry-after" | "reset-derived" | "default"; -} | null -``` - -Map `retry-after` → `rate_limit`, others → `quota` for health reason. Do **not** change `recordCodexUpstreamOutcome`. - -Set `action` strings: -- reauth: `run \`ocx login <provider>\`` -- cooldown: `wait until <local time> or start a new session with another eligible account` -- warning refresh_conflict: `re-run \`ocx doctor\` after ensuring only one proxy process writes the credential store` - -- [ ] **Step 4: Run test to verify it passes** - -Run: `bun test tests/oauth-health.test.ts tests/codex-routing.test.ts` - -Expected: PASS - -- [ ] **Step 5: Commit** - -```bash -git add src/oauth/health.ts src/oauth/index.ts src/codex/routing.ts tests/oauth-health.test.ts -git commit -m "$(cat <<'EOF' -feat(oauth): add shared account health projection - -EOF -)" -``` - ---- - -### Task 5: `ocx status` OAuth health output - -**Files:** -- Modify: `src/cli/index.ts` (status human printer that currently calls `oauthLoginSummary`) -- Modify: `src/cli/status.ts` only if JSON status should gain a redacted health summary (prefer human-first; add JSON only if existing tests/docs allow a non-secret block) -- Test: `tests/cli-status-oauth-health.test.ts` - -**Interfaces:** -- Consumes: `collectOAuthHealthEntries`, `maskAccountId` -- Produces: human-readable block matching the spec examples (warning / rate limited) - -- [ ] **Step 1: Write the failing test** - -Drive `collectOAuthHealthEntries` via store fixtures, then call a new pure formatter: - -```ts -import { formatOAuthHealthForStatus } from "../src/cli/status-oauth"; - -test("formats reauthentication required", () => { - const text = formatOAuthHealthForStatus([{ - provider: "openai", - accountId: "acct_abcdefghijklmnopqrstuvwxyz", - health: { status: "reauth_required", reason: "refresh_failed" }, - action: "run `ocx login openai`", - }]); - expect(text).toContain("OAuth health: warning"); - expect(text).toContain("account-…wxyz"); - expect(text).not.toContain("acct_abcdefghijklmnopqrstuvwxyz"); - expect(text).toContain("reauthentication required"); -}); -``` - -- [ ] **Step 2: Run test to verify it fails** - -Run: `bun test tests/cli-status-oauth-health.test.ts` - -Expected: FAIL - -- [ ] **Step 3: Write minimal implementation** - -Create `src/cli/status-oauth.ts` with `formatOAuthHealthForStatus`. Wire into `handleStatus` human output after the existing OAuth logins summary (or replace sparse summary with health-aware block when non-healthy entries exist). Keep emails masked; never print tokens. - -- [ ] **Step 4: Run tests** - -Run: `bun test tests/cli-status-oauth-health.test.ts tests/cli-status-json.test.ts` - -Expected: PASS - -- [ ] **Step 5: Commit** - -```bash -git add src/cli/status-oauth.ts src/cli/index.ts tests/cli-status-oauth-health.test.ts -git commit -m "$(cat <<'EOF' -feat(cli): show OAuth health in ocx status - -EOF -)" -``` - ---- - -### Task 6: `ocx doctor` OAuth checks - -**Files:** -- Modify: `src/cli/doctor.ts` -- Test: `tests/doctor-oauth.test.ts` (or extend `tests/doctor.test.ts`) - -**Interfaces:** -- Consumes: `collectOAuthHealthEntries`, auth store writability checks, refresh lock path helpers if exported -- Produces: doctor rows like: - - `[OK] OAuth credential storage is writable.` - - `[OK] Token refresh single-flight is active.` - - `[WARN] Account account-…42 requires reauthentication. Action: run \`ocx login <provider>\`` - - `[WARN] Account account-…17 is rate limited until … Action: …` - - `[OK] No fabricated official-client metadata detected.` (static OK for Codex forward path unless a runtime detector exists; do not invent a false positive scanner) - -- [ ] **Step 1: Write the failing test** - -Seed a temp account with `needsReauth`, run the new `collectOAuthDoctorChecks()` (pure), assert WARN + action present and account id redacted. - -- [ ] **Step 2: Run test to verify it fails** - -Run: `bun test tests/doctor-oauth.test.ts` - -Expected: FAIL - -- [ ] **Step 3: Write minimal implementation** - -Add `collectOAuthDoctorChecks(): Array<{ level: "OK" | "WARN"; message: string }>` and append in `runDoctor()` output. Observe-only: no mutations, no auto-repair. - -- [ ] **Step 4: Run tests** - -Run: `bun test tests/doctor-oauth.test.ts tests/doctor.test.ts` - -Expected: PASS - -- [ ] **Step 5: Commit** - -```bash -git add src/cli/doctor.ts tests/doctor-oauth.test.ts -git commit -m "$(cat <<'EOF' -feat(cli): add OAuth reliability checks to ocx doctor - -EOF -)" -``` - ---- - -### Task 7: Management API + dashboard health - -**Files:** -- Modify: `src/server/management/oauth-account-routes.ts` (and Codex auth DTO path in `src/codex/auth-api.ts` if Codex accounts are the primary UI) -- Modify: `gui/src/components/provider-workspace/ProviderAuthPanel.tsx` -- Modify: `gui/src/components/CodexAccountPool.tsx` (if showing Codex cooldown/reauth) -- Possibly: `gui/src/provider-workspace/catalog.ts` / types for account DTO -- Test: `tests/oauth-accounts-api.test.ts` (extend) -- Test: GUI unit/render test if the repo already has a pattern; otherwise a pure formatter test for badge labels in `gui/src/...` plus API contract test - -**Interfaces:** -- API account objects gain: - -```ts -health: OAuthAccountHealth -healthLabel: "Healthy" | "Rate limited" | "Reauthentication required" | "Refresh failed" | "Metadata mismatch" | "Credential conflict" -``` - -Map warning reasons to labels (`refresh_conflict` → Credential conflict, etc.). - -- [ ] **Step 1: Write the failing API test** - -Assert `/api/oauth/accounts?provider=...` includes `health` and redacted display helpers never return full raw id in `healthSummary` strings. - -- [ ] **Step 2: Run test to verify it fails** - -Run: `bun test tests/oauth-accounts-api.test.ts` - -Expected: FAIL on missing `health` - -- [ ] **Step 3: Minimal API + UI implementation** - -Attach projected health to account DTOs. In GUI, show badge + short explanation (what happened, provider/account redacted, blocked?, next action). Actions: Reauthenticate button (existing), copy `ocx doctor`, disable probe messaging during cooldown. No “anti-ban” copy. - -- [ ] **Step 4: Run tests** - -Run: - -```bash -bun test tests/oauth-accounts-api.test.ts -bun run lint:gui -``` - -Expected: PASS / lint clean for touched files - -- [ ] **Step 5: Commit** - -```bash -git add src/server/management/oauth-account-routes.ts src/codex/auth-api.ts gui/src/components/provider-workspace/ProviderAuthPanel.tsx gui/src/components/CodexAccountPool.tsx tests/oauth-accounts-api.test.ts -git commit -m "$(cat <<'EOF' -feat(gui): surface OAuth account health diagnostics - -EOF -)" -``` - ---- - -### Task 8: Codex metadata integrity regressions + 401 replay invariants - -**Files:** -- Test: `tests/codex-metadata-integrity.test.ts` (new) -- Modify only if a real gap is found: `src/codex/auth-context.ts`, `src/adapters/openai-responses.ts` -- Confirm existing: `tests/server-xai-oauth-401-replay.test.ts`, `tests/server-kiro-oauth-401-replay.test.ts`, `tests/codex-routing.test.ts` (policy A) - -**Interfaces:** -- Consumes: `headersForCodexAuthContext`, `FORWARD_HEADERS` -- Produces: tests proving: - 1. Genuine `originator` / `session_id` / `thread-id` preserved - 2. Missing `originator` is not filled with `codex_cli_rs` - 3. Outgoing `chatgpt-account-id` matches selected pool credential - 4. Policy A: 429 clears affinity (existing tests remain green) — do not invert - -- [ ] **Step 1: Write failing tests for any missing assertion** - -```ts -test("does not fabricate originator when absent", () => { - const incoming = new Headers({ - "x-codex-parent-thread-id": "thread-1", - }); - // resolve auth context with pool account A - const headers = headersForCodexAuthContext(incoming, authContext); - expect(headers.get("originator")).toBeNull(); - expect(headers.get("chatgpt-account-id")).toBe(accountA.chatgptAccountId); -}); - -test("preserves genuine originator", () => { - const incoming = new Headers({ - originator: "codex_cli_rs", - "x-codex-parent-thread-id": "thread-1", - }); - const headers = headersForCodexAuthContext(incoming, authContext); - expect(headers.get("originator")).toBe("codex_cli_rs"); -}); -``` - -- [ ] **Step 2: Run tests** - -Run: `bun test tests/codex-metadata-integrity.test.ts` - -Expected: FAIL only if implementation gap exists; if PASS immediately, keep tests as regressions and skip code changes. - -- [ ] **Step 3: Fix only real gaps** - -If fabrication or account-id mismatch is found, fix the minimal header path. Do not add fake official metadata. - -- [ ] **Step 4: Run related suite** - -```bash -bun test tests/codex-metadata-integrity.test.ts tests/codex-auth-context.test.ts tests/codex-routing.test.ts tests/session-affinity.test.ts tests/server-xai-oauth-401-replay.test.ts tests/server-kiro-oauth-401-replay.test.ts -``` - -Expected: PASS - -- [ ] **Step 5: Commit** - -```bash -git add tests/codex-metadata-integrity.test.ts src/codex/auth-context.ts src/adapters/openai-responses.ts -git commit -m "$(cat <<'EOF' -test(codex): lock metadata pass-through and non-fabrication - -EOF -)" -``` - ---- - -### Task 9: Documentation - -**Files:** -- Modify: `docs-site/src/content/docs/guides/providers.md` -- Modify: `docs-site/src/content/docs/reference/cli.md` -- Modify: `docs-site/src/content/docs/reference/architecture.md` (brief) -- Update translated locales only enough to avoid contradictions if they mirror the changed English sections; prefer English-first + short note if locale sync is heavy - -Content to add (factual, concise): - -- How OAuth refresh coordination works (in-process single-flight + per-account file lock + generation CAS) -- How cooldowns work (Retry-After / reset headers / backoff; no probe during Retry-After cooldowns) -- Session affinity is process-local; policy on errors (policy A) -- Which Codex client metadata is preserved; what is not fabricated -- How to use `ocx status` and `ocx doctor` for OAuth health -- How to reauthenticate -- Explicit: this does not guarantee protection from provider enforcement - -- [ ] **Step 1: Update English docs** - -- [ ] **Step 2: Skim locales for contradictory statements; fix only contradictions** - -- [ ] **Step 3: Commit** - -```bash -git add docs-site/src/content/docs -git commit -m "$(cat <<'EOF' -docs: document OAuth reliability and diagnostics - -EOF -)" -``` - ---- - -### Task 10: Full verification and handoff - -- [ ] **Step 1: Run verification commands** - -```bash -bun test tests/privacy-mask-account.test.ts tests/oauth-log.test.ts tests/oauth-refresh-generic-lock.test.ts tests/oauth-health.test.ts tests/cli-status-oauth-health.test.ts tests/doctor-oauth.test.ts tests/oauth-accounts-api.test.ts tests/codex-metadata-integrity.test.ts -bun test tests/oauth-refresh.test.ts tests/xai-refresh-lock.test.ts tests/codex-routing.test.ts tests/session-affinity.test.ts tests/codex-auth-context.test.ts -bun run test -bun run typecheck -bun run lint:gui -bun run privacy:scan -bun run build:gui -``` - -- [ ] **Step 2: Inspect final diff for** - -- duplicated OAuth state -- token leakage -- weak locking left on generic path -- accidental affinity policy changes -- fabricated official-client metadata -- unrelated changes - -- [ ] **Step 3: Write handoff summary** covering findings, files changed, behaviours, tests, command results, limitations, and confirmation that no impersonation/fingerprint spoofing/limit-bypass was added - ---- - -## Spec coverage checklist - -| Spec item | Task | -|-----------|------| -| Refresh single-flight + cross-process lock | 3 | -| Atomic CAS persistence / no stale overwrite | 3 | -| 401 replay where existing providers support it | 8 (regression) | -| 403/429 policy A unchanged | 8 + existing routing tests | -| Affinity process-local, policy A | 8 + design decision | -| Client metadata integrity | 8 | -| Health model | 4 | -| `ocx status` | 5 | -| `ocx doctor` | 6 | -| Dashboard | 7 | -| Structured logs | 2 (+ hooks in 3) | -| Account redaction | 1 (+ consumers 5–7) | -| Docs | 9 | -| Verification | 10 | - -## Placeholder / consistency self-review - -- No TBD/TODO left in tasks -- `OAuthAccountHealth` shape is identical in Tasks 4–7 -- `maskAccountId` / `logOAuthEvent` / `collectOAuthHealthEntries` names are stable across tasks -- Policy A is restated wherever affinity/429 tests are mentioned so implementers do not “fix” it to pin-through-429 diff --git a/docs/superpowers/plans/2026-07-28-pr-quality-gates.md b/docs/superpowers/plans/2026-07-28-pr-quality-gates.md deleted file mode 100644 index fe04ac5aaf..0000000000 --- a/docs/superpowers/plans/2026-07-28-pr-quality-gates.md +++ /dev/null @@ -1,645 +0,0 @@ -# PR Quality Gates (Ancestry + Description) Implementation Plan - -> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. - -**Goal:** Extend `enforce-pr-target` so PRs like #644 fail: wrong ancestry (branched from `main` while targeting `dev`/`dev2-go`) and empty/thin/malformed descriptions, with the same draft + comment + `setFailed` UX as wrong-base. - -**Architecture:** Pure validators live in `.github/scripts/pr-quality.cjs` (reusing `issue-quality` helpers for placeholders / structured sections). The workflow checks out **trusted** scripts from the repository default branch (sparse, no PR head), then the existing `github-script` step requires that module, evaluates base + ancestry + description, and drafts/`setFailed`s when any gate fails. - -**Tech Stack:** Node CommonJS (Actions scripts), `node:test` for script unit tests, Bun/`tests/ci-workflows.test.ts` + `enforce-pr-target-harness.ts` for workflow behavioral coverage, Astro docs-site for contributing copy. - -**Spec:** `docs/superpowers/specs/2026-07-28-pr-quality-gates-design.md` - -## Global Constraints - -- `ANCESTRY_BEHIND_THRESHOLD = 20` -- Ancestry fail when `behind_main === 0 && behind_base >= 20` -- Release compare ref = `main` -- Description: min section length `40`, min rich sections `2`, unstructured min length `120`, min blocks `2` -- Skip ancestry only for authors with push/maintain/admin on the base repo; permission API failure → fail closed (apply ancestry) -- Do **not** skip description for maintainers -- `[WRONG BRANCH]` title prefix only for wrong **base** -- `pull_request_target`: never check out PR head; checkout only `github.event.repository.default_branch` + sparse `.github/scripts` -- Permissions stay `contents: write` + `pull-requests: write` -- Add trigger type `synchronize` -- No live GitHub in unit tests - -## File map - -| File | Role | -| --- | --- | -| `.github/scripts/pr-quality.cjs` | Pure ancestry + description assessment + failure collectors | -| `.github/scripts/pr-quality.test.cjs` | Node unit tests for pure rules | -| `.github/workflows/enforce-pr-target.yml` | Checkout + require + multi-gate orchestration | -| `.github/scripts/enforce-pr-target.test.cjs` | Static workflow assertions (checkout safety, synchronize, paths) | -| `tests/helpers/enforce-pr-target-harness.ts` | Allow `require` of scripts; mock compare + permission; PR `body` | -| `tests/ci-workflows.test.ts` | Structural allowlist + behavioral scenarios | -| `.github/workflows/issue-quality-tests.yml` | Path filters for new script/tests | -| `docs-site/src/content/docs/contributing.md` | User-facing branch + description rules | -| `AGENTS.md` / `MAINTAINERS.md` | One-line CI policy note | - ---- - -### Task 1: Pure `pr-quality.cjs` (ancestry + description) - -**Files:** -- Create: `.github/scripts/pr-quality.cjs` -- Create: `.github/scripts/pr-quality.test.cjs` -- Modify: `.github/workflows/issue-quality-tests.yml` (add path filters + `node --test` line) - -**Interfaces:** -- Produces: - - `ANCESTRY_BEHIND_THRESHOLD` number (`20`) - - `isWrongAncestry({ behindMain, behindBase, threshold? }) → boolean` - - `authorHasPushPermission(permission: string | null | undefined) → boolean` — true for `admin` \| `maintain` \| `write` - - `assessPrDescription(body: string | null | undefined) → { ok: true } | { ok: false, reason: "empty" | "placeholder" | "escaped_newlines" | "thin" }` - - `collectPrQualityFailures({ baseRef, allowedBases, body, behindMain, behindBase, authorPermission, permissionLookupFailed? }) → Array<{ code: "wrong_base" | "wrong_ancestry" | "bad_description", reason?: string }>` - - `wrong_base` when `!allowedBases.includes(baseRef)` - - `wrong_ancestry` only when base allowed, and (`permissionLookupFailed` or `!authorHasPushPermission(authorPermission)`), and `isWrongAncestry(...)` - - `bad_description` whenever `assessPrDescription` is not ok (even if wrong_base) - -- [ ] **Step 1: Write the failing tests** - -Create `.github/scripts/pr-quality.test.cjs`: - -```js -"use strict"; - -const { describe, it } = require("node:test"); -const assert = require("node:assert/strict"); -const { - ANCESTRY_BEHIND_THRESHOLD, - isWrongAncestry, - authorHasPushPermission, - assessPrDescription, - collectPrQualityFailures, -} = require("./pr-quality.cjs"); - -describe("isWrongAncestry", () => { - it("flags #644-shaped compares (0 behind main, far behind base)", () => { - assert.equal( - isWrongAncestry({ behindMain: 0, behindBase: 44 }), - true, - ); - }); - - it("uses threshold 20 by default", () => { - assert.equal(ANCESTRY_BEHIND_THRESHOLD, 20); - assert.equal(isWrongAncestry({ behindMain: 0, behindBase: 20 }), true); - assert.equal(isWrongAncestry({ behindMain: 0, behindBase: 19 }), false); - }); - - it("passes when head is behind main (not sitting on main tip)", () => { - assert.equal(isWrongAncestry({ behindMain: 1, behindBase: 44 }), false); - }); -}); - -describe("authorHasPushPermission", () => { - it("accepts write/maintain/admin only", () => { - assert.equal(authorHasPushPermission("admin"), true); - assert.equal(authorHasPushPermission("maintain"), true); - assert.equal(authorHasPushPermission("write"), true); - assert.equal(authorHasPushPermission("triage"), false); - assert.equal(authorHasPushPermission("read"), false); - assert.equal(authorHasPushPermission(null), false); - }); -}); - -describe("assessPrDescription", () => { - it("rejects empty and comment-only bodies", () => { - assert.equal(assessPrDescription("").ok, false); - assert.equal(assessPrDescription(" ").ok, false); - assert.equal( - assessPrDescription("<!-- release notes by coderabbit.ai -->\n\n<!-- end -->").reason, - "empty", - ); - }); - - it("rejects placeholder-only bodies", () => { - assert.equal(assessPrDescription("N/A").reason, "placeholder"); - assert.equal(assessPrDescription("TODO").reason, "placeholder"); - }); - - it("rejects literal escaped newlines like #644", () => { - const body = - "## What changed\\n- make the Windows tray launcher resolve Codex home\\n\\n## Validation\\n- git diff --check"; - assert.equal(assessPrDescription(body).reason, "escaped_newlines"); - }); - - it("rejects thin real-newline bodies", () => { - assert.equal(assessPrDescription("fix stuff").reason, "thin"); - }); - - it("accepts two rich markdown sections", () => { - const body = [ - "## Summary", - "This change updates the Windows tray launcher so it resolves CODEX_HOME through the shared helper instead of a hardcoded path.", - "", - "## Test plan", - "- Launch the tray app after setting CODEX_HOME", - "- Confirm the listener and launcher use the same workspace root", - ].join("\n"); - assert.equal(assessPrDescription(body).ok, true); - }); - - it("accepts unstructured bodies that are long enough with multiple blocks", () => { - const p1 = - "Updates the Windows tray launcher to resolve the active Codex home through the shared helper so listener and launcher stay aligned."; - const p2 = - "Validated with git diff --check on the changed tray module; typecheck was not available in that session so CI must cover it."; - assert.equal(assessPrDescription(`${p1}\n\n${p2}`).ok, true); - }); -}); - -describe("collectPrQualityFailures", () => { - const allowed = ["dev", "dev2-go"]; - - it("reports wrong_base without requiring ancestry inputs", () => { - const failures = collectPrQualityFailures({ - baseRef: "main", - allowedBases: allowed, - body: "## Summary\n" + "x".repeat(50) + "\n\n## Test plan\n" + "y".repeat(50), - behindMain: 0, - behindBase: 0, - authorPermission: "read", - }); - assert.ok(failures.some((f) => f.code === "wrong_base")); - assert.ok(!failures.some((f) => f.code === "wrong_ancestry")); - }); - - it("reports wrong_ancestry for contributor on #644-shaped compare", () => { - const failures = collectPrQualityFailures({ - baseRef: "dev", - allowedBases: allowed, - body: [ - "## Summary", - "This change updates the Windows tray launcher so it resolves CODEX_HOME through the shared helper instead of a hardcoded path.", - "", - "## Test plan", - "- Launch the tray app after setting CODEX_HOME", - "- Confirm the listener and launcher use the same workspace root", - ].join("\n"), - behindMain: 0, - behindBase: 44, - authorPermission: "read", - }); - assert.deepEqual( - failures.map((f) => f.code), - ["wrong_ancestry"], - ); - }); - - it("skips ancestry for push permission but still flags bad description", () => { - const failures = collectPrQualityFailures({ - baseRef: "dev", - allowedBases: allowed, - body: "", - behindMain: 0, - behindBase: 44, - authorPermission: "write", - }); - assert.ok(!failures.some((f) => f.code === "wrong_ancestry")); - assert.ok(failures.some((f) => f.code === "bad_description")); - }); - - it("applies ancestry when permission lookup failed (fail closed)", () => { - const failures = collectPrQualityFailures({ - baseRef: "dev", - allowedBases: allowed, - body: [ - "## Summary", - "This change updates the Windows tray launcher so it resolves CODEX_HOME through the shared helper instead of a hardcoded path.", - "", - "## Test plan", - "- Launch the tray app after setting CODEX_HOME", - "- Confirm the listener and launcher use the same workspace root", - ].join("\n"), - behindMain: 0, - behindBase: 44, - authorPermission: null, - permissionLookupFailed: true, - }); - assert.ok(failures.some((f) => f.code === "wrong_ancestry")); - }); -}); -``` - -- [ ] **Step 2: Run tests — expect FAIL (module missing)** - -Run: - -```bash -node --test .github/scripts/pr-quality.test.cjs -``` - -Expected: FAIL — `Cannot find module './pr-quality.cjs'` - -- [ ] **Step 3: Implement `.github/scripts/pr-quality.cjs`** - -```js -"use strict"; - -const path = require("node:path"); -const { - clean, - isPlaceholderOnlyValue, - hasSubstantialStructuredContent, -} = require(path.join(__dirname, "issue-quality.cjs")); - -const ANCESTRY_BEHIND_THRESHOLD = 20; -const MIN_SECTION_LEN = 40; -const MIN_RICH_SECTIONS = 2; -const UNSTRUCTURED_MIN_LEN = 120; -const UNSTRUCTURED_MIN_BLOCKS = 2; - -function isWrongAncestry({ behindMain, behindBase, threshold = ANCESTRY_BEHIND_THRESHOLD }) { - return behindMain === 0 && behindBase >= threshold; -} - -function authorHasPushPermission(permission) { - return permission === "admin" || permission === "maintain" || permission === "write"; -} - -/** - * True when the body uses literal backslash-n as the dominant line break - * (agent bug seen on #644) rather than real newlines. - */ -function hasEscapedNewlines(text) { - const escaped = (text.match(/\\n/g) || []).length; - if (escaped < 2) return false; - const real = (text.match(/\n/g) || []).length; - return escaped > real; -} - -function countContentBlocks(text) { - const blocks = text - .split(/\n\s*\n/) - .map((b) => b.trim()) - .filter(Boolean); - if (blocks.length >= 2) return blocks.length; - const bullets = text - .split("\n") - .map((l) => l.trim()) - .filter((l) => /^[-*+]\s+\S/.test(l)); - return Math.max(blocks.length, bullets.length); -} - -function assessPrDescription(body) { - if (typeof body !== "string" || !body.trim()) { - return { ok: false, reason: "empty" }; - } - if (hasEscapedNewlines(body)) { - return { ok: false, reason: "escaped_newlines" }; - } - const cleaned = clean(body); - if (!cleaned) { - const strippedComments = body.replace(/<!--[\s\S]*?-->/g, "").trim(); - if (!strippedComments) return { ok: false, reason: "empty" }; - if (isPlaceholderOnlyValue(strippedComments)) { - return { ok: false, reason: "placeholder" }; - } - return { ok: false, reason: "empty" }; - } - if (isPlaceholderOnlyValue(cleaned)) { - return { ok: false, reason: "placeholder" }; - } - if (hasSubstantialStructuredContent(cleaned, MIN_SECTION_LEN, MIN_RICH_SECTIONS)) { - return { ok: true }; - } - if ( - cleaned.length >= UNSTRUCTURED_MIN_LEN && - countContentBlocks(cleaned) >= UNSTRUCTURED_MIN_BLOCKS - ) { - return { ok: true }; - } - return { ok: false, reason: "thin" }; -} - -function collectPrQualityFailures({ - baseRef, - allowedBases, - body, - behindMain, - behindBase, - authorPermission, - permissionLookupFailed = false, -}) { - const failures = []; - const wrongBase = !allowedBases.includes(baseRef); - if (wrongBase) { - failures.push({ code: "wrong_base" }); - } else { - const skipAncestry = - !permissionLookupFailed && authorHasPushPermission(authorPermission); - if (!skipAncestry && isWrongAncestry({ behindMain, behindBase })) { - failures.push({ code: "wrong_ancestry" }); - } - } - - const desc = assessPrDescription(body); - if (!desc.ok) { - failures.push({ code: "bad_description", reason: desc.reason }); - } - return failures; -} - -module.exports = { - ANCESTRY_BEHIND_THRESHOLD, - isWrongAncestry, - authorHasPushPermission, - assessPrDescription, - collectPrQualityFailures, - hasEscapedNewlines, -}; -``` - -- [ ] **Step 4: Run tests — expect PASS** - -```bash -node --test .github/scripts/pr-quality.test.cjs -``` - -Expected: all tests pass. - -- [ ] **Step 5: Wire path filters in `issue-quality-tests.yml`** - -In both `pull_request` and `push` `paths:` lists, add: - -```yaml - - ".github/scripts/pr-quality.cjs" - - ".github/scripts/pr-quality.test.cjs" -``` - -In the test step commands, add: - -```yaml - node --test .github/scripts/pr-quality.test.cjs -``` - -- [ ] **Step 6: Commit** - -```bash -git add .github/scripts/pr-quality.cjs .github/scripts/pr-quality.test.cjs .github/workflows/issue-quality-tests.yml -git commit -m "feat(ci): add pure PR ancestry and description quality checks" -``` - ---- - -### Task 2: Workflow orchestration (checkout + multi-gate) - -**Files:** -- Modify: `.github/workflows/enforce-pr-target.yml` -- Modify: `.github/scripts/enforce-pr-target.test.cjs` - -**Interfaces:** -- Consumes: `collectPrQualityFailures` from `pr-quality.cjs` -- Produces: workflow that on any failure drafts (soft-fail) + upserts multi-section comment + `core.setFailed`; on all-clear restores prior bot draft/title state - -- [ ] **Step 1: Extend static workflow tests (fail until yml updated)** - -Append to `.github/scripts/enforce-pr-target.test.cjs`: - -```js - it("listens for synchronize so rebase can clear ancestry failures", () => { - assert.match(workflow, /synchronize/); - }); - - it("checks out trusted default-branch scripts only (never PR head)", () => { - assert.match(workflow, /actions\/checkout@[0-9a-f]{40}/); - assert.match(workflow, /ref:\s*\$\{\{\s*github\.event\.repository\.default_branch\s*\}\}/); - assert.match(workflow, /sparse-checkout:\s*\.github\/scripts/); - assert.match(workflow, /persist-credentials:\s*false/); - assert.doesNotMatch(workflow, /ref:\s*\$\{\{\s*github\.event\.pull_request\.head/); - }); - - it("loads pr-quality via require from the checked-out scripts", () => { - assert.match(workflow, /pr-quality\.cjs/); - assert.match(workflow, /collectPrQualityFailures/); - }); -``` - -- [ ] **Step 2: Run static test — expect FAIL** - -```bash -node --test .github/scripts/enforce-pr-target.test.cjs -``` - -Expected: FAIL on new assertions (no synchronize / checkout / pr-quality yet). - -- [ ] **Step 3: Rewrite `enforce-pr-target.yml` job steps** - -Replace the single-step job with two steps. Keep the existing GraphQL helpers, comment marker, title prefix, and soft-fail draft pattern from #631. - -1. Add `synchronize` to `on.pull_request_target.types`. -2. First step: trusted checkout - -```yaml - - name: Checkout trusted PR-quality scripts - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - ref: ${{ github.event.repository.default_branch }} - persist-credentials: false - sparse-checkout: .github/scripts -``` - -3. Second step: `github-script` that: - -```js -const path = require("path"); -const { collectPrQualityFailures } = require( - path.join(process.cwd(), ".github", "scripts", "pr-quality.cjs"), -); -``` - -Then: - -- `pulls.get` for live PR (include `body`, `head.sha`, `user.login`, `base.ref`, `draft`, `title`, `node_id`) -- `repos.getCollaboratorPermissionLevel` — on error set `permissionLookupFailed = true` and warn -- If base allowed: `repos.compareCommitsWithBasehead` for `main...${headSha}` and `${base}...${headSha}`; read `behind_by` -- `failures = collectPrQualityFailures({...})` -- If `failures.length > 0`: - - Upsert one comment listing each failure section (`wrong_base`, `wrong_ancestry`, `bad_description`) - - Title-prefix **only** when `wrong_base` - - Soft-fail `convertToDraft` like #631; checkpoint ownership in comment state - - `core.setFailed(summary)` and return -- If no failures and `storedState?.active`: restore title/ready like #631; success comment -- If no failures and no active state: `core.info` and return - -Accept bot comments containing either `<!-- wrong-branch-enforcer -->` or `<!-- pr-quality-enforcer -->` when locating state. - -Hidden state keeps `version`, `active`, `autoDraftedByBot`, `titlePrefixedByBot`; may add `ancestryFailed` / `descriptionFailed` booleans. - -- [ ] **Step 4: Run static tests — expect PASS** - -```bash -node --test .github/scripts/enforce-pr-target.test.cjs .github/scripts/pr-quality.test.cjs -``` - -Expected: PASS. - -- [ ] **Step 5: Commit** - -```bash -git add .github/workflows/enforce-pr-target.yml .github/scripts/enforce-pr-target.test.cjs -git commit -m "feat(ci): enforce PR ancestry and description in target gate" -``` - ---- - -### Task 3: Harness + behavioral CI tests - -**Files:** -- Modify: `tests/helpers/enforce-pr-target-harness.ts` -- Modify: `tests/ci-workflows.test.ts` - -**Interfaces:** -- Consumes: workflow script that `require`s `pr-quality.cjs` and calls compare/permission APIs -- Produces: harness options for `body`, compare fixtures, permission; scoped `require` for `.github/scripts/*` only - -- [ ] **Step 1: Extend harness** - -1. Add to `RunOptions`: - - `authorPermission?: string` (default `"read"`) - - `failPermissionLookup?: boolean` - - `compareByBasehead?: Record<string, { ahead_by: number; behind_by: number }>` -2. Ensure `pr.body` and `pr.head.sha` are present on `pulls.get` payload. -3. DEFAULT_PR must include a **passing** description (two rich sections) and default compares that are **not** wrong ancestry (`main...sha` → `behind_by: 5`, `dev...sha` → `behind_by: 0`). -4. Replace `require: forbidden("require")` with a scoped loader: - -```ts -import { createRequire } from "node:module"; -import path from "node:path"; - -const nodeRequire = createRequire(path.join(process.cwd(), "package.json")); -const scriptsRoot = path.resolve(process.cwd(), ".github", "scripts"); - -function scopedRequire(id: string) { - calls.push({ method: "require", args: [id] }); - const resolved = path.isAbsolute(id) ? id : path.resolve(process.cwd(), id); - if (!resolved.startsWith(scriptsRoot + path.sep) && resolved !== scriptsRoot) { - // Also allow require of files already under scripts via absolute path from path.join - const norm = resolved.replace(/\\/g, "/"); - if (!norm.includes("/.github/scripts/")) { - throw new Error(`the script must not require ${id}`); - } - } - return nodeRequire(resolved); -} -``` - -5. Record `repos.getCollaboratorPermissionLevel` and `repos.compareCommitsWithBasehead` on the fake github client. - -- [ ] **Step 2: Update structural allowlist in `tests/ci-workflows.test.ts`** - -- Steps length **2**: checkout then github-script -- Pin checkout SHA `11bd71901bbe5b1630ceea73d27597364c9af683`, default_branch ref, `persist-credentials: false`, sparse `.github/scripts`, no PR head ref -- Types sorted: `edited`, `opened`, `ready_for_review`, `reopened`, `synchronize` -- Keep permissions object unchanged -- Keep “no `${{` in script” assertion on the github-script step only - -- [ ] **Step 3: Add behavioral scenarios** - -1. **Ancestry fail (#644):** base `dev`, permission `read`, `main...sha` behind 0 / `dev...sha` behind 44, good body → `setFailed`, draft attempted, ancestry in comment, **no** title prefix. -2. **Maintainer ancestry skip:** permission `write`, same compares, good body → no `setFailed`. -3. **Empty description:** good ancestry, `body: ""` → `setFailed` + draft. -4. **Escaped newlines:** body with literal `\\n` → `setFailed`. -5. **Clear after active:** prior bot state `active` + `autoDraftedByBot`, now good → mark ready, no `setFailed`. -6. Existing wrong-base scenarios still pass (title prefix + setFailed); give them a good body so description does not double-fail unless intended. - -- [ ] **Step 4: Run focused tests** - -```bash -node --test .github/scripts/pr-quality.test.cjs .github/scripts/enforce-pr-target.test.cjs -bun test tests/ci-workflows.test.ts -``` - -Expected: PASS. - -- [ ] **Step 5: Commit** - -```bash -git add tests/helpers/enforce-pr-target-harness.ts tests/ci-workflows.test.ts -git commit -m "test(ci): cover PR ancestry and description enforcement paths" -``` - ---- - -### Task 4: Docs and agent policy notes - -**Files:** -- Modify: `docs-site/src/content/docs/contributing.md` -- Modify: `AGENTS.md` -- Modify: `MAINTAINERS.md` - -- [ ] **Step 1: Contributing (English)** - -Add a short **Pull requests** subsection: - -- Target `dev` (or `dev2-go` only for scoped Go work); never open ordinary PRs at `main`. -- Branch from current `dev`, not from `main`. CI rejects heads that sit on the `main` tip while far behind the PR base (the #644 failure mode). -- Include a real description (Summary + Test plan, or equivalent substance). Empty, placeholder-only, or escaped-`\n` bodies fail the required `enforce-target` check. -- Note that `pull_request_target` workflow updates apply after promotion to the repository default branch (same ops caveat as #631). - -Do not bulk-edit ja/ko/ru/zh-cn in this task. - -- [ ] **Step 2: AGENTS.md / MAINTAINERS.md** - -One sentence each: CI rejects main-based ancestry into `dev`/`dev2-go` and empty/thin/malformed PR descriptions; push-permission authors skip the ancestry heuristic only. - -- [ ] **Step 3: Commit** - -```bash -git add docs-site/src/content/docs/contributing.md AGENTS.md MAINTAINERS.md -git commit -m "docs: document PR ancestry and description quality gates" -``` - ---- - -### Task 5: Final validation - -- [ ] **Step 1: Run required gates** - -```bash -node --test .github/scripts/pr-quality.test.cjs .github/scripts/enforce-pr-target.test.cjs -bun test tests/ci-workflows.test.ts -bun run typecheck -bun run privacy:scan -``` - -Expected: all PASS. - -- [ ] **Step 2: Docs-site build** - -```bash -cd docs-site && bun install --frozen-lockfile && bun run build -``` - -Expected: build succeeds. - -- [ ] **Step 3: Diff review** - -Confirm no unrelated files; no PR-head checkout; title prefix only on wrong base; description still enforced for maintainers. - ---- - -## Spec coverage checklist - -| Spec requirement | Task | -| --- | --- | -| Wrong ancestry rule + threshold 20 | Task 1 | -| Maintainer push escape hatch; fail-closed permission | Task 1–3 | -| Description option 2 | Task 1 | -| Collect all failures; draft + setFailed | Task 2–3 | -| No `[WRONG BRANCH]` for ancestry/description | Task 2–3 | -| `synchronize` trigger | Task 2–3 | -| Trusted checkout only | Task 2–3 | -| Unit + harness + ci-workflows tests | Task 1–3, 5 | -| Contributing + AGENTS/MAINTAINERS | Task 4 | -| Default-branch promotion ops note | Task 4 | - -## Placeholder / consistency self-review - -- No TBD/TODO left in steps. -- `collectPrQualityFailures` / `assessPrDescription` names consistent across tasks. -- Checkout action SHA matches issue-quality (`11bd7190…`). -- DEFAULT_PR body/compares updated so legacy harness scenarios stay green. diff --git a/docs/superpowers/specs/2026-07-26-oauth-reliability-integrity-design.md b/docs/superpowers/specs/2026-07-26-oauth-reliability-integrity-design.md deleted file mode 100644 index 60cbd7333d..0000000000 --- a/docs/superpowers/specs/2026-07-26-oauth-reliability-integrity-design.md +++ /dev/null @@ -1,113 +0,0 @@ -# OAuth Reliability and Client Integrity — Design - -**Date:** 2026-07-26 -**Branch:** `feat/oauth-reliability-integrity` -**Status:** Approved (Approach 1 + affinity policy A) - -## Goal - -Improve OAuth refresh reliability, token persistence safety, actionable diagnostics, and legitimate client-metadata integrity — without client impersonation, fingerprint spoofing, or rate-limit circumvention. - -## Product decisions - -1. **Approach 1 — Strengthen + surface:** generalize existing xAI/Anthropic lock+CAS patterns; add a thin health projection; wire status/doctor/dashboard. -2. **Affinity policy A:** keep current Codex pool behaviour: - - 401/403 → reauth quarantine + clear affinities - - 429 → cooldown + clear affinities + may rotate `activeCodexAccountId` - - Do **not** pin threads through 429 in this work -3. Affinity remains process-local (`threadAccountMap`); no new disk persistence. -4. Do not remove existing non-Codex adapter client headers (xAI/MiMo) in this work; Codex forward path must not fabricate official Codex identity. - -## Non-goals - -- Ban protection / anti-detection marketing or behaviour -- Fabricating `originator: codex_cli_rs`, official Codex versions, or device fingerprints -- Account rotation to bypass provider limits -- Automatic destructive doctor repairs -- New npm dependencies - -## Current architecture (baseline) - -```text -request - → client metadata (FORWARD_HEADERS / adapter headers) - → routeModel / resolveCodexAuthContext - → credential load (auth.json / codex-accounts.json) - → refresh if needed (tokenRefreshes ± file lock/CAS) - → provider request - → classify outcome → reauth / cooldown / failover - → atomic persist - → status / doctor / dashboard (thin OAuth surface today) -``` - -Existing strengths: in-process single-flight; atomic writes; xAI/Anthropic/Codex cross-process refresh locks + generation CAS; Codex cooldown/Retry-After/probe leases; Codex header passthrough with pool account injection. - -Gaps: generic OAuth providers lack cross-process refresh lock + CAS; no shared health projection; weak status/doctor/dashboard OAuth detail; no `maskAccountId`; sparse structured OAuth logs. - -## Design units - -### 1. Privacy helper — `maskAccountId` - -Extend `src/lib/privacy.ts` with account-id redaction (`account-…42` style). Use in CLI, doctor, logs, and dashboard secondary labels where full IDs are currently shown. - -### 2. Structured OAuth logger - -Small helper (e.g. `src/oauth/log.ts`) that emits one-line transition events with redacted account ids. Never logs tokens, auth headers, codes, or full account identifiers. - -### 3. Generalized locked refresh - -Extract/generalize the xAI/Anthropic pattern into a shared path for remaining OAuth providers in `refreshAndPersistAccessToken`: - -1. Acquire `createOAuthRefreshIntentLock(provider, accountId)` -2. Reload credential from store -3. If another writer already refreshed (generation changed + still valid) → return stored access -4. Call `def.refresh` -5. Persist via `mergeAccountCredential` with `expectedGeneration` (CAS) -6. On terminal failure → `markAccountNeedsReauthIfGeneration` -7. Release lock in `finally` -8. Keep in-process `tokenRefreshes` map as first-layer single-flight - -Preserve provider-specific branches (xAI Grok CLI adoption, Anthropic durable intent, Kiro local-cli import). - -### 4. Health projection - -New module (e.g. `src/oauth/health.ts`) projecting existing state into: - -```ts -type OAuthAccountHealth = - | { status: "healthy" } - | { status: "cooldown"; until: string; reason: "rate_limit" | "quota" } - | { status: "reauth_required"; reason: "unauthorized" | "forbidden" | "refresh_failed" } - | { status: "warning"; reason: "refresh_conflict" | "metadata_mismatch" | "stale_credentials" }; -``` - -Sources: `needsReauth`, Codex `upstreamHealth` cooldowns, refresh-intent / CAS conflict markers, incomplete credentials. Single projection consumed by status, doctor, management API, dashboard — no parallel stores. - -### 5. Diagnostics surfaces - -- **`ocx status`:** concise OAuth health block (provider, redacted account, status, reason/action or retry-after). -- **`ocx doctor`:** checks for writable credential store, single-flight/lock readiness, reauth, cooldown, incomplete credentials, refresh conflicts; each WARN includes recovery action. -- **Dashboard:** health badge on provider/account views with explanation + actions (reauthenticate, copy `ocx doctor`, retry after cooldown). Copy must say reliability/diagnostics — never “anti-ban”. - -### 6. Client metadata integrity (Codex path) - -Keep `FORWARD_HEADERS` passthrough. Ensure pool mode overwrites only auth + `chatgpt-account-id` to match selected credential. Add regression tests that genuine metadata is preserved and official-client values are not fabricated when absent. Treat untrusted remote identity headers as untrusted unless already authenticated by architecture. - -### 7. Documentation - -Update docs-site guides/reference: refresh coordination, cooldowns, affinity (process-local + policy A), preserved vs non-fabricated metadata, status/doctor usage, reauth, explicit statement that this cannot guarantee protection from provider enforcement. - -## Testing strategy - -TDD: failing test → implement → pass → commit per task. - -Cover: concurrent refresh → one IdP call; shared result; failed refresh clears single-flight; retry after failure; rotated refresh persisted; older result cannot overwrite newer; reload after lock; 401 path where applicable (one refresh + one retry); repeated auth failure → reauth; 403/429 policy A assertions; metadata pass-through + non-fabrication; status/doctor/dashboard; redaction; no secrets in logs. - -## Success criteria - -- Generic OAuth refresh uses file lock + generation CAS -- Health projection shared across CLI/API/UI -- Diagnostics actionable and redacted -- Codex metadata integrity tests green -- `bun run typecheck`, targeted OAuth tests, and full `bun run test` pass -- No impersonation / fingerprint spoofing / limit-bypass behaviour added diff --git a/docs/superpowers/specs/2026-07-28-pr-quality-gates-design.md b/docs/superpowers/specs/2026-07-28-pr-quality-gates-design.md deleted file mode 100644 index a5f00449b2..0000000000 --- a/docs/superpowers/specs/2026-07-28-pr-quality-gates-design.md +++ /dev/null @@ -1,173 +0,0 @@ -# PR quality gates (ancestry + description) — Design - -**Date:** 2026-07-28 -**Status:** Approved (brainstorm) -**Related:** #631 (wrong-base enforcer), #644 (motivating bad PR), `AGENTS.md` / `MAINTAINERS.md` branch table -**Branch base for implementation:** tip of #631 (`fix/enforce-pr-target-draft-fallback`) or `dev` after #631 merges - -## Problem - -`enforce-pr-target` only rejects wrong **base** refs (`main`, etc.). It does not catch: - -1. **Wrong ancestry** — head branched from `main` (or another release tip) while targeting `dev` / `dev2-go`, so the PR diff dumps already-released or unrelated commits into the integration branch (seen on #644: 0 behind `main`, 44 behind `dev`). -2. **Empty or low-quality descriptions** — blank bodies, comment-only bodies (e.g. only CodeRabbit release notes), placeholder-only text, literal `\n` escapes instead of real newlines, or thin bodies that lack a minimum “what/why” structure (option 2 from brainstorm). - -Wrong-base UX already drafts the PR, comments, and `setFailed`s the required check. New gates should reuse that pattern without overloading the `[WRONG BRANCH]` title prefix. - -## Goals - -- Fail the required `enforce-target` check when ancestry or description is unacceptable. -- Convert ready PRs to draft (soft-fail GraphQL, same as #631) and leave a single bot comment listing **all** open violations. -- Clear draft/comment/`setFailed` only when every gate passes (including after `synchronize` / body edits). -- Keep `pull_request_target` safe: **no checkout of PR head**; GitHub compare/API only; pure validators unit-tested offline. -- Escape hatch for maintainers with repo `push` so intentional release / promotion work is not blocked by the ancestry heuristic. - -## Non-goals - -- Rejecting local machine paths (`E:\…`), “tests not run” admissions, or forcing a fixed PR template (deferred). -- Auto-retargeting or auto-rebasing contributor branches. -- Retitling with `[WRONG BRANCH]` for ancestry/description (prefix stays wrong-**base** only). -- Blocking Dependabot / GitHub App bots beyond what the existing workflow already does (document any bot skips if added). - -## Approach - -**Extend the existing enforcer (Approach A):** extract pure checks into `.github/scripts/pr-quality.cjs`, orchestrate from `enforce-pr-target.yml` (or a thin shared runner), reuse draft/comment/`setFailed` state machine. - -Rejected alternatives: soft gate only (B — weaker); separate workflow (C — duplicated draft/comment machinery). - -## Gate composition - -Evaluate in order; collect **all** failures before mutating: - -1. **Wrong base** (existing) — `base ∉ {dev, dev2-go}` -2. **Wrong ancestry** (new) — when base is allowed -3. **Bad description** (new) — always when base is allowed (and optionally also when base is wrong, so authors fix body while retargeting; **default: run description whenever we have a PR body**, independent of ancestry) - -If any failure is active: - -- Upsert one bot comment (existing marker family, extended state) listing every open issue. -- Draft the PR if ready (soft-fail). -- `core.setFailed` with a concise summary (required check red). - -If previously active and now all clear: restore ready only if bot drafted; update comment to success; do not leave `setFailed`. - -## Wrong ancestry - -### Inputs (API only) - -For `base ∈ {dev, dev2-go}` and head SHA `H`: - -- `GET /repos/{owner}/{repo}/compare/main...{H}` → `{ ahead_by, behind_by }` -- `GET /repos/{owner}/{repo}/compare/{base}...{H}` → `{ ahead_by, behind_by }` - -No `actions/checkout` of the PR head. - -### Rule - -Flag **wrong ancestry** when: - -```text -behind_main === 0 -AND behind_base >= ANCESTRY_BEHIND_THRESHOLD # default 20 -``` - -This matches #644 (`behind_main = 0`, `behind_dev = 44`). - -Optional refinement (not required for v1): also require `ahead_main <= ahead_base` so a long-lived fork that somehow sits on `main` tip but is not dumping main-only commits is less likely to false-positive. Prefer shipping the two-clause rule first with tests against recorded compare fixtures. - -### Escape hatch - -Skip the ancestry gate when the PR author has **push** permission on the base repository (`GET /repos/{owner}/{repo}/collaborators/{login}/permission` → `admin` | `maintain` | `write`). Contributors / fork authors without push remain gated. - -Do **not** skip description quality for maintainers (empty/bad bodies remain rejected). - -### Threshold - -`ANCESTRY_BEHIND_THRESHOLD = 20` constant in the script. Document in comment why (tolerant of slightly stale `dev` forks; catches “branched from current main”). - -## Description quality (option 2) - -### Normalize body - -1. Strip HTML comments (`<!-- … -->`), including CodeRabbit release-notes blocks. -2. Trim; treat placeholder-only whole body / lines like issue-quality (`N/A`, `TODO`, `No response`, …) as empty. -3. Detect **escaped newlines**: if the cleaned body contains few or no real `\n` characters but contains the two-character sequence `\` + `n` (or `\` + `r` + `\` + `n`) as a dominant separator, classify as **malformed** (fail). #644’s API body showed literal `\n` sequences. - -### Accept when (after normalize) - -**Substantial structured content**, either: - -- **Structured path:** ≥ 2 markdown sections (h2–h4) whose cleaned text is each ≥ 40 characters, **or** -- **Unstructured path:** cleaned body length ≥ 120 characters **and** at least 2 bullets and/or paragraph breaks (real newlines separating non-empty blocks). - -### Reject when - -| Condition | Code / message key | -| --- | --- | -| Empty after strip | `empty` | -| Placeholder-only | `placeholder` | -| Escaped-newline malformed | `escaped_newlines` | -| Not substantial by either path | `thin` | - -Reuse helpers from `issue-quality.cjs` where practical (placeholder / section richness), or duplicate minimal copies to avoid coupling PR and issue workflows if import paths are awkward in Actions. Prefer shared tiny helpers over drift. - -## Workflow / UX - -### Triggers - -Extend `pull_request_target` types with **`synchronize`** so a rebase onto `dev` re-evaluates ancestry and can clear the failure. Keep: `opened`, `reopened`, `edited`, `ready_for_review`. - -### Comment shape - -Single bot comment (existing `<!-- wrong-branch-enforcer -->` marker **or** rename to a neutral `<!-- pr-quality-enforcer -->` with migration: accept either marker when finding the comment). Body sections: - -- Wrong target branch (existing copy) -- Wrong branch ancestry (rebase onto current `base`; do not open from `main`) -- Pull request description (what failed + what “good enough” means) - -Hidden JSON state extended with flags such as `ancestryFailed`, `descriptionFailed`, plus existing `autoDraftedByBot` / `titlePrefixedByBot` / `active`. - -Title prefix `[WRONG BRANCH]` remains **only** for wrong base. - -### Permissions - -Unchanged from #631: `contents: write` + `pull-requests: write` for draft GraphQL; still no untrusted checkout. - -## Testing - -| Layer | Coverage | -| --- | --- | -| `.github/scripts/pr-quality.test.cjs` | Pure rules: #644-like compare fixture fails ancestry; behind_main>0 passes; maintainer skip N/A at pure layer; empty / comment-only / escaped `\n` / thin / good structured / good unstructured bodies | -| `enforce-pr-target.test.cjs` / harness | Workflow wires `synchronize`; calls quality module; `setFailed` when ancestry or description fails; soft-fail draft still; no checkout | -| `tests/ci-workflows.test.ts` | Permissions + trigger types stay in sync | - -Offline fixtures only — no live GitHub in unit tests. - -## Docs / policy - -- Short note in contributing docs (docs-site) when user-facing: PRs must target `dev`, be based on current `dev` (not `main`), and include a real description. -- `AGENTS.md` / `MAINTAINERS.md` already define branch targets; add one sentence that CI rejects main-based ancestry and empty/thin PR bodies once shipped. -- Reminder: `pull_request_target` only picks up workflow changes after promotion to the **default branch** (and typically `dev` for fork PR path consistency) — same ops note as #631. - -## Security - -- No execution of PR head code. -- Compare API uses base-repo token; head SHA is attacker-influenced only as an opaque ref for compare (GitHub-side). Do not interpolate head ref into shell. -- Collaborator permission lookup is read-only; failure of that API should **fail closed for ancestry** (treat as non-maintainer) or soft-skip with warning — choose **fail closed** (apply ancestry gate) to avoid accidental bypass. - -## Rollout - -1. Land #631 if not already merged. -2. Implement this design on a follow-up branch from #631 tip / `dev`. -3. After merge + default-branch promotion, verify on a synthetic fork PR (main-based head → `dev`, empty body) that draft + red check appear, then fix body + rebase and confirm clear. - -## Open constants (locked for v1) - -| Name | Value | -| --- | --- | -| `ANCESTRY_BEHIND_THRESHOLD` | `20` | -| Min section length | `40` | -| Min rich sections | `2` | -| Unstructured min length | `120` | -| Unstructured min blocks | `2` | -| Release compare ref | `main` | diff --git a/docs/superpowers/specs/2026-08-02-pr-hygiene-design.md b/docs/superpowers/specs/2026-08-02-pr-hygiene-design.md deleted file mode 100644 index 884117fd80..0000000000 --- a/docs/superpowers/specs/2026-08-02-pr-hygiene-design.md +++ /dev/null @@ -1,20 +0,0 @@ -# Deterministic anti-slop CI — Design - -**Stack:** 4/5, based on `agent/pr-trust-lane` - -This layer rejects concrete defect patterns rather than guessing whether code was AI-generated. - -Blocking checks: - -- runtime or dashboard behavior changed without a test change; -- newly added TypeScript/lint/formatter suppressions; -- newly focused or skipped tests; -- empty catch blocks; -- committed generated build output; -- `bun.lock` churn without `package.json`. - -Narrow exception labels exist for cases that genuinely need maintainer judgment. Empty catches have no bypass because swallowing errors without behavior is not an acceptable implementation choice. - -The workflow reads PR patches through GitHub APIs using trusted default-branch code and never executes the PR head. - -Empty-catch detection scans hunk context as well as additions when a hunk deletes lines, so removing a catch body cannot bypass the rule. Removed generated files and removed test files are excluded from the generated-output and regression-coverage checks respectively. Exception labels are head-specific: a `synchronize` event revokes them so approvals cannot cover unreviewed new commits. diff --git a/gui/.eslint/i18n-allowlist.ts b/gui/.eslint/i18n-allowlist.ts index 83974db5a8..8652c6158f 100644 --- a/gui/.eslint/i18n-allowlist.ts +++ b/gui/.eslint/i18n-allowlist.ts @@ -25,8 +25,7 @@ const BRAND_LITERALS = new Set([ "Mimo", "Claude", "ChatGPT", - "OpenCodex", - "opencodex", + "CodexCommander", "OAuth", "API", ]); @@ -94,8 +93,9 @@ export function isTechnicalLiteral(value: string): boolean { // `^-H` rule above never sees it. Still a shell sample, still not translatable. The // leading run is one-or-more because the raw template text keeps the escape. if (/^\\+\s+-(?:H|d)\b/.test(trimmed)) return true; - if (/^ocx\b/i.test(trimmed)) return true; if (/^codex\b/i.test(trimmed)) return true; + if (/^ccx\b/i.test(trimmed)) return true; + if (/^codexcommander\b/i.test(trimmed)) return true; // HTTP headers / auth schemes if (/^Authorization\b/i.test(trimmed)) return true; diff --git a/gui/.npmignore b/gui/.npmignore index 7d48e6a122..93c2e0c2b9 100644 --- a/gui/.npmignore +++ b/gui/.npmignore @@ -1,5 +1,5 @@ # Present so npm uses THIS (not gui/.gitignore, which excludes dist/) for the gui/ subtree — -# otherwise the built gui/dist would never ship and `ocx gui` would 404 for installed users. +# otherwise the built gui/dist would never ship and `ccx gui` would 404 for installed users. # The root package.json "files" allowlist already narrows the package to gui/dist only. node_modules src diff --git a/gui/AGENTS.md b/gui/AGENTS.md index 61459e58b1..e7ce909b90 100644 --- a/gui/AGENTS.md +++ b/gui/AGENTS.md @@ -1,4 +1,4 @@ -# OpenCodex GUI — agent rules +# CodexCommander GUI — agent rules This file applies to `gui/` and inherits the repository-wide rules in `/AGENTS.md`. @@ -20,7 +20,7 @@ This file applies to `gui/` and inherits the repository-wide rules in `/AGENTS.m - **Company / product names** (e.g. OpenAI, Anthropic, GitHub, Codex). - **Model identifiers** from APIs/catalogs (e.g. `gpt-4o`, `deepseek-v4-flash-free`) when displaying provider data, not labels like "Default model". - **Technical / machine text** — do **not** put these in locale files: - - CLI/shell samples (`curl …`, `export VAR=…`, `ocx claude`) + - CLI/shell samples (`curl …`, `export VAR=…`, `ccx claude`) - Content inside `<pre>` / `<code>` - HTTP headers, env var names, protocol field dumps (`model=…`, `thinking`) - Units/abbreviations next to numbers (`ms`, `k`, `1M`, cache `c`/`w`) diff --git a/gui/README.md b/gui/README.md index d46ca34a5e..cd34337c51 100644 --- a/gui/README.md +++ b/gui/README.md @@ -1,6 +1,6 @@ -# opencodex dashboard +# CodexCommander dashboard -This is the Vite/React dashboard used by `ocx gui` in packaged installs. +This is the Vite/React dashboard used by `ccx gui` in packaged installs. ## Source checkout development @@ -27,7 +27,7 @@ bun run build:gui ``` That command installs/builds this dashboard and copies the production assets into -the package layout used by `ocx gui`. +the package layout used by `ccx gui`. ## Lint and React Doctor diff --git a/gui/bun.lock b/gui/bun.lock index 1c7e030ba9..a59c072eee 100644 --- a/gui/bun.lock +++ b/gui/bun.lock @@ -28,6 +28,7 @@ }, "overrides": { "brace-expansion": "5.0.9", + "nanoid": "3.3.17", "postcss": "8.5.18", }, "packages": { @@ -331,7 +332,7 @@ "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], - "nanoid": ["nanoid@3.3.12", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ=="], + "nanoid": ["nanoid@3.3.17", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-xQLf0A3HOMlgHq0n247/LRuAOYmB7dXJ/DvAxGvsSBij45XtBSmQycu+F8ODbHwns/XyFZagyL1+J0Offw1E0g=="], "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="], diff --git a/gui/index.html b/gui/index.html index 0210bc2145..e0c4b02f96 100644 --- a/gui/index.html +++ b/gui/index.html @@ -5,13 +5,13 @@ <link rel="icon" type="image/png" href="/favicon.png" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="color-scheme" content="light dark" /> - <title>opencodex · proxy dashboard + CodexCommander · proxy dashboard