Skip to content

feat(qoder): support PAT via qodercli and remove stale qoder.cn defaults - #913

Merged
diegosouzapw merged 1 commit into
diegosouzapw:release/v3.4.5from
carmin777:feat/qoder-pat-qodercli
Apr 2, 2026
Merged

diegosouzapw merged 1 commit into
diegosouzapw:release/v3.4.5from
carmin777:feat/qoder-pat-qodercli

Conversation

@carmin777

@carmin777 carmin777 commented Apr 2, 2026 •

Copy link
Copy Markdown

Summary

  • support Qoder Personal Access Tokens through qodercli instead of the legacy HTTP/HMAC path
  • stop defaulting Qoder browser auth to stale .cn endpoints and gate experimental OAuth behind QODER_OAUTH_*
  • add provider validation, runtime detection, static model exposure, dashboard support, and focused unit coverage for the PAT transport

Details

  • add a shared qoderCli service used by the executor, PAT validation, and static model listing
  • route Qoder API-key connections through PAT + qodercli transport metadata
  • treat Qoder as a free provider that supports PAT while keeping browser OAuth explicitly experimental
  • make provider test/runtime checks understand Qoder CLI runtime health
  • return clear UI/API errors when browser OAuth is not configured instead of generating dead auth URLs

Testing

  • node --import tsx/esm --test tests/unit/qoder-executor.test.mjs tests/unit/qoder-oauth-config.test.mjs tests/unit/cli-runtime-detection.test.mjs

Fixes #879

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request transitions the Qoder provider from a direct API integration using HMAC signatures to a CLI-based transport via qodercli using Personal Access Tokens (PAT). It includes a major rewrite of the Qoder executor to handle child process spawning for both streaming and non-streaming requests, updates the UI to support PAT management, and makes browser-based OAuth experimental and environment-dependent. Feedback focuses on improving the robustness of process termination in the executor and ensuring cross-platform compatibility when resolving the user's home directory in the CLI service.

Comment on lines +177 to +181
const abortChild = () => {
try {
child.kill("SIGTERM");
} catch {}
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The abortChild function should include a SIGKILL fallback after a short delay to ensure the CLI process is terminated if it doesn't respond to SIGTERM. This prevents orphaned processes from hanging around if the CLI becomes unresponsive. This pattern is correctly implemented in open-sse/services/qoderCli.ts but was missed here.

        const abortChild = () => {
          try {
            child.kill("SIGTERM");
          } catch {}
          setTimeout(() => {
            try {
              child.kill("SIGKILL");
            } catch {}
          }, 250).unref?.();
        };

Comment on lines +1 to +2
import { spawn } from "child_process";
import crypto from "crypto";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Add the os module import to provide a more reliable, cross-platform way of retrieving the user's home directory.

Suggested change
import { spawn } from "child_process";
import crypto from "crypto";
import { spawn } from "child_process";
import crypto from "crypto";
import os from "os";

Comment on lines +71 to +72
const home = String(process.env.HOME || "").trim();
return home || process.cwd();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

process.env.HOME is not consistently available on all platforms, particularly Windows (where USERPROFILE is the standard). Using os.homedir() is the recommended cross-platform approach in Node.js.

Suggested change
const home = String(process.env.HOME || "").trim();
return home || process.cwd();
const home = os.homedir();
return home || process.cwd();

@kilo-code-bot kilo-code-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

Reviewed the Qoder provider migration from OAuth to Personal Access Token (PAT) via qodercli. The changes look solid overall. A few observations below.

token: "https://qoder.cn/oauth/token",
auth: "https://qoder.cn/oauth",
token: process.env.QODER_OAUTH_TOKEN_URL || "",
auth: process.env.QODER_OAUTH_AUTHORIZE_URL || "",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

WARNING: If env vars not set, OAuth endpoints default to empty string. Ensure documentation clarifies QODER_OAUTH_* vars required for browser OAuth.

const child = spawn(cliCommand, args, {
env: {
...process.env,
QODER_PERSONAL_ACCESS_TOKEN: pat,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

WARNING: PAT passed via environment variable QODER_PERSONAL_ACCESS_TOKEN. Verify qodercli accepts this env var for auth.

providerId={key}
provider={info}
stats={getProviderStats(key, "oauth")}
stats={getProviderStats(key, "free")}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

SUGGESTION: Passing authType="free" for Qoder which has authType="apikey" in DB. The filter logic handles this (line 173), but consider naming consistency.

@kilo-code-bot

kilo-code-bot Bot commented Apr 2, 2026

Copy link
Copy Markdown

Code Review Summary

Status: 3 Warnings Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 3
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
open-sse/config/constants.ts 48 OAuth endpoints default to empty string when env vars not set. Documentation should clarify QODER_OAUTH_* variables are required for browser OAuth to work.
open-sse/executors/qoder.ts 145 PAT passed via environment variable QODER_PERSONAL_ACCESS_TOKEN. Verify qodercli accepts this env var for authentication.
src/app/(dashboard)/dashboard/providers/page.tsx 453 Passing authType="free" for Qoder which has authType="apikey" in DB. Filter logic handles this but consider naming consistency.
Files Reviewed (17 files)
  • README.md
  • open-sse/config/constants.ts
  • open-sse/config/providerRegistry.ts
  • open-sse/executors/qoder.ts
  • open-sse/services/qoderCli.ts
  • src/app/(dashboard)/dashboard/providers/[id]/page.tsx
  • src/app/(dashboard)/dashboard/providers/page.tsx
  • src/app/api/oauth/[provider]/[action]/route.ts
  • src/app/api/providers/[id]/models/route.ts
  • src/app/api/providers/[id]/test/route.ts
  • src/app/api/providers/route.ts
  • src/lib/oauth/constants/oauth.ts
  • src/lib/oauth/providers/qoder.ts
  • src/lib/oauth/services/qoder.ts
  • src/lib/providers/validation.ts
  • src/shared/components/OAuthModal.tsx
  • src/shared/constants/providers.ts

The PR implements a significant migration for the Qoder provider from OAuth-based authentication to Personal Access Token (PAT) via qodercli transport. This is a well-structured change that:

  1. Removes hardcoded credentials — QODER_OAUTH_* now require explicit env vars
  2. Adds PAT support — New qoderCli.ts service handles CLI-based auth
  3. Updates provider registry — Qoder now uses apikey authType with qodercli transport
  4. Adds UI flow — Dashboard shows PAT as primary, OAuth as experimental option
  5. Includes tests — New test files for qoder executor and OAuth config

No critical issues found. The warnings above are minor operational concerns.

@diegosouzapw
diegosouzapw changed the base branch from main to release/v3.4.5 April 2, 2026 17:36
@diegosouzapw
diegosouzapw merged commit 0bfee82 into diegosouzapw:release/v3.4.5 Apr 2, 2026
1 check passed
@diegosouzapw

Copy link
Copy Markdown
Owner

Thanks @carmin777 for this great contribution! 🎉 This PR has been integrated into the release/v3.4.5 branch and will be part of the next release. We appreciate your effort!

@bankir82 bankir82 mentioned this pull request Apr 17, 2026
@diegosouzapw diegosouzapw mentioned this pull request Apr 22, 2026
diegosouzapw pushed a commit that referenced this pull request Jun 22, 2026
…ted base-reds

- Reconcile [3.8.33] CHANGELOG to 1:1 commit coverage (51 bullets) + env contract
  (QUOTA_PREFLIGHT_CUTOFF_ENABLED, KIRO_VERIFY_FULL_CRC) + README What's New range.
- fix(translator): dedupe the duplicate input_audio handler in geminiHelper; mp3
  normalizes to canonical audio/mpeg and the data: prefix is stripped (#912/#913).
- fix(auth): wire admin-configured maxCooldownMs to all 4 markAccountUnavailable
  model-lockout sites (#4530 follow-up — combo.ts sites were already covered).
- fix(api): add src/models/ to package.json files so the published --mcp closure
  ships it (#3578 gate).
- test: align stale expectations to intentional code (10 essential MCP tools incl.
  web_fetch; busy_timeout 2s cap from v3.8.32).
- chore(quality): rebaseline file-size for auth.ts 2279->2289 + db-core-init.test.ts.
Poid-ZA pushed a commit to Poid-ZA/OmniRoute that referenced this pull request Aug 5, 2026
…ercli

feat(qoder): support PAT via qodercli and remove stale qoder.cn defaults
tkgo11 pushed a commit to tkgo11/OmniRoute that referenced this pull request Sep 23, 2026
…ted base-reds

- Reconcile [3.8.33] CHANGELOG to 1:1 commit coverage (51 bullets) + env contract
  (QUOTA_PREFLIGHT_CUTOFF_ENABLED, KIRO_VERIFY_FULL_CRC) + README What's New range.
- fix(translator): dedupe the duplicate input_audio handler in geminiHelper; mp3
  normalizes to canonical audio/mpeg and the data: prefix is stripped (diegosouzapw#912/diegosouzapw#913).
- fix(auth): wire admin-configured maxCooldownMs to all 4 markAccountUnavailable
  model-lockout sites (diegosouzapw#4530 follow-up — combo.ts sites were already covered).
- fix(api): add src/models/ to package.json files so the published --mcp closure
  ships it (diegosouzapw#3578 gate).
- test: align stale expectations to intentional code (10 essential MCP tools incl.
  web_fetch; busy_timeout 2s cap from v3.8.32).
- chore(quality): rebaseline file-size for auth.ts 2279->2289 + db-core-init.test.ts.
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…ercli

feat(qoder): support PAT via qodercli and remove stale qoder.cn defaults
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]

2 participants