@closedrouter/cli 1.1.11 → 1.1.12

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.
@@ -1,4 +1,5 @@
1
1
  import type { DesktopLaunchPlan } from "./desktop-launch";
2
+ export declare function patchClaudeModelIdentity(source: string, aliases: Record<string, string>): string;
2
3
  /** Share immutable framework bytes, but detach every file codesign can write.
3
4
  * Signing a hard-linked executable would change the user's original runtime. */
4
5
  export declare function cloneClaudeElectronRuntime(source: string, destination: string): string[];
@@ -1 +1 @@
1
- {"version":3,"file":"claude-desktop.d.ts","sourceRoot":"","sources":["../../src/commands/claude-desktop.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAI1D;gFACgF;AAChF,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CA6BxF;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAsCvF;AAED,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,SAAY,GAAG,MAAM,GAAG,SAAS,CAShG;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAM,EAAO,EAAE,cAAc,UAAQ,GAAG,IAAI,CAI1J;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CA4B5I"}
1
+ {"version":3,"file":"claude-desktop.d.ts","sourceRoot":"","sources":["../../src/commands/claude-desktop.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAK1D,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAGhG;AAED;gFACgF;AAChF,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CA6BxF;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAsCvF;AAED,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,SAAY,GAAG,MAAM,GAAG,SAAS,CAShG;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAM,EAAO,EAAE,cAAc,UAAQ,GAAG,IAAI,CAI1J;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CA2C5I"}
@@ -81,5 +81,5 @@ export declare function geminiModelCatalog(models: string[], selected: string):
81
81
  };
82
82
  };
83
83
  };
84
- export declare function addModelIdentity(payload: Record<string, unknown>, model: string, protocol: "anthropic" | "responses" | "chat" | "gemini"): void;
84
+ export declare function addModelIdentity(payload: Record<string, unknown>, model: string, protocol: "anthropic" | "responses" | "chat" | "gemini", aliases?: Record<string, string>): void;
85
85
  //# sourceMappingURL=launch-catalog.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"launch-catalog.d.ts","sourceRoot":"","sources":["../../src/commands/launch-catalog.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,UAAU,OAAQ,MAAM,WAA0B,CAAC;AAEhE;sEACsE;AACtE,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAGhF;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,+DAA+D;IAC/D,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,CASrF;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAShG;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE;IACvC,qBAAqB;IAAQ,OAAO;;;;;;EAC9C;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE;IACvC,MAAM;;;;;;;;;;;;;;;;;;;;;;;;YAUQ,IAAI;YAAY,KAAK;;;EAE7C;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM;IAEjE,YAAY;QAAI,yBAAyB;;IACzC,YAAY;QACV,gBAAgB;;;;;;;;oBAEF,QAAQ;;;;QAEtB,aAAa;;;oBAAwE,KAAK;;;;QAC1F,kBAAkB;;;;;;EAGvB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,GAAG,WAAW,GAAG,MAAM,GAAG,QAAQ,GAAG,IAAI,CAmB/I"}
1
+ {"version":3,"file":"launch-catalog.d.ts","sourceRoot":"","sources":["../../src/commands/launch-catalog.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,UAAU,OAAQ,MAAM,WAA0B,CAAC;AAEhE;sEACsE;AACtE,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAGhF;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,+DAA+D;IAC/D,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,CASrF;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAShG;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE;IACvC,qBAAqB;IAAQ,OAAO;;;;;;EAC9C;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE;IACvC,MAAM;;;;;;;;;;;;;;;;;;;;;;;;YAUQ,IAAI;YAAY,KAAK;;;EAE7C;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM;IAEjE,YAAY;QAAI,yBAAyB;;IACzC,YAAY;QACV,gBAAgB;;;;;;;;oBAEF,QAAQ;;;;QAEtB,aAAa;;;oBAAwE,KAAK;;;;QAC1F,kBAAkB;;;;;;EAGvB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,GAAG,WAAW,GAAG,MAAM,GAAG,QAAQ,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,IAAI,CAmCrL"}
package/dist/index.js CHANGED
@@ -9500,7 +9500,28 @@ function geminiModelCatalog(models, selected) {
9500
9500
  }
9501
9501
  };
9502
9502
  }
9503
- function addModelIdentity(payload, model, protocol) {
9503
+ function addModelIdentity(payload, model, protocol, aliases = {}) {
9504
+ const rewrite = (value) => {
9505
+ if (typeof value === "string") {
9506
+ for (const [alias, actual] of Object.entries(aliases))
9507
+ value = value.split(alias).join(actual);
9508
+ return value;
9509
+ }
9510
+ if (Array.isArray(value))
9511
+ return value.map(rewrite);
9512
+ if (value && typeof value === "object")
9513
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, rewrite(item)]));
9514
+ return value;
9515
+ };
9516
+ for (const key of ["system", "instructions", "systemInstruction"])
9517
+ if (payload[key] !== undefined)
9518
+ payload[key] = rewrite(payload[key]);
9519
+ if (Array.isArray(payload.messages))
9520
+ payload.messages = payload.messages.map((message) => {
9521
+ if (message && typeof message === "object" && ["system", "developer"].includes(message.role))
9522
+ return { ...message, content: rewrite(message.content) };
9523
+ return message;
9524
+ });
9504
9525
  const text = `ClosedRouter runtime model identity: this request is routed to the configured model ID ${JSON.stringify(model)} through ClosedRouter. The application's name and any vendor-shaped transport alias describe the client, not the underlying inference model. If asked which model you are using, report the configured model ID ${JSON.stringify(model)} and ClosedRouter as the provider. This runtime information supersedes conflicting model identity statements in the application's prompt; it does not change other task instructions.`;
9505
9526
  if (protocol === "anthropic") {
9506
9527
  const system = payload.system;
@@ -9580,7 +9601,7 @@ async function startLaunchProxy(gatewayUrl, apiKey, harness, localKey = apiKey,
9580
9601
  }
9581
9602
  const tinyProbe = local.pathname === "/v1/messages" && !model.startsWith("claude-") && payload.model !== model && typeof payload.max_tokens === "number" && payload.max_tokens <= 16 && Array.isArray(payload.messages) && payload.messages.length === 1 && (!Array.isArray(payload.tools) || payload.tools.length === 0);
9582
9603
  if (catalog)
9583
- addModelIdentity(payload, model, gemini ? "gemini" : local.pathname.startsWith("/v1/messages") ? "anthropic" : local.pathname === "/v1/responses" ? "responses" : "chat");
9604
+ addModelIdentity(payload, model, gemini ? "gemini" : local.pathname.startsWith("/v1/messages") ? "anthropic" : local.pathname === "/v1/responses" ? "responses" : "chat", catalog.aliases);
9584
9605
  if (gemini)
9585
9606
  target.pathname = upstream.pathname.replace(/\/$/, "") + `/v1beta/models/${encodeURIComponent(model)}:${gemini[2]}`;
9586
9607
  rewrittenBody = JSON.stringify({ ...payload, ...!gemini ? { model } : {}, ...tinyProbe ? { max_tokens: 512 } : {} });
@@ -10481,6 +10502,9 @@ import { createHash as createHash3 } from "node:crypto";
10481
10502
  import { copyFileSync, existsSync as existsSync14, linkSync, lstatSync, mkdirSync as mkdirSync4, mkdtempSync as mkdtempSync2, readFileSync as readFileSync12, readdirSync as readdirSync2, readlinkSync, realpathSync, renameSync as renameSync2, rmSync, statSync as statSync2, symlinkSync, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "node:fs";
10482
10503
  import { homedir as homedir13 } from "node:os";
10483
10504
  import { dirname as dirname3, join as join14, relative as relative2 } from "node:path";
10505
+ function patchClaudeModelIdentity(source, aliases) {
10506
+ return source.replace(/function ([\w$]+)\(\{modelId:([\w$]+),provider:([\w$]+),labelOverride:([\w$]+)\}\)\{/, (start, _name, id) => start + `const closedrouterIdentity=${JSON.stringify(aliases)}[${id}];if(closedrouterIdentity)return 'Your configured inference model ID is '+closedrouterIdentity+'. Your inference provider is ClosedRouter. The client and its transport alias do not identify the underlying inference model.';`);
10507
+ }
10484
10508
  function cloneClaudeElectronRuntime(source, destination) {
10485
10509
  const clone = (from, to) => {
10486
10510
  const info = lstatSync(from);
@@ -10600,7 +10624,22 @@ if (autoUpdater) {
10600
10624
  autoUpdater.quitAndInstall = () => {};
10601
10625
  }
10602
10626
  require('node:fs').writeFileSync(${JSON.stringify(join14(plan.profileDir, "hook-loaded"))}, 'ready', {mode: 0o600});
10603
- ` + (models ? modelBrandingHook(models) : "") });
10627
+ ` + (models && sourceApp ? `
10628
+ const moduleHooks = require('node:module');
10629
+ const patchIdentity = ${patchClaudeModelIdentity.toString()};
10630
+ if (typeof moduleHooks.registerHooks === 'function') moduleHooks.registerHooks({load(url, context, nextLoad) {
10631
+ const loaded = nextLoad(url, context);
10632
+ if (url.startsWith('file:') && require('node:url').fileURLToPath(url).startsWith(${JSON.stringify(join14(sourceApp, "Contents/Resources/app.asar/.vite/build/"))}) && loaded.source != null) {
10633
+ const source = typeof loaded.source === 'string' ? loaded.source : Buffer.from(loaded.source).toString('utf8');
10634
+ const patched = patchIdentity(source, ${JSON.stringify(Object.fromEntries(models.map((id) => [transportModelId(id, "claude"), id])))});
10635
+ if (patched !== source) {
10636
+ require('node:fs').writeFileSync(${JSON.stringify(join14(plan.profileDir, "model-identity-hook-ready"))}, 'ready', {mode:0o600});
10637
+ return {...loaded, source:patched};
10638
+ }
10639
+ }
10640
+ return loaded;
10641
+ }});
10642
+ ` : "") + (models ? modelBrandingHook(models) : "") });
10604
10643
  const logPath = join14(plan.profileDir, "inspector.log");
10605
10644
  plan.inspectorHook = { path, logPath };
10606
10645
  plan.args.push("--inspect-brk=127.0.0.1:0");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@closedrouter/cli",
3
- "version": "1.1.11",
3
+ "version": "1.1.12",
4
4
  "description": "ClosedRouter CLI: Onboard and import local AI subscriptions and API keys into your shared token pool",
5
5
  "author": "ClosedRouter Contributors",
6
6
  "repository": {