trinity-config 1.3.0 → 1.3.2

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 +101 -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.2";
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,37 @@ 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 result = await execa(
463
+ "powershell.exe",
464
+ [
465
+ "-NoProfile",
466
+ "-NonInteractive",
467
+ "-Command",
468
+ `Start-Process ${JSON.stringify(url)}`
469
+ ],
470
+ { reject: false, windowsHide: true }
471
+ );
472
+ if (result.exitCode !== 0) {
473
+ await execa(
474
+ "rundll32",
475
+ ["url.dll,FileProtocolHandler", url],
476
+ { reject: false, windowsHide: true }
477
+ );
478
+ }
479
+ return "opened";
510
480
  }
511
481
  if (platform === "darwin") {
512
482
  await execa("open", [url], { reject: false });
513
- return;
483
+ return "opened";
514
484
  }
515
485
  await execa("xdg-open", [url], { reject: false });
486
+ return "opened";
516
487
  }
517
488
 
518
489
  // src/merge-claude-env.ts
@@ -1157,19 +1128,17 @@ async function run() {
1157
1128
  spinner2.stop(
1158
1129
  `\u5DF2\u751F\u6210 ${app}\uFF1A${protocolLabel(protocol2)} \u2192 ${link.endpoint}`
1159
1130
  );
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
- );
1131
+ p.log.info(`\u5BFC\u5165\u6587\u4EF6: ${files.urlFile}`);
1132
+ if (opts.printOnly) {
1133
+ continue;
1167
1134
  }
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");
1135
+ const openResult = await openCcSwitchDeepLink(link.url, files.urlFile);
1136
+ if (openResult === "too_long") {
1137
+ p.log.warn(
1138
+ `\u94FE\u63A5\u8FC7\u957F\uFF08${link.url.length}\uFF09\uFF0C\u672A\u81EA\u52A8\u5524\u8D77\uFF1B\u8BF7\u53CC\u51FB\u5BFC\u5165\u6587\u4EF6`
1139
+ );
1171
1140
  } else {
1172
- p.log.info(link.url);
1141
+ p.log.info("\u5DF2\u5524\u8D77 CC Switch\uFF0C\u8BF7\u5728\u5BFC\u5165\u6846\u4E2D\u786E\u8BA4");
1173
1142
  }
1174
1143
  } catch (error) {
1175
1144
  spinner2.stop(pc.red(`${app} Deep Link \u5931\u8D25`));
@@ -1178,16 +1147,13 @@ async function run() {
1178
1147
  }
1179
1148
  }
1180
1149
  if (verifyFailed) {
1181
- p.outro(pc.yellow("\u914D\u7F6E\u5B8C\u6210\uFF08\u9A8C\u8BC1\u672A\u901A\u8FC7\uFF09"));
1150
+ p.outro(pc.yellow("\u5B8C\u6210\uFF08\u9A8C\u8BC1\u672A\u901A\u8FC7\uFF09"));
1182
1151
  return 1;
1183
1152
  }
1184
1153
  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"),
1154
+ opts.printOnly ? `\u5DF2\u751F\u6210\u5BFC\u5165\u6587\u4EF6\uFF08\u672A\u5524\u8D77\uFF09:
1155
+ ${saved.join("\n")}` : `\u8BF7\u5728 CC Switch \u5BFC\u5165\u6846\u70B9\u786E\u8BA4\uFF1B\u672A\u5F39\u7A97\u5219\u53CC\u51FB:
1156
+ ${saved.join("\n")}`,
1191
1157
  "\u4E0B\u4E00\u6B65"
1192
1158
  );
1193
1159
  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.2",
4
4
  "description": "一键把 Trinity API 接入 Claude Code、Codex、OpenCode、OpenClaw、ZCode、CC Switch",
5
5
  "license": "MIT",
6
6
  "type": "module",