opencode-aicodewith-auth 0.1.17 → 0.1.19

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/README.md CHANGED
@@ -63,8 +63,8 @@ User Request → OpenCode → Plugin Auth Hook → Route by Model:
63
63
  |---------|---------|:-------:|---------|
64
64
  | `aicodewith/gpt-5.2-codex` | GPT-5.2 Codex | ✅ | 日常编程、代码生成 |
65
65
  | `aicodewith/gpt-5.2` | GPT-5.2 | ✅ | 架构设计、逻辑推理 |
66
- | `aicodewith/claude-sonnet-4-5-20250929 | Claude Sonnet 4.5 | ✅ | 代码审查、文档查询 |
67
- | `aicodewith/claude-opus-4-5-20251101 | Claude Opus 4.5 | ✅ | 复杂任务、深度思考 |
66
+ | `aicodewith/claude-sonnet-4-5-20250929` | Claude Sonnet 4.5 | ✅ | 代码审查、文档查询 |
67
+ | `aicodewith/claude-opus-4-5-20251101` | Claude Opus 4.5 | ✅ | 复杂任务、深度思考 |
68
68
  | `aicodewith/gemini-3-pro` | Gemini 3 Pro | ✅ | 前端 UI、多模态任务 |
69
69
 
70
70
  ---
package/dist/index.js CHANGED
@@ -69,6 +69,7 @@ var PROVIDER_ID = "aicodewith";
69
69
  var AUTH_METHOD_LABEL = "AICodewith API Key";
70
70
  var CODEX_BASE_URL = "https://api.aicodewith.com/chatgpt/v1";
71
71
  var AICODEWITH_ANTHROPIC_BASE_URL = "https://api.aicodewith.com/v1";
72
+ var AICODEWITH_LITE_URL = "https://api.aicodewith.com/lite";
72
73
  var AICODEWITH_GEMINI_BASE_URL = "https://api.aicodewith.com/gemini_cli";
73
74
  var GEMINI_USER_AGENT = "GeminiCLI/v25.2.1 (darwin; arm64)";
74
75
  var GEMINI_API_CLIENT = "google-genai-sdk/1.30.0 gl-node/v25.2.1";
@@ -1026,6 +1027,7 @@ async function handleSuccessResponse(response, isStreaming) {
1026
1027
 
1027
1028
  // lib/request/claude-tools-transform.ts
1028
1029
  var TOOL_PREFIX = "mcp_";
1030
+ var CLAUDE_USER_ID = "user_7b18c0b8358639d7ff4cdbf78a1552a7d5ca63ba83aee236c4b22ae2be77ba5f_account_3bb3dcbe-4efe-4795-b248-b73603575290_session_4a72737c-93d6-4c45-aebe-6e2d47281338";
1029
1031
  function transformClaudeRequest(init) {
1030
1032
  if (!init?.body || typeof init.body !== "string") {
1031
1033
  return init;
@@ -1033,6 +1035,13 @@ function transformClaudeRequest(init) {
1033
1035
  try {
1034
1036
  const parsed = JSON.parse(init.body);
1035
1037
  let modified = false;
1038
+ if (!parsed.metadata) {
1039
+ parsed.metadata = {};
1040
+ }
1041
+ if (!parsed.metadata.user_id) {
1042
+ parsed.metadata.user_id = CLAUDE_USER_ID;
1043
+ modified = true;
1044
+ }
1036
1045
  if (parsed.tools && Array.isArray(parsed.tools)) {
1037
1046
  parsed.tools = parsed.tools.map((tool) => {
1038
1047
  if (tool.name) {
@@ -1351,6 +1360,26 @@ async function getLatestVersion() {
1351
1360
  clearTimeout(timeoutId);
1352
1361
  }
1353
1362
  }
1363
+ var OH_MY_OPENCODE = "oh-my-opencode";
1364
+ function hasOhMyOpencode(directory) {
1365
+ for (const configPath of getConfigPaths(directory)) {
1366
+ try {
1367
+ if (!fs2.existsSync(configPath))
1368
+ continue;
1369
+ const content = fs2.readFileSync(configPath, "utf-8");
1370
+ const config = JSON.parse(stripJsonComments(content));
1371
+ const plugins = config.plugin ?? [];
1372
+ for (const entry of plugins) {
1373
+ if (entry === OH_MY_OPENCODE || entry.startsWith(`${OH_MY_OPENCODE}@`) || entry.includes(OH_MY_OPENCODE)) {
1374
+ return true;
1375
+ }
1376
+ }
1377
+ } catch {
1378
+ continue;
1379
+ }
1380
+ }
1381
+ return false;
1382
+ }
1354
1383
 
1355
1384
  // lib/hooks/auto-update/cache.ts
1356
1385
  import * as fs3 from "fs";
@@ -1420,7 +1449,8 @@ function invalidatePackage(packageName = PACKAGE_NAME) {
1420
1449
  // lib/hooks/auto-update/index.ts
1421
1450
  var DISPLAY_NAME = "AICodewith";
1422
1451
  var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
1423
- var STARTUP_TOAST_DELAY = 6000;
1452
+ var STARTUP_TOAST_DELAY_WITH_OMO = 6000;
1453
+ var STARTUP_TOAST_DELAY_WITHOUT_OMO = 0;
1424
1454
  function createAutoUpdateHook(ctx, options = {}) {
1425
1455
  const { autoUpdate = true, showStartupToast = true } = options;
1426
1456
  let hasChecked = false;
@@ -1437,11 +1467,13 @@ function createAutoUpdateHook(ctx, options = {}) {
1437
1467
  const cachedVersion = getCachedVersion();
1438
1468
  const localDevVersion = getLocalDevVersion(ctx.directory);
1439
1469
  const displayVersion = localDevVersion ?? cachedVersion ?? "unknown";
1470
+ const hasOmo = hasOhMyOpencode(ctx.directory);
1471
+ const startupDelay = hasOmo ? STARTUP_TOAST_DELAY_WITH_OMO : STARTUP_TOAST_DELAY_WITHOUT_OMO;
1440
1472
  if (localDevVersion) {
1441
1473
  if (showStartupToast) {
1442
1474
  setTimeout(() => {
1443
1475
  showStartupToastWithSpinner(ctx, `${displayVersion} (dev)`, "Local development mode").catch(() => {});
1444
- }, STARTUP_TOAST_DELAY);
1476
+ }, startupDelay);
1445
1477
  }
1446
1478
  log("Local development mode, skipping update check");
1447
1479
  return;
@@ -1449,7 +1481,7 @@ function createAutoUpdateHook(ctx, options = {}) {
1449
1481
  if (showStartupToast) {
1450
1482
  setTimeout(() => {
1451
1483
  showStartupToastWithSpinner(ctx, displayVersion, "GPT-5.2 \xB7 Claude \xB7 Gemini").catch(() => {});
1452
- }, STARTUP_TOAST_DELAY);
1484
+ }, startupDelay);
1453
1485
  }
1454
1486
  runBackgroundUpdateCheck(ctx, autoUpdate).catch((err) => {
1455
1487
  log("Background update check failed:", err);
@@ -1589,6 +1621,14 @@ var provider_config_default = {
1589
1621
  name: "Claude Opus 4.5",
1590
1622
  modalities: { input: ["text", "image"], output: ["text"] }
1591
1623
  },
1624
+ "claude-sonnet-4-5-20250929-third-party": {
1625
+ name: "Claude Sonnet 4.5 (third party)",
1626
+ modalities: { input: ["text", "image"], output: ["text"] }
1627
+ },
1628
+ "claude-opus-4-5-20251101-third-party": {
1629
+ name: "Claude Opus 4.5 (third party)",
1630
+ modalities: { input: ["text", "image"], output: ["text"] }
1631
+ },
1592
1632
  "gemini-3-pro": {
1593
1633
  name: "Gemini 3 Pro",
1594
1634
  modalities: { input: ["text", "image"], output: ["text"] }
@@ -1733,6 +1773,8 @@ var parseRequestBody = (init) => {
1733
1773
  };
1734
1774
  var isGeminiUrl = (url) => url.includes(":generateContent") || url.includes(":streamGenerateContent") || url.includes("/models/") && url.includes("/v1");
1735
1775
  var isClaudeUrl = (url) => url.includes("/v1/messages");
1776
+ var isThirdPartyModel = (model) => Boolean(model && model.endsWith("-third-party"));
1777
+ var stripThirdPartySuffix = (model) => model.replace(/-third-party$/, "");
1736
1778
  var isModel = (model, prefix) => Boolean(model && model.startsWith(prefix));
1737
1779
  var isCodexModel = (model) => Boolean(model && CODEX_MODEL_PREFIXES.some((prefix) => model.startsWith(prefix)));
1738
1780
  var saveResponseIfEnabled = async (response, provider, metadata) => {
@@ -1863,10 +1905,19 @@ var AicodewithCodexAuthPlugin = async (ctx) => {
1863
1905
  return await saveResponseIfEnabled(response, "gemini", { url: geminiUrl, model });
1864
1906
  }
1865
1907
  if (isClaudeRequest) {
1866
- const targetUrl = rewriteUrl(originalUrl, AICODEWITH_ANTHROPIC_BASE_URL);
1867
- const transformedInit = transformClaudeRequest(init);
1908
+ const isThirdParty = isThirdPartyModel(model);
1909
+ const baseUrl = isThirdParty ? AICODEWITH_LITE_URL : AICODEWITH_ANTHROPIC_BASE_URL;
1910
+ const targetUrl = rewriteUrl(originalUrl, baseUrl);
1911
+ let transformedInit = transformClaudeRequest(init);
1912
+ if (isThirdParty && model && transformedInit?.body && typeof transformedInit.body === "string") {
1913
+ try {
1914
+ const body = JSON.parse(transformedInit.body);
1915
+ body.model = stripThirdPartySuffix(model);
1916
+ transformedInit = { ...transformedInit, body: JSON.stringify(body) };
1917
+ } catch {}
1918
+ }
1868
1919
  const response = await fetch(targetUrl, transformedInit);
1869
- const savedResponse = await saveResponseIfEnabled(response, "claude", { url: targetUrl, model });
1920
+ const savedResponse = await saveResponseIfEnabled(response, isThirdParty ? "claude-third-party" : "claude", { url: targetUrl, model });
1870
1921
  return transformClaudeResponse(savedResponse);
1871
1922
  }
1872
1923
  return await fetch(originalUrl, init);
@@ -11,6 +11,7 @@ export declare const PROVIDER_ID = "aicodewith";
11
11
  export declare const AUTH_METHOD_LABEL = "AICodewith API Key";
12
12
  export declare const CODEX_BASE_URL = "https://api.aicodewith.com/chatgpt/v1";
13
13
  export declare const AICODEWITH_ANTHROPIC_BASE_URL = "https://api.aicodewith.com/v1";
14
+ export declare const AICODEWITH_LITE_URL = "https://api.aicodewith.com/lite";
14
15
  export declare const AICODEWITH_GEMINI_BASE_URL = "https://api.aicodewith.com/gemini_cli";
15
16
  export declare const GEMINI_USER_AGENT = "GeminiCLI/v25.2.1 (darwin; arm64)";
16
17
  export declare const GEMINI_API_CLIENT = "google-genai-sdk/1.30.0 gl-node/v25.2.1";
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * @file claude-tools-transform.ts
3
3
  * @input Claude API request body and response
4
- * @output Transformed request/response with mcp_ prefix handling
4
+ * @output Transformed request/response with mcp_ prefix handling and metadata
5
5
  * @pos Handles tool name transformation to bypass Claude Code OAuth restrictions
6
6
  *
7
7
  * 📌 On change: Update this header + lib/request/ARCHITECTURE.md
8
8
  */
9
9
  /**
10
- * Transform Claude API request to add mcp_ prefix to tool names
10
+ * Transform Claude API request to add mcp_ prefix to tool names and inject user_id metadata
11
11
  * This bypasses the "This credential is only authorized for use with Claude Code" error
12
12
  */
13
13
  export declare function transformClaudeRequest(init?: RequestInit): RequestInit | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-aicodewith-auth",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "description": "OpenCode plugin for AICodewith authentication - Access GPT-5.2, Claude, and Gemini models through AICodewith API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",