@iislee/opencodex 2.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +225 -0
- package/assets/architecture.png +0 -0
- package/assets/banner.png +0 -0
- package/assets/claude-code-models.gif +0 -0
- package/assets/codex-app-picker.png +0 -0
- package/bin/ocx.mjs +451 -0
- package/bin/package-main.mjs +9 -0
- package/gui/dist/assets/index-DTpMHS4F.js +67 -0
- package/gui/dist/assets/index-ZNVDE3C7.css +1 -0
- package/gui/dist/favicon.png +0 -0
- package/gui/dist/icons.svg +24 -0
- package/gui/dist/index.html +25 -0
- package/gui/dist/logo.png +0 -0
- package/gui/dist/provider-icons/alibaba-color.svg +1 -0
- package/gui/dist/provider-icons/antigravity-color.svg +1 -0
- package/gui/dist/provider-icons/antigravity.svg +1 -0
- package/gui/dist/provider-icons/claude-color.svg +1 -0
- package/gui/dist/provider-icons/claude.svg +1 -0
- package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -0
- package/gui/dist/provider-icons/copilot-color.svg +1 -0
- package/gui/dist/provider-icons/copilot.svg +1 -0
- package/gui/dist/provider-icons/cursor-color.svg +2 -0
- package/gui/dist/provider-icons/cursor.svg +2 -0
- package/gui/dist/provider-icons/deepseek-color.svg +1 -0
- package/gui/dist/provider-icons/discord.svg +1 -0
- package/gui/dist/provider-icons/firepass-color.svg +1 -0
- package/gui/dist/provider-icons/fireworks-color.svg +1 -0
- package/gui/dist/provider-icons/gemini-color.svg +1 -0
- package/gui/dist/provider-icons/gemini.svg +1 -0
- package/gui/dist/provider-icons/github-copilot-color.svg +1 -0
- package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -0
- package/gui/dist/provider-icons/grok-color.svg +1 -0
- package/gui/dist/provider-icons/grok.svg +1 -0
- package/gui/dist/provider-icons/groq-color.svg +1 -0
- package/gui/dist/provider-icons/huggingface-color.svg +1 -0
- package/gui/dist/provider-icons/kimi-color.svg +1 -0
- package/gui/dist/provider-icons/kiro-color.svg +15 -0
- package/gui/dist/provider-icons/kiro.svg +14 -0
- package/gui/dist/provider-icons/lm-studio-color.svg +1 -0
- package/gui/dist/provider-icons/mistral-color.svg +1 -0
- package/gui/dist/provider-icons/moonshot-color.svg +1 -0
- package/gui/dist/provider-icons/nvidia-color.svg +1 -0
- package/gui/dist/provider-icons/ollama-color.svg +1 -0
- package/gui/dist/provider-icons/openai.svg +1 -0
- package/gui/dist/provider-icons/opencode.svg +1 -0
- package/gui/dist/provider-icons/openrouter-color.svg +1 -0
- package/gui/dist/provider-icons/pi.svg +21 -0
- package/gui/dist/provider-icons/qianfan-color.svg +1 -0
- package/gui/dist/provider-icons/qwen-portal-color.svg +1 -0
- package/gui/dist/provider-icons/telegram.svg +1 -0
- package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -0
- package/gui/dist/provider-icons/vllm-color.svg +1 -0
- package/gui/dist/provider-icons/xiaomi-color.svg +1 -0
- package/package.json +102 -0
- package/src/AGENTS.md +28 -0
- package/src/adapters/anthropic-image-guard.ts +251 -0
- package/src/adapters/anthropic-image-normalize.ts +518 -0
- package/src/adapters/anthropic.ts +1003 -0
- package/src/adapters/azure.ts +36 -0
- package/src/adapters/base.ts +72 -0
- package/src/adapters/client-fingerprint.ts +59 -0
- package/src/adapters/cursor/arg-codec.ts +38 -0
- package/src/adapters/cursor/arg-normalize.ts +104 -0
- package/src/adapters/cursor/cursor-errors.ts +165 -0
- package/src/adapters/cursor/discovery.ts +276 -0
- package/src/adapters/cursor/effort-map.ts +127 -0
- package/src/adapters/cursor/exec-policy.ts +88 -0
- package/src/adapters/cursor/framing.ts +211 -0
- package/src/adapters/cursor/gen/agent_pb.ts +15274 -0
- package/src/adapters/cursor/kv-store.ts +52 -0
- package/src/adapters/cursor/live-models.ts +153 -0
- package/src/adapters/cursor/live-smoke-gate.ts +41 -0
- package/src/adapters/cursor/live-transport.ts +1214 -0
- package/src/adapters/cursor/mcp-config.ts +42 -0
- package/src/adapters/cursor/mcp-manager.ts +333 -0
- package/src/adapters/cursor/message-mapper.ts +49 -0
- package/src/adapters/cursor/native-exec-common.ts +55 -0
- package/src/adapters/cursor/native-exec-desktop.ts +184 -0
- package/src/adapters/cursor/native-exec-fs.ts +329 -0
- package/src/adapters/cursor/native-exec-mcp.ts +153 -0
- package/src/adapters/cursor/native-exec-network.ts +43 -0
- package/src/adapters/cursor/native-exec-shell.ts +548 -0
- package/src/adapters/cursor/native-exec-tools.ts +118 -0
- package/src/adapters/cursor/native-exec.ts +576 -0
- package/src/adapters/cursor/protobuf-events.ts +563 -0
- package/src/adapters/cursor/protobuf-request.ts +714 -0
- package/src/adapters/cursor/request-builder.ts +255 -0
- package/src/adapters/cursor/thread-continuity.ts +67 -0
- package/src/adapters/cursor/tool-definitions.ts +505 -0
- package/src/adapters/cursor/transport-retry.ts +132 -0
- package/src/adapters/cursor/transport.ts +57 -0
- package/src/adapters/cursor/types.ts +52 -0
- package/src/adapters/cursor.ts +196 -0
- package/src/adapters/google-antigravity-replay.ts +303 -0
- package/src/adapters/google-antigravity-wire.ts +108 -0
- package/src/adapters/google-errors.ts +85 -0
- package/src/adapters/google-http.ts +100 -0
- package/src/adapters/google-tool-schema.ts +173 -0
- package/src/adapters/google-truncation.ts +13 -0
- package/src/adapters/google-wire-compiler.ts +232 -0
- package/src/adapters/google.ts +758 -0
- package/src/adapters/identity.ts +44 -0
- package/src/adapters/image.ts +23 -0
- package/src/adapters/kiro-constants.ts +16 -0
- package/src/adapters/kiro-errors.ts +197 -0
- package/src/adapters/kiro-events.ts +179 -0
- package/src/adapters/kiro-images.ts +129 -0
- package/src/adapters/kiro-retry.ts +312 -0
- package/src/adapters/kiro-thinking.ts +96 -0
- package/src/adapters/kiro-tool-fallback.ts +36 -0
- package/src/adapters/kiro-tools.ts +215 -0
- package/src/adapters/kiro-truncation.ts +33 -0
- package/src/adapters/kiro-wire.ts +129 -0
- package/src/adapters/kiro.ts +1898 -0
- package/src/adapters/mimo-free.ts +263 -0
- package/src/adapters/openai-chat.ts +1005 -0
- package/src/adapters/openai-responses.ts +1137 -0
- package/src/adapters/run-turn-queue.ts +114 -0
- package/src/adapters/tool-catalog-nudge.ts +71 -0
- package/src/adapters/upstream-http-error.ts +48 -0
- package/src/bridge.ts +1619 -0
- package/src/chat/inbound.ts +295 -0
- package/src/chat/outbound.ts +765 -0
- package/src/claude/agents-inject.ts +243 -0
- package/src/claude/alias.ts +149 -0
- package/src/claude/auth-detect.ts +229 -0
- package/src/claude/auth-mode-migration.ts +32 -0
- package/src/claude/auth-mode.ts +62 -0
- package/src/claude/context-windows.ts +189 -0
- package/src/claude/desktop-3p-guard.ts +35 -0
- package/src/claude/desktop-3p-paths.ts +84 -0
- package/src/claude/desktop-3p.ts +381 -0
- package/src/claude/desktop-health.ts +26 -0
- package/src/claude/desktop-profile.ts +263 -0
- package/src/claude/gateway-cache.ts +70 -0
- package/src/claude/inbound-debug.ts +163 -0
- package/src/claude/inbound.ts +509 -0
- package/src/claude/model-info.ts +151 -0
- package/src/claude/outbound.ts +872 -0
- package/src/cli/access.ts +108 -0
- package/src/cli/account-api.ts +268 -0
- package/src/cli/account-auth.ts +223 -0
- package/src/cli/account-extended.ts +350 -0
- package/src/cli/account.ts +275 -0
- package/src/cli/agent-driven.ts +70 -0
- package/src/cli/agent.ts +184 -0
- package/src/cli/catalog-prewarm.ts +27 -0
- package/src/cli/claude-desktop.ts +188 -0
- package/src/cli/claude.ts +286 -0
- package/src/cli/codex-shim-autorestore.ts +45 -0
- package/src/cli/combo.ts +119 -0
- package/src/cli/config-command.ts +145 -0
- package/src/cli/debug.ts +228 -0
- package/src/cli/doctor.ts +930 -0
- package/src/cli/export-command.ts +187 -0
- package/src/cli/help.ts +354 -0
- package/src/cli/index.ts +1113 -0
- package/src/cli/init.ts +224 -0
- package/src/cli/integrations.ts +142 -0
- package/src/cli/interactive-confirm.ts +133 -0
- package/src/cli/internal-dispatch.ts +20 -0
- package/src/cli/models-runtime.ts +212 -0
- package/src/cli/models.ts +336 -0
- package/src/cli/observe.ts +117 -0
- package/src/cli/opencode.ts +586 -0
- package/src/cli/pi.ts +188 -0
- package/src/cli/provider-runtime.ts +162 -0
- package/src/cli/provider.ts +463 -0
- package/src/cli/runtime-api.ts +325 -0
- package/src/cli/star-prompt.ts +155 -0
- package/src/cli/status-oauth.ts +78 -0
- package/src/cli/status.ts +321 -0
- package/src/cli/sync-cloud.ts +283 -0
- package/src/cli/system-command.ts +112 -0
- package/src/cli/tray-proxy.ts +52 -0
- package/src/cli/v2.ts +173 -0
- package/src/cli.ts +10 -0
- package/src/clients/config-export.ts +377 -0
- package/src/clients/effective-status.ts +385 -0
- package/src/clients/probes/agy.ts +55 -0
- package/src/clients/probes/cc-switch.ts +110 -0
- package/src/clients/probes/claude.ts +90 -0
- package/src/clients/probes/codex.ts +125 -0
- package/src/clients/probes/grok.ts +29 -0
- package/src/clients/probes/opencode.ts +109 -0
- package/src/clients/probes/paseo.ts +55 -0
- package/src/clients/probes/pi.ts +55 -0
- package/src/cloud/onedrive-auth.ts +666 -0
- package/src/cloud/onedrive-graph.ts +108 -0
- package/src/cloud/settings.ts +75 -0
- package/src/cloud/sync.ts +212 -0
- package/src/cloud/types.ts +56 -0
- package/src/cloud/vault.ts +89 -0
- package/src/codex/account-id.ts +34 -0
- package/src/codex/account-label.ts +34 -0
- package/src/codex/account-lifecycle.ts +55 -0
- package/src/codex/account-namespace-match.ts +63 -0
- package/src/codex/account-namespaces.ts +149 -0
- package/src/codex/account-pause.ts +20 -0
- package/src/codex/account-runtime-state.ts +31 -0
- package/src/codex/account-store.ts +517 -0
- package/src/codex/account-usability.ts +20 -0
- package/src/codex/app-server-processes.ts +756 -0
- package/src/codex/auth-api.ts +1540 -0
- package/src/codex/auth-collision.ts +107 -0
- package/src/codex/auth-context.ts +352 -0
- package/src/codex/autostart-health.ts +149 -0
- package/src/codex/catalog/aggregation.ts +378 -0
- package/src/codex/catalog/bundled.ts +251 -0
- package/src/codex/catalog/effort.ts +355 -0
- package/src/codex/catalog/metadata.ts +180 -0
- package/src/codex/catalog/parsing.ts +456 -0
- package/src/codex/catalog/provider-fetch.ts +902 -0
- package/src/codex/catalog/sync.ts +620 -0
- package/src/codex/catalog.ts +12 -0
- package/src/codex/data/upstream-models.json +830 -0
- package/src/codex/exec-invocation.ts +22 -0
- package/src/codex/features.ts +969 -0
- package/src/codex/history-migration-guardian.ts +102 -0
- package/src/codex/history-provider.ts +776 -0
- package/src/codex/home.ts +206 -0
- package/src/codex/inject.ts +799 -0
- package/src/codex/injected-marker.ts +72 -0
- package/src/codex/journal.ts +163 -0
- package/src/codex/main-account-cache.ts +32 -0
- package/src/codex/main-account.ts +40 -0
- package/src/codex/model-cache.ts +227 -0
- package/src/codex/paths.ts +65 -0
- package/src/codex/plugins-doctor.ts +242 -0
- package/src/codex/pool-rotation.ts +225 -0
- package/src/codex/project-config-warnings.ts +411 -0
- package/src/codex/quota.ts +411 -0
- package/src/codex/refresh.ts +53 -0
- package/src/codex/routing.ts +1477 -0
- package/src/codex/runtime.ts +538 -0
- package/src/codex/shim.ts +1189 -0
- package/src/codex/subagent-defaults.ts +550 -0
- package/src/codex/subagent-model-fallback.ts +469 -0
- package/src/codex/sync.ts +130 -0
- package/src/codex/warmup.ts +192 -0
- package/src/codex/websocket-registry.ts +100 -0
- package/src/combos/failover.ts +140 -0
- package/src/combos/index.ts +41 -0
- package/src/combos/request.ts +62 -0
- package/src/combos/resolve.ts +232 -0
- package/src/combos/types.ts +326 -0
- package/src/config.ts +2356 -0
- package/src/generated/jawcode-model-metadata.ts +104 -0
- package/src/github/star-state.ts +203 -0
- package/src/grok/inject.ts +545 -0
- package/src/grok/status.ts +121 -0
- package/src/grok/sync.ts +103 -0
- package/src/grok/usage-hook/report.mjs +348 -0
- package/src/grok/usage-hook.ts +278 -0
- package/src/images/artifacts.ts +516 -0
- package/src/images/fulfill-video.ts +163 -0
- package/src/images/fulfill.ts +149 -0
- package/src/images/index.ts +4 -0
- package/src/images/loop.ts +829 -0
- package/src/images/plan.ts +133 -0
- package/src/images/synthetic-tool.ts +133 -0
- package/src/images/types.ts +41 -0
- package/src/images/xai-client.ts +141 -0
- package/src/images/xai-video-client.ts +163 -0
- package/src/index.ts +22 -0
- package/src/lib/abort.ts +146 -0
- package/src/lib/admin-secrets.ts +25 -0
- package/src/lib/admission.ts +83 -0
- package/src/lib/app-owned-memory-stores.ts +173 -0
- package/src/lib/app-owned-memory.ts +265 -0
- package/src/lib/bounded-body.ts +202 -0
- package/src/lib/bun-binary-validator.d.mts +3 -0
- package/src/lib/bun-binary-validator.mjs +18 -0
- package/src/lib/bun-runtime.ts +71 -0
- package/src/lib/bun-stream-caps.ts +126 -0
- package/src/lib/config-ownership.ts +360 -0
- package/src/lib/crash-guard.ts +344 -0
- package/src/lib/debug-log-buffer.ts +83 -0
- package/src/lib/debug-settings.ts +108 -0
- package/src/lib/debug.ts +31 -0
- package/src/lib/destination-policy.ts +316 -0
- package/src/lib/errors.ts +364 -0
- package/src/lib/eventstream-decoder.ts +253 -0
- package/src/lib/gcp-adc.ts +341 -0
- package/src/lib/injection-debug-log.ts +58 -0
- package/src/lib/open-url.ts +25 -0
- package/src/lib/pinned-http.ts +151 -0
- package/src/lib/privacy.ts +20 -0
- package/src/lib/process-control.ts +165 -0
- package/src/lib/provider-outbound.ts +170 -0
- package/src/lib/provider-url.ts +14 -0
- package/src/lib/proxy-env.ts +18 -0
- package/src/lib/redact.ts +105 -0
- package/src/lib/retry-after.ts +55 -0
- package/src/lib/service-secrets.ts +25 -0
- package/src/lib/shadow-call.ts +30 -0
- package/src/lib/sidecar-tracker.ts +52 -0
- package/src/lib/sse-decoder.ts +323 -0
- package/src/lib/state-store-registrations.ts +109 -0
- package/src/lib/state-store-sweeper.ts +184 -0
- package/src/lib/test-home-guard.ts +90 -0
- package/src/lib/token-estimate.ts +69 -0
- package/src/lib/translator-budget.ts +356 -0
- package/src/lib/upstream-retry.ts +239 -0
- package/src/lib/win-exec.ts +115 -0
- package/src/lib/win-paths.ts +68 -0
- package/src/lib/windows-elevation.ts +705 -0
- package/src/lib/windows-secret-acl.ts +514 -0
- package/src/lib/winsw.ts +375 -0
- package/src/oauth/anthropic-routing.ts +594 -0
- package/src/oauth/anthropic.ts +177 -0
- package/src/oauth/callback-server.ts +294 -0
- package/src/oauth/chatgpt.ts +150 -0
- package/src/oauth/cursor.ts +211 -0
- package/src/oauth/github-copilot.ts +428 -0
- package/src/oauth/google-antigravity.ts +230 -0
- package/src/oauth/health.ts +399 -0
- package/src/oauth/index.ts +1174 -0
- package/src/oauth/key-providers.ts +108 -0
- package/src/oauth/kimi.ts +213 -0
- package/src/oauth/kiro-credentials.ts +726 -0
- package/src/oauth/kiro.ts +577 -0
- package/src/oauth/local-token-detect.ts +121 -0
- package/src/oauth/log.ts +48 -0
- package/src/oauth/login-cli.ts +163 -0
- package/src/oauth/pkce.ts +15 -0
- package/src/oauth/store.ts +630 -0
- package/src/oauth/token-guardian.ts +303 -0
- package/src/oauth/types.ts +62 -0
- package/src/oauth/xai.ts +241 -0
- package/src/pi/extensions.ts +72 -0
- package/src/pi/home.ts +42 -0
- package/src/pi/index.ts +40 -0
- package/src/pi/models.ts +278 -0
- package/src/pi/packages.ts +219 -0
- package/src/pi/settings.ts +365 -0
- package/src/pi/status.ts +68 -0
- package/src/pi/sync.ts +75 -0
- package/src/providers/alibaba-region-backup.ts +75 -0
- package/src/providers/alibaba-region-migration.ts +156 -0
- package/src/providers/alibaba-region-startup.ts +36 -0
- package/src/providers/antigravity-models.ts +205 -0
- package/src/providers/api-keys.ts +140 -0
- package/src/providers/base-url-choices.ts +64 -0
- package/src/providers/context-cap.ts +65 -0
- package/src/providers/derive.ts +339 -0
- package/src/providers/free-directory.ts +184 -0
- package/src/providers/github-copilot-transport.ts +56 -0
- package/src/providers/key-failover.ts +203 -0
- package/src/providers/kiro-models.ts +67 -0
- package/src/providers/label.ts +19 -0
- package/src/providers/model-discovery.ts +356 -0
- package/src/providers/openai-sidecar.ts +175 -0
- package/src/providers/openai-tier-startup.ts +27 -0
- package/src/providers/openai-tiers.ts +301 -0
- package/src/providers/openai-virtual-models.ts +82 -0
- package/src/providers/openrouter-routing.ts +102 -0
- package/src/providers/provider-id-rewrite.ts +150 -0
- package/src/providers/quota.ts +1260 -0
- package/src/providers/registry.ts +1600 -0
- package/src/providers/slug-codec.ts +67 -0
- package/src/providers/xai-transport.ts +141 -0
- package/src/reasoning-effort.ts +135 -0
- package/src/responses/compaction.ts +117 -0
- package/src/responses/parser.ts +656 -0
- package/src/responses/reasoning-envelope.ts +52 -0
- package/src/responses/schema.ts +159 -0
- package/src/responses/spill-store.ts +394 -0
- package/src/responses/state.ts +895 -0
- package/src/responses/tool-groups.ts +19 -0
- package/src/router.ts +425 -0
- package/src/server/adapter-resolve.ts +80 -0
- package/src/server/auth-cors.ts +530 -0
- package/src/server/chat-completions.ts +368 -0
- package/src/server/claude-messages.ts +914 -0
- package/src/server/effort-policy.ts +172 -0
- package/src/server/gui-static.ts +123 -0
- package/src/server/image-retry.ts +42 -0
- package/src/server/images.ts +476 -0
- package/src/server/index.ts +1126 -0
- package/src/server/lifecycle.ts +227 -0
- package/src/server/live.ts +598 -0
- package/src/server/management/agent-settings-routes.ts +1169 -0
- package/src/server/management/api-access.ts +141 -0
- package/src/server/management/api-key-usage.ts +167 -0
- package/src/server/management/body.ts +35 -0
- package/src/server/management/clients-routes.ts +63 -0
- package/src/server/management/cloud-sync-routes.ts +266 -0
- package/src/server/management/combo-routes.ts +220 -0
- package/src/server/management/config-routes.ts +422 -0
- package/src/server/management/context.ts +31 -0
- package/src/server/management/logs-usage-routes.ts +707 -0
- package/src/server/management/model-routes.ts +525 -0
- package/src/server/management/oauth-account-routes.ts +563 -0
- package/src/server/management/provider-routes.ts +556 -0
- package/src/server/management/shared.ts +277 -0
- package/src/server/management/sidebar-routes.ts +90 -0
- package/src/server/management/system-restart.ts +179 -0
- package/src/server/management/system-routes.ts +117 -0
- package/src/server/management/usage-summary-cache.ts +86 -0
- package/src/server/management-api.ts +215 -0
- package/src/server/management-auth.ts +267 -0
- package/src/server/memory-watchdog.ts +156 -0
- package/src/server/port-reclaim.ts +307 -0
- package/src/server/ports.ts +116 -0
- package/src/server/proxy-liveness.ts +201 -0
- package/src/server/relay-eager.ts +313 -0
- package/src/server/relay.ts +1049 -0
- package/src/server/request-decompress.ts +132 -0
- package/src/server/request-log-conversation.ts +168 -0
- package/src/server/request-log.ts +1046 -0
- package/src/server/responses/collaboration.ts +354 -0
- package/src/server/responses/compact.ts +384 -0
- package/src/server/responses/core.ts +2758 -0
- package/src/server/responses/encrypted-payload.ts +308 -0
- package/src/server/responses/fetch-helpers.ts +157 -0
- package/src/server/responses/passthrough-error.ts +78 -0
- package/src/server/responses/terminal-guard.ts +230 -0
- package/src/server/responses/upstream-error.ts +48 -0
- package/src/server/responses-image-gen-repair.ts +132 -0
- package/src/server/responses-item-id-repair.ts +224 -0
- package/src/server/responses.ts +9 -0
- package/src/server/search.ts +136 -0
- package/src/server/sse-payload-rewrite.ts +175 -0
- package/src/server/startup-action-control.ts +308 -0
- package/src/server/startup-health-cache.ts +113 -0
- package/src/server/system-env.ts +413 -0
- package/src/server/windows-tcp-drop.ts +184 -0
- package/src/server/windows-tray-control.ts +41 -0
- package/src/server/ws-bridge.ts +471 -0
- package/src/service.ts +2554 -0
- package/src/stall-timeout.ts +20 -0
- package/src/storage/cleanup-job.ts +57 -0
- package/src/storage/cleanup.ts +3085 -0
- package/src/storage/policy-job.ts +457 -0
- package/src/storage/policy-scheduler.ts +40 -0
- package/src/storage/policy-worker.ts +59 -0
- package/src/storage/policy.ts +527 -0
- package/src/storage/restore-job.ts +299 -0
- package/src/storage/restore-worker.ts +58 -0
- package/src/storage/scanner.ts +238 -0
- package/src/storage/storage-mutation-coordinator.ts +139 -0
- package/src/storage/worker-lifecycle.ts +215 -0
- package/src/tray/assets/opencodex-tray-offline.ico +0 -0
- package/src/tray/assets/opencodex-tray-online.ico +0 -0
- package/src/tray/assets/opencodex-tray-warning.ico +0 -0
- package/src/tray/assets/opencodex-tray.png +0 -0
- package/src/tray/windows-tray.ps1 +290 -0
- package/src/tray/windows.ts +730 -0
- package/src/types.ts +1237 -0
- package/src/update/badge.ts +72 -0
- package/src/update/index.ts +407 -0
- package/src/update/job.ts +1520 -0
- package/src/update/notify.ts +257 -0
- package/src/update/npm-invocation.d.mts +23 -0
- package/src/update/npm-invocation.mjs +94 -0
- package/src/update/tray-update-plan.d.mts +18 -0
- package/src/update/tray-update-plan.mjs +38 -0
- package/src/usage/cost.ts +0 -0
- package/src/usage/debug.ts +97 -0
- package/src/usage/expected-prices.ts +164 -0
- package/src/usage/log.ts +658 -0
- package/src/usage/summary.ts +585 -0
- package/src/usage/totals.ts +14 -0
- package/src/vision/anthropic-describe.ts +185 -0
- package/src/vision/describe.ts +125 -0
- package/src/vision/index.ts +467 -0
- package/src/web-search/anthropic-executor.ts +189 -0
- package/src/web-search/executor.ts +105 -0
- package/src/web-search/format-result.ts +89 -0
- package/src/web-search/index.ts +196 -0
- package/src/web-search/loop.ts +664 -0
- package/src/web-search/parse.ts +220 -0
- package/src/web-search/progress-stream.ts +342 -0
- package/src/web-search/synthetic-tool.ts +47 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { OcxProviderConfig } from "../types";
|
|
2
|
+
import { deriveKeyLoginMap, enrichProviderFromRegistry, type DerivedKeyLoginProvider } from "../providers/derive";
|
|
3
|
+
import { resolveProviderModelDiscoveryUrl } from "../providers/model-discovery";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* API-key "login" providers: not OAuth — the flow opens the provider's dashboard so the user can
|
|
7
|
+
* create/copy a key, then validates + stores it as the provider's `apiKey` (authMode "key").
|
|
8
|
+
* Most use the OpenAI-compatible chat API (`openai-chat` adapter, `Authorization: Bearer <key>`); a
|
|
9
|
+
* few expose only an Anthropic-compatible endpoint and set `adapter: "anthropic"` (default
|
|
10
|
+
* `x-api-key`, optional bearer via `apiKeyTransport`).
|
|
11
|
+
*/
|
|
12
|
+
export interface KeyLoginProvider extends DerivedKeyLoginProvider {}
|
|
13
|
+
|
|
14
|
+
export const KEY_LOGIN_PROVIDERS: Record<string, KeyLoginProvider> = deriveKeyLoginMap();
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Copy a registry entry's seed/classification (`models`, `liveModels`, `noVisionModels`,
|
|
18
|
+
* `noReasoningModels`, `defaultModel`) onto a provider config being created, for any field the
|
|
19
|
+
* caller didn't already supply. Lets the vision/reasoning classification actually reach the saved
|
|
20
|
+
* config (the GUI/API only send adapter/baseUrl/apiKey/defaultModel). No-op for unknown names.
|
|
21
|
+
*/
|
|
22
|
+
export function enrichProviderFromCatalog(name: string, prov: OcxProviderConfig): void {
|
|
23
|
+
enrichProviderFromRegistry(name, prov);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function isKeyLoginProvider(name: string): boolean {
|
|
27
|
+
return name in KEY_LOGIN_PROVIDERS;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function listKeyLoginProviders(): Array<{ id: string } & KeyLoginProvider> {
|
|
31
|
+
return Object.entries(KEY_LOGIN_PROVIDERS).map(([id, p]) => ({ id, ...p }));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function anthropicKeyValidationHeaders(provider: Pick<KeyLoginProvider, "apiKeyTransport">, key: string): HeadersInit {
|
|
35
|
+
return provider.apiKeyTransport === "bearer"
|
|
36
|
+
? {
|
|
37
|
+
"Content-Type": "application/json",
|
|
38
|
+
"anthropic-version": "2023-06-01",
|
|
39
|
+
"Authorization": `Bearer ${key}`,
|
|
40
|
+
}
|
|
41
|
+
: {
|
|
42
|
+
"Content-Type": "application/json",
|
|
43
|
+
"anthropic-version": "2023-06-01",
|
|
44
|
+
"x-api-key": key,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Best-effort key validation. Returns true/false/unknown; never persists the key itself. */
|
|
49
|
+
export async function validateApiKey(
|
|
50
|
+
providerName: string,
|
|
51
|
+
provider: KeyLoginProvider,
|
|
52
|
+
key: string,
|
|
53
|
+
): Promise<boolean | "unknown"> {
|
|
54
|
+
try {
|
|
55
|
+
if (provider.adapter === "anthropic") {
|
|
56
|
+
const base = provider.baseUrl.replace(/\/v1\/?$/, "");
|
|
57
|
+
const res = await fetch(`${base}/v1/messages`, {
|
|
58
|
+
method: "POST",
|
|
59
|
+
headers: anthropicKeyValidationHeaders(provider, key),
|
|
60
|
+
body: JSON.stringify({
|
|
61
|
+
model: provider.defaultModel ?? "claude-haiku-4-5",
|
|
62
|
+
max_tokens: 1,
|
|
63
|
+
messages: [{ role: "user", content: "ping" }],
|
|
64
|
+
}),
|
|
65
|
+
redirect: "error",
|
|
66
|
+
signal: AbortSignal.timeout(8000),
|
|
67
|
+
});
|
|
68
|
+
if (res.ok) return true;
|
|
69
|
+
if (res.status === 401 || res.status === 403) return false;
|
|
70
|
+
return "unknown";
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (provider.adapter === "google" && (provider.googleMode ?? "ai-studio") === "ai-studio") {
|
|
74
|
+
// Generative Language API rejects Bearer-wrapped API keys; probe models.list with the
|
|
75
|
+
// documented x-goog-api-key header instead (pageSize=1 — validation only needs a 200).
|
|
76
|
+
const res = await fetch(`${provider.baseUrl}/v1beta/models?pageSize=1`, {
|
|
77
|
+
headers: { "x-goog-api-key": key },
|
|
78
|
+
redirect: "error",
|
|
79
|
+
signal: AbortSignal.timeout(8000),
|
|
80
|
+
});
|
|
81
|
+
if (res.ok) return true;
|
|
82
|
+
if (res.status === 400 || res.status === 401 || res.status === 403) return false;
|
|
83
|
+
return "unknown";
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const configuredProvider: OcxProviderConfig = {
|
|
87
|
+
adapter: provider.adapter,
|
|
88
|
+
baseUrl: provider.baseUrl,
|
|
89
|
+
authMode: "key",
|
|
90
|
+
};
|
|
91
|
+
const modelsUrl = resolveProviderModelDiscoveryUrl(
|
|
92
|
+
providerName,
|
|
93
|
+
configuredProvider,
|
|
94
|
+
provider.baseUrl,
|
|
95
|
+
`${provider.baseUrl}/models`,
|
|
96
|
+
);
|
|
97
|
+
const res = await fetch(modelsUrl, {
|
|
98
|
+
headers: { Authorization: `Bearer ${key}` },
|
|
99
|
+
redirect: "error",
|
|
100
|
+
signal: AbortSignal.timeout(8000),
|
|
101
|
+
});
|
|
102
|
+
if (res.ok) return true;
|
|
103
|
+
if (res.status === 401 || res.status === 403) return false;
|
|
104
|
+
return "unknown";
|
|
105
|
+
} catch {
|
|
106
|
+
return "unknown";
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/** Kimi Code OAuth flow (device authorization grant). Ported from jawcode oauth/kimi.ts. */
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
import * as os from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { randomUUID } from "node:crypto";
|
|
6
|
+
import { recordOwnedConfigPath } from "../lib/config-ownership";
|
|
7
|
+
import { getConfigDir } from "../config";
|
|
8
|
+
import type { OAuthController, OAuthCredentials } from "./types";
|
|
9
|
+
|
|
10
|
+
const CLIENT_ID = "17e5f671-d194-4dfb-9706-5516cb48c098";
|
|
11
|
+
const DEFAULT_OAUTH_HOST = "https://auth.kimi.com";
|
|
12
|
+
const DEVICE_ID_FILENAME = "kimi-device-id";
|
|
13
|
+
const DEFAULT_POLL_INTERVAL_MS = 5000;
|
|
14
|
+
const DEFAULT_DEVICE_FLOW_TTL_MS = 15 * 60 * 1000;
|
|
15
|
+
const OAUTH_EXPIRY_SKEW_MS = 5 * 60 * 1000;
|
|
16
|
+
const KIMI_CLI_VERSION = "0.14.0";
|
|
17
|
+
|
|
18
|
+
interface DeviceAuthorizationResponse {
|
|
19
|
+
user_code?: string;
|
|
20
|
+
device_code?: string;
|
|
21
|
+
verification_uri?: string;
|
|
22
|
+
verification_uri_complete?: string;
|
|
23
|
+
expires_in?: number;
|
|
24
|
+
interval?: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface TokenResponse {
|
|
28
|
+
access_token?: string;
|
|
29
|
+
refresh_token?: string;
|
|
30
|
+
expires_in?: number;
|
|
31
|
+
error?: string;
|
|
32
|
+
error_description?: string;
|
|
33
|
+
interval?: number;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface KimiJwtPayload {
|
|
37
|
+
user_id?: unknown;
|
|
38
|
+
sub?: unknown;
|
|
39
|
+
email?: unknown;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function decodeKimiJwtPayload(token: string): KimiJwtPayload | undefined {
|
|
43
|
+
const parts = token.split(".");
|
|
44
|
+
const payload = parts[1];
|
|
45
|
+
if (parts.length !== 3 || !payload) return undefined;
|
|
46
|
+
try {
|
|
47
|
+
return JSON.parse(Buffer.from(payload, "base64url").toString("utf-8")) as KimiJwtPayload;
|
|
48
|
+
} catch {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function nonEmptyString(value: unknown): string | undefined {
|
|
54
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Stable multiauth identity from Kimi JWTs. `user_id` is preferred ACROSS both tokens
|
|
59
|
+
* before falling back to `sub` — the two claims come from the same issuer namespace but
|
|
60
|
+
* `sub` is the weaker fallback, so a refresh-token `user_id` must beat an access-token
|
|
61
|
+
* `sub`. Email fills from either token and is lowercased.
|
|
62
|
+
*/
|
|
63
|
+
export function identityFromKimiTokens(accessToken: string, refreshToken?: string): {
|
|
64
|
+
accountId?: string;
|
|
65
|
+
email?: string;
|
|
66
|
+
} {
|
|
67
|
+
const access = decodeKimiJwtPayload(accessToken);
|
|
68
|
+
const refresh = refreshToken ? decodeKimiJwtPayload(refreshToken) : undefined;
|
|
69
|
+
const accountId =
|
|
70
|
+
nonEmptyString(access?.user_id) ??
|
|
71
|
+
nonEmptyString(refresh?.user_id) ??
|
|
72
|
+
nonEmptyString(access?.sub) ??
|
|
73
|
+
nonEmptyString(refresh?.sub);
|
|
74
|
+
const email = (nonEmptyString(access?.email) ?? nonEmptyString(refresh?.email))?.toLowerCase();
|
|
75
|
+
return {
|
|
76
|
+
...(accountId ? { accountId } : {}),
|
|
77
|
+
...(email ? { email } : {}),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function resolveOAuthHost(): string {
|
|
82
|
+
return process.env.KIMI_CODE_OAUTH_HOST || process.env.KIMI_OAUTH_HOST || DEFAULT_OAUTH_HOST;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function sleep(ms: number, signal?: AbortSignal): Promise<void> {
|
|
86
|
+
return new Promise((resolve, reject) => {
|
|
87
|
+
if (signal?.aborted) return reject(new Error("Login cancelled"));
|
|
88
|
+
const t = setTimeout(resolve, ms);
|
|
89
|
+
signal?.addEventListener("abort", () => { clearTimeout(t); reject(new Error("Login cancelled")); }, { once: true });
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function getDeviceModel(): string {
|
|
94
|
+
const platform = os.platform();
|
|
95
|
+
const label = platform === "darwin" ? "macOS" : platform === "win32" ? "Windows" : platform === "linux" ? "Linux" : platform;
|
|
96
|
+
return [label, os.release(), os.arch()].filter(Boolean).join(" ").trim();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
let deviceIdCache: string | undefined;
|
|
100
|
+
function getDeviceId(): string {
|
|
101
|
+
if (deviceIdCache) return deviceIdCache;
|
|
102
|
+
const p = join(getConfigDir(), DEVICE_ID_FILENAME);
|
|
103
|
+
try {
|
|
104
|
+
const existing = readFileSync(p, "utf-8").trim();
|
|
105
|
+
if (existing) { deviceIdCache = existing; return existing; }
|
|
106
|
+
} catch (e) {
|
|
107
|
+
if ((e as { code?: string })?.code !== "ENOENT") throw e;
|
|
108
|
+
}
|
|
109
|
+
const id = randomUUID().replace(/-/g, "");
|
|
110
|
+
recordOwnedConfigPath(getConfigDir(), p);
|
|
111
|
+
if (!existsSync(getConfigDir())) mkdirSync(getConfigDir(), { recursive: true });
|
|
112
|
+
writeFileSync(p, id + "\n", { mode: 0o600 });
|
|
113
|
+
deviceIdCache = id;
|
|
114
|
+
return id;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function getKimiCommonHeaders(): Record<string, string> {
|
|
118
|
+
return {
|
|
119
|
+
"User-Agent": `KimiCLI/${KIMI_CLI_VERSION}`,
|
|
120
|
+
"X-Msh-Platform": "kimi_code_cli",
|
|
121
|
+
"X-Msh-Version": KIMI_CLI_VERSION,
|
|
122
|
+
"X-Msh-Device-Name": os.hostname(),
|
|
123
|
+
"X-Msh-Device-Model": getDeviceModel(),
|
|
124
|
+
"X-Msh-Os-Version": os.version(),
|
|
125
|
+
"X-Msh-Device-Id": getDeviceId(),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async function requestDeviceAuthorization(): Promise<{
|
|
130
|
+
userCode: string; deviceCode: string; verificationUriComplete: string; expiresInMs: number; intervalMs: number;
|
|
131
|
+
}> {
|
|
132
|
+
const response = await fetch(`${resolveOAuthHost()}/api/oauth/device_authorization`, {
|
|
133
|
+
method: "POST",
|
|
134
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded", ...getKimiCommonHeaders() },
|
|
135
|
+
body: new URLSearchParams({ client_id: CLIENT_ID }),
|
|
136
|
+
});
|
|
137
|
+
if (!response.ok) {
|
|
138
|
+
throw new Error(`Kimi device authorization failed: ${response.status} ${await response.text()}`);
|
|
139
|
+
}
|
|
140
|
+
const payload = (await response.json()) as DeviceAuthorizationResponse;
|
|
141
|
+
if (!payload.user_code || !payload.device_code || !payload.verification_uri) {
|
|
142
|
+
throw new Error("Kimi device authorization response missing required fields");
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
userCode: payload.user_code,
|
|
146
|
+
deviceCode: payload.device_code,
|
|
147
|
+
verificationUriComplete: payload.verification_uri_complete || payload.verification_uri,
|
|
148
|
+
expiresInMs: typeof payload.expires_in === "number" ? payload.expires_in * 1000 : DEFAULT_DEVICE_FLOW_TTL_MS,
|
|
149
|
+
intervalMs: typeof payload.interval === "number" && payload.interval > 0 ? payload.interval * 1000 : DEFAULT_POLL_INTERVAL_MS,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function parseTokenPayload(payload: TokenResponse, refreshFallback?: string): OAuthCredentials {
|
|
154
|
+
if (!payload.access_token || typeof payload.expires_in !== "number") {
|
|
155
|
+
throw new Error("Kimi token response missing required fields");
|
|
156
|
+
}
|
|
157
|
+
const refresh = payload.refresh_token ?? refreshFallback;
|
|
158
|
+
if (!refresh) throw new Error("Kimi token response missing refresh token");
|
|
159
|
+
const identity = identityFromKimiTokens(payload.access_token, refresh);
|
|
160
|
+
return {
|
|
161
|
+
access: payload.access_token,
|
|
162
|
+
refresh,
|
|
163
|
+
expires: Date.now() + payload.expires_in * 1000 - OAUTH_EXPIRY_SKEW_MS,
|
|
164
|
+
...identity,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
async function pollForToken(deviceCode: string, intervalMs: number, expiresInMs: number, signal?: AbortSignal): Promise<OAuthCredentials> {
|
|
169
|
+
const deadline = Date.now() + expiresInMs;
|
|
170
|
+
let waitMs = Math.max(1000, intervalMs);
|
|
171
|
+
while (Date.now() < deadline) {
|
|
172
|
+
if (signal?.aborted) throw new Error("Login cancelled");
|
|
173
|
+
const response = await fetch(`${resolveOAuthHost()}/api/oauth/token`, {
|
|
174
|
+
method: "POST",
|
|
175
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded", ...getKimiCommonHeaders() },
|
|
176
|
+
body: new URLSearchParams({ client_id: CLIENT_ID, device_code: deviceCode, grant_type: "urn:ietf:params:oauth:grant-type:device_code" }),
|
|
177
|
+
});
|
|
178
|
+
const payload = (await response.json()) as TokenResponse;
|
|
179
|
+
if (response.ok && payload.access_token) return parseTokenPayload(payload);
|
|
180
|
+
const error = payload.error;
|
|
181
|
+
if (error === "authorization_pending") { await sleep(waitMs, signal); continue; }
|
|
182
|
+
if (error === "slow_down") {
|
|
183
|
+
waitMs += 5000;
|
|
184
|
+
const retryAfter = typeof payload.interval === "number" ? payload.interval * 1000 : undefined;
|
|
185
|
+
if (retryAfter && retryAfter > waitMs) waitMs = retryAfter;
|
|
186
|
+
await sleep(waitMs, signal);
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
if (error === "expired_token") throw new Error("Kimi device authorization expired");
|
|
190
|
+
if (error === "access_denied") throw new Error("Kimi device authorization denied");
|
|
191
|
+
throw new Error(`Kimi device flow failed: ${error ?? response.status}${payload.error_description ? `: ${payload.error_description}` : ""}`);
|
|
192
|
+
}
|
|
193
|
+
throw new Error("Kimi device flow timed out");
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export async function loginKimi(ctrl: OAuthController): Promise<OAuthCredentials> {
|
|
197
|
+
const device = await requestDeviceAuthorization();
|
|
198
|
+
ctrl.onAuth?.({ url: device.verificationUriComplete, instructions: `Enter code: ${device.userCode}` });
|
|
199
|
+
return pollForToken(device.deviceCode, device.intervalMs, device.expiresInMs, ctrl.signal);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export async function refreshKimiToken(refreshToken: string): Promise<OAuthCredentials> {
|
|
203
|
+
const response = await fetch(`${resolveOAuthHost()}/api/oauth/token`, {
|
|
204
|
+
method: "POST",
|
|
205
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded", ...getKimiCommonHeaders() },
|
|
206
|
+
body: new URLSearchParams({ grant_type: "refresh_token", refresh_token: refreshToken, client_id: CLIENT_ID }),
|
|
207
|
+
});
|
|
208
|
+
if (!response.ok) {
|
|
209
|
+
const payload = (await response.json().catch(() => undefined)) as TokenResponse | undefined;
|
|
210
|
+
throw new Error(`Kimi token refresh failed: ${response.status}${payload?.error_description ? `: ${payload.error_description}` : ""}`);
|
|
211
|
+
}
|
|
212
|
+
return parseTokenPayload((await response.json()) as TokenResponse, refreshToken);
|
|
213
|
+
}
|