trinity-config 1.3.0 → 1.3.1

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.
Files changed (2) hide show
  1. package/dist/index.js +90 -135
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import pc from "picocolors";
9
9
 
10
10
  // src/constants.ts
11
11
  var PACKAGE_NAME = "trinity-config";
12
- var PACKAGE_VERSION = "1.3.0";
12
+ var PACKAGE_VERSION = "1.3.1";
13
13
  var TRINITY_BASE_URL = "https://api.trinitydesk.ai";
14
14
  var DEFAULT_CLAUDE_MODEL = "claude-sonnet-4-6";
15
15
  var DEFAULT_CLAUDE_FAST_MODEL = "claude-sonnet-4-6";
@@ -283,129 +283,86 @@ import os from "os";
283
283
  import path from "path";
284
284
  import { execa } from "execa";
285
285
  var TRINITY_CCSWITCH_PROVIDER_NAME = "Trinity";
286
+ var CCSWITCH_URL_SAFE_MAX = 2e3;
286
287
  function encodeConfigBase64(raw) {
287
288
  return Buffer.from(raw, "utf8").toString("base64");
288
289
  }
289
290
  function buildClaudeConfigJson(apiKey, endpoint, model) {
290
- return `${JSON.stringify(
291
- {
292
- env: {
293
- ANTHROPIC_AUTH_TOKEN: apiKey,
294
- ANTHROPIC_API_KEY: apiKey,
295
- ANTHROPIC_BASE_URL: endpoint.replace(/\/v1\/?$/, "").replace(/\/+$/, ""),
296
- ANTHROPIC_MODEL: model,
297
- ANTHROPIC_DEFAULT_SONNET_MODEL: model,
298
- ANTHROPIC_DEFAULT_HAIKU_MODEL: model
299
- }
300
- },
301
- null,
302
- 2
303
- )}
304
- `;
291
+ return JSON.stringify({
292
+ env: {
293
+ ANTHROPIC_AUTH_TOKEN: apiKey,
294
+ ANTHROPIC_API_KEY: apiKey,
295
+ ANTHROPIC_BASE_URL: endpoint.replace(/\/v1\/?$/, "").replace(/\/+$/, ""),
296
+ ANTHROPIC_MODEL: model,
297
+ ANTHROPIC_DEFAULT_SONNET_MODEL: model,
298
+ ANTHROPIC_DEFAULT_HAIKU_MODEL: model
299
+ }
300
+ });
305
301
  }
306
- function buildCodexConfigToml(apiKey, endpointWithV1, model) {
302
+ function buildCodexConfigToml(_apiKey, endpointWithV1, model) {
307
303
  const base = endpointWithV1.replace(/\/+$/, "");
308
- return `model_provider = "trinity"
309
- model = ${JSON.stringify(model)}
310
- disable_response_storage = true
311
-
312
- [model_providers.trinity]
313
- name = "Trinity"
314
- base_url = ${JSON.stringify(base)}
315
- wire_api = "responses"
316
- requires_openai_auth = true
317
- temp_env_key = "TRINITY_API_KEY"
318
- `;
304
+ return [
305
+ 'model_provider = "trinity"',
306
+ `model = ${JSON.stringify(model)}`,
307
+ "disable_response_storage = true",
308
+ "",
309
+ "[model_providers.trinity]",
310
+ 'name = "Trinity"',
311
+ `base_url = ${JSON.stringify(base)}`,
312
+ 'wire_api = "responses"',
313
+ "requires_openai_auth = true"
314
+ ].join("\n");
319
315
  }
320
316
  function buildOpenCodeConfigJson(apiKey, endpoint, model, protocol) {
321
317
  const npm = protocol === "anthropic_messages" ? "@ai-sdk/anthropic" : protocol === "responses" ? "@ai-sdk/openai" : "@ai-sdk/openai-compatible";
322
- return `${JSON.stringify(
323
- {
324
- $schema: "https://opencode.ai/config.json",
325
- model: `trinity/${model}`,
326
- provider: {
327
- trinity: {
328
- npm,
329
- name: "Trinity",
330
- options: {
331
- baseURL: endpoint.replace(/\/+$/, ""),
332
- apiKey
333
- },
334
- models: {
335
- [model]: { name: model }
336
- }
318
+ return JSON.stringify({
319
+ $schema: "https://opencode.ai/config.json",
320
+ model: `trinity/${model}`,
321
+ provider: {
322
+ trinity: {
323
+ npm,
324
+ name: "Trinity",
325
+ options: {
326
+ baseURL: endpoint.replace(/\/+$/, ""),
327
+ apiKey
328
+ },
329
+ models: {
330
+ [model]: { name: model }
337
331
  }
338
332
  }
339
- },
340
- null,
341
- 2
342
- )}
343
- `;
333
+ }
334
+ });
344
335
  }
345
336
  function buildOpenClawConfigJson(apiKey, endpoint, model, protocol) {
346
337
  const api = protocol === "anthropic_messages" ? "anthropic-messages" : protocol === "responses" ? "openai-responses" : "openai-completions";
347
- return `${JSON.stringify(
348
- {
349
- models: {
350
- mode: "merge",
351
- providers: {
352
- trinity: {
353
- baseUrl: endpoint.replace(/\/+$/, ""),
354
- apiKey,
355
- api,
356
- models: [
357
- {
358
- id: model,
359
- name: model,
360
- reasoning: false,
361
- input: ["text"],
362
- contextWindow: 128e3,
363
- maxTokens: 8192
364
- }
365
- ]
366
- }
367
- }
368
- },
369
- agents: {
370
- defaults: {
371
- model: { primary: `trinity/${model}` },
372
- models: { "trinity/*": {} }
338
+ return JSON.stringify({
339
+ models: {
340
+ mode: "merge",
341
+ providers: {
342
+ trinity: {
343
+ baseUrl: endpoint.replace(/\/+$/, ""),
344
+ apiKey,
345
+ api,
346
+ models: [
347
+ {
348
+ id: model,
349
+ name: model,
350
+ reasoning: false,
351
+ input: ["text"],
352
+ contextWindow: 128e3,
353
+ maxTokens: 8192
354
+ }
355
+ ]
373
356
  }
374
357
  }
375
358
  },
376
- null,
377
- 2
378
- )}
379
- `;
380
- }
381
- function notesForCcSwitchApp(app, protocol) {
382
- const common = [
383
- "App-specific Provider\uFF08\u975E Universal\uFF09",
384
- "\u5BFC\u5165\u540E\u8BF7\u5728 CC Switch \u4E2D Activate Trinity",
385
- "\u52FF\u518D\u5BF9\u540C\u4E00\u5DE5\u5177\u8DD1 trinity-config --type \u76F4\u8FDE\uFF0C\u4EE5\u514D\u4E92\u76F8\u8986\u76D6",
386
- "\u6A21\u578B\u5217\u8868\u4EE5\u8BE5 API Key Call Allowlist \u4E3A\u51C6"
387
- ];
388
- switch (app) {
389
- case "claude":
390
- return [
391
- ...common,
392
- "API Format = Anthropic Messages\uFF08\u9ED8\u8BA4\uFF09",
393
- "Endpoint \u4E0D\u5E26 /v1",
394
- protocol !== "anthropic_messages" ? `\u8B66\u544A: \u5F53\u524D\u62E9\u4F18\u534F\u8BAE\u4E3A ${protocol}\uFF0CClaude \u69FD\u4ECD\u6309 Messages \u5199\u5165\uFF1B\u82E5\u6A21\u578B\u65E0 Messages \u8BF7\u6362\u6A21\u578B` : ""
395
- ].filter(Boolean).join("\uFF1B");
396
- case "codex":
397
- return [
398
- ...common,
399
- "wire_api=responses\uFF1B\u8BF7\u5173\u95ED Needs Local Routing\uFF08\u76F4\u8FDE Trinity Responses\uFF09",
400
- "Endpoint \u586B\u5E26 /v1 \u7684\u524D\u7F00\uFF0C\u907F\u514D\u5199\u6210 \u2026/v1/v1"
401
- ].join("\uFF1B");
402
- case "opencode":
403
- return [...common, `\u534F\u8BAE: ${protocol}`].join("\uFF1B");
404
- case "openclaw":
405
- return [...common, `\u534F\u8BAE: ${protocol}`, "\u6539\u5B8C\u8BF7\u91CD\u542F OpenClaw Gateway"].join("\uFF1B");
406
- case "gemini":
407
- return "\u4E0D\u652F\u6301";
408
- }
359
+ agents: {
360
+ defaults: {
361
+ model: { primary: `trinity/${model}` },
362
+ models: { "trinity/*": {} }
363
+ }
364
+ }
365
+ });
409
366
  }
410
367
  function buildCcSwitchDeepLink(options) {
411
368
  const root = (options.rootBaseUrl ?? TRINITY_BASE_URL).replace(/\/+$/, "");
@@ -452,7 +409,6 @@ function buildCcSwitchDeepLink(options) {
452
409
  case "gemini":
453
410
  throw new Error("gemini \u4E0D\u53D7\u652F\u6301");
454
411
  }
455
- const notes = notesForCcSwitchApp(options.app, options.protocol);
456
412
  const params = new URLSearchParams();
457
413
  params.set("resource", "provider");
458
414
  params.set("app", options.app);
@@ -465,7 +421,6 @@ function buildCcSwitchDeepLink(options) {
465
421
  params.set("sonnetModel", options.model);
466
422
  params.set("haikuModel", options.model);
467
423
  }
468
- params.set("notes", notes);
469
424
  params.set("config", encodeConfigBase64(config));
470
425
  params.set("configFormat", configFormat);
471
426
  if (options.enabled !== false) {
@@ -474,7 +429,6 @@ function buildCcSwitchDeepLink(options) {
474
429
  return {
475
430
  url: `ccswitch://v1/import?${params.toString()}`,
476
431
  endpoint,
477
- notes,
478
432
  configFormat
479
433
  };
480
434
  }
@@ -499,20 +453,26 @@ URL=${url}\r
499
453
  `, "utf8");
500
454
  return { urlFile, txtFile };
501
455
  }
502
- async function openCcSwitchDeepLink(url) {
456
+ async function openCcSwitchDeepLink(url, urlFile) {
457
+ if (url.length > CCSWITCH_URL_SAFE_MAX) {
458
+ return "too_long";
459
+ }
503
460
  const platform = process.platform;
504
461
  if (platform === "win32") {
505
- await execa("cmd", ["/c", "start", "", url], {
506
- windowsHide: true,
507
- reject: false
508
- });
509
- return;
462
+ const command = urlFile && fs.existsSync(urlFile) ? `Start-Process -LiteralPath ${JSON.stringify(urlFile)}` : `Start-Process ${JSON.stringify(url)}`;
463
+ await execa(
464
+ "powershell.exe",
465
+ ["-NoProfile", "-NonInteractive", "-Command", command],
466
+ { reject: false, windowsHide: true }
467
+ );
468
+ return "opened";
510
469
  }
511
470
  if (platform === "darwin") {
512
471
  await execa("open", [url], { reject: false });
513
- return;
472
+ return "opened";
514
473
  }
515
474
  await execa("xdg-open", [url], { reject: false });
475
+ return "opened";
516
476
  }
517
477
 
518
478
  // src/merge-claude-env.ts
@@ -1157,19 +1117,17 @@ async function run() {
1157
1117
  spinner2.stop(
1158
1118
  `\u5DF2\u751F\u6210 ${app}\uFF1A${protocolLabel(protocol2)} \u2192 ${link.endpoint}`
1159
1119
  );
1160
- p.note(link.notes, `${app} \u6CE8\u610F`);
1161
- p.log.info(`Deep Link \u5DF2\u4FDD\u5B58: ${files.txtFile}`);
1162
- if (link.url.length > 2e3) {
1163
- p.note(
1164
- "Deep Link \u8F83\u957F\uFF0C\u82E5\u7CFB\u7EDF\u65E0\u6CD5\u5524\u8D77\uFF0C\u8BF7\u53CC\u51FB\u843D\u76D8\u7684 .url \u6587\u4EF6\u5BFC\u5165",
1165
- "\u63D0\u793A"
1166
- );
1120
+ p.log.info(`\u5BFC\u5165\u6587\u4EF6: ${files.urlFile}`);
1121
+ if (opts.printOnly) {
1122
+ continue;
1167
1123
  }
1168
- if (!opts.printOnly) {
1169
- await openCcSwitchDeepLink(link.url);
1170
- p.log.info("\u5DF2\u5C1D\u8BD5\u5524\u8D77 CC Switch \u5BFC\u5165\u5BF9\u8BDD\u6846\uFF08\u82E5\u672A\u5F39\u51FA\u8BF7\u53CC\u51FB .url \u6587\u4EF6\uFF09");
1124
+ const openResult = await openCcSwitchDeepLink(link.url, files.urlFile);
1125
+ if (openResult === "too_long") {
1126
+ p.log.warn(
1127
+ `\u94FE\u63A5\u8FC7\u957F\uFF08${link.url.length}\uFF09\uFF0C\u672A\u81EA\u52A8\u5524\u8D77\uFF1B\u8BF7\u53CC\u51FB\u5BFC\u5165\u6587\u4EF6`
1128
+ );
1171
1129
  } else {
1172
- p.log.info(link.url);
1130
+ p.log.info("\u5DF2\u5524\u8D77 CC Switch\uFF0C\u8BF7\u5728\u5BFC\u5165\u6846\u4E2D\u786E\u8BA4");
1173
1131
  }
1174
1132
  } catch (error) {
1175
1133
  spinner2.stop(pc.red(`${app} Deep Link \u5931\u8D25`));
@@ -1178,16 +1136,13 @@ async function run() {
1178
1136
  }
1179
1137
  }
1180
1138
  if (verifyFailed) {
1181
- p.outro(pc.yellow("\u914D\u7F6E\u5B8C\u6210\uFF08\u9A8C\u8BC1\u672A\u901A\u8FC7\uFF09"));
1139
+ p.outro(pc.yellow("\u5B8C\u6210\uFF08\u9A8C\u8BC1\u672A\u901A\u8FC7\uFF09"));
1182
1140
  return 1;
1183
1141
  }
1184
1142
  p.note(
1185
- [
1186
- "\u5728 CC Switch \u5BFC\u5165\u786E\u8BA4\u6846\u4E2D\u6838\u5BF9\u540E Confirm",
1187
- "\u5207\u6362\u5230\u5BF9\u5E94 App \u9875\u7B7E\uFF0CActivate\u300CTrinity\u300D",
1188
- `\u843D\u76D8\u6587\u4EF6: ${saved.join(" | ")}`,
1189
- opts.printOnly ? "\u5DF2 --print-only\uFF0C\u672A\u81EA\u52A8\u6253\u5F00\u5E94\u7528" : "\u82E5\u672A\u5F39\u7A97\uFF1A\u53CC\u51FB\u4E0A\u8FF0 .url\uFF0C\u6216\u68C0\u67E5 ccswitch:// \u534F\u8BAE\u6CE8\u518C"
1190
- ].join("\n"),
1143
+ opts.printOnly ? `\u5DF2\u751F\u6210\u5BFC\u5165\u6587\u4EF6\uFF08\u672A\u5524\u8D77\uFF09:
1144
+ ${saved.join("\n")}` : `\u8BF7\u5728 CC Switch \u5BFC\u5165\u6846\u70B9\u786E\u8BA4\uFF1B\u672A\u5F39\u7A97\u5219\u53CC\u51FB:
1145
+ ${saved.join("\n")}`,
1191
1146
  "\u4E0B\u4E00\u6B65"
1192
1147
  );
1193
1148
  p.outro(pc.green("\u5B8C\u6210"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trinity-config",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "一键把 Trinity API 接入 Claude Code、Codex、OpenCode、OpenClaw、ZCode、CC Switch",
5
5
  "license": "MIT",
6
6
  "type": "module",