nextclaw 0.13.22 → 0.13.23

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 (30) hide show
  1. package/README.md +2 -2
  2. package/dist/cli/index.js +47 -38
  3. package/package.json +8 -8
  4. package/templates/USAGE.md +19 -19
  5. package/ui-dist/assets/{ChannelsList-CIMYaIji.js → ChannelsList-a063_8pv.js} +1 -1
  6. package/ui-dist/assets/{ChatPage-B5UpeEIp.js → ChatPage-CMthudUt.js} +1 -1
  7. package/ui-dist/assets/{DocBrowser-BJ610SPa.js → DocBrowser-BOvBC_5q.js} +1 -1
  8. package/ui-dist/assets/{LogoBadge-BKq1GKWP.js → LogoBadge-BUvLZbji.js} +1 -1
  9. package/ui-dist/assets/{MarketplacePage-Bs3sLsgx.js → MarketplacePage-CcbfvtGX.js} +1 -1
  10. package/ui-dist/assets/{McpMarketplacePage-BWTguHCs.js → McpMarketplacePage-D56yvyWI.js} +1 -1
  11. package/ui-dist/assets/{ModelConfig-B-oTP-Bc.js → ModelConfig-D5AuTffd.js} +1 -1
  12. package/ui-dist/assets/{ProvidersList-r7bD0-R0.js → ProvidersList-Bd4n7muZ.js} +1 -1
  13. package/ui-dist/assets/{RemoteAccessPage-D7On6waK.js → RemoteAccessPage-Be8jduPM.js} +1 -1
  14. package/ui-dist/assets/{RuntimeConfig-C11xVxH9.js → RuntimeConfig-D8DYogZ1.js} +1 -1
  15. package/ui-dist/assets/{SearchConfig-BVZdCxiM.js → SearchConfig-BtiGCmXR.js} +1 -1
  16. package/ui-dist/assets/{SecretsConfig-DuEDdC3X.js → SecretsConfig-fwAjbwlq.js} +1 -1
  17. package/ui-dist/assets/{SessionsConfig-Y-Blf_-K.js → SessionsConfig-Y7_TDSk2.js} +1 -1
  18. package/ui-dist/assets/{chat-message-B6VCCEXF.js → chat-message-Cwq8nW0e.js} +1 -1
  19. package/ui-dist/assets/index-C6dwNe7e.js +8 -0
  20. package/ui-dist/assets/{label-DzwitL78.js → label-C0dJBNgU.js} +1 -1
  21. package/ui-dist/assets/{page-layout-DEq5N_8L.js → page-layout-4_789zOC.js} +1 -1
  22. package/ui-dist/assets/{popover-CY54V8F6.js → popover-CWmq2f6H.js} +1 -1
  23. package/ui-dist/assets/{security-config-CgbYP57d.js → security-config-CZeVwEwq.js} +1 -1
  24. package/ui-dist/assets/{skeleton-zjQZMWu9.js → skeleton-kjkadEki.js} +1 -1
  25. package/ui-dist/assets/{status-dot-CU_P0tvO.js → status-dot-C7cVa53V.js} +1 -1
  26. package/ui-dist/assets/{switch-PvjTvlcs.js → switch-C6zdGbY0.js} +1 -1
  27. package/ui-dist/assets/{tabs-custom-Bke5J9ny.js → tabs-custom-BQj0Z-ZC.js} +1 -1
  28. package/ui-dist/assets/{useConfirmDialog-8tzzp_oW.js → useConfirmDialog-yX-ZMNf9.js} +1 -1
  29. package/ui-dist/index.html +1 -1
  30. package/ui-dist/assets/index-DvA7S11O.js +0 -8
package/README.md CHANGED
@@ -14,9 +14,9 @@ npm i -g nextclaw
14
14
  nextclaw start
15
15
  ```
16
16
 
17
- Then open `http://127.0.0.1:18791`.
17
+ Then open `http://127.0.0.1:55667`.
18
18
 
19
- On a VPS, NextClaw serves plain HTTP on `18791`. Use `http://<server-ip>:18791` directly for a quick check, or put Nginx/Caddy in front for `80/443`. `https://` must be terminated by the reverse proxy, not by NextClaw itself.
19
+ On a VPS, NextClaw serves plain HTTP on `55667`. Use `http://<server-ip>:55667` directly for a quick check, or put Nginx/Caddy in front for `80/443`. `https://` must be terminated by the reverse proxy, not by NextClaw itself.
20
20
 
21
21
  ## Common commands
22
22
 
package/dist/cli/index.js CHANGED
@@ -771,7 +771,7 @@ import { isIP } from "net";
771
771
  import { fileURLToPath } from "url";
772
772
  import { getDataDir as getDataDir2, getPackageVersion as getCorePackageVersion } from "@nextclaw/core";
773
773
  function resolveUiConfig(config2, overrides) {
774
- const base = config2.ui ?? { enabled: false, host: "127.0.0.1", port: 18791, open: false };
774
+ const base = config2.ui ?? { enabled: false, host: "127.0.0.1", port: 55667, open: false };
775
775
  return { ...base, ...overrides ?? {} };
776
776
  }
777
777
  function resolveUiApiBase(host, port) {
@@ -3067,8 +3067,7 @@ var PlatformAuthCommands = class {
3067
3067
  async loginResult(opts = {}) {
3068
3068
  const { configPath, config: config2, providers, nextclawProvider, platformBase, v1Base, inputApiBase } = resolveProviderConfig(opts);
3069
3069
  const { email, password } = await resolveCredentials(opts);
3070
- const endpoint = opts.register ? `${platformBase}/platform/auth/register` : `${platformBase}/platform/auth/login`;
3071
- const response = await fetch(endpoint, {
3070
+ const response = await fetch(`${platformBase}/platform/auth/login`, {
3072
3071
  method: "POST",
3073
3072
  headers: {
3074
3073
  "Content-Type": "application/json"
@@ -3181,7 +3180,9 @@ var PlatformAuthCommands = class {
3181
3180
 
3182
3181
  // src/cli/commands/remote.ts
3183
3182
  import { getConfigPath as getConfigPath5, loadConfig as loadConfig10, saveConfig as saveConfig7 } from "@nextclaw/core";
3184
- import "@nextclaw/remote";
3183
+ import {
3184
+ readPlatformSessionTokenState
3185
+ } from "@nextclaw/remote";
3185
3186
  import { hostname } from "os";
3186
3187
 
3187
3188
  // src/cli/commands/remote-runtime-support.ts
@@ -3262,15 +3263,12 @@ function normalizeOptionalString3(value) {
3262
3263
  const trimmed = value.trim();
3263
3264
  return trimmed.length > 0 ? trimmed : void 0;
3264
3265
  }
3265
- function isPlatformSessionToken(value) {
3266
- return typeof value === "string" && value.startsWith("nca.");
3267
- }
3268
3266
  function resolveConfiguredLocalOrigin(config2) {
3269
3267
  const state = readServiceState();
3270
3268
  if (state && isProcessRunning(state.pid) && Number.isFinite(state.uiPort)) {
3271
3269
  return `http://127.0.0.1:${state.uiPort}`;
3272
3270
  }
3273
- const port = typeof config2.ui.port === "number" && Number.isFinite(config2.ui.port) ? config2.ui.port : 18791;
3271
+ const port = typeof config2.ui.port === "number" && Number.isFinite(config2.ui.port) ? config2.ui.port : 55667;
3274
3272
  return `http://127.0.0.1:${port}`;
3275
3273
  }
3276
3274
  async function probeLocalUi(localOrigin) {
@@ -3287,6 +3285,35 @@ async function probeLocalUi(localOrigin) {
3287
3285
  };
3288
3286
  }
3289
3287
  }
3288
+ function describePlatformTokenCheck(token) {
3289
+ const tokenState = readPlatformSessionTokenState(token);
3290
+ if (tokenState.valid) {
3291
+ return {
3292
+ name: "platform-token",
3293
+ ok: true,
3294
+ detail: "platform session token configured"
3295
+ };
3296
+ }
3297
+ if (tokenState.reason === "expired") {
3298
+ return {
3299
+ name: "platform-token",
3300
+ ok: false,
3301
+ detail: 'platform session token expired; run remote browser login or "nextclaw login" again'
3302
+ };
3303
+ }
3304
+ if (tokenState.reason === "malformed") {
3305
+ return {
3306
+ name: "platform-token",
3307
+ ok: false,
3308
+ detail: 'platform session token invalid; run remote browser login or "nextclaw login" again'
3309
+ };
3310
+ }
3311
+ return {
3312
+ name: "platform-token",
3313
+ ok: false,
3314
+ detail: 'run remote browser login or "nextclaw login" first'
3315
+ };
3316
+ }
3290
3317
  var RemoteCommands = class {
3291
3318
  constructor(deps = {}) {
3292
3319
  this.deps = deps;
@@ -3377,11 +3404,7 @@ var RemoteCommands = class {
3377
3404
  ok: snapshot.configuredEnabled,
3378
3405
  detail: snapshot.configuredEnabled ? "enabled in config" : "disabled in config"
3379
3406
  },
3380
- {
3381
- name: "platform-token",
3382
- ok: isPlatformSessionToken(token),
3383
- detail: isPlatformSessionToken(token) ? "platform session token configured" : 'run remote browser login or "nextclaw login" first'
3384
- },
3407
+ describePlatformTokenCheck(token),
3385
3408
  {
3386
3409
  name: "platform-api-base",
3387
3410
  ok: Boolean(platformApiBase),
@@ -3545,7 +3568,7 @@ var DiagnosticsCommands = class {
3545
3568
  const base = report.process.running && report.endpoints.uiUrl ? report.endpoints.uiUrl : report.endpoints.configuredUiUrl;
3546
3569
  return Number(new URL(base).port || 80);
3547
3570
  } catch {
3548
- return 18791;
3571
+ return 55667;
3549
3572
  }
3550
3573
  })()
3551
3574
  });
@@ -6620,6 +6643,7 @@ function writeReadyManagedServiceState(params) {
6620
6643
 
6621
6644
  // src/cli/commands/remote-access-host.ts
6622
6645
  import { getConfigPath as getConfigPath8, loadConfig as loadConfig16 } from "@nextclaw/core";
6646
+ import { readPlatformSessionTokenState as readPlatformSessionTokenState2 } from "@nextclaw/remote";
6623
6647
 
6624
6648
  // src/cli/commands/remote-access-service-control.ts
6625
6649
  import { getConfigPath as getConfigPath7, loadConfig as loadConfig15 } from "@nextclaw/core";
@@ -6692,7 +6716,7 @@ async function controlManagedService(action, deps) {
6692
6716
  }
6693
6717
  if (currentProcess) {
6694
6718
  if (action === "restart") {
6695
- await deps.requestManagedServiceRestart({ uiPort: uiOverrides.port ?? 18791 });
6719
+ await deps.requestManagedServiceRestart({ uiPort: uiOverrides.port ?? 55667 });
6696
6720
  } else {
6697
6721
  scheduleManagedSelfStop();
6698
6722
  }
@@ -6789,22 +6813,6 @@ function normalizeOptionalString5(value) {
6789
6813
  const trimmed = value.trim();
6790
6814
  return trimmed.length > 0 ? trimmed : null;
6791
6815
  }
6792
- function decodeJwtPayload(token) {
6793
- const segments = token.split(".");
6794
- if (segments.length < 2) {
6795
- return null;
6796
- }
6797
- try {
6798
- const raw = Buffer.from(segments[1], "base64url").toString("utf-8");
6799
- const parsed = JSON.parse(raw);
6800
- return typeof parsed === "object" && parsed !== null ? parsed : null;
6801
- } catch {
6802
- return null;
6803
- }
6804
- }
6805
- function isPlatformSessionToken2(token) {
6806
- return typeof token === "string" && token.startsWith("nca.");
6807
- }
6808
6816
  function toRemoteRuntimeView(runtime2) {
6809
6817
  if (!runtime2) {
6810
6818
  return null;
@@ -6905,14 +6913,15 @@ var RemoteAccessHost = class {
6905
6913
  return controlRemoteService(action, this.deps);
6906
6914
  }
6907
6915
  readAccountView(params) {
6908
- if (!isPlatformSessionToken2(params.token)) {
6916
+ const tokenState = readPlatformSessionTokenState2(params.token);
6917
+ if (!tokenState.valid) {
6909
6918
  return {
6910
6919
  loggedIn: false,
6911
6920
  apiBase: params.apiBase,
6912
6921
  platformBase: params.platformBase
6913
6922
  };
6914
6923
  }
6915
- const payload = decodeJwtPayload(params.token);
6924
+ const payload = tokenState.payload;
6916
6925
  const email = typeof payload?.email === "string" ? payload.email : void 0;
6917
6926
  const role = typeof payload?.role === "string" ? payload.role : void 0;
6918
6927
  return {
@@ -7961,12 +7970,12 @@ var ServiceCommands = class {
7961
7970
  const port = Number(parsed.port || 80);
7962
7971
  return {
7963
7972
  host: existing.uiHost ?? parsed.hostname,
7964
- port: Number.isFinite(port) ? port : existing.uiPort ?? 18791
7973
+ port: Number.isFinite(port) ? port : existing.uiPort ?? 55667
7965
7974
  };
7966
7975
  } catch {
7967
7976
  return {
7968
7977
  host: existing.uiHost ?? "127.0.0.1",
7969
- port: existing.uiPort ?? 18791
7978
+ port: existing.uiPort ?? 55667
7970
7979
  };
7971
7980
  }
7972
7981
  })();
@@ -8912,7 +8921,7 @@ var CliRuntime = class {
8912
8921
  return false;
8913
8922
  }
8914
8923
  const uiHost = FORCED_PUBLIC_UI_HOST2;
8915
- const uiPort = typeof state.uiPort === "number" && Number.isFinite(state.uiPort) ? state.uiPort : 18791;
8924
+ const uiPort = typeof state.uiPort === "number" && Number.isFinite(state.uiPort) ? state.uiPort : 55667;
8916
8925
  console.log(
8917
8926
  `Applying changes (${reason}): restarting ${APP_NAME5} background service...`
8918
8927
  );
@@ -8945,7 +8954,7 @@ var CliRuntime = class {
8945
8954
  if (!state || state.pid !== process.pid) {
8946
8955
  return;
8947
8956
  }
8948
- const uiPort = typeof state.uiPort === "number" && Number.isFinite(state.uiPort) ? state.uiPort : 18791;
8957
+ const uiPort = typeof state.uiPort === "number" && Number.isFinite(state.uiPort) ? state.uiPort : 55667;
8949
8958
  const delayMs = typeof params.delayMs === "number" && Number.isFinite(params.delayMs) ? Math.max(0, Math.floor(params.delayMs)) : 100;
8950
8959
  const cliPath = process.env.NEXTCLAW_SELF_RELAUNCH_CLI?.trim() || fileURLToPath5(new URL("./index.js", import.meta.url));
8951
8960
  const startArgs = [cliPath, "start", "--ui-port", String(uiPort)];
@@ -9517,7 +9526,7 @@ var runtime = new CliRuntime({ logo: LOGO });
9517
9526
  program.name(APP_NAME6).description(`${LOGO} ${APP_NAME6} - ${APP_TAGLINE}`).version(getPackageVersion(), "-v, --version", "show version");
9518
9527
  program.command("onboard").description(`Initialize ${APP_NAME6} configuration and workspace`).action(async () => runtime.onboard());
9519
9528
  program.command("init").description(`Initialize ${APP_NAME6} configuration and workspace`).option("-f, --force", "Overwrite existing template files").action(async (opts) => runtime.init({ force: Boolean(opts.force) }));
9520
- program.command("login").description("Login to NextClaw platform and save token into providers.nextclaw.apiKey").option("--api-base <url>", "Platform API base (supports /v1 suffix)").option("--email <email>", "Login email").option("--password <password>", "Login password").option("--register", "Register first, then login", false).action(async (opts) => runtime.login(opts));
9529
+ program.command("login").description("Login to NextClaw platform and save token into providers.nextclaw.apiKey").option("--api-base <url>", "Platform API base (supports /v1 suffix)").option("--email <email>", "Login email").option("--password <password>", "Login password").action(async (opts) => runtime.login(opts));
9521
9530
  registerRemoteCommands(program, runtime.remote);
9522
9531
  program.command("gateway").description(`Start the ${APP_NAME6} gateway`).option("-p, --port <port>", "Gateway port", "18790").option("-v, --verbose", "Verbose output", false).option("--ui", "Enable UI server", false).option("--ui-port <port>", "UI port").option("--ui-open", "Open browser when UI starts", false).action(async (opts) => runtime.gateway(opts));
9523
9532
  program.command("ui").description(`Start the ${APP_NAME6} UI with gateway`).option("--port <port>", "UI port").option("--no-open", "Disable opening browser").action(async (opts) => runtime.ui(opts));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nextclaw",
3
- "version": "0.13.22",
3
+ "version": "0.13.23",
4
4
  "description": "Lightweight personal AI assistant with CLI, multi-provider routing, and channel integrations.",
5
5
  "private": false,
6
6
  "type": "module",
@@ -39,15 +39,15 @@
39
39
  "chokidar": "^3.6.0",
40
40
  "commander": "^12.1.0",
41
41
  "yaml": "^2.8.1",
42
- "@nextclaw/core": "0.9.7",
43
- "@nextclaw/mcp": "0.1.18",
42
+ "@nextclaw/core": "0.9.8",
43
+ "@nextclaw/mcp": "0.1.19",
44
44
  "@nextclaw/ncp": "0.3.1",
45
- "@nextclaw/ncp-mcp": "0.1.18",
46
45
  "@nextclaw/ncp-toolkit": "0.4.1",
47
- "@nextclaw/remote": "0.1.14",
48
- "@nextclaw/runtime": "0.2.7",
49
- "@nextclaw/server": "0.10.18",
50
- "@nextclaw/openclaw-compat": "0.3.10",
46
+ "@nextclaw/runtime": "0.2.8",
47
+ "@nextclaw/server": "0.10.19",
48
+ "@nextclaw/openclaw-compat": "0.3.11",
49
+ "@nextclaw/ncp-mcp": "0.1.19",
50
+ "@nextclaw/remote": "0.1.15",
51
51
  "@nextclaw/ncp-agent-runtime": "0.2.1"
52
52
  },
53
53
  "devDependencies": {
@@ -51,7 +51,7 @@ When NextClaw AI needs to operate the product itself (version/status/doctor/chan
51
51
  nextclaw start
52
52
  ```
53
53
 
54
- 3. Open **http://127.0.0.1:18791** in your browser. Set a provider (e.g. OpenRouter) and model in the UI.
54
+ 3. Open **http://127.0.0.1:55667** in your browser. Set a provider (e.g. OpenRouter) and model in the UI.
55
55
 
56
56
  4. Optionally run `nextclaw init` to create a workspace with agent templates, or chat from the CLI:
57
57
 
@@ -67,10 +67,10 @@ When NextClaw AI needs to operate the product itself (version/status/doctor/chan
67
67
 
68
68
  For internet access on a VPS:
69
69
 
70
- - NextClaw itself serves plain HTTP on port `18791`.
71
- - Direct access is `http://<server-ip>:18791`.
72
- - If you want `https://` or standard `80/443`, put Nginx/Caddy in front and proxy to `http://127.0.0.1:18791`.
73
- - Do not point a reverse proxy upstream to `https://127.0.0.1:18791`; NextClaw does not terminate TLS itself.
70
+ - NextClaw itself serves plain HTTP on port `55667`.
71
+ - Direct access is `http://<server-ip>:55667`.
72
+ - If you want `https://` or standard `80/443`, put Nginx/Caddy in front and proxy to `http://127.0.0.1:55667`.
73
+ - Do not point a reverse proxy upstream to `https://127.0.0.1:55667`; NextClaw does not terminate TLS itself.
74
74
 
75
75
  ---
76
76
 
@@ -81,7 +81,7 @@ NextClaw binds the UI to `0.0.0.0` by default, but the built-in server is still
81
81
  1. Direct HTTP for quick validation:
82
82
 
83
83
  ```text
84
- http://<server-ip>:18791
84
+ http://<server-ip>:55667
85
85
  ```
86
86
 
87
87
  2. Recommended: terminate TLS in Nginx/Caddy and proxy to local NextClaw HTTP:
@@ -92,7 +92,7 @@ NextClaw binds the UI to `0.0.0.0` by default, but the built-in server is still
92
92
  server_name _;
93
93
 
94
94
  location / {
95
- proxy_pass http://127.0.0.1:18791;
95
+ proxy_pass http://127.0.0.1:55667;
96
96
  proxy_http_version 1.1;
97
97
  proxy_set_header Host $host;
98
98
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@@ -105,19 +105,19 @@ NextClaw binds the UI to `0.0.0.0` by default, but the built-in server is still
105
105
 
106
106
  Important rules:
107
107
 
108
- - NextClaw upstream must stay `http://127.0.0.1:18791`.
108
+ - NextClaw upstream must stay `http://127.0.0.1:55667`.
109
109
  - `443` belongs to Nginx/Caddy plus your certificate, not to NextClaw directly.
110
- - If you later add HTTPS, keep TLS termination in the reverse proxy, then forward to `http://127.0.0.1:18791`.
110
+ - If you later add HTTPS, keep TLS termination in the reverse proxy, then forward to `http://127.0.0.1:55667`.
111
111
 
112
112
  Minimal verification sequence:
113
113
 
114
114
  ```bash
115
- curl http://127.0.0.1:18791/api/health
116
- curl -I http://127.0.0.1:18791/
115
+ curl http://127.0.0.1:55667/api/health
116
+ curl -I http://127.0.0.1:55667/
117
117
  curl -I http://<server-ip>/
118
118
  ```
119
119
 
120
- If `127.0.0.1:18791` is healthy but the public entry returns `502`, the problem is in your reverse proxy, firewall, or upstream target, not in the NextClaw HTTP server.
120
+ If `127.0.0.1:55667` is healthy but the public entry returns `502`, the problem is in your reverse proxy, firewall, or upstream target, not in the NextClaw HTTP server.
121
121
 
122
122
  ---
123
123
 
@@ -517,7 +517,7 @@ Created under the workspace:
517
517
  Gateway options (when running `nextclaw gateway` or `nextclaw start`):
518
518
 
519
519
  - `--ui` — enable the UI server with the gateway
520
- - `--ui-port <port>` — UI port (default 18791 for start)
520
+ - `--ui-port <port>` — UI port (default 55667 for start)
521
521
  - `--ui-open` — open the browser when the UI starts
522
522
 
523
523
  If service is already running, new UI port flags do not hot-apply; use `nextclaw restart ...` to apply them.
@@ -587,7 +587,7 @@ All message channels use a common **allowFrom** rule:
587
587
  - **Empty `allowFrom`** (`[]`): allow all senders.
588
588
  - **Non-empty `allowFrom`**: only messages from the listed user IDs are accepted.
589
589
 
590
- Configure channels in the UI at http://127.0.0.1:18791 or in `~/.nextclaw/config.json` under `channels`.
590
+ Configure channels in the UI at http://127.0.0.1:55667 or in `~/.nextclaw/config.json` under `channels`.
591
591
 
592
592
  ### Discord
593
593
 
@@ -973,7 +973,7 @@ You can tune the UI server in config:
973
973
  "ui": {
974
974
  "enabled": true,
975
975
  "host": "0.0.0.0",
976
- "port": 18791,
976
+ "port": 55667,
977
977
  "open": false
978
978
  }
979
979
  }
@@ -983,7 +983,7 @@ You can tune the UI server in config:
983
983
  - `host` / `port`: bind address and port; `ui.host` is read-only in practice (CLI start paths always enforce `0.0.0.0`).
984
984
  - `open`: open the default browser when the UI starts.
985
985
 
986
- Default URL when using `nextclaw start`: **http://127.0.0.1:18791**.
986
+ Default URL when using `nextclaw start`: **http://127.0.0.1:55667**.
987
987
 
988
988
  NextClaw binds UI to `0.0.0.0` by default and attempts to detect/print a public IP-based URL at startup.
989
989
 
@@ -996,9 +996,9 @@ NextClaw binds UI to `0.0.0.0` by default and attempts to detect/print a public
996
996
  | **401 / invalid API key** | Verify the provider `apiKey` and `apiBase` in config or UI. Ensure no extra spaces or wrong key. |
997
997
  | **Unknown model** | Confirm the model ID is supported by your provider (e.g. OpenRouter model list). |
998
998
  | **No replies on a channel** | Ensure the channel is `enabled`, `allowFrom` includes your user ID if set, and the gateway is running (`nextclaw start` or `nextclaw gateway`). Run `nextclaw channels status` to see channel status. |
999
- | **Port already in use** | Change `ui.port` in config or use `--ui-port` when starting. Default UI port is 18791, gateway 18790. |
1000
- | **Port connects but the UI never responds** | This usually means the target port is occupied by a stale or wrong listener instead of a healthy NextClaw HTTP server. Newer `nextclaw start` now preflights the UI port and fails fast with diagnostics. On the server, run `ss -ltnp | grep 18791` or `lsof -iTCP:18791 -sTCP:LISTEN -n -P`, then free the port or restart with `--ui-port <port>`. |
1001
- | **Public browser access returns 502** | First verify `curl http://127.0.0.1:18791/api/health` on the server. If it is `200`, your reverse proxy is misconfigured. Make sure it proxies to `http://127.0.0.1:18791` instead of `https://127.0.0.1:18791`, and that `443` is terminated by Nginx/Caddy rather than NextClaw itself. |
999
+ | **Port already in use** | Change `ui.port` in config or use `--ui-port` when starting. Default UI port is 55667, gateway 18790. |
1000
+ | **Port connects but the UI never responds** | This usually means the target port is occupied by a stale or wrong listener instead of a healthy NextClaw HTTP server. Newer `nextclaw start` now preflights the UI port and fails fast with diagnostics. On the server, run `ss -ltnp | grep 55667` or `lsof -iTCP:55667 -sTCP:LISTEN -n -P`, then free the port or restart with `--ui-port <port>`. |
1001
+ | **Public browser access returns 502** | First verify `curl http://127.0.0.1:55667/api/health` on the server. If it is `200`, your reverse proxy is misconfigured. Make sure it proxies to `http://127.0.0.1:55667` instead of `https://127.0.0.1:55667`, and that `443` is terminated by Nginx/Caddy rather than NextClaw itself. |
1002
1002
  | **Config not loading** | Ensure `NEXTCLAW_HOME` (if set) points to the directory that contains `config.json`. Run `nextclaw status` to see which config file is used. |
1003
1003
  | **Agent not responding in CLI** | Run `nextclaw init` if you have not yet; ensure a provider and model are set and the provider key is valid. |
1004
1004
 
@@ -1 +1 @@
1
- import{r as v,j as a,X as Z,a3 as ee,e as T,K as ae,ap as te,b0 as se,b1 as ne,b2 as le,a0 as re,G as oe,ah as ce,H as ie}from"./vendor-CmQZsDAE.js";import{t as e,c as I,_ as me,u as q,a as $,b as H,a0 as pe,a1 as de,I as D,S as be,e as ue,f as xe,g as ye,h as ge,B as E}from"./index-DvA7S11O.js";import{L as he}from"./label-DzwitL78.js";import{S as fe}from"./switch-PvjTvlcs.js";import{S as K}from"./status-dot-CU_P0tvO.js";import{L as J}from"./LogoBadge-BKq1GKWP.js";import{h as _}from"./config-hints-CApS3K_7.js";import{c as we,b as ve,a as je,C as ke}from"./config-layout-BHnOoweL.js";import{T as Se}from"./tabs-custom-Bke5J9ny.js";import{P as Ce,a as Ne}from"./page-layout-DEq5N_8L.js";function Pe({value:t,onChange:m,className:i,placeholder:r=""}){const[o,u]=v.useState(""),d=x=>{x.key==="Enter"&&o.trim()?(x.preventDefault(),m([...t,o.trim()]),u("")):x.key==="Backspace"&&!o&&t.length>0&&m(t.slice(0,-1))},g=x=>{m(t.filter((j,h)=>h!==x))};return a.jsxs("div",{className:I("flex flex-wrap gap-2 p-2 border rounded-md min-h-[42px]",i),children:[t.map((x,j)=>a.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-1 bg-primary text-primary-foreground rounded text-sm",children:[x,a.jsx("button",{type:"button",onClick:()=>g(j),className:"hover:text-red-300 transition-colors",children:a.jsx(Z,{className:"h-3 w-3"})})]},j)),a.jsx("input",{type:"text",value:o,onChange:x=>u(x.target.value),onKeyDown:d,className:"flex-1 outline-none min-w-[100px] bg-transparent text-sm",placeholder:r||e("enterTag")})]})}function z(t){var r,o;const m=me();return((r=t.tutorialUrls)==null?void 0:r[m])||((o=t.tutorialUrls)==null?void 0:o.default)||t.tutorialUrl}const Ie={telegram:"telegram.svg",slack:"slack.svg",discord:"discord.svg",whatsapp:"whatsapp.svg",qq:"qq.svg",feishu:"feishu.svg",dingtalk:"dingtalk.svg",wecom:"wecom.svg",mochat:"mochat.svg",email:"email.svg"};function Fe(t,m){const i=m.toLowerCase(),r=t[i];return r?`/logos/${r}`:null}function Y(t){return Fe(Ie,t)}const B=[{value:"pairing",label:"pairing"},{value:"allowlist",label:"allowlist"},{value:"open",label:"open"},{value:"disabled",label:"disabled"}],G=[{value:"open",label:"open"},{value:"allowlist",label:"allowlist"},{value:"disabled",label:"disabled"}],Te=[{value:"off",label:"off"},{value:"partial",label:"partial"},{value:"block",label:"block"},{value:"progress",label:"progress"}],De=t=>t.includes("token")||t.includes("secret")||t.includes("password")?a.jsx(ae,{className:"h-3.5 w-3.5 text-gray-500"}):t.includes("url")||t.includes("host")?a.jsx(te,{className:"h-3.5 w-3.5 text-gray-500"}):t.includes("email")||t.includes("mail")?a.jsx(se,{className:"h-3.5 w-3.5 text-gray-500"}):t.includes("id")||t.includes("from")?a.jsx(ne,{className:"h-3.5 w-3.5 text-gray-500"}):t==="enabled"||t==="consentGranted"?a.jsx(le,{className:"h-3.5 w-3.5 text-gray-500"}):a.jsx(re,{className:"h-3.5 w-3.5 text-gray-500"});function R(){return{telegram:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"token",type:"password",label:e("botToken")},{name:"allowFrom",type:"tags",label:e("allowFrom")},{name:"proxy",type:"text",label:e("proxy")},{name:"accountId",type:"text",label:e("accountId")},{name:"dmPolicy",type:"select",label:e("dmPolicy"),options:B},{name:"groupPolicy",type:"select",label:e("groupPolicy"),options:G},{name:"groupAllowFrom",type:"tags",label:e("groupAllowFrom")},{name:"requireMention",type:"boolean",label:e("requireMention")},{name:"mentionPatterns",type:"tags",label:e("mentionPatterns")},{name:"groups",type:"json",label:e("groupRulesJson")}],discord:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"token",type:"password",label:e("botToken")},{name:"allowBots",type:"boolean",label:e("allowBotMessages")},{name:"allowFrom",type:"tags",label:e("allowFrom")},{name:"gatewayUrl",type:"text",label:e("gatewayUrl")},{name:"intents",type:"number",label:e("intents")},{name:"proxy",type:"text",label:e("proxy")},{name:"mediaMaxMb",type:"number",label:e("attachmentMaxSizeMb")},{name:"streaming",type:"select",label:e("streamingMode"),options:Te},{name:"draftChunk",type:"json",label:e("draftChunkingJson")},{name:"textChunkLimit",type:"number",label:e("textChunkLimit")},{name:"accountId",type:"text",label:e("accountId")},{name:"dmPolicy",type:"select",label:e("dmPolicy"),options:B},{name:"groupPolicy",type:"select",label:e("groupPolicy"),options:G},{name:"groupAllowFrom",type:"tags",label:e("groupAllowFrom")},{name:"requireMention",type:"boolean",label:e("requireMention")},{name:"mentionPatterns",type:"tags",label:e("mentionPatterns")},{name:"groups",type:"json",label:e("groupRulesJson")}],whatsapp:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"bridgeUrl",type:"text",label:e("bridgeUrl")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],feishu:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"appId",type:"text",label:e("appId")},{name:"appSecret",type:"password",label:e("appSecret")},{name:"encryptKey",type:"password",label:e("encryptKey")},{name:"verificationToken",type:"password",label:e("verificationToken")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],dingtalk:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"clientId",type:"text",label:e("clientId")},{name:"clientSecret",type:"password",label:e("clientSecret")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],wecom:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"corpId",type:"text",label:e("corpId")},{name:"agentId",type:"text",label:e("agentId")},{name:"secret",type:"password",label:e("secret")},{name:"token",type:"password",label:e("token")},{name:"callbackPort",type:"number",label:e("callbackPort")},{name:"callbackPath",type:"text",label:e("callbackPath")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],slack:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"mode",type:"text",label:e("mode")},{name:"webhookPath",type:"text",label:e("webhookPath")},{name:"allowBots",type:"boolean",label:e("allowBotMessages")},{name:"botToken",type:"password",label:e("botToken")},{name:"appToken",type:"password",label:e("appToken")}],email:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"consentGranted",type:"boolean",label:e("consentGranted")},{name:"imapHost",type:"text",label:e("imapHost")},{name:"imapPort",type:"number",label:e("imapPort")},{name:"imapUsername",type:"text",label:e("imapUsername")},{name:"imapPassword",type:"password",label:e("imapPassword")},{name:"fromAddress",type:"email",label:e("fromAddress")}],mochat:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"baseUrl",type:"text",label:e("baseUrl")},{name:"clawToken",type:"password",label:e("clawToken")},{name:"agentUserId",type:"text",label:e("agentUserId")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],qq:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"appId",type:"text",label:e("appId")},{name:"secret",type:"password",label:e("appSecret")},{name:"markdownSupport",type:"boolean",label:e("markdownSupport")},{name:"allowFrom",type:"tags",label:e("allowFrom")}]}}function A(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function V(t,m){const i={...t};for(const[r,o]of Object.entries(m)){const u=i[r];if(A(u)&&A(o)){i[r]=V(u,o);continue}i[r]=o}return i}function Ae(t,m){const i=t.split("."),r={};let o=r;for(let u=0;u<i.length-1;u+=1){const d=i[u];o[d]={},o=o[d]}return o[i[i.length-1]]=m,r}function Le({channelName:t}){var O,U;const{data:m}=q(),{data:i}=$(),{data:r}=H(),o=pe(),u=de(),[d,g]=v.useState({}),[x,j]=v.useState({}),[h,f]=v.useState(null),k=t?m==null?void 0:m.channels[t]:null,w=t?R()[t]??[]:[],c=r==null?void 0:r.uiHints,p=t?`channels.${t}`:null,S=((O=r==null?void 0:r.actions)==null?void 0:O.filter(s=>s.scope===p))??[],C=t&&(((U=_(`channels.${t}`,c))==null?void 0:U.label)??t),P=i==null?void 0:i.channels.find(s=>s.name===t),F=P?z(P):void 0;v.useEffect(()=>{if(k){g({...k});const s={};(t?R()[t]??[]:[]).filter(l=>l.type==="json").forEach(l=>{const y=k[l.name];s[l.name]=JSON.stringify(y??{},null,2)}),j(s)}else g({}),j({})},[k,t]);const N=(s,n)=>{g(l=>({...l,[s]:n}))},L=s=>{if(s.preventDefault(),!t)return;const n={...d};for(const l of w){if(l.type!=="password")continue;const y=n[l.name];(typeof y!="string"||y.length===0)&&delete n[l.name]}for(const l of w){if(l.type!=="json")continue;const y=x[l.name]??"";try{n[l.name]=y.trim()?JSON.parse(y):{}}catch{T.error(`${e("invalidJson")}: ${l.name}`);return}}o.mutate({channel:t,data:n})},Q=s=>{if(!s||!t)return;const n=s.channels;if(!A(n))return;const l=n[t];A(l)&&g(y=>V(y,l))},W=async s=>{if(!(!t||!p)){f(s.id);try{let n={...d};s.saveBeforeRun&&(n={...n,...s.savePatch??{}},g(n),await o.mutateAsync({channel:t,data:n}));const l=await u.mutateAsync({actionId:s.id,data:{scope:p,draftConfig:Ae(p,n)}});Q(l.patch),l.ok?T.success(l.message||e("success")):T.error(l.message||e("error"))}catch(n){const l=n instanceof Error?n.message:String(n);T.error(`${e("error")}: ${l}`)}finally{f(null)}}};if(!t||!P||!k)return a.jsx("div",{className:we,children:a.jsxs("div",{children:[a.jsx("h3",{className:"text-base font-semibold text-gray-900",children:e("channelsSelectTitle")}),a.jsx("p",{className:"mt-2 text-sm text-gray-500",children:e("channelsSelectDescription")})]})});const M=!!k.enabled;return a.jsxs("div",{className:ve,children:[a.jsx("div",{className:"border-b border-gray-100 px-6 py-5",children:a.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[a.jsxs("div",{className:"min-w-0",children:[a.jsxs("div",{className:"flex items-center gap-3",children:[a.jsx(J,{name:t,src:Y(t),className:I("h-9 w-9 rounded-lg border",M?"border-primary/30 bg-white":"border-gray-200/70 bg-white"),imgClassName:"h-5 w-5 object-contain",fallback:a.jsx("span",{className:"text-sm font-semibold uppercase text-gray-500",children:t[0]})}),a.jsx("h3",{className:"truncate text-lg font-semibold text-gray-900 capitalize",children:C})]}),a.jsx("p",{className:"mt-2 text-sm text-gray-500",children:e("channelsFormDescription")}),F&&a.jsxs("a",{href:F,className:"mt-2 inline-flex items-center gap-1.5 text-xs text-primary transition-colors hover:text-primary-hover",children:[a.jsx(ee,{className:"h-3.5 w-3.5"}),e("channelsGuideTitle")]})]}),a.jsx(K,{status:M?"active":"inactive",label:M?e("statusActive"):e("statusInactive")})]})}),a.jsxs("form",{onSubmit:L,className:"flex min-h-0 flex-1 flex-col",children:[a.jsx("div",{className:"min-h-0 flex-1 space-y-6 overflow-y-auto overscroll-contain px-6 py-5",children:w.map(s=>{const n=t?_(`channels.${t}.${s.name}`,c):void 0,l=(n==null?void 0:n.label)??s.label,y=n==null?void 0:n.placeholder;return a.jsxs("div",{className:"space-y-2.5",children:[a.jsxs(he,{htmlFor:s.name,className:"flex items-center gap-2 text-sm font-medium text-gray-900",children:[De(s.name),l]}),s.type==="boolean"&&a.jsxs("div",{className:"flex items-center justify-between rounded-xl bg-gray-50 p-3",children:[a.jsx("span",{className:"text-sm text-gray-500",children:d[s.name]?e("enabled"):e("disabled")}),a.jsx(fe,{id:s.name,checked:d[s.name]||!1,onCheckedChange:b=>N(s.name,b),className:"data-[state=checked]:bg-emerald-500"})]}),(s.type==="text"||s.type==="email")&&a.jsx(D,{id:s.name,type:s.type,value:d[s.name]||"",onChange:b=>N(s.name,b.target.value),placeholder:y,className:"rounded-xl"}),s.type==="password"&&a.jsx(D,{id:s.name,type:"password",value:d[s.name]||"",onChange:b=>N(s.name,b.target.value),placeholder:y??e("leaveBlankToKeepUnchanged"),className:"rounded-xl"}),s.type==="number"&&a.jsx(D,{id:s.name,type:"number",value:d[s.name]||0,onChange:b=>N(s.name,parseInt(b.target.value,10)||0),placeholder:y,className:"rounded-xl"}),s.type==="tags"&&a.jsx(Pe,{value:d[s.name]||[],onChange:b=>N(s.name,b)}),s.type==="select"&&a.jsxs(be,{value:d[s.name]||"",onValueChange:b=>N(s.name,b),children:[a.jsx(ue,{className:"rounded-xl",children:a.jsx(xe,{})}),a.jsx(ye,{children:(s.options??[]).map(b=>a.jsx(ge,{value:b.value,children:b.label},b.value))})]}),s.type==="json"&&a.jsx("textarea",{id:s.name,value:x[s.name]??"{}",onChange:b=>j(X=>({...X,[s.name]:b.target.value})),className:"min-h-[120px] w-full resize-none rounded-lg border border-gray-200 bg-white px-3 py-2 text-xs font-mono"})]},s.name)})}),a.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 border-t border-gray-100 px-6 py-4",children:[a.jsx("div",{className:"flex flex-wrap items-center gap-2",children:S.filter(s=>s.trigger==="manual").map(s=>a.jsx(E,{type:"button",onClick:()=>W(s),disabled:o.isPending||!!h,variant:"secondary",children:h===s.id?e("connecting"):s.title},s.id))}),a.jsx(E,{type:"submit",disabled:o.isPending||!!h,children:o.isPending?e("saving"):e("save")})]})]})]})}const Me={telegram:"channelDescTelegram",slack:"channelDescSlack",email:"channelDescEmail",webhook:"channelDescWebhook",discord:"channelDescDiscord",feishu:"channelDescFeishu"};function Ke(){const{data:t}=q(),{data:m}=$(),{data:i}=H(),[r,o]=v.useState("enabled"),[u,d]=v.useState(),[g,x]=v.useState(""),j=i==null?void 0:i.uiHints,h=m==null?void 0:m.channels,f=t==null?void 0:t.channels,k=[{id:"enabled",label:e("channelsTabEnabled"),count:(h??[]).filter(c=>{var p;return(p=f==null?void 0:f[c.name])==null?void 0:p.enabled}).length},{id:"all",label:e("channelsTabAll"),count:(h??[]).length}],w=v.useMemo(()=>{const c=g.trim().toLowerCase();return(h??[]).filter(p=>{var C;const S=((C=f==null?void 0:f[p.name])==null?void 0:C.enabled)||!1;return r==="enabled"?S:!0}).filter(p=>c?(p.displayName||p.name).toLowerCase().includes(c)||p.name.toLowerCase().includes(c):!0)},[r,f,h,g]);return v.useEffect(()=>{if(w.length===0){d(void 0);return}w.some(p=>p.name===u)||d(w[0].name)},[w,u]),!t||!m?a.jsx("div",{className:"p-8 text-gray-400",children:e("channelsLoading")}):a.jsxs(Ce,{className:"xl:flex xl:h-full xl:min-h-0 xl:flex-col xl:pb-0",children:[a.jsx(Ne,{title:e("channelsPageTitle"),description:e("channelsPageDescription")}),a.jsxs("div",{className:I(ke,"xl:min-h-0 xl:flex-1"),children:[a.jsxs("section",{className:je,children:[a.jsx("div",{className:"border-b border-gray-100 px-4 pt-4",children:a.jsx(Se,{tabs:k,activeTab:r,onChange:o,className:"mb-0"})}),a.jsx("div",{className:"border-b border-gray-100 px-4 py-3",children:a.jsxs("div",{className:"relative",children:[a.jsx(oe,{className:"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-400"}),a.jsx(D,{value:g,onChange:c=>x(c.target.value),placeholder:e("channelsFilterPlaceholder"),className:"h-10 rounded-xl pl-9"})]})}),a.jsxs("div",{className:"min-h-0 flex-1 space-y-2 overflow-y-auto overscroll-contain p-3",children:[w.map(c=>{const p=t.channels[c.name],S=(p==null?void 0:p.enabled)||!1,C=_(`channels.${c.name}`,j),P=z(c),F=(C==null?void 0:C.help)||e(Me[c.name]||"channelDescriptionDefault"),N=u===c.name;return a.jsx("button",{type:"button",onClick:()=>d(c.name),className:I("w-full rounded-xl border p-2.5 text-left transition-all",N?"border-primary/30 bg-primary-50/40 shadow-sm":"border-gray-200/70 bg-white hover:border-gray-300 hover:bg-gray-50/70"),children:a.jsxs("div",{className:"flex items-start justify-between gap-3",children:[a.jsxs("div",{className:"flex min-w-0 items-center gap-3",children:[a.jsx(J,{name:c.name,src:Y(c.name),className:I("h-10 w-10 rounded-lg border",S?"border-primary/30 bg-white":"border-gray-200/70 bg-white"),imgClassName:"h-5 w-5 object-contain",fallback:a.jsx("span",{className:"text-sm font-semibold uppercase text-gray-500",children:c.name[0]})}),a.jsxs("div",{className:"min-w-0",children:[a.jsx("p",{className:"truncate text-sm font-semibold text-gray-900",children:c.displayName||c.name}),a.jsx("p",{className:"line-clamp-1 text-[11px] text-gray-500",children:F})]})]}),a.jsxs("div",{className:"flex items-center gap-2",children:[P&&a.jsx("a",{href:P,onClick:L=>L.stopPropagation(),className:"inline-flex h-7 w-7 items-center justify-center rounded-md text-gray-300 transition-colors hover:bg-gray-100/70 hover:text-gray-500",title:e("channelsGuideTitle"),children:a.jsx(ce,{className:"h-3.5 w-3.5"})}),a.jsx(K,{status:S?"active":"inactive",label:S?e("statusActive"):e("statusInactive"),className:"min-w-[56px] justify-center"})]})]})},c.name)}),w.length===0&&a.jsxs("div",{className:"flex h-full min-h-[220px] flex-col items-center justify-center rounded-xl border border-dashed border-gray-200 bg-gray-50/70 py-10 text-center",children:[a.jsx("div",{className:"mb-3 flex h-10 w-10 items-center justify-center rounded-lg bg-white",children:a.jsx(ie,{className:"h-5 w-5 text-gray-300"})}),a.jsx("p",{className:"text-sm font-medium text-gray-700",children:e("channelsNoMatch")})]})]})]}),a.jsx(Le,{channelName:u})]})]})}export{Ke as ChannelsList};
1
+ import{r as v,j as a,X as Z,a3 as ee,e as T,K as ae,ap as te,b0 as se,b1 as ne,b2 as le,a0 as re,G as oe,ah as ce,H as ie}from"./vendor-CmQZsDAE.js";import{t as e,c as I,_ as me,u as q,a as $,b as H,a0 as pe,a1 as de,I as D,S as be,e as ue,f as xe,g as ye,h as ge,B as E}from"./index-C6dwNe7e.js";import{L as he}from"./label-C0dJBNgU.js";import{S as fe}from"./switch-C6zdGbY0.js";import{S as K}from"./status-dot-C7cVa53V.js";import{L as J}from"./LogoBadge-BUvLZbji.js";import{h as _}from"./config-hints-CApS3K_7.js";import{c as we,b as ve,a as je,C as ke}from"./config-layout-BHnOoweL.js";import{T as Se}from"./tabs-custom-BQj0Z-ZC.js";import{P as Ce,a as Ne}from"./page-layout-4_789zOC.js";function Pe({value:t,onChange:m,className:i,placeholder:r=""}){const[o,u]=v.useState(""),d=x=>{x.key==="Enter"&&o.trim()?(x.preventDefault(),m([...t,o.trim()]),u("")):x.key==="Backspace"&&!o&&t.length>0&&m(t.slice(0,-1))},g=x=>{m(t.filter((j,h)=>h!==x))};return a.jsxs("div",{className:I("flex flex-wrap gap-2 p-2 border rounded-md min-h-[42px]",i),children:[t.map((x,j)=>a.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-1 bg-primary text-primary-foreground rounded text-sm",children:[x,a.jsx("button",{type:"button",onClick:()=>g(j),className:"hover:text-red-300 transition-colors",children:a.jsx(Z,{className:"h-3 w-3"})})]},j)),a.jsx("input",{type:"text",value:o,onChange:x=>u(x.target.value),onKeyDown:d,className:"flex-1 outline-none min-w-[100px] bg-transparent text-sm",placeholder:r||e("enterTag")})]})}function z(t){var r,o;const m=me();return((r=t.tutorialUrls)==null?void 0:r[m])||((o=t.tutorialUrls)==null?void 0:o.default)||t.tutorialUrl}const Ie={telegram:"telegram.svg",slack:"slack.svg",discord:"discord.svg",whatsapp:"whatsapp.svg",qq:"qq.svg",feishu:"feishu.svg",dingtalk:"dingtalk.svg",wecom:"wecom.svg",mochat:"mochat.svg",email:"email.svg"};function Fe(t,m){const i=m.toLowerCase(),r=t[i];return r?`/logos/${r}`:null}function Y(t){return Fe(Ie,t)}const B=[{value:"pairing",label:"pairing"},{value:"allowlist",label:"allowlist"},{value:"open",label:"open"},{value:"disabled",label:"disabled"}],G=[{value:"open",label:"open"},{value:"allowlist",label:"allowlist"},{value:"disabled",label:"disabled"}],Te=[{value:"off",label:"off"},{value:"partial",label:"partial"},{value:"block",label:"block"},{value:"progress",label:"progress"}],De=t=>t.includes("token")||t.includes("secret")||t.includes("password")?a.jsx(ae,{className:"h-3.5 w-3.5 text-gray-500"}):t.includes("url")||t.includes("host")?a.jsx(te,{className:"h-3.5 w-3.5 text-gray-500"}):t.includes("email")||t.includes("mail")?a.jsx(se,{className:"h-3.5 w-3.5 text-gray-500"}):t.includes("id")||t.includes("from")?a.jsx(ne,{className:"h-3.5 w-3.5 text-gray-500"}):t==="enabled"||t==="consentGranted"?a.jsx(le,{className:"h-3.5 w-3.5 text-gray-500"}):a.jsx(re,{className:"h-3.5 w-3.5 text-gray-500"});function R(){return{telegram:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"token",type:"password",label:e("botToken")},{name:"allowFrom",type:"tags",label:e("allowFrom")},{name:"proxy",type:"text",label:e("proxy")},{name:"accountId",type:"text",label:e("accountId")},{name:"dmPolicy",type:"select",label:e("dmPolicy"),options:B},{name:"groupPolicy",type:"select",label:e("groupPolicy"),options:G},{name:"groupAllowFrom",type:"tags",label:e("groupAllowFrom")},{name:"requireMention",type:"boolean",label:e("requireMention")},{name:"mentionPatterns",type:"tags",label:e("mentionPatterns")},{name:"groups",type:"json",label:e("groupRulesJson")}],discord:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"token",type:"password",label:e("botToken")},{name:"allowBots",type:"boolean",label:e("allowBotMessages")},{name:"allowFrom",type:"tags",label:e("allowFrom")},{name:"gatewayUrl",type:"text",label:e("gatewayUrl")},{name:"intents",type:"number",label:e("intents")},{name:"proxy",type:"text",label:e("proxy")},{name:"mediaMaxMb",type:"number",label:e("attachmentMaxSizeMb")},{name:"streaming",type:"select",label:e("streamingMode"),options:Te},{name:"draftChunk",type:"json",label:e("draftChunkingJson")},{name:"textChunkLimit",type:"number",label:e("textChunkLimit")},{name:"accountId",type:"text",label:e("accountId")},{name:"dmPolicy",type:"select",label:e("dmPolicy"),options:B},{name:"groupPolicy",type:"select",label:e("groupPolicy"),options:G},{name:"groupAllowFrom",type:"tags",label:e("groupAllowFrom")},{name:"requireMention",type:"boolean",label:e("requireMention")},{name:"mentionPatterns",type:"tags",label:e("mentionPatterns")},{name:"groups",type:"json",label:e("groupRulesJson")}],whatsapp:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"bridgeUrl",type:"text",label:e("bridgeUrl")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],feishu:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"appId",type:"text",label:e("appId")},{name:"appSecret",type:"password",label:e("appSecret")},{name:"encryptKey",type:"password",label:e("encryptKey")},{name:"verificationToken",type:"password",label:e("verificationToken")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],dingtalk:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"clientId",type:"text",label:e("clientId")},{name:"clientSecret",type:"password",label:e("clientSecret")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],wecom:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"corpId",type:"text",label:e("corpId")},{name:"agentId",type:"text",label:e("agentId")},{name:"secret",type:"password",label:e("secret")},{name:"token",type:"password",label:e("token")},{name:"callbackPort",type:"number",label:e("callbackPort")},{name:"callbackPath",type:"text",label:e("callbackPath")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],slack:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"mode",type:"text",label:e("mode")},{name:"webhookPath",type:"text",label:e("webhookPath")},{name:"allowBots",type:"boolean",label:e("allowBotMessages")},{name:"botToken",type:"password",label:e("botToken")},{name:"appToken",type:"password",label:e("appToken")}],email:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"consentGranted",type:"boolean",label:e("consentGranted")},{name:"imapHost",type:"text",label:e("imapHost")},{name:"imapPort",type:"number",label:e("imapPort")},{name:"imapUsername",type:"text",label:e("imapUsername")},{name:"imapPassword",type:"password",label:e("imapPassword")},{name:"fromAddress",type:"email",label:e("fromAddress")}],mochat:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"baseUrl",type:"text",label:e("baseUrl")},{name:"clawToken",type:"password",label:e("clawToken")},{name:"agentUserId",type:"text",label:e("agentUserId")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],qq:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"appId",type:"text",label:e("appId")},{name:"secret",type:"password",label:e("appSecret")},{name:"markdownSupport",type:"boolean",label:e("markdownSupport")},{name:"allowFrom",type:"tags",label:e("allowFrom")}]}}function A(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function V(t,m){const i={...t};for(const[r,o]of Object.entries(m)){const u=i[r];if(A(u)&&A(o)){i[r]=V(u,o);continue}i[r]=o}return i}function Ae(t,m){const i=t.split("."),r={};let o=r;for(let u=0;u<i.length-1;u+=1){const d=i[u];o[d]={},o=o[d]}return o[i[i.length-1]]=m,r}function Le({channelName:t}){var O,U;const{data:m}=q(),{data:i}=$(),{data:r}=H(),o=pe(),u=de(),[d,g]=v.useState({}),[x,j]=v.useState({}),[h,f]=v.useState(null),k=t?m==null?void 0:m.channels[t]:null,w=t?R()[t]??[]:[],c=r==null?void 0:r.uiHints,p=t?`channels.${t}`:null,S=((O=r==null?void 0:r.actions)==null?void 0:O.filter(s=>s.scope===p))??[],C=t&&(((U=_(`channels.${t}`,c))==null?void 0:U.label)??t),P=i==null?void 0:i.channels.find(s=>s.name===t),F=P?z(P):void 0;v.useEffect(()=>{if(k){g({...k});const s={};(t?R()[t]??[]:[]).filter(l=>l.type==="json").forEach(l=>{const y=k[l.name];s[l.name]=JSON.stringify(y??{},null,2)}),j(s)}else g({}),j({})},[k,t]);const N=(s,n)=>{g(l=>({...l,[s]:n}))},L=s=>{if(s.preventDefault(),!t)return;const n={...d};for(const l of w){if(l.type!=="password")continue;const y=n[l.name];(typeof y!="string"||y.length===0)&&delete n[l.name]}for(const l of w){if(l.type!=="json")continue;const y=x[l.name]??"";try{n[l.name]=y.trim()?JSON.parse(y):{}}catch{T.error(`${e("invalidJson")}: ${l.name}`);return}}o.mutate({channel:t,data:n})},Q=s=>{if(!s||!t)return;const n=s.channels;if(!A(n))return;const l=n[t];A(l)&&g(y=>V(y,l))},W=async s=>{if(!(!t||!p)){f(s.id);try{let n={...d};s.saveBeforeRun&&(n={...n,...s.savePatch??{}},g(n),await o.mutateAsync({channel:t,data:n}));const l=await u.mutateAsync({actionId:s.id,data:{scope:p,draftConfig:Ae(p,n)}});Q(l.patch),l.ok?T.success(l.message||e("success")):T.error(l.message||e("error"))}catch(n){const l=n instanceof Error?n.message:String(n);T.error(`${e("error")}: ${l}`)}finally{f(null)}}};if(!t||!P||!k)return a.jsx("div",{className:we,children:a.jsxs("div",{children:[a.jsx("h3",{className:"text-base font-semibold text-gray-900",children:e("channelsSelectTitle")}),a.jsx("p",{className:"mt-2 text-sm text-gray-500",children:e("channelsSelectDescription")})]})});const M=!!k.enabled;return a.jsxs("div",{className:ve,children:[a.jsx("div",{className:"border-b border-gray-100 px-6 py-5",children:a.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[a.jsxs("div",{className:"min-w-0",children:[a.jsxs("div",{className:"flex items-center gap-3",children:[a.jsx(J,{name:t,src:Y(t),className:I("h-9 w-9 rounded-lg border",M?"border-primary/30 bg-white":"border-gray-200/70 bg-white"),imgClassName:"h-5 w-5 object-contain",fallback:a.jsx("span",{className:"text-sm font-semibold uppercase text-gray-500",children:t[0]})}),a.jsx("h3",{className:"truncate text-lg font-semibold text-gray-900 capitalize",children:C})]}),a.jsx("p",{className:"mt-2 text-sm text-gray-500",children:e("channelsFormDescription")}),F&&a.jsxs("a",{href:F,className:"mt-2 inline-flex items-center gap-1.5 text-xs text-primary transition-colors hover:text-primary-hover",children:[a.jsx(ee,{className:"h-3.5 w-3.5"}),e("channelsGuideTitle")]})]}),a.jsx(K,{status:M?"active":"inactive",label:M?e("statusActive"):e("statusInactive")})]})}),a.jsxs("form",{onSubmit:L,className:"flex min-h-0 flex-1 flex-col",children:[a.jsx("div",{className:"min-h-0 flex-1 space-y-6 overflow-y-auto overscroll-contain px-6 py-5",children:w.map(s=>{const n=t?_(`channels.${t}.${s.name}`,c):void 0,l=(n==null?void 0:n.label)??s.label,y=n==null?void 0:n.placeholder;return a.jsxs("div",{className:"space-y-2.5",children:[a.jsxs(he,{htmlFor:s.name,className:"flex items-center gap-2 text-sm font-medium text-gray-900",children:[De(s.name),l]}),s.type==="boolean"&&a.jsxs("div",{className:"flex items-center justify-between rounded-xl bg-gray-50 p-3",children:[a.jsx("span",{className:"text-sm text-gray-500",children:d[s.name]?e("enabled"):e("disabled")}),a.jsx(fe,{id:s.name,checked:d[s.name]||!1,onCheckedChange:b=>N(s.name,b),className:"data-[state=checked]:bg-emerald-500"})]}),(s.type==="text"||s.type==="email")&&a.jsx(D,{id:s.name,type:s.type,value:d[s.name]||"",onChange:b=>N(s.name,b.target.value),placeholder:y,className:"rounded-xl"}),s.type==="password"&&a.jsx(D,{id:s.name,type:"password",value:d[s.name]||"",onChange:b=>N(s.name,b.target.value),placeholder:y??e("leaveBlankToKeepUnchanged"),className:"rounded-xl"}),s.type==="number"&&a.jsx(D,{id:s.name,type:"number",value:d[s.name]||0,onChange:b=>N(s.name,parseInt(b.target.value,10)||0),placeholder:y,className:"rounded-xl"}),s.type==="tags"&&a.jsx(Pe,{value:d[s.name]||[],onChange:b=>N(s.name,b)}),s.type==="select"&&a.jsxs(be,{value:d[s.name]||"",onValueChange:b=>N(s.name,b),children:[a.jsx(ue,{className:"rounded-xl",children:a.jsx(xe,{})}),a.jsx(ye,{children:(s.options??[]).map(b=>a.jsx(ge,{value:b.value,children:b.label},b.value))})]}),s.type==="json"&&a.jsx("textarea",{id:s.name,value:x[s.name]??"{}",onChange:b=>j(X=>({...X,[s.name]:b.target.value})),className:"min-h-[120px] w-full resize-none rounded-lg border border-gray-200 bg-white px-3 py-2 text-xs font-mono"})]},s.name)})}),a.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 border-t border-gray-100 px-6 py-4",children:[a.jsx("div",{className:"flex flex-wrap items-center gap-2",children:S.filter(s=>s.trigger==="manual").map(s=>a.jsx(E,{type:"button",onClick:()=>W(s),disabled:o.isPending||!!h,variant:"secondary",children:h===s.id?e("connecting"):s.title},s.id))}),a.jsx(E,{type:"submit",disabled:o.isPending||!!h,children:o.isPending?e("saving"):e("save")})]})]})]})}const Me={telegram:"channelDescTelegram",slack:"channelDescSlack",email:"channelDescEmail",webhook:"channelDescWebhook",discord:"channelDescDiscord",feishu:"channelDescFeishu"};function Ke(){const{data:t}=q(),{data:m}=$(),{data:i}=H(),[r,o]=v.useState("enabled"),[u,d]=v.useState(),[g,x]=v.useState(""),j=i==null?void 0:i.uiHints,h=m==null?void 0:m.channels,f=t==null?void 0:t.channels,k=[{id:"enabled",label:e("channelsTabEnabled"),count:(h??[]).filter(c=>{var p;return(p=f==null?void 0:f[c.name])==null?void 0:p.enabled}).length},{id:"all",label:e("channelsTabAll"),count:(h??[]).length}],w=v.useMemo(()=>{const c=g.trim().toLowerCase();return(h??[]).filter(p=>{var C;const S=((C=f==null?void 0:f[p.name])==null?void 0:C.enabled)||!1;return r==="enabled"?S:!0}).filter(p=>c?(p.displayName||p.name).toLowerCase().includes(c)||p.name.toLowerCase().includes(c):!0)},[r,f,h,g]);return v.useEffect(()=>{if(w.length===0){d(void 0);return}w.some(p=>p.name===u)||d(w[0].name)},[w,u]),!t||!m?a.jsx("div",{className:"p-8 text-gray-400",children:e("channelsLoading")}):a.jsxs(Ce,{className:"xl:flex xl:h-full xl:min-h-0 xl:flex-col xl:pb-0",children:[a.jsx(Ne,{title:e("channelsPageTitle"),description:e("channelsPageDescription")}),a.jsxs("div",{className:I(ke,"xl:min-h-0 xl:flex-1"),children:[a.jsxs("section",{className:je,children:[a.jsx("div",{className:"border-b border-gray-100 px-4 pt-4",children:a.jsx(Se,{tabs:k,activeTab:r,onChange:o,className:"mb-0"})}),a.jsx("div",{className:"border-b border-gray-100 px-4 py-3",children:a.jsxs("div",{className:"relative",children:[a.jsx(oe,{className:"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-400"}),a.jsx(D,{value:g,onChange:c=>x(c.target.value),placeholder:e("channelsFilterPlaceholder"),className:"h-10 rounded-xl pl-9"})]})}),a.jsxs("div",{className:"min-h-0 flex-1 space-y-2 overflow-y-auto overscroll-contain p-3",children:[w.map(c=>{const p=t.channels[c.name],S=(p==null?void 0:p.enabled)||!1,C=_(`channels.${c.name}`,j),P=z(c),F=(C==null?void 0:C.help)||e(Me[c.name]||"channelDescriptionDefault"),N=u===c.name;return a.jsx("button",{type:"button",onClick:()=>d(c.name),className:I("w-full rounded-xl border p-2.5 text-left transition-all",N?"border-primary/30 bg-primary-50/40 shadow-sm":"border-gray-200/70 bg-white hover:border-gray-300 hover:bg-gray-50/70"),children:a.jsxs("div",{className:"flex items-start justify-between gap-3",children:[a.jsxs("div",{className:"flex min-w-0 items-center gap-3",children:[a.jsx(J,{name:c.name,src:Y(c.name),className:I("h-10 w-10 rounded-lg border",S?"border-primary/30 bg-white":"border-gray-200/70 bg-white"),imgClassName:"h-5 w-5 object-contain",fallback:a.jsx("span",{className:"text-sm font-semibold uppercase text-gray-500",children:c.name[0]})}),a.jsxs("div",{className:"min-w-0",children:[a.jsx("p",{className:"truncate text-sm font-semibold text-gray-900",children:c.displayName||c.name}),a.jsx("p",{className:"line-clamp-1 text-[11px] text-gray-500",children:F})]})]}),a.jsxs("div",{className:"flex items-center gap-2",children:[P&&a.jsx("a",{href:P,onClick:L=>L.stopPropagation(),className:"inline-flex h-7 w-7 items-center justify-center rounded-md text-gray-300 transition-colors hover:bg-gray-100/70 hover:text-gray-500",title:e("channelsGuideTitle"),children:a.jsx(ce,{className:"h-3.5 w-3.5"})}),a.jsx(K,{status:S?"active":"inactive",label:S?e("statusActive"):e("statusInactive"),className:"min-w-[56px] justify-center"})]})]})},c.name)}),w.length===0&&a.jsxs("div",{className:"flex h-full min-h-[220px] flex-col items-center justify-center rounded-xl border border-dashed border-gray-200 bg-gray-50/70 py-10 text-center",children:[a.jsx("div",{className:"mb-3 flex h-10 w-10 items-center justify-center rounded-lg bg-white",children:a.jsx(ie,{className:"h-5 w-5 text-gray-300"})}),a.jsx("p",{className:"text-sm font-medium text-gray-700",children:e("channelsNoMatch")})]})]})]}),a.jsx(Le,{channelName:u})]})]})}export{Ke as ChannelsList};