@lakphy/local-router 0.5.6 → 0.5.7

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/dist/cli.js CHANGED
@@ -9179,257 +9179,6 @@ var init_output = __esm(() => {
9179
9179
  init_global_flags();
9180
9180
  });
9181
9181
 
9182
- // src/cli/runtime.ts
9183
- import { existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync4, rmSync, writeFileSync as writeFileSync3 } from "fs";
9184
- import { homedir as homedir2 } from "os";
9185
- import { join as join3, resolve as resolve2 } from "path";
9186
- function getRuntimeDirs() {
9187
- const override = process.env.LOCAL_ROUTER_RUNTIME_DIR;
9188
- const root = override?.trim() ? override.trim() : join3(homedir2(), ".local-router");
9189
- return {
9190
- root,
9191
- run: join3(root, "run"),
9192
- logs: join3(root, "logs")
9193
- };
9194
- }
9195
- function getRuntimeFiles() {
9196
- const dirs = getRuntimeDirs();
9197
- return {
9198
- pid: join3(dirs.run, "local-router.pid"),
9199
- state: join3(dirs.run, "status.json"),
9200
- daemonLog: join3(dirs.logs, "daemon.log")
9201
- };
9202
- }
9203
- function ensureRuntimeDirs() {
9204
- const dirs = getRuntimeDirs();
9205
- mkdirSync3(dirs.root, { recursive: true });
9206
- mkdirSync3(dirs.run, { recursive: true });
9207
- mkdirSync3(dirs.logs, { recursive: true });
9208
- }
9209
- function writeRuntimeState(state) {
9210
- ensureRuntimeDirs();
9211
- const files = getRuntimeFiles();
9212
- writeFileSync3(files.pid, `${state.pid}
9213
- `, "utf-8");
9214
- writeFileSync3(files.state, JSON.stringify(state, null, 2), "utf-8");
9215
- }
9216
- function readRuntimeState() {
9217
- const files = getRuntimeFiles();
9218
- if (!existsSync2(files.state)) {
9219
- return null;
9220
- }
9221
- try {
9222
- return JSON.parse(readFileSync4(files.state, "utf-8"));
9223
- } catch {
9224
- return null;
9225
- }
9226
- }
9227
- function clearRuntimeFiles() {
9228
- const files = getRuntimeFiles();
9229
- rmSync(files.pid, { force: true });
9230
- rmSync(files.state, { force: true });
9231
- }
9232
- function resolveConfigArgPath(pathValue) {
9233
- return resolve2(pathValue);
9234
- }
9235
- var init_runtime = () => {};
9236
-
9237
- // src/cli/autostart.ts
9238
- import { execSync } from "child_process";
9239
- import { existsSync as existsSync3, mkdirSync as mkdirSync4, readFileSync as readFileSync5, rmSync as rmSync2, writeFileSync as writeFileSync4 } from "fs";
9240
- import { homedir as homedir3, platform } from "os";
9241
- import { dirname as dirname2, join as join4 } from "path";
9242
- function getDaemonLogPath() {
9243
- return getRuntimeDirs().logs + "/daemon.log";
9244
- }
9245
- function getLaunchAgentPath() {
9246
- return join4(homedir3(), "Library", "LaunchAgents", `${LABEL}.plist`);
9247
- }
9248
- function buildPlist(opts) {
9249
- const logPath = getDaemonLogPath();
9250
- const args = [opts.execPath, ...opts.args].map((a) => ` <string>${escapeXml(a)}</string>`).join(`
9251
- `);
9252
- return `<?xml version="1.0" encoding="UTF-8"?>
9253
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
9254
- <plist version="1.0">
9255
- <dict>
9256
- <key>Label</key>
9257
- <string>${escapeXml(opts.label)}</string>
9258
- <key>ProgramArguments</key>
9259
- <array>
9260
- ${args}
9261
- </array>
9262
- <key>RunAtLoad</key>
9263
- <true/>
9264
- <key>KeepAlive</key>
9265
- <false/>
9266
- <key>StandardOutPath</key>
9267
- <string>${escapeXml(logPath)}</string>
9268
- <key>StandardErrorPath</key>
9269
- <string>${escapeXml(logPath)}</string>
9270
- </dict>
9271
- </plist>
9272
- `;
9273
- }
9274
- function escapeXml(s) {
9275
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
9276
- }
9277
- function createMacosManager() {
9278
- const plistPath = getLaunchAgentPath();
9279
- return {
9280
- platform: "macos",
9281
- async isInstalled() {
9282
- return existsSync3(plistPath);
9283
- },
9284
- async install(opts) {
9285
- const dir = dirname2(plistPath);
9286
- if (!existsSync3(dir))
9287
- mkdirSync4(dir, { recursive: true });
9288
- writeFileSync4(plistPath, buildPlist(opts), "utf-8");
9289
- try {
9290
- execSync(`launchctl bootout gui/$(id -u) ${plistPath} 2>/dev/null`, { stdio: "ignore" });
9291
- } catch {}
9292
- execSync(`launchctl bootstrap gui/$(id -u) ${plistPath}`, { stdio: "ignore" });
9293
- },
9294
- async uninstall() {
9295
- if (!existsSync3(plistPath))
9296
- return;
9297
- try {
9298
- execSync(`launchctl bootout gui/$(id -u) ${plistPath}`, { stdio: "ignore" });
9299
- } catch {}
9300
- rmSync2(plistPath, { force: true });
9301
- },
9302
- getServicePath() {
9303
- return plistPath;
9304
- }
9305
- };
9306
- }
9307
- function getSystemdUnitPath() {
9308
- return join4(homedir3(), ".config", "systemd", "user", "local-router.service");
9309
- }
9310
- function buildUnit(opts) {
9311
- const logPath = getDaemonLogPath();
9312
- const execStart = [opts.execPath, ...opts.args].join(" ");
9313
- return `[Unit]
9314
- Description=Local Router API Gateway
9315
- After=network-online.target
9316
-
9317
- [Service]
9318
- Type=simple
9319
- ExecStart=${execStart}
9320
- Restart=on-failure
9321
- RestartSec=5
9322
- StandardOutput=append:${logPath}
9323
- StandardError=append:${logPath}
9324
-
9325
- [Install]
9326
- WantedBy=default.target
9327
- `;
9328
- }
9329
- function createLinuxManager() {
9330
- const unitPath = getSystemdUnitPath();
9331
- return {
9332
- platform: "linux",
9333
- async isInstalled() {
9334
- if (!existsSync3(unitPath))
9335
- return false;
9336
- try {
9337
- const out = execSync("systemctl --user is-enabled local-router 2>/dev/null", {
9338
- encoding: "utf-8"
9339
- }).trim();
9340
- return out === "enabled";
9341
- } catch {
9342
- return false;
9343
- }
9344
- },
9345
- async install(opts) {
9346
- const dir = dirname2(unitPath);
9347
- if (!existsSync3(dir))
9348
- mkdirSync4(dir, { recursive: true });
9349
- writeFileSync4(unitPath, buildUnit(opts), "utf-8");
9350
- execSync("systemctl --user daemon-reload", { stdio: "ignore" });
9351
- execSync("systemctl --user enable local-router", { stdio: "ignore" });
9352
- },
9353
- async uninstall() {
9354
- try {
9355
- execSync("systemctl --user disable local-router", { stdio: "ignore" });
9356
- } catch {}
9357
- rmSync2(unitPath, { force: true });
9358
- try {
9359
- execSync("systemctl --user daemon-reload", { stdio: "ignore" });
9360
- } catch {}
9361
- },
9362
- getServicePath() {
9363
- return unitPath;
9364
- }
9365
- };
9366
- }
9367
- function createWindowsManager() {
9368
- return {
9369
- platform: "windows",
9370
- async isInstalled() {
9371
- try {
9372
- execSync(`reg query "${WIN_REG_KEY}" /v ${WIN_REG_VALUE}`, { stdio: "ignore" });
9373
- return true;
9374
- } catch {
9375
- return false;
9376
- }
9377
- },
9378
- async install(opts) {
9379
- const cmd = [opts.execPath, ...opts.args].map((a) => `"${a}"`).join(" ");
9380
- execSync(`reg add "${WIN_REG_KEY}" /v ${WIN_REG_VALUE} /t REG_SZ /d "${cmd}" /f`, {
9381
- stdio: "ignore"
9382
- });
9383
- },
9384
- async uninstall() {
9385
- try {
9386
- execSync(`reg delete "${WIN_REG_KEY}" /v ${WIN_REG_VALUE} /f`, { stdio: "ignore" });
9387
- } catch {}
9388
- },
9389
- getServicePath() {
9390
- return `${WIN_REG_KEY}\\${WIN_REG_VALUE}`;
9391
- }
9392
- };
9393
- }
9394
- function createUnsupportedManager() {
9395
- return {
9396
- platform: "unsupported",
9397
- async isInstalled() {
9398
- return false;
9399
- },
9400
- async install() {
9401
- throw new Error("\u5F53\u524D\u5E73\u53F0\u4E0D\u652F\u6301\u81EA\u542F\u52A8");
9402
- },
9403
- async uninstall() {
9404
- throw new Error("\u5F53\u524D\u5E73\u53F0\u4E0D\u652F\u6301\u81EA\u542F\u52A8");
9405
- },
9406
- getServicePath() {
9407
- return "";
9408
- }
9409
- };
9410
- }
9411
- function createAutostartManager() {
9412
- const p = platform();
9413
- if (p === "darwin")
9414
- return createMacosManager();
9415
- if (p === "linux")
9416
- return createLinuxManager();
9417
- if (p === "win32")
9418
- return createWindowsManager();
9419
- return createUnsupportedManager();
9420
- }
9421
- function getAutostartExecArgs() {
9422
- const script = process.argv[1] ?? "dist/cli.js";
9423
- return {
9424
- execPath: process.execPath,
9425
- args: [script, "__run-server", "--mode", "daemon"]
9426
- };
9427
- }
9428
- var LABEL = "com.lakphy.local-router", WIN_REG_KEY = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", WIN_REG_VALUE = "LocalRouter";
9429
- var init_autostart = __esm(() => {
9430
- init_runtime();
9431
- });
9432
-
9433
9182
  // node_modules/.bun/@ai-sdk+provider@3.0.8/node_modules/@ai-sdk/provider/dist/index.mjs
9434
9183
  function getErrorMessage(error) {
9435
9184
  if (error == null) {
@@ -27547,14 +27296,14 @@ async function delay(delayInMs, options) {
27547
27296
  return Promise.resolve();
27548
27297
  }
27549
27298
  const signal = options == null ? undefined : options.abortSignal;
27550
- return new Promise((resolve22, reject) => {
27299
+ return new Promise((resolve2, reject) => {
27551
27300
  if (signal == null ? undefined : signal.aborted) {
27552
27301
  reject(createAbortError());
27553
27302
  return;
27554
27303
  }
27555
27304
  const timeoutId = setTimeout(() => {
27556
27305
  cleanup();
27557
- resolve22();
27306
+ resolve2();
27558
27307
  }, delayInMs);
27559
27308
  const cleanup = () => {
27560
27309
  clearTimeout(timeoutId);
@@ -29012,7 +28761,7 @@ function createProviderToolFactoryWithOutputSchema({
29012
28761
  supportsDeferredResults
29013
28762
  });
29014
28763
  }
29015
- async function resolve3(value) {
28764
+ async function resolve2(value) {
29016
28765
  if (typeof value === "function") {
29017
28766
  value = value();
29018
28767
  }
@@ -29051,13 +28800,13 @@ var DelayedPromise = class {
29051
28800
  if (this._promise) {
29052
28801
  return this._promise;
29053
28802
  }
29054
- this._promise = new Promise((resolve22, reject) => {
28803
+ this._promise = new Promise((resolve2, reject) => {
29055
28804
  if (this.status.type === "resolved") {
29056
- resolve22(this.status.value);
28805
+ resolve2(this.status.value);
29057
28806
  } else if (this.status.type === "rejected") {
29058
28807
  reject(this.status.error);
29059
28808
  }
29060
- this._resolve = resolve22;
28809
+ this._resolve = resolve2;
29061
28810
  this._reject = reject;
29062
28811
  });
29063
28812
  return this._promise;
@@ -31515,11 +31264,11 @@ var VERSION2 = "3.0.58", anthropicErrorDataSchema, anthropicFailedResponseHandle
31515
31264
  betas,
31516
31265
  headers
31517
31266
  }) {
31518
- return combineHeaders(await resolve3(this.config.headers), headers, betas.size > 0 ? { "anthropic-beta": Array.from(betas).join(",") } : {});
31267
+ return combineHeaders(await resolve2(this.config.headers), headers, betas.size > 0 ? { "anthropic-beta": Array.from(betas).join(",") } : {});
31519
31268
  }
31520
31269
  async getBetasFromHeaders(requestHeaders) {
31521
31270
  var _a16, _b16;
31522
- const configHeaders = await resolve3(this.config.headers);
31271
+ const configHeaders = await resolve2(this.config.headers);
31523
31272
  const configBetaHeader = (_a16 = configHeaders["anthropic-beta"]) != null ? _a16 : "";
31524
31273
  const requestBetaHeader = (_b16 = requestHeaders == null ? undefined : requestHeaders["anthropic-beta"]) != null ? _b16 : "";
31525
31274
  return new Set([
@@ -42350,7 +42099,7 @@ var import_oidc, import_oidc2, marker17 = "vercel.ai.gateway.error", symbol18, _
42350
42099
  try {
42351
42100
  const { value } = await getFromApi({
42352
42101
  url: `${this.config.baseURL}/config`,
42353
- headers: await resolve3(this.config.headers()),
42102
+ headers: await resolve2(this.config.headers()),
42354
42103
  successfulResponseHandler: createJsonResponseHandler(gatewayAvailableModelsResponseSchema),
42355
42104
  failedResponseHandler: createJsonErrorResponseHandler({
42356
42105
  errorSchema: exports_external.any(),
@@ -42368,7 +42117,7 @@ var import_oidc, import_oidc2, marker17 = "vercel.ai.gateway.error", symbol18, _
42368
42117
  const baseUrl = new URL(this.config.baseURL);
42369
42118
  const { value } = await getFromApi({
42370
42119
  url: `${baseUrl.origin}/v1/credits`,
42371
- headers: await resolve3(this.config.headers()),
42120
+ headers: await resolve2(this.config.headers()),
42372
42121
  successfulResponseHandler: createJsonResponseHandler(gatewayCreditsResponseSchema),
42373
42122
  failedResponseHandler: createJsonErrorResponseHandler({
42374
42123
  errorSchema: exports_external.any(),
@@ -42401,7 +42150,7 @@ var import_oidc, import_oidc2, marker17 = "vercel.ai.gateway.error", symbol18, _
42401
42150
  async doGenerate(options) {
42402
42151
  const { args, warnings } = await this.getArgs(options);
42403
42152
  const { abortSignal } = options;
42404
- const resolvedHeaders = await resolve3(this.config.headers());
42153
+ const resolvedHeaders = await resolve2(this.config.headers());
42405
42154
  try {
42406
42155
  const {
42407
42156
  responseHeaders,
@@ -42409,7 +42158,7 @@ var import_oidc, import_oidc2, marker17 = "vercel.ai.gateway.error", symbol18, _
42409
42158
  rawValue: rawResponse
42410
42159
  } = await postJsonToApi({
42411
42160
  url: this.getUrl(),
42412
- headers: combineHeaders(resolvedHeaders, options.headers, this.getModelConfigHeaders(this.modelId, false), await resolve3(this.config.o11yHeaders)),
42161
+ headers: combineHeaders(resolvedHeaders, options.headers, this.getModelConfigHeaders(this.modelId, false), await resolve2(this.config.o11yHeaders)),
42413
42162
  body: args,
42414
42163
  successfulResponseHandler: createJsonResponseHandler(exports_external.any()),
42415
42164
  failedResponseHandler: createJsonErrorResponseHandler({
@@ -42432,11 +42181,11 @@ var import_oidc, import_oidc2, marker17 = "vercel.ai.gateway.error", symbol18, _
42432
42181
  async doStream(options) {
42433
42182
  const { args, warnings } = await this.getArgs(options);
42434
42183
  const { abortSignal } = options;
42435
- const resolvedHeaders = await resolve3(this.config.headers());
42184
+ const resolvedHeaders = await resolve2(this.config.headers());
42436
42185
  try {
42437
42186
  const { value: response, responseHeaders } = await postJsonToApi({
42438
42187
  url: this.getUrl(),
42439
- headers: combineHeaders(resolvedHeaders, options.headers, this.getModelConfigHeaders(this.modelId, true), await resolve3(this.config.o11yHeaders)),
42188
+ headers: combineHeaders(resolvedHeaders, options.headers, this.getModelConfigHeaders(this.modelId, true), await resolve2(this.config.o11yHeaders)),
42440
42189
  body: args,
42441
42190
  successfulResponseHandler: createEventSourceResponseHandler(exports_external.any()),
42442
42191
  failedResponseHandler: createJsonErrorResponseHandler({
@@ -42521,7 +42270,7 @@ var import_oidc, import_oidc2, marker17 = "vercel.ai.gateway.error", symbol18, _
42521
42270
  providerOptions
42522
42271
  }) {
42523
42272
  var _a92;
42524
- const resolvedHeaders = await resolve3(this.config.headers());
42273
+ const resolvedHeaders = await resolve2(this.config.headers());
42525
42274
  try {
42526
42275
  const {
42527
42276
  responseHeaders,
@@ -42529,7 +42278,7 @@ var import_oidc, import_oidc2, marker17 = "vercel.ai.gateway.error", symbol18, _
42529
42278
  rawValue
42530
42279
  } = await postJsonToApi({
42531
42280
  url: this.getUrl(),
42532
- headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await resolve3(this.config.o11yHeaders)),
42281
+ headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await resolve2(this.config.o11yHeaders)),
42533
42282
  body: {
42534
42283
  values,
42535
42284
  ...providerOptions ? { providerOptions } : {}
@@ -42585,7 +42334,7 @@ var import_oidc, import_oidc2, marker17 = "vercel.ai.gateway.error", symbol18, _
42585
42334
  abortSignal
42586
42335
  }) {
42587
42336
  var _a92, _b92, _c, _d;
42588
- const resolvedHeaders = await resolve3(this.config.headers());
42337
+ const resolvedHeaders = await resolve2(this.config.headers());
42589
42338
  try {
42590
42339
  const {
42591
42340
  responseHeaders,
@@ -42593,7 +42342,7 @@ var import_oidc, import_oidc2, marker17 = "vercel.ai.gateway.error", symbol18, _
42593
42342
  rawValue
42594
42343
  } = await postJsonToApi({
42595
42344
  url: this.getUrl(),
42596
- headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await resolve3(this.config.o11yHeaders)),
42345
+ headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await resolve2(this.config.o11yHeaders)),
42597
42346
  body: {
42598
42347
  prompt,
42599
42348
  n,
@@ -42668,11 +42417,11 @@ var import_oidc, import_oidc2, marker17 = "vercel.ai.gateway.error", symbol18, _
42668
42417
  abortSignal
42669
42418
  }) {
42670
42419
  var _a92;
42671
- const resolvedHeaders = await resolve3(this.config.headers());
42420
+ const resolvedHeaders = await resolve2(this.config.headers());
42672
42421
  try {
42673
42422
  const { responseHeaders, value: responseBody } = await postJsonToApi({
42674
42423
  url: this.getUrl(),
42675
- headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await resolve3(this.config.o11yHeaders), { accept: "text/event-stream" }),
42424
+ headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await resolve2(this.config.o11yHeaders), { accept: "text/event-stream" }),
42676
42425
  body: {
42677
42426
  prompt,
42678
42427
  n,
@@ -46662,8 +46411,8 @@ function writeToServerResponse({
46662
46411
  break;
46663
46412
  const canContinue = response.write(value);
46664
46413
  if (!canContinue) {
46665
- await new Promise((resolve32) => {
46666
- response.once("drain", resolve32);
46414
+ await new Promise((resolve3) => {
46415
+ response.once("drain", resolve3);
46667
46416
  });
46668
46417
  }
46669
46418
  }
@@ -47424,15 +47173,15 @@ async function consumeStream({
47424
47173
  }
47425
47174
  }
47426
47175
  function createResolvablePromise() {
47427
- let resolve32;
47176
+ let resolve3;
47428
47177
  let reject;
47429
47178
  const promise2 = new Promise((res, rej) => {
47430
- resolve32 = res;
47179
+ resolve3 = res;
47431
47180
  reject = rej;
47432
47181
  });
47433
47182
  return {
47434
47183
  promise: promise2,
47435
- resolve: resolve32,
47184
+ resolve: resolve3,
47436
47185
  reject
47437
47186
  };
47438
47187
  }
@@ -48014,7 +47763,7 @@ var import_api, import_api2, __defProp2, __export2 = (target, all) => {
48014
47763
  const schema = asSchema(inputSchema);
48015
47764
  return {
48016
47765
  name: "object",
48017
- responseFormat: resolve3(schema.jsonSchema).then((jsonSchema2) => ({
47766
+ responseFormat: resolve2(schema.jsonSchema).then((jsonSchema2) => ({
48018
47767
  type: "json",
48019
47768
  schema: jsonSchema2,
48020
47769
  ...name21 != null && { name: name21 },
@@ -48075,7 +47824,7 @@ var import_api, import_api2, __defProp2, __export2 = (target, all) => {
48075
47824
  const elementSchema = asSchema(inputElementSchema);
48076
47825
  return {
48077
47826
  name: "array",
48078
- responseFormat: resolve3(elementSchema.jsonSchema).then((jsonSchema2) => {
47827
+ responseFormat: resolve2(elementSchema.jsonSchema).then((jsonSchema2) => {
48079
47828
  const { $schema, ...itemSchema } = jsonSchema2;
48080
47829
  return {
48081
47830
  type: "json",
@@ -52573,7 +52322,7 @@ var init_path = () => {};
52573
52322
  var ENCODINGS, ENCODINGS_ORDERED_KEYS, DEFAULT_DOCUMENT = "index.html", serveStatic = (options) => {
52574
52323
  const root = options.root ?? "./";
52575
52324
  const optionPath = options.path;
52576
- const join5 = options.join ?? defaultJoin;
52325
+ const join3 = options.join ?? defaultJoin;
52577
52326
  return async (c, next) => {
52578
52327
  if (c.finalized) {
52579
52328
  return next();
@@ -52592,9 +52341,9 @@ var ENCODINGS, ENCODINGS_ORDERED_KEYS, DEFAULT_DOCUMENT = "index.html", serveSta
52592
52341
  return next();
52593
52342
  }
52594
52343
  }
52595
- let path = join5(root, !optionPath && options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename);
52344
+ let path = join3(root, !optionPath && options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename);
52596
52345
  if (options.isDir && await options.isDir(path)) {
52597
- path = join5(path, DEFAULT_DOCUMENT);
52346
+ path = join3(path, DEFAULT_DOCUMENT);
52598
52347
  }
52599
52348
  const getContent = options.getContent;
52600
52349
  let content = await getContent(path, c);
@@ -52642,7 +52391,7 @@ var init_serve_static = __esm(() => {
52642
52391
 
52643
52392
  // node_modules/.bun/hono@4.12.5/node_modules/hono/dist/adapter/bun/serve-static.js
52644
52393
  import { stat } from "fs/promises";
52645
- import { join as join5 } from "path";
52394
+ import { join as join3 } from "path";
52646
52395
  var serveStatic2 = (options) => {
52647
52396
  return async function serveStatic22(c, next) {
52648
52397
  const getContent = async (path) => {
@@ -52660,7 +52409,7 @@ var serveStatic2 = (options) => {
52660
52409
  return serveStatic({
52661
52410
  ...options,
52662
52411
  getContent,
52663
- join: join5,
52412
+ join: join3,
52664
52413
  isDir
52665
52414
  })(c, next);
52666
52415
  };
@@ -52826,6 +52575,257 @@ var init_bun = __esm(() => {
52826
52575
  init_server();
52827
52576
  });
52828
52577
 
52578
+ // src/cli/runtime.ts
52579
+ import { existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync4, rmSync, writeFileSync as writeFileSync3 } from "fs";
52580
+ import { homedir as homedir2 } from "os";
52581
+ import { join as join4, resolve as resolve3 } from "path";
52582
+ function getRuntimeDirs() {
52583
+ const override = process.env.LOCAL_ROUTER_RUNTIME_DIR;
52584
+ const root = override?.trim() ? override.trim() : join4(homedir2(), ".local-router");
52585
+ return {
52586
+ root,
52587
+ run: join4(root, "run"),
52588
+ logs: join4(root, "logs")
52589
+ };
52590
+ }
52591
+ function getRuntimeFiles() {
52592
+ const dirs = getRuntimeDirs();
52593
+ return {
52594
+ pid: join4(dirs.run, "local-router.pid"),
52595
+ state: join4(dirs.run, "status.json"),
52596
+ daemonLog: join4(dirs.logs, "daemon.log")
52597
+ };
52598
+ }
52599
+ function ensureRuntimeDirs() {
52600
+ const dirs = getRuntimeDirs();
52601
+ mkdirSync3(dirs.root, { recursive: true });
52602
+ mkdirSync3(dirs.run, { recursive: true });
52603
+ mkdirSync3(dirs.logs, { recursive: true });
52604
+ }
52605
+ function writeRuntimeState(state) {
52606
+ ensureRuntimeDirs();
52607
+ const files = getRuntimeFiles();
52608
+ writeFileSync3(files.pid, `${state.pid}
52609
+ `, "utf-8");
52610
+ writeFileSync3(files.state, JSON.stringify(state, null, 2), "utf-8");
52611
+ }
52612
+ function readRuntimeState() {
52613
+ const files = getRuntimeFiles();
52614
+ if (!existsSync2(files.state)) {
52615
+ return null;
52616
+ }
52617
+ try {
52618
+ return JSON.parse(readFileSync4(files.state, "utf-8"));
52619
+ } catch {
52620
+ return null;
52621
+ }
52622
+ }
52623
+ function clearRuntimeFiles() {
52624
+ const files = getRuntimeFiles();
52625
+ rmSync(files.pid, { force: true });
52626
+ rmSync(files.state, { force: true });
52627
+ }
52628
+ function resolveConfigArgPath(pathValue) {
52629
+ return resolve3(pathValue);
52630
+ }
52631
+ var init_runtime = () => {};
52632
+
52633
+ // src/cli/autostart.ts
52634
+ import { execSync } from "child_process";
52635
+ import { existsSync as existsSync3, mkdirSync as mkdirSync4, readFileSync as readFileSync5, rmSync as rmSync2, writeFileSync as writeFileSync4 } from "fs";
52636
+ import { homedir as homedir3, platform } from "os";
52637
+ import { dirname as dirname3, join as join5 } from "path";
52638
+ function getDaemonLogPath() {
52639
+ return getRuntimeDirs().logs + "/daemon.log";
52640
+ }
52641
+ function getLaunchAgentPath() {
52642
+ return join5(homedir3(), "Library", "LaunchAgents", `${LABEL}.plist`);
52643
+ }
52644
+ function buildPlist(opts) {
52645
+ const logPath = getDaemonLogPath();
52646
+ const args = [opts.execPath, ...opts.args].map((a) => ` <string>${escapeXml(a)}</string>`).join(`
52647
+ `);
52648
+ return `<?xml version="1.0" encoding="UTF-8"?>
52649
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
52650
+ <plist version="1.0">
52651
+ <dict>
52652
+ <key>Label</key>
52653
+ <string>${escapeXml(opts.label)}</string>
52654
+ <key>ProgramArguments</key>
52655
+ <array>
52656
+ ${args}
52657
+ </array>
52658
+ <key>RunAtLoad</key>
52659
+ <true/>
52660
+ <key>KeepAlive</key>
52661
+ <false/>
52662
+ <key>StandardOutPath</key>
52663
+ <string>${escapeXml(logPath)}</string>
52664
+ <key>StandardErrorPath</key>
52665
+ <string>${escapeXml(logPath)}</string>
52666
+ </dict>
52667
+ </plist>
52668
+ `;
52669
+ }
52670
+ function escapeXml(s) {
52671
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
52672
+ }
52673
+ function createMacosManager() {
52674
+ const plistPath = getLaunchAgentPath();
52675
+ return {
52676
+ platform: "macos",
52677
+ async isInstalled() {
52678
+ return existsSync3(plistPath);
52679
+ },
52680
+ async install(opts) {
52681
+ const dir = dirname3(plistPath);
52682
+ if (!existsSync3(dir))
52683
+ mkdirSync4(dir, { recursive: true });
52684
+ writeFileSync4(plistPath, buildPlist(opts), "utf-8");
52685
+ try {
52686
+ execSync(`launchctl bootout gui/$(id -u) ${plistPath} 2>/dev/null`, { stdio: "ignore" });
52687
+ } catch {}
52688
+ execSync(`launchctl bootstrap gui/$(id -u) ${plistPath}`, { stdio: "ignore" });
52689
+ },
52690
+ async uninstall() {
52691
+ if (!existsSync3(plistPath))
52692
+ return;
52693
+ try {
52694
+ execSync(`launchctl bootout gui/$(id -u) ${plistPath}`, { stdio: "ignore" });
52695
+ } catch {}
52696
+ rmSync2(plistPath, { force: true });
52697
+ },
52698
+ getServicePath() {
52699
+ return plistPath;
52700
+ }
52701
+ };
52702
+ }
52703
+ function getSystemdUnitPath() {
52704
+ return join5(homedir3(), ".config", "systemd", "user", "local-router.service");
52705
+ }
52706
+ function buildUnit(opts) {
52707
+ const logPath = getDaemonLogPath();
52708
+ const execStart = [opts.execPath, ...opts.args].join(" ");
52709
+ return `[Unit]
52710
+ Description=Local Router API Gateway
52711
+ After=network-online.target
52712
+
52713
+ [Service]
52714
+ Type=simple
52715
+ ExecStart=${execStart}
52716
+ Restart=on-failure
52717
+ RestartSec=5
52718
+ StandardOutput=append:${logPath}
52719
+ StandardError=append:${logPath}
52720
+
52721
+ [Install]
52722
+ WantedBy=default.target
52723
+ `;
52724
+ }
52725
+ function createLinuxManager() {
52726
+ const unitPath = getSystemdUnitPath();
52727
+ return {
52728
+ platform: "linux",
52729
+ async isInstalled() {
52730
+ if (!existsSync3(unitPath))
52731
+ return false;
52732
+ try {
52733
+ const out = execSync("systemctl --user is-enabled local-router 2>/dev/null", {
52734
+ encoding: "utf-8"
52735
+ }).trim();
52736
+ return out === "enabled";
52737
+ } catch {
52738
+ return false;
52739
+ }
52740
+ },
52741
+ async install(opts) {
52742
+ const dir = dirname3(unitPath);
52743
+ if (!existsSync3(dir))
52744
+ mkdirSync4(dir, { recursive: true });
52745
+ writeFileSync4(unitPath, buildUnit(opts), "utf-8");
52746
+ execSync("systemctl --user daemon-reload", { stdio: "ignore" });
52747
+ execSync("systemctl --user enable local-router", { stdio: "ignore" });
52748
+ },
52749
+ async uninstall() {
52750
+ try {
52751
+ execSync("systemctl --user disable local-router", { stdio: "ignore" });
52752
+ } catch {}
52753
+ rmSync2(unitPath, { force: true });
52754
+ try {
52755
+ execSync("systemctl --user daemon-reload", { stdio: "ignore" });
52756
+ } catch {}
52757
+ },
52758
+ getServicePath() {
52759
+ return unitPath;
52760
+ }
52761
+ };
52762
+ }
52763
+ function createWindowsManager() {
52764
+ return {
52765
+ platform: "windows",
52766
+ async isInstalled() {
52767
+ try {
52768
+ execSync(`reg query "${WIN_REG_KEY}" /v ${WIN_REG_VALUE}`, { stdio: "ignore" });
52769
+ return true;
52770
+ } catch {
52771
+ return false;
52772
+ }
52773
+ },
52774
+ async install(opts) {
52775
+ const cmd = [opts.execPath, ...opts.args].map((a) => `"${a}"`).join(" ");
52776
+ execSync(`reg add "${WIN_REG_KEY}" /v ${WIN_REG_VALUE} /t REG_SZ /d "${cmd}" /f`, {
52777
+ stdio: "ignore"
52778
+ });
52779
+ },
52780
+ async uninstall() {
52781
+ try {
52782
+ execSync(`reg delete "${WIN_REG_KEY}" /v ${WIN_REG_VALUE} /f`, { stdio: "ignore" });
52783
+ } catch {}
52784
+ },
52785
+ getServicePath() {
52786
+ return `${WIN_REG_KEY}\\${WIN_REG_VALUE}`;
52787
+ }
52788
+ };
52789
+ }
52790
+ function createUnsupportedManager() {
52791
+ return {
52792
+ platform: "unsupported",
52793
+ async isInstalled() {
52794
+ return false;
52795
+ },
52796
+ async install() {
52797
+ throw new Error("\u5F53\u524D\u5E73\u53F0\u4E0D\u652F\u6301\u81EA\u542F\u52A8");
52798
+ },
52799
+ async uninstall() {
52800
+ throw new Error("\u5F53\u524D\u5E73\u53F0\u4E0D\u652F\u6301\u81EA\u542F\u52A8");
52801
+ },
52802
+ getServicePath() {
52803
+ return "";
52804
+ }
52805
+ };
52806
+ }
52807
+ function createAutostartManager() {
52808
+ const p = platform();
52809
+ if (p === "darwin")
52810
+ return createMacosManager();
52811
+ if (p === "linux")
52812
+ return createLinuxManager();
52813
+ if (p === "win32")
52814
+ return createWindowsManager();
52815
+ return createUnsupportedManager();
52816
+ }
52817
+ function getAutostartExecArgs() {
52818
+ const script = process.argv[1] ?? "dist/cli.js";
52819
+ return {
52820
+ execPath: process.execPath,
52821
+ args: [script, "__run-server", "--mode", "daemon"]
52822
+ };
52823
+ }
52824
+ var LABEL = "com.lakphy.local-router", WIN_REG_KEY = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", WIN_REG_VALUE = "LocalRouter";
52825
+ var init_autostart = __esm(() => {
52826
+ init_runtime();
52827
+ });
52828
+
52829
52829
  // src/config-store.ts
52830
52830
  import { writeFileSync as writeFileSync5 } from "fs";
52831
52831
  import { resolve as resolve4 } from "path";
@@ -57455,6 +57455,97 @@ var init_openapi = __esm(() => {
57455
57455
  }
57456
57456
  }
57457
57457
  },
57458
+ "/api/models": {
57459
+ get: {
57460
+ tags: ["Health"],
57461
+ summary: "\u55C5\u63A2\u53EF\u7528\u6A21\u578B\u8DEF\u7531",
57462
+ description: "\u8FD4\u56DE\u672C\u673A\u6307\u5B9A\u534F\u8BAE\u4E0B\u53EF\u7528\u7684\u6A21\u578B\u8DEF\u7531\u522B\u540D\uFF08routes[protocol] \u7684 key\uFF0C\u6392\u9664 * \u901A\u914D\uFF09\u3002\u4F9B\u5C40\u57DF\u7F51\u5185\u5176\u4ED6 local-router \u63A2\u6D4B\u4F7F\u7528\u3002",
57463
+ parameters: [
57464
+ {
57465
+ name: "protocol",
57466
+ in: "query",
57467
+ required: true,
57468
+ schema: {
57469
+ type: "string",
57470
+ enum: ["openai-completions", "openai-responses", "anthropic-messages"]
57471
+ },
57472
+ description: "\u534F\u8BAE\u7C7B\u578B"
57473
+ }
57474
+ ],
57475
+ responses: {
57476
+ "200": {
57477
+ description: "\u53EF\u7528\u6A21\u578B\u8DEF\u7531\u5217\u8868",
57478
+ content: {
57479
+ "application/json": {
57480
+ schema: {
57481
+ type: "object",
57482
+ properties: {
57483
+ protocol: { type: "string", example: "anthropic-messages" },
57484
+ models: {
57485
+ type: "array",
57486
+ items: { type: "string" },
57487
+ example: ["claude-3-5-sonnet", "claude-3-opus"]
57488
+ }
57489
+ }
57490
+ }
57491
+ }
57492
+ }
57493
+ },
57494
+ "400": { description: "\u534F\u8BAE\u53C2\u6570\u7F3A\u5931\u6216\u65E0\u6548" }
57495
+ }
57496
+ }
57497
+ },
57498
+ "/api/providers/discover": {
57499
+ get: {
57500
+ tags: ["Health"],
57501
+ summary: "\u53D1\u73B0\u5C40\u57DF\u7F51 local-router \u7684\u6A21\u578B",
57502
+ description: "\u7531\u672C\u673A server \u4EE3\u4E3A\u8BF7\u6C42\u5BF9\u7AEF local-router \u7684 /api/models\uFF08\u89C4\u907F\u6D4F\u89C8\u5668\u8DE8\u57DF\uFF09\uFF0C\u8FD4\u56DE\u5BF9\u7AEF\u67D0\u534F\u8BAE\u4E0B\u7684\u53EF\u7528\u6A21\u578B\u8DEF\u7531\u3002",
57503
+ parameters: [
57504
+ {
57505
+ name: "ip",
57506
+ in: "query",
57507
+ required: true,
57508
+ schema: { type: "string" },
57509
+ description: "\u5BF9\u7AEF IP"
57510
+ },
57511
+ {
57512
+ name: "port",
57513
+ in: "query",
57514
+ required: false,
57515
+ schema: { type: "string", default: "4099" },
57516
+ description: "\u5BF9\u7AEF\u7AEF\u53E3\uFF0C\u9ED8\u8BA4 4099"
57517
+ },
57518
+ {
57519
+ name: "protocol",
57520
+ in: "query",
57521
+ required: true,
57522
+ schema: {
57523
+ type: "string",
57524
+ enum: ["openai-completions", "openai-responses", "anthropic-messages"]
57525
+ },
57526
+ description: "\u534F\u8BAE\u7C7B\u578B"
57527
+ }
57528
+ ],
57529
+ responses: {
57530
+ "200": {
57531
+ description: "\u5BF9\u7AEF\u53EF\u7528\u6A21\u578B\u8DEF\u7531\u5217\u8868",
57532
+ content: {
57533
+ "application/json": {
57534
+ schema: {
57535
+ type: "object",
57536
+ properties: {
57537
+ protocol: { type: "string", example: "anthropic-messages" },
57538
+ models: { type: "array", items: { type: "string" } }
57539
+ }
57540
+ }
57541
+ }
57542
+ }
57543
+ },
57544
+ "400": { description: "\u53C2\u6570\u7F3A\u5931" },
57545
+ "502": { description: "\u65E0\u6CD5\u8FDE\u63A5\u5BF9\u7AEF\u6216\u5BF9\u7AEF\u8FD4\u56DE\u9519\u8BEF" }
57546
+ }
57547
+ }
57548
+ },
57458
57549
  "/api/metrics/logs": {
57459
57550
  get: {
57460
57551
  tags: ["Health"],
@@ -59452,6 +59543,43 @@ function createAdminApiRoutes(store, pluginManager, registerCleanup) {
59452
59543
  routeTypes: Object.keys(ROUTE_REGISTRY)
59453
59544
  });
59454
59545
  });
59546
+ api2.get("/models", (c) => {
59547
+ const protocol = c.req.query("protocol");
59548
+ const routeTypes = Object.keys(ROUTE_REGISTRY);
59549
+ if (!protocol || !routeTypes.includes(protocol)) {
59550
+ return c.json({ error: "invalid or missing protocol", routeTypes }, 400);
59551
+ }
59552
+ const routes = store.get().routes[protocol] ?? {};
59553
+ const models = Object.keys(routes).filter((k) => k !== "*");
59554
+ return c.json({ protocol, models });
59555
+ });
59556
+ api2.get("/providers/discover", async (c) => {
59557
+ const ip = c.req.query("ip");
59558
+ const portStr = c.req.query("port") ?? "4099";
59559
+ const protocol = c.req.query("protocol");
59560
+ if (!ip || !protocol) {
59561
+ return c.json({ error: "ip and protocol are required" }, 400);
59562
+ }
59563
+ const port = Number(portStr);
59564
+ if (!Number.isInteger(port) || port < 1 || port > 65535) {
59565
+ return c.json({ error: "\u7AEF\u53E3\u65E0\u6548\uFF0C\u5FC5\u987B\u662F 1-65535 \u7684\u6574\u6570" }, 400);
59566
+ }
59567
+ if (!isLoopbackAddress(ip) && !isLanAddress(ip)) {
59568
+ return c.json({ error: "\u4EC5\u652F\u6301\u5C40\u57DF\u7F51\u6216\u672C\u673A IP \u5730\u5740" }, 400);
59569
+ }
59570
+ const url2 = `http://${ip}:${port}/api/models?protocol=${encodeURIComponent(protocol)}`;
59571
+ try {
59572
+ const res = await fetch(url2, { signal: AbortSignal.timeout(5000) });
59573
+ if (!res.ok) {
59574
+ const body = await res.json().catch(() => ({}));
59575
+ return c.json({ error: body.error ?? `remote returned ${res.status}` }, 502);
59576
+ }
59577
+ const data = await res.json();
59578
+ return c.json(data);
59579
+ } catch (err) {
59580
+ return c.json({ error: `\u65E0\u6CD5\u8FDE\u63A5\u5BF9\u7AEF local-router: ${err instanceof Error ? err.message : err}` }, 502);
59581
+ }
59582
+ });
59455
59583
  api2.get("/config/schema", (c) => {
59456
59584
  try {
59457
59585
  return c.json(schemaJson);
@@ -60035,7 +60163,6 @@ async function createAppRuntimeFromConfigPath(configPath, listen) {
60035
60163
  }
60036
60164
  var ROUTE_REGISTRY;
60037
60165
  var init_src = __esm(() => {
60038
- init_autostart();
60039
60166
  init_dist4();
60040
60167
  init_dist5();
60041
60168
  init_dist6();
@@ -60043,6 +60170,7 @@ var init_src = __esm(() => {
60043
60170
  init_dist9();
60044
60171
  init_dist10();
60045
60172
  init_bun();
60173
+ init_autostart();
60046
60174
  init_config();
60047
60175
  init_config_store();
60048
60176
  init_config_validate();
@@ -61537,6 +61665,7 @@ Commands:
61537
61665
  config provider list [--json] [--config <path>]
61538
61666
  config provider show <name> [--show-secrets] [--config <path>]
61539
61667
  config provider add <name> --type <type> --base <url> --api-key <key> --model <name> [--image-input] [--reasoning] [--proxy <url>] [--dry-run] [--config <path>]
61668
+ config provider add-lan <ip> --type <protocol> [--port 4099] [--dry-run] [--config <path>]
61540
61669
  config provider set <name> [--base <url>] [--api-key <key>] [--proxy <url>] [--dry-run] [--config <path>]
61541
61670
  config provider remove <name> [--force] [--dry-run] [--config <path>]
61542
61671
  config provider model list <provider> [--config <path>]
@@ -61716,6 +61845,89 @@ async function handleProviderAdd(args, flags) {
61716
61845
  }
61717
61846
  });
61718
61847
  }
61848
+ async function handleProviderAddLan(args, flags) {
61849
+ return runCommand({
61850
+ command: "config.provider.add-lan",
61851
+ flags,
61852
+ fn: async (ctx) => {
61853
+ const [ip, ...flagArgs] = args;
61854
+ ensureNoFlag("ip", ip);
61855
+ if (!ip) {
61856
+ throw new CliError("USAGE_ERROR", "ip \u5FC5\u586B", {
61857
+ hint: "\u7528\u6CD5: config provider add-lan <ip> --type <protocol> [--port 4099]"
61858
+ });
61859
+ }
61860
+ const parsed = parseArgs3({
61861
+ args: flagArgs,
61862
+ options: {
61863
+ type: { type: "string" },
61864
+ port: { type: "string", default: "4099" },
61865
+ "dry-run": { type: "boolean", default: false },
61866
+ config: { type: "string" }
61867
+ },
61868
+ allowPositionals: true,
61869
+ strict: false
61870
+ });
61871
+ const type = parsed.values.type;
61872
+ if (!type || !providerTypes().includes(type)) {
61873
+ throw new CliError("USAGE_ERROR", "type \u5FC5\u586B\u4E14\u5FC5\u987B\u662F openai-completions/openai-responses/anthropic-messages", { details: { acceptable: providerTypes() } });
61874
+ }
61875
+ const portStr = parsed.values.port ?? "4099";
61876
+ const port = Number(portStr);
61877
+ if (!Number.isInteger(port) || port < 1 || port > 65535) {
61878
+ throw new CliError("USAGE_ERROR", `\u7AEF\u53E3\u65E0\u6548: ${portStr}\uFF08\u5FC5\u987B\u662F 1-65535 \u7684\u6574\u6570\uFF09`);
61879
+ }
61880
+ const name21 = `${ip}-${type}`;
61881
+ const { path, config: config2 } = readConfig(parsed.values.config);
61882
+ if (config2.providers[name21]) {
61883
+ throw new CliError("PROVIDER_EXISTS", `provider \u5DF2\u5B58\u5728: ${name21}`, {
61884
+ hint: "\u4F7F\u7528 `config provider set` \u4FEE\u6539\u5B57\u6BB5"
61885
+ });
61886
+ }
61887
+ const url2 = `http://${ip}:${port}/api/models?protocol=${encodeURIComponent(type)}`;
61888
+ let models;
61889
+ try {
61890
+ const res = await fetch(url2, { signal: AbortSignal.timeout(5000) });
61891
+ if (!res.ok) {
61892
+ const body = await res.json().catch(() => ({}));
61893
+ throw new CliError("UPSTREAM_UNREACHABLE", `\u5BF9\u7AEF\u8FD4\u56DE\u9519\u8BEF: ${body.error ?? res.status}`, {
61894
+ details: { url: url2 }
61895
+ });
61896
+ }
61897
+ const data = await res.json();
61898
+ models = Array.isArray(data.models) ? data.models : [];
61899
+ } catch (err) {
61900
+ if (err instanceof CliError)
61901
+ throw err;
61902
+ throw new CliError("UPSTREAM_UNREACHABLE", `\u65E0\u6CD5\u8FDE\u63A5\u5BF9\u7AEF local-router: ${err instanceof Error ? err.message : err}`, { details: { url: url2 } });
61903
+ }
61904
+ if (models.length === 0) {
61905
+ throw new CliError("USAGE_ERROR", `\u5BF9\u7AEF\u5728\u534F\u8BAE "${type}" \u4E0B\u6CA1\u6709\u53EF\u7528\u7684\u6A21\u578B\u8DEF\u7531\uFF0C\u65E0\u6CD5\u521B\u5EFA provider`, { hint: "\u786E\u8BA4\u5BF9\u7AEF\u5DF2\u4E3A\u8BE5\u534F\u8BAE\u914D\u7F6E\u4E86\u5177\u4F53\u6A21\u578B\u8DEF\u7531\uFF08\u800C\u975E\u4EC5 * \u515C\u5E95\uFF09" });
61906
+ }
61907
+ const modelMap = {};
61908
+ for (const m of models) {
61909
+ modelMap[m] = { "image-input": false, reasoning: false };
61910
+ }
61911
+ config2.providers[name21] = {
61912
+ type,
61913
+ base: `http://${ip}:${port}/${type}`,
61914
+ apiKey: "no_key",
61915
+ models: modelMap
61916
+ };
61917
+ const result = applyConfigChange(path, config2, { dryRun: parsed.values["dry-run"] });
61918
+ emitResult(ctx, {
61919
+ command: "config.provider.add-lan",
61920
+ data: { provider: name21, models: models.length, ...result },
61921
+ md: {
61922
+ heading: `config.provider.add-lan \xB7 ${name21} \xB7 ${result.written ? "\u2713" : "dry-run"}`,
61923
+ data: applyResultToMd(result, `provider ${name21} (${models.length} \u4E2A\u6A21\u578B)`),
61924
+ hints: result.written ? ["\u70ED\u52A0\u8F7D: `local-router config apply`"] : ["\u6267\u884C\u5199\u5165: \u53BB\u6389 `--dry-run`"]
61925
+ },
61926
+ text: result.written ? `\u5DF2\u6DFB\u52A0 provider: ${name21}\uFF08\u55C5\u63A2\u5230 ${models.length} \u4E2A\u6A21\u578B\uFF09` : applyResultToText(result)
61927
+ });
61928
+ }
61929
+ });
61930
+ }
61719
61931
  async function handleProviderSet(args, flags) {
61720
61932
  return runCommand({
61721
61933
  command: "config.provider.set",
@@ -62338,6 +62550,8 @@ async function handleProvider(args, flags) {
62338
62550
  return handleProviderShow(rest, flags);
62339
62551
  case "add":
62340
62552
  return handleProviderAdd(rest, flags);
62553
+ case "add-lan":
62554
+ return handleProviderAddLan(rest, flags);
62341
62555
  case "set":
62342
62556
  return handleProviderSet(rest, flags);
62343
62557
  case "remove":
@@ -62445,7 +62659,11 @@ async function dispatchConfig(group, rest, flags) {
62445
62659
  init_registry();
62446
62660
  var PROVIDER_TYPE_ENUM = ["openai-completions", "openai-responses", "anthropic-messages"];
62447
62661
  var COMMON_CONFIG_FLAG = { name: "config", type: "string", description: "\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84" };
62448
- var DRY_RUN_FLAG = { name: "dry-run", type: "boolean", description: "\u53EA\u9884\u89C8 diff\uFF0C\u4E0D\u5199\u5165" };
62662
+ var DRY_RUN_FLAG = {
62663
+ name: "dry-run",
62664
+ type: "boolean",
62665
+ description: "\u53EA\u9884\u89C8 diff\uFF0C\u4E0D\u5199\u5165"
62666
+ };
62449
62667
  function forward(prefix) {
62450
62668
  return async (args, flags) => cmdConfig([...prefix, ...args], flags);
62451
62669
  }
@@ -62462,10 +62680,7 @@ defineCommand({
62462
62680
  defineCommand({
62463
62681
  name: "config diff",
62464
62682
  summary: "\u4E0E\u5907\u4EFD\u6216\u6307\u5B9A\u6587\u4EF6\u5BF9\u6BD4",
62465
- flags: [
62466
- { name: "against", type: "string", description: "\u5907\u4EFD id \u6216\u8DEF\u5F84" },
62467
- COMMON_CONFIG_FLAG
62468
- ],
62683
+ flags: [{ name: "against", type: "string", description: "\u5907\u4EFD id \u6216\u8DEF\u5F84" }, COMMON_CONFIG_FLAG],
62469
62684
  supportsJson: true,
62470
62685
  handler: forward(["diff"])
62471
62686
  });
@@ -62579,6 +62794,26 @@ defineCommand({
62579
62794
  supportsJson: true,
62580
62795
  handler: forward(["provider", "add"])
62581
62796
  });
62797
+ defineCommand({
62798
+ name: "config provider add-lan",
62799
+ summary: "\u4ECE\u5C40\u57DF\u7F51\u5185\u5176\u4ED6 local-router \u55C5\u63A2\u5E76\u65B0\u589E provider",
62800
+ positionals: [{ name: "ip", required: true, description: "\u5BF9\u7AEF IP" }],
62801
+ flags: [
62802
+ {
62803
+ name: "type",
62804
+ type: "enum",
62805
+ enum: [...PROVIDER_TYPE_ENUM],
62806
+ required: true,
62807
+ description: "\u534F\u8BAE\u7C7B\u578B"
62808
+ },
62809
+ { name: "port", type: "string", description: "\u5BF9\u7AEF\u7AEF\u53E3\uFF08\u9ED8\u8BA4 4099\uFF09" },
62810
+ DRY_RUN_FLAG,
62811
+ COMMON_CONFIG_FLAG
62812
+ ],
62813
+ mutates: true,
62814
+ supportsJson: true,
62815
+ handler: forward(["provider", "add-lan"])
62816
+ });
62582
62817
  defineCommand({
62583
62818
  name: "config provider set",
62584
62819
  summary: "\u4FEE\u6539 provider \u5B57\u6BB5",
@@ -62664,10 +62899,7 @@ defineCommand({
62664
62899
  defineCommand({
62665
62900
  name: "config route list",
62666
62901
  summary: "\u5217\u51FA\u6240\u6709\u8DEF\u7531",
62667
- flags: [
62668
- { name: "entry", type: "string", description: "\u53EA\u770B\u67D0\u5165\u53E3" },
62669
- COMMON_CONFIG_FLAG
62670
- ],
62902
+ flags: [{ name: "entry", type: "string", description: "\u53EA\u770B\u67D0\u5165\u53E3" }, COMMON_CONFIG_FLAG],
62671
62903
  supportsJson: true,
62672
62904
  handler: forward(["route", "list"])
62673
62905
  });