nextclaw 0.13.28 → 0.13.31

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 (35) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cli/index.js +158 -37
  3. package/package.json +23 -24
  4. package/ui-dist/assets/{ChannelsList-Brc1qLSU.js → ChannelsList-bROKR37R.js} +1 -1
  5. package/ui-dist/assets/ChatPage-B9dHVmrV.js +41 -0
  6. package/ui-dist/assets/{DocBrowser-xLVf1p4L.js → DocBrowser-S-1-qnZQ.js} +1 -1
  7. package/ui-dist/assets/{LogoBadge-CcTyimdr.js → LogoBadge-t1JzzCtI.js} +1 -1
  8. package/ui-dist/assets/{MarketplacePage-Bk-qXxyh.js → MarketplacePage-CzIHYJpM.js} +2 -2
  9. package/ui-dist/assets/{McpMarketplacePage-gFqAYekc.js → McpMarketplacePage-BTJdjNQ1.js} +1 -1
  10. package/ui-dist/assets/{ModelConfig-DnKNTuw6.js → ModelConfig-BD4o3Kna.js} +1 -1
  11. package/ui-dist/assets/{ProvidersList-Cjr8EFu_.js → ProvidersList-BOQArFRk.js} +1 -1
  12. package/ui-dist/assets/RemoteAccessPage-CYNQ53xu.js +1 -0
  13. package/ui-dist/assets/{RuntimeConfig-CttN--Tv.js → RuntimeConfig-B0B73pye.js} +1 -1
  14. package/ui-dist/assets/{SearchConfig-D-GzinsL.js → SearchConfig-CKy2QkAP.js} +1 -1
  15. package/ui-dist/assets/{SecretsConfig-BvqQq4Ds.js → SecretsConfig-BpZLUu88.js} +2 -2
  16. package/ui-dist/assets/{SessionsConfig-DbtnLmI6.js → SessionsConfig-CoFI6Fa2.js} +1 -1
  17. package/ui-dist/assets/{chat-message-DYQjL1tD.js → chat-message-D3jZIASl.js} +1 -1
  18. package/ui-dist/assets/index-CmGwUgcl.js +8 -0
  19. package/ui-dist/assets/{index-DfEAJJsA.css → index-SGSkQCPi.css} +1 -1
  20. package/ui-dist/assets/{label-DBSKOMGE.js → label-BOvIOmQx.js} +1 -1
  21. package/ui-dist/assets/{page-layout-B5th9UzR.js → page-layout-PG3cwSpz.js} +1 -1
  22. package/ui-dist/assets/popover-BB-kINz7.js +1 -0
  23. package/ui-dist/assets/{security-config-D72JskP5.js → security-config-Bb6l-viE.js} +1 -1
  24. package/ui-dist/assets/skeleton-CLSc5FYO.js +1 -0
  25. package/ui-dist/assets/{status-dot-CU5ZpOn1.js → status-dot-Behu7kDZ.js} +1 -1
  26. package/ui-dist/assets/{switch-BdaXEtXk.js → switch-CvNG9775.js} +1 -1
  27. package/ui-dist/assets/{tabs-custom-BVhSoteN.js → tabs-custom-CUdBQO_7.js} +1 -1
  28. package/ui-dist/assets/{useConfirmDialog-Dugi9V-Z.js → useConfirmDialog-CLLe2uIJ.js} +1 -1
  29. package/ui-dist/assets/{vendor-CmQZsDAE.js → vendor-TJ2hy_Lv.js} +87 -82
  30. package/ui-dist/index.html +3 -3
  31. package/ui-dist/assets/ChatPage-DmGI776q.js +0 -38
  32. package/ui-dist/assets/RemoteAccessPage-Rzi5a6Gc.js +0 -1
  33. package/ui-dist/assets/index-ClLy_7T2.js +0 -8
  34. package/ui-dist/assets/popover-BEIWRoeP.js +0 -1
  35. package/ui-dist/assets/skeleton-B_Pn9x0i.js +0 -1
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 NextClaw contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/cli/index.js CHANGED
@@ -2733,7 +2733,30 @@ var ChannelCommands = class {
2733
2733
  }
2734
2734
  }
2735
2735
  }
2736
- channelsLogin() {
2736
+ async channelsLogin(opts = {}) {
2737
+ const channelId = opts.channel?.trim();
2738
+ if (!channelId) {
2739
+ this.runLegacyBridgeLogin();
2740
+ return;
2741
+ }
2742
+ const config2 = loadConfig7();
2743
+ const binding = this.resolvePluginChannelBinding(config2, channelId);
2744
+ if (!binding) {
2745
+ console.error(`No plugin channel found for: ${channelId}`);
2746
+ process.exit(1);
2747
+ }
2748
+ const result = await this.loginPluginChannel(config2, binding, opts);
2749
+ if (!result) {
2750
+ return;
2751
+ }
2752
+ saveConfig5(this.buildNextConfigAfterChannelLogin(config2, binding, result));
2753
+ this.printPluginChannelLoginResult(binding, result);
2754
+ await this.deps.requestRestart({
2755
+ reason: `channel login via plugin: ${binding.pluginId}`,
2756
+ manualMessage: "Restart the gateway to apply changes."
2757
+ });
2758
+ }
2759
+ runLegacyBridgeLogin() {
2737
2760
  const bridgeDir = this.deps.getBridgeDir();
2738
2761
  console.log(`${this.deps.logo} Starting bridge...`);
2739
2762
  console.log("Scan the QR code to connect.\n");
@@ -2742,6 +2765,78 @@ var ChannelCommands = class {
2742
2765
  console.error(`Bridge failed: ${result.status ?? 1}`);
2743
2766
  }
2744
2767
  }
2768
+ resolvePluginChannelBinding(config2, channelId) {
2769
+ const workspaceDir = getWorkspacePath3(config2.agents.defaults.workspace);
2770
+ const pluginRegistry = loadPluginRegistry(config2, workspaceDir);
2771
+ const bindings = getPluginChannelBindings(pluginRegistry);
2772
+ return bindings.find((entry) => entry.channelId === channelId || entry.pluginId === channelId);
2773
+ }
2774
+ async loginPluginChannel(config2, binding, opts) {
2775
+ const login = binding.channel.auth?.login;
2776
+ if (!login) {
2777
+ if (binding.channelId === "whatsapp") {
2778
+ this.runLegacyBridgeLogin();
2779
+ return null;
2780
+ }
2781
+ console.error(`Channel "${binding.channelId}" does not support login.`);
2782
+ process.exit(1);
2783
+ }
2784
+ const result = await login({
2785
+ cfg: config2,
2786
+ pluginId: binding.pluginId,
2787
+ channelId: binding.channelId,
2788
+ pluginConfig: this.clonePluginConfig(config2.plugins.entries?.[binding.pluginId]?.config),
2789
+ accountId: opts.account?.trim() || null,
2790
+ baseUrl: opts.url?.trim() || opts.httpUrl?.trim() || null,
2791
+ verbose: Boolean(opts.verbose)
2792
+ });
2793
+ this.assertValidPluginLoginResult(result);
2794
+ return result;
2795
+ }
2796
+ clonePluginConfig(value) {
2797
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
2798
+ return void 0;
2799
+ }
2800
+ return JSON.parse(JSON.stringify(value));
2801
+ }
2802
+ assertValidPluginLoginResult(result) {
2803
+ if (!result || typeof result !== "object" || Array.isArray(result)) {
2804
+ console.error("Channel login returned an invalid result.");
2805
+ process.exit(1);
2806
+ }
2807
+ const record = result;
2808
+ if (!record.pluginConfig || typeof record.pluginConfig !== "object" || Array.isArray(record.pluginConfig)) {
2809
+ console.error("Channel login returned an invalid plugin config.");
2810
+ process.exit(1);
2811
+ }
2812
+ }
2813
+ buildNextConfigAfterChannelLogin(config2, binding, result) {
2814
+ return enablePluginInConfig2(
2815
+ {
2816
+ ...config2,
2817
+ plugins: {
2818
+ ...config2.plugins,
2819
+ entries: {
2820
+ ...config2.plugins.entries ?? {},
2821
+ [binding.pluginId]: {
2822
+ ...config2.plugins.entries?.[binding.pluginId] ?? {},
2823
+ config: result.pluginConfig
2824
+ }
2825
+ }
2826
+ }
2827
+ },
2828
+ binding.pluginId
2829
+ );
2830
+ }
2831
+ printPluginChannelLoginResult(binding, result) {
2832
+ console.log(`Logged into channel "${binding.channelId}" via plugin "${binding.pluginId}".`);
2833
+ if (result.accountId) {
2834
+ console.log(`Active account: ${result.accountId}`);
2835
+ }
2836
+ for (const note of result.notes ?? []) {
2837
+ console.log(note);
2838
+ }
2839
+ }
2745
2840
  async channelsAdd(opts) {
2746
2841
  const channelId = opts.channel?.trim();
2747
2842
  if (!channelId) {
@@ -2845,7 +2940,8 @@ var CronCommands = class {
2845
2940
  message: opts.message,
2846
2941
  deliver: Boolean(opts.deliver),
2847
2942
  channel: opts.channel,
2848
- to: opts.to
2943
+ to: opts.to,
2944
+ accountId: opts.account
2849
2945
  });
2850
2946
  console.log(`\u2713 Added job '${job.name}' (${job.id})`);
2851
2947
  }
@@ -4563,6 +4659,45 @@ var ServiceMarketplaceInstaller = class {
4563
4659
  }
4564
4660
  };
4565
4661
 
4662
+ // src/cli/commands/service-cron-job-handler.ts
4663
+ function normalizeOptionalString4(value) {
4664
+ if (typeof value !== "string") {
4665
+ return void 0;
4666
+ }
4667
+ const trimmed = value.trim();
4668
+ return trimmed || void 0;
4669
+ }
4670
+ function buildCronJobMetadata(accountId) {
4671
+ if (!accountId) {
4672
+ return {};
4673
+ }
4674
+ return { accountId, account_id: accountId };
4675
+ }
4676
+ function createCronJobHandler(params) {
4677
+ return async (job) => {
4678
+ const accountId = normalizeOptionalString4(job.payload.accountId);
4679
+ const metadata = buildCronJobMetadata(accountId);
4680
+ const response = await params.runtimePool.processDirect({
4681
+ content: job.payload.message,
4682
+ sessionKey: `cron:${job.id}`,
4683
+ channel: job.payload.channel ?? "cli",
4684
+ chatId: job.payload.to ?? "direct",
4685
+ metadata,
4686
+ agentId: params.runtimePool.primaryAgentId
4687
+ });
4688
+ if (job.payload.deliver && job.payload.to) {
4689
+ await params.bus.publishOutbound({
4690
+ channel: job.payload.channel ?? "cli",
4691
+ chatId: job.payload.to,
4692
+ content: response,
4693
+ media: [],
4694
+ metadata
4695
+ });
4696
+ }
4697
+ return response;
4698
+ };
4699
+ }
4700
+
4566
4701
  // src/cli/commands/service-plugin-runtime-bridge.ts
4567
4702
  import { loadConfig as loadConfig14, resolveConfigSecrets as resolveConfigSecrets2, saveConfig as saveConfig9 } from "@nextclaw/core";
4568
4703
  import { setPluginRuntimeBridge } from "@nextclaw/openclaw-compat";
@@ -5605,9 +5740,7 @@ var NextclawNcpToolRegistry = class {
5605
5740
  this.registerTool(execTool);
5606
5741
  this.registerTool(new WebSearchTool(context.searchConfig));
5607
5742
  this.registerTool(new WebFetchTool());
5608
- const messageTool = new MessageTool((message) => this.options.bus.publishOutbound(message));
5609
- messageTool.setContext(context.channel, context.chatId);
5610
- this.registerTool(messageTool);
5743
+ this.registerMessagingTools(context);
5611
5744
  const spawnTool = new SpawnTool(this.subagents);
5612
5745
  spawnTool.setContext(
5613
5746
  context.channel,
@@ -5635,9 +5768,15 @@ var NextclawNcpToolRegistry = class {
5635
5768
  const gatewayTool = new GatewayTool(this.options.gatewayController);
5636
5769
  gatewayTool.setContext({ sessionKey: context.sessionId });
5637
5770
  this.registerTool(gatewayTool);
5771
+ }
5772
+ registerMessagingTools(context) {
5773
+ const accountId = readMetadataAccountId(context.metadata, {});
5774
+ const messageTool = new MessageTool((message) => this.options.bus.publishOutbound(message));
5775
+ messageTool.setContext(context.channel, context.chatId, accountId ?? null);
5776
+ this.registerTool(messageTool);
5638
5777
  if (this.options.cronService) {
5639
5778
  const cronTool = new CronTool(this.options.cronService);
5640
- cronTool.setContext(context.channel, context.chatId);
5779
+ cronTool.setContext(context.channel, context.chatId, accountId ?? null);
5641
5780
  this.registerTool(cronTool);
5642
5781
  }
5643
5782
  }
@@ -5737,7 +5876,7 @@ function resolveRequestedToolNames(metadata) {
5737
5876
  )
5738
5877
  );
5739
5878
  }
5740
- function normalizeOptionalString4(value) {
5879
+ function normalizeOptionalString5(value) {
5741
5880
  return normalizeString(value) ?? void 0;
5742
5881
  }
5743
5882
  function readMetadataModel(metadata) {
@@ -5857,7 +5996,7 @@ var NextclawNcpContextBuilder = class {
5857
5996
  if (inboundModel) {
5858
5997
  session.metadata.preferred_model = inboundModel;
5859
5998
  }
5860
- const effectiveModel = normalizeOptionalString4(session.metadata.preferred_model) ?? profile.model;
5999
+ const effectiveModel = normalizeOptionalString5(session.metadata.preferred_model) ?? profile.model;
5861
6000
  const clearThinking = requestMetadata.clear_thinking === true || requestMetadata.reset_thinking === true;
5862
6001
  if (clearThinking) {
5863
6002
  delete session.metadata.preferred_thinking;
@@ -5874,8 +6013,8 @@ var NextclawNcpContextBuilder = class {
5874
6013
  model: effectiveModel,
5875
6014
  sessionThinkingLevel: parseThinkingLevel(session.metadata.preferred_thinking) ?? null
5876
6015
  });
5877
- const channel = normalizeOptionalString4(requestMetadata.channel) ?? normalizeOptionalString4(session.metadata.last_channel) ?? "ui";
5878
- const chatId = normalizeOptionalString4(requestMetadata.chatId) ?? normalizeOptionalString4(requestMetadata.chat_id) ?? normalizeOptionalString4(session.metadata.last_to) ?? "web-ui";
6016
+ const channel = normalizeOptionalString5(requestMetadata.channel) ?? normalizeOptionalString5(session.metadata.last_channel) ?? "ui";
6017
+ const chatId = normalizeOptionalString5(requestMetadata.chatId) ?? normalizeOptionalString5(requestMetadata.chat_id) ?? normalizeOptionalString5(session.metadata.last_to) ?? "web-ui";
5879
6018
  session.metadata.last_channel = channel;
5880
6019
  session.metadata.last_to = chatId;
5881
6020
  const requestedSkillNames = resolveRequestedSkillNames(requestMetadata);
@@ -6819,7 +6958,7 @@ function launchManagedSelfControl(params = {}) {
6819
6958
  }
6820
6959
 
6821
6960
  // src/cli/commands/remote-access-host.ts
6822
- function normalizeOptionalString5(value) {
6961
+ function normalizeOptionalString6(value) {
6823
6962
  if (typeof value !== "string") {
6824
6963
  return null;
6825
6964
  }
@@ -6851,8 +6990,8 @@ var RemoteAccessHost = class {
6851
6990
  const config2 = loadConfig16(getConfigPath8());
6852
6991
  const status = this.deps.remoteCommands.getStatusView();
6853
6992
  const account = this.readAccountView({
6854
- token: normalizeOptionalString5(config2.providers.nextclaw?.apiKey),
6855
- apiBase: normalizeOptionalString5(config2.providers.nextclaw?.apiBase),
6993
+ token: normalizeOptionalString6(config2.providers.nextclaw?.apiKey),
6994
+ apiBase: normalizeOptionalString6(config2.providers.nextclaw?.apiBase),
6856
6995
  platformBase: status.platformBase
6857
6996
  });
6858
6997
  return {
@@ -6887,7 +7026,7 @@ var RemoteAccessHost = class {
6887
7026
  async pollBrowserAuth(input) {
6888
7027
  const config2 = loadConfig16(getConfigPath8());
6889
7028
  const result = await this.deps.platformAuthCommands.pollBrowserAuth({
6890
- apiBase: normalizeOptionalString5(input.apiBase) ?? normalizeOptionalString5(config2.remote.platformApiBase) ?? normalizeOptionalString5(config2.providers.nextclaw?.apiBase) ?? void 0,
7029
+ apiBase: normalizeOptionalString6(input.apiBase) ?? normalizeOptionalString6(config2.remote.platformApiBase) ?? normalizeOptionalString6(config2.providers.nextclaw?.apiBase) ?? void 0,
6891
7030
  sessionId: input.sessionId
6892
7031
  });
6893
7032
  if (result.status !== "authorized") {
@@ -7751,25 +7890,7 @@ var ServiceCommands = class {
7751
7890
  runtimeConfigPath,
7752
7891
  pluginChannelBindings
7753
7892
  });
7754
- cron2.onJob = async (job) => {
7755
- const response = await runtimePool.processDirect({
7756
- content: job.payload.message,
7757
- sessionKey: `cron:${job.id}`,
7758
- channel: job.payload.channel ?? "cli",
7759
- chatId: job.payload.to ?? "direct",
7760
- agentId: runtimePool.primaryAgentId
7761
- });
7762
- if (job.payload.deliver && job.payload.to) {
7763
- await bus.publishOutbound({
7764
- channel: job.payload.channel ?? "cli",
7765
- chatId: job.payload.to,
7766
- content: response,
7767
- media: [],
7768
- metadata: {}
7769
- });
7770
- }
7771
- return response;
7772
- };
7893
+ cron2.onJob = createCronJobHandler({ runtimePool, bus });
7773
7894
  const heartbeat = new HeartbeatService(
7774
7895
  workspace,
7775
7896
  async (promptText) => runtimePool.processDirect({ content: promptText, sessionKey: "heartbeat", agentId: runtimePool.primaryAgentId }),
@@ -9444,8 +9565,8 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
9444
9565
  channelsStatus() {
9445
9566
  this.channelCommands.channelsStatus();
9446
9567
  }
9447
- channelsLogin() {
9448
- this.channelCommands.channelsLogin();
9568
+ async channelsLogin(opts) {
9569
+ await this.channelCommands.channelsLogin(opts);
9449
9570
  }
9450
9571
  async channelsAdd(opts) {
9451
9572
  await this.channelCommands.channelsAdd(opts);
@@ -9586,10 +9707,10 @@ secrets.command("reload").description("Trigger runtime secrets reload signal").o
9586
9707
  var channels = program.command("channels").description("Manage channels");
9587
9708
  channels.command("add").description("Configure a plugin channel (OpenClaw-compatible setup)").requiredOption("--channel <id>", "Plugin channel id").option("--code <code>", "Pairing code").option("--token <token>", "Connector token").option("--name <name>", "Display name").option("--url <url>", "API base URL").option("--http-url <url>", "Alias for --url").action((opts) => runtime.channelsAdd(opts));
9588
9709
  channels.command("status").description("Show channel status").action(() => runtime.channelsStatus());
9589
- channels.command("login").description("Link device via QR code").action(() => runtime.channelsLogin());
9710
+ channels.command("login").description("Link device via QR code").option("--channel <id>", "Plugin channel id").option("--account <id>", "Channel account id").option("--url <url>", "Channel API base URL").option("--http-url <url>", "Alias for --url").option("-v, --verbose", "Verbose output", false).action(async (opts) => runtime.channelsLogin(opts));
9590
9711
  var cron = program.command("cron").description("Manage scheduled tasks");
9591
9712
  cron.command("list").option("-a, --all", "Include disabled jobs").action((opts) => runtime.cronList(opts));
9592
- cron.command("add").requiredOption("-n, --name <name>", "Job name").requiredOption("-m, --message <message>", "Message for agent").option("-e, --every <seconds>", "Run every N seconds").option("-c, --cron <expr>", "Cron expression").option("--at <iso>", "Run once at time (ISO format)").option("-d, --deliver", "Deliver response to channel").option("--to <recipient>", "Recipient for delivery").option("--channel <channel>", "Channel for delivery").action((opts) => runtime.cronAdd(opts));
9713
+ cron.command("add").requiredOption("-n, --name <name>", "Job name").requiredOption("-m, --message <message>", "Message for agent").option("-e, --every <seconds>", "Run every N seconds").option("-c, --cron <expr>", "Cron expression").option("--at <iso>", "Run once at time (ISO format)").option("-d, --deliver", "Deliver response to channel").option("--to <recipient>", "Recipient for delivery").option("--channel <channel>", "Channel for delivery").option("--account <id>", "Account id for channel delivery").action((opts) => runtime.cronAdd(opts));
9593
9714
  cron.command("remove <jobId>").action((jobId) => runtime.cronRemove(jobId));
9594
9715
  cron.command("enable <jobId>").option("--disable", "Disable instead of enable").action((jobId, opts) => runtime.cronEnable(jobId, opts));
9595
9716
  cron.command("run <jobId>").option("-f, --force", "Run even if disabled").action(async (jobId, opts) => runtime.cronRun(jobId, opts));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nextclaw",
3
- "version": "0.13.28",
3
+ "version": "0.13.31",
4
4
  "description": "Lightweight personal AI assistant with CLI, multi-provider routing, and channel integrations.",
5
5
  "private": false,
6
6
  "type": "module",
@@ -35,38 +35,37 @@
35
35
  "ui-dist",
36
36
  "templates"
37
37
  ],
38
- "scripts": {
39
- "dev": "tsx watch --tsconfig tsconfig.json src/cli/index.ts",
40
- "dev:build": "tsx src/cli/index.ts",
41
- "build": "node scripts/sync-usage-template.mjs && tsup src/index.ts src/cli/index.ts --format esm --dts --out-dir dist && node scripts/copy-ui-dist.mjs",
42
- "prepack": "pnpm run build",
43
- "start": "node dist/cli.js",
44
- "lint": "eslint .",
45
- "tsc": "tsc -p tsconfig.json",
46
- "test": "vitest"
47
- },
48
38
  "dependencies": {
49
39
  "chokidar": "^3.6.0",
50
40
  "commander": "^12.1.0",
51
41
  "yaml": "^2.8.1",
52
- "@nextclaw/core": "workspace:*",
53
- "@nextclaw/mcp": "workspace:*",
54
- "@nextclaw/ncp": "workspace:*",
55
- "@nextclaw/ncp-agent-runtime": "workspace:*",
56
- "@nextclaw/ncp-mcp": "workspace:*",
57
- "@nextclaw/ncp-toolkit": "workspace:*",
58
- "@nextclaw/remote": "workspace:*",
59
- "@nextclaw/runtime": "workspace:*",
60
- "@nextclaw/server": "workspace:*",
61
- "@nextclaw/openclaw-compat": "workspace:*"
42
+ "@nextclaw/core": "0.9.10",
43
+ "@nextclaw/mcp": "0.1.27",
44
+ "@nextclaw/ncp": "0.3.1",
45
+ "@nextclaw/ncp-agent-runtime": "0.2.1",
46
+ "@nextclaw/ncp-mcp": "0.1.27",
47
+ "@nextclaw/ncp-toolkit": "0.4.1",
48
+ "@nextclaw/remote": "0.1.23",
49
+ "@nextclaw/runtime": "0.2.10",
50
+ "@nextclaw/server": "0.10.27",
51
+ "@nextclaw/openclaw-compat": "0.3.13"
62
52
  },
63
53
  "devDependencies": {
64
- "@nextclaw/ui": "workspace:*",
65
54
  "@types/node": "^20.17.6",
66
55
  "prettier": "^3.3.3",
67
56
  "tsup": "^8.3.5",
68
57
  "tsx": "^4.19.2",
69
58
  "typescript": "^5.6.3",
70
- "vitest": "^2.1.2"
59
+ "vitest": "^2.1.2",
60
+ "@nextclaw/ui": "0.9.13"
61
+ },
62
+ "scripts": {
63
+ "dev": "tsx watch --tsconfig tsconfig.json src/cli/index.ts",
64
+ "dev:build": "tsx src/cli/index.ts",
65
+ "build": "node scripts/sync-usage-template.mjs && tsup src/index.ts src/cli/index.ts --format esm --dts --out-dir dist && node scripts/copy-ui-dist.mjs",
66
+ "start": "node dist/cli.js",
67
+ "lint": "eslint .",
68
+ "tsc": "tsc -p tsconfig.json",
69
+ "test": "vitest"
71
70
  }
72
- }
71
+ }
@@ -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,Z as me,u as q,a as $,b as H,$ as pe,a0 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-ClLy_7T2.js";import{L as he}from"./label-DBSKOMGE.js";import{S as fe}from"./switch-BdaXEtXk.js";import{S as K}from"./status-dot-CU5ZpOn1.js";import{L as J}from"./LogoBadge-CcTyimdr.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-BVhSoteN.js";import{P as Ce,a as Ne}from"./page-layout-B5th9UzR.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,aq as te,b1 as se,b2 as ne,b3 as le,a0 as re,G as oe,ai as ce,H as ie}from"./vendor-TJ2hy_Lv.js";import{t as e,c as I,Z as me,u as q,a as $,b as H,$ as pe,a0 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-CmGwUgcl.js";import{L as he}from"./label-BOvIOmQx.js";import{S as fe}from"./switch-CvNG9775.js";import{S as K}from"./status-dot-Behu7kDZ.js";import{L as J}from"./LogoBadge-t1JzzCtI.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-CUdBQO_7.js";import{P as Ce,a as Ne}from"./page-layout-PG3cwSpz.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};