nextclaw 0.13.10 → 0.13.11

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/dist/cli/index.js +57 -38
  2. package/package.json +22 -21
  3. package/ui-dist/assets/ChannelsList-Byfj2R01.js +1 -0
  4. package/ui-dist/assets/ChatPage-DM1ewbWf.js +38 -0
  5. package/ui-dist/assets/DocBrowser-BLv77lJ0.js +1 -0
  6. package/ui-dist/assets/LogoBadge-D7j1al-w.js +1 -0
  7. package/ui-dist/assets/MarketplacePage-DuskLKYh.js +49 -0
  8. package/ui-dist/assets/McpMarketplacePage-DpMjaD3m.js +40 -0
  9. package/ui-dist/assets/ModelConfig-ubaecweS.js +1 -0
  10. package/ui-dist/assets/ProvidersList-w8MJH2LI.js +1 -0
  11. package/ui-dist/assets/RemoteAccessPage-D79_5Kbn.js +1 -0
  12. package/ui-dist/assets/RuntimeConfig-BbX4yFKy.js +1 -0
  13. package/ui-dist/assets/SearchConfig-BmmmeyJd.js +1 -0
  14. package/ui-dist/assets/SecretsConfig-CWG8J01H.js +3 -0
  15. package/ui-dist/assets/SessionsConfig-D-vg_Lgv.js +2 -0
  16. package/ui-dist/assets/chat-message-CGXiVhyN.js +3 -0
  17. package/ui-dist/assets/config-hints-CApS3K_7.js +1 -0
  18. package/ui-dist/assets/config-layout-BHnOoweL.js +1 -0
  19. package/ui-dist/assets/index-COrhpAdh.css +1 -0
  20. package/ui-dist/assets/index-CeRbsQ90.js +8 -0
  21. package/ui-dist/assets/index-Ct7FQpxN.js +1 -0
  22. package/ui-dist/assets/label-CCSffS1D.js +1 -0
  23. package/ui-dist/assets/marketplace-localization-Dk31LJJJ.js +1 -0
  24. package/ui-dist/assets/page-layout-ud8wZ8gX.js +1 -0
  25. package/ui-dist/assets/popover-Bfoe6YBX.js +1 -0
  26. package/ui-dist/assets/provider-models-D3B_xWXx.js +1 -0
  27. package/ui-dist/assets/security-config-DJJUCMov.js +1 -0
  28. package/ui-dist/assets/skeleton-IOOTmHzP.js +1 -0
  29. package/ui-dist/assets/status-dot-Fz9-eKsl.js +1 -0
  30. package/ui-dist/assets/switch-B-_SrMSL.js +1 -0
  31. package/ui-dist/assets/tabs-custom-6Tm1ZHfS.js +1 -0
  32. package/ui-dist/assets/useConfirmDialog-BeOW2bOI.js +5 -0
  33. package/ui-dist/assets/vendor-CwsIoNvJ.js +442 -0
  34. package/ui-dist/index.html +18 -0
  35. package/LICENSE +0 -21
package/dist/cli/index.js CHANGED
@@ -29,7 +29,7 @@ import {
29
29
  setPluginRuntimeBridge as setPluginRuntimeBridge2
30
30
  } from "@nextclaw/openclaw-compat";
31
31
  import { existsSync as existsSync12, mkdirSync as mkdirSync7, readFileSync as readFileSync10, writeFileSync as writeFileSync6 } from "fs";
32
- import { join as join8, resolve as resolve12 } from "path";
32
+ import { join as join9, resolve as resolve12 } from "path";
33
33
  import { createInterface as createInterface3 } from "readline";
34
34
  import { fileURLToPath as fileURLToPath5 } from "url";
35
35
  import { spawn as spawn4 } from "child_process";
@@ -3415,7 +3415,7 @@ var RemoteCommands = class {
3415
3415
  // src/cli/commands/diagnostics.ts
3416
3416
  import { createServer as createNetServer } from "net";
3417
3417
  import { existsSync as existsSync6, readFileSync as readFileSync6 } from "fs";
3418
- import { resolve as resolve8 } from "path";
3418
+ import { join as join4, resolve as resolve8 } from "path";
3419
3419
  import {
3420
3420
  APP_NAME as APP_NAME2,
3421
3421
  getConfigPath as getConfigPath5,
@@ -3556,6 +3556,11 @@ var DiagnosticsCommands = class {
3556
3556
  status: report.workspaceExists ? "pass" : "warn",
3557
3557
  detail: report.workspacePath
3558
3558
  },
3559
+ {
3560
+ name: "ui-assets",
3561
+ status: report.uiAssets.indexHtmlPresent ? "pass" : "fail",
3562
+ detail: report.uiAssets.resolvedStaticDir ? `${report.uiAssets.resolvedStaticDir} (${report.uiAssets.indexHtmlPresent ? "index.html found" : "index.html missing"})` : "no UI static directory resolved"
3563
+ },
3559
3564
  {
3560
3565
  name: "service-state",
3561
3566
  status: report.process.staleState ? "fail" : report.process.running ? "pass" : "warn",
@@ -3624,6 +3629,8 @@ var DiagnosticsCommands = class {
3624
3629
  const configuredUi = resolveUiConfig(config2, { enabled: true, host: config2.ui.host, port: config2.ui.port });
3625
3630
  const configuredUiUrl = resolveUiApiBase(configuredUi.host, configuredUi.port);
3626
3631
  const configuredApiUrl = `${configuredUiUrl}/api`;
3632
+ const resolvedStaticDir = serviceState?.uiStaticDir ?? resolveUiStaticDir();
3633
+ const indexHtmlPresent = Boolean(resolvedStaticDir && existsSync6(join4(resolvedStaticDir, "index.html")));
3627
3634
  const managedUiUrl = serviceState?.uiUrl ?? null;
3628
3635
  const managedApiUrl = serviceState?.apiUrl ?? null;
3629
3636
  const managedHealth = running && managedApiUrl ? await this.probeApiHealth(`${managedApiUrl}/health`) : { state: "unreachable", detail: "service not running" };
@@ -3658,6 +3665,10 @@ var DiagnosticsCommands = class {
3658
3665
  providers,
3659
3666
  serviceStatePath,
3660
3667
  serviceStateExists: existsSync6(serviceStatePath),
3668
+ uiAssets: {
3669
+ resolvedStaticDir,
3670
+ indexHtmlPresent
3671
+ },
3661
3672
  fixActions,
3662
3673
  process: {
3663
3674
  managedByState,
@@ -3757,7 +3768,11 @@ var DiagnosticsCommands = class {
3757
3768
  params.issues.push("A service appears healthy on configured API endpoint, but state is missing/stale.");
3758
3769
  params.recommendations.push("Another process may be occupying the UI port; stop it or use --ui-port with a free port.");
3759
3770
  }
3760
- if (!params.providers.some((provider) => provider.configured)) {
3771
+ if (params.running && !params.serviceState?.uiStaticDir) {
3772
+ params.issues.push("Managed service did not record a resolved UI static asset directory.");
3773
+ params.recommendations.push(`Check logs at ${params.serviceState?.logPath ?? resolveServiceLogPath()} and verify packaged ui-dist assets exist.`);
3774
+ }
3775
+ if (!params.running && !params.providers.some((provider) => provider.configured)) {
3761
3776
  params.recommendations.push("Configure at least one provider API key in UI or config before expecting agent replies.");
3762
3777
  }
3763
3778
  }
@@ -3807,7 +3822,7 @@ import {
3807
3822
  } from "@nextclaw/openclaw-compat";
3808
3823
  import { startUiServer } from "@nextclaw/server";
3809
3824
  import { appendFileSync, closeSync, cpSync as cpSync2, existsSync as existsSync10, mkdirSync as mkdirSync5, openSync } from "fs";
3810
- import { dirname as dirname2, join as join6, resolve as resolve10 } from "path";
3825
+ import { dirname as dirname2, join as join7, resolve as resolve10 } from "path";
3811
3826
  import { spawn as spawn3 } from "child_process";
3812
3827
  import { request as httpRequest } from "http";
3813
3828
  import { request as httpsRequest } from "https";
@@ -4288,7 +4303,7 @@ var MissingProvider = class extends LLMProvider {
4288
4303
  // src/cli/commands/service-marketplace-installer.ts
4289
4304
  import { getWorkspacePath as getWorkspacePath5, loadConfig as loadConfig12 } from "@nextclaw/core";
4290
4305
  import { existsSync as existsSync8, rmSync as rmSync4 } from "fs";
4291
- import { join as join4 } from "path";
4306
+ import { join as join5 } from "path";
4292
4307
 
4293
4308
  // src/cli/commands/service-marketplace-helpers.ts
4294
4309
  var containsAbsoluteFsPath = (line) => {
@@ -4491,7 +4506,7 @@ var ServiceMarketplaceInstaller = class {
4491
4506
  }
4492
4507
  async uninstallSkill(slug) {
4493
4508
  const workspace = getWorkspacePath5(loadConfig12().agents.defaults.workspace);
4494
- const targetDir = join4(workspace, "skills", slug);
4509
+ const targetDir = join5(workspace, "skills", slug);
4495
4510
  if (!existsSync8(targetDir)) {
4496
4511
  throw new Error(`Skill not installed in workspace: ${slug}`);
4497
4512
  }
@@ -6484,7 +6499,7 @@ async function createUiNcpAgent(params) {
6484
6499
  // src/cli/commands/service-remote-runtime.ts
6485
6500
  import { RemoteServiceModule } from "@nextclaw/remote";
6486
6501
  function createManagedRemoteModule(params) {
6487
- if (!params.config.ui.enabled) {
6502
+ if (!params.uiEnabled) {
6488
6503
  return null;
6489
6504
  }
6490
6505
  return new RemoteServiceModule({
@@ -6508,6 +6523,7 @@ function writeInitialManagedServiceState(params) {
6508
6523
  uiHost: params.snapshot.uiHost,
6509
6524
  uiPort: params.snapshot.uiPort,
6510
6525
  logPath: params.snapshot.logPath,
6526
+ uiStaticDir: params.snapshot.uiStaticDir ?? null,
6511
6527
  startupLastProbeError: null,
6512
6528
  startupTimeoutMs: params.readinessTimeoutMs,
6513
6529
  startupCheckedAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -6524,6 +6540,7 @@ function writeReadyManagedServiceState(params) {
6524
6540
  uiHost: params.snapshot.uiHost,
6525
6541
  uiPort: params.snapshot.uiPort,
6526
6542
  logPath: params.snapshot.logPath,
6543
+ uiStaticDir: params.snapshot.uiStaticDir ?? currentState?.uiStaticDir ?? null,
6527
6544
  startupState: params.readiness.ready ? "ready" : "degraded",
6528
6545
  startupLastProbeError: params.readiness.lastProbeError,
6529
6546
  startupTimeoutMs: params.readinessTimeoutMs,
@@ -6855,13 +6872,13 @@ function createRemoteAccessHost(params) {
6855
6872
 
6856
6873
  // src/cli/commands/ui-chat-run-coordinator.ts
6857
6874
  import { existsSync as existsSync9, mkdirSync as mkdirSync4, readdirSync as readdirSync2, readFileSync as readFileSync8, writeFileSync as writeFileSync4 } from "fs";
6858
- import { join as join5 } from "path";
6875
+ import { join as join6 } from "path";
6859
6876
  import {
6860
6877
  getDataDir as getDataDir6,
6861
6878
  parseAgentScopedSessionKey as parseAgentScopedSessionKey2,
6862
6879
  safeFilename
6863
6880
  } from "@nextclaw/core";
6864
- var RUNS_DIR = join5(getDataDir6(), "runs");
6881
+ var RUNS_DIR = join6(getDataDir6(), "runs");
6865
6882
  var NON_TERMINAL_STATES = /* @__PURE__ */ new Set(["queued", "running"]);
6866
6883
  var DEFAULT_SESSION_TYPE = "native";
6867
6884
  var SESSION_TYPE_METADATA_KEY = "session_type";
@@ -7387,7 +7404,7 @@ var UiChatRunCoordinator = class {
7387
7404
  };
7388
7405
  }
7389
7406
  getRunPath(runId) {
7390
- return join5(RUNS_DIR, `${safeFilename(runId)}.json`);
7407
+ return join6(RUNS_DIR, `${safeFilename(runId)}.json`);
7391
7408
  }
7392
7409
  persistRun(run) {
7393
7410
  const persisted = {
@@ -7416,7 +7433,7 @@ var UiChatRunCoordinator = class {
7416
7433
  if (!entry.isFile() || !entry.name.endsWith(".json")) {
7417
7434
  continue;
7418
7435
  }
7419
- const path2 = join5(RUNS_DIR, entry.name);
7436
+ const path2 = join6(RUNS_DIR, entry.name);
7420
7437
  try {
7421
7438
  const parsed = JSON.parse(readFileSync8(path2, "utf-8"));
7422
7439
  const runId = readOptionalString(parsed.runId);
@@ -7522,7 +7539,7 @@ var ServiceCommands = class {
7522
7539
  });
7523
7540
  const sessionManager = new SessionManager(workspace);
7524
7541
  let pluginGatewayHandles = [];
7525
- const cronStorePath = join6(getDataDir7(), "cron", "jobs.json");
7542
+ const cronStorePath = join7(getDataDir7(), "cron", "jobs.json");
7526
7543
  const cron2 = new CronService2(cronStorePath);
7527
7544
  const uiConfig = resolveUiConfig(config2, options.uiOverrides);
7528
7545
  const uiStaticDir = options.uiStaticDir === void 0 ? resolveUiStaticDir() : options.uiStaticDir;
@@ -7705,7 +7722,7 @@ var ServiceCommands = class {
7705
7722
  accountId
7706
7723
  })
7707
7724
  );
7708
- const remoteModule = createManagedRemoteModule({ config: config2, localOrigin });
7725
+ const remoteModule = createManagedRemoteModule({ config: config2, uiEnabled: uiConfig.enabled, localOrigin });
7709
7726
  await startGatewaySupportServices({
7710
7727
  cronJobs: cron2.status().jobs,
7711
7728
  remoteModule,
@@ -7918,6 +7935,8 @@ var ServiceCommands = class {
7918
7935
  if (existing) {
7919
7936
  clearServiceState();
7920
7937
  }
7938
+ const staticDirDescription = staticDir ? `staticDir=${staticDir}` : "staticDir=<missing>";
7939
+ this.appendStartupStage(logPath, `ui asset resolution: ${staticDirDescription}`);
7921
7940
  if (!staticDir) {
7922
7941
  console.log("Warning: UI frontend not found in package assets.");
7923
7942
  }
@@ -7968,7 +7987,7 @@ var ServiceCommands = class {
7968
7987
  writeInitialManagedServiceState({
7969
7988
  config: config2,
7970
7989
  readinessTimeoutMs,
7971
- snapshot: { pid: child.pid, uiUrl, apiUrl, uiHost: uiConfig.host, uiPort: uiConfig.port, logPath }
7990
+ snapshot: { pid: child.pid, uiUrl, apiUrl, uiHost: uiConfig.host, uiPort: uiConfig.port, logPath, uiStaticDir: staticDir }
7972
7991
  });
7973
7992
  this.appendStartupStage(logPath, `health probe started: ${healthUrl} (phase=quick, timeoutMs=${quickPhaseTimeoutMs})`);
7974
7993
  let readiness = await this.waitForBackgroundServiceReady({
@@ -8496,8 +8515,8 @@ var ServiceCommands = class {
8496
8515
  }
8497
8516
  installBuiltinMarketplaceSkill(slug, force) {
8498
8517
  const workspace = getWorkspacePath9(loadConfig14().agents.defaults.workspace);
8499
- const destination = join6(workspace, "skills", slug);
8500
- const destinationSkillFile = join6(destination, "SKILL.md");
8518
+ const destination = join7(workspace, "skills", slug);
8519
+ const destinationSkillFile = join7(destination, "SKILL.md");
8501
8520
  if (existsSync10(destinationSkillFile) && !force) {
8502
8521
  return {
8503
8522
  message: `${slug} is already installed`
@@ -8513,7 +8532,7 @@ var ServiceCommands = class {
8513
8532
  }
8514
8533
  return null;
8515
8534
  }
8516
- mkdirSync5(join6(workspace, "skills"), { recursive: true });
8535
+ mkdirSync5(join7(workspace, "skills"), { recursive: true });
8517
8536
  cpSync2(dirname2(builtin.path), destination, { recursive: true, force: true });
8518
8537
  return {
8519
8538
  message: `Installed skill: ${slug}`
@@ -8575,7 +8594,7 @@ ${stderr}`.trim();
8575
8594
  // src/cli/workspace.ts
8576
8595
  import { cpSync as cpSync3, existsSync as existsSync11, mkdirSync as mkdirSync6, readFileSync as readFileSync9, readdirSync as readdirSync3, rmSync as rmSync5, writeFileSync as writeFileSync5 } from "fs";
8577
8596
  import { createRequire as createRequire2 } from "module";
8578
- import { dirname as dirname3, join as join7, resolve as resolve11 } from "path";
8597
+ import { dirname as dirname3, join as join8, resolve as resolve11 } from "path";
8579
8598
  import { fileURLToPath as fileURLToPath4 } from "url";
8580
8599
  import { APP_NAME as APP_NAME4, getDataDir as getDataDir8 } from "@nextclaw/core";
8581
8600
  import { spawnSync as spawnSync3 } from "child_process";
@@ -8605,11 +8624,11 @@ var WorkspaceManager = class {
8605
8624
  { source: "memory/MEMORY.md", target: "memory/MEMORY.md" }
8606
8625
  ];
8607
8626
  for (const entry of templateFiles) {
8608
- const filePath = join7(workspace, entry.target);
8627
+ const filePath = join8(workspace, entry.target);
8609
8628
  if (!force && existsSync11(filePath)) {
8610
8629
  continue;
8611
8630
  }
8612
- const templatePath = join7(templateDir, entry.source);
8631
+ const templatePath = join8(templateDir, entry.source);
8613
8632
  if (!existsSync11(templatePath)) {
8614
8633
  console.warn(`Warning: Template file missing: ${templatePath}`);
8615
8634
  continue;
@@ -8620,15 +8639,15 @@ var WorkspaceManager = class {
8620
8639
  writeFileSync5(filePath, content);
8621
8640
  created.push(entry.target);
8622
8641
  }
8623
- const memoryDir = join7(workspace, "memory");
8642
+ const memoryDir = join8(workspace, "memory");
8624
8643
  if (!existsSync11(memoryDir)) {
8625
8644
  mkdirSync6(memoryDir, { recursive: true });
8626
- created.push(join7("memory", ""));
8645
+ created.push(join8("memory", ""));
8627
8646
  }
8628
- const skillsDir = join7(workspace, "skills");
8647
+ const skillsDir = join8(workspace, "skills");
8629
8648
  if (!existsSync11(skillsDir)) {
8630
8649
  mkdirSync6(skillsDir, { recursive: true });
8631
- created.push(join7("skills", ""));
8650
+ created.push(join8("skills", ""));
8632
8651
  }
8633
8652
  const seeded = this.seedBuiltinSkills(skillsDir, { force });
8634
8653
  if (seeded > 0) {
@@ -8647,11 +8666,11 @@ var WorkspaceManager = class {
8647
8666
  if (!entry.isDirectory()) {
8648
8667
  continue;
8649
8668
  }
8650
- const src = join7(sourceDir, entry.name);
8651
- if (!existsSync11(join7(src, "SKILL.md"))) {
8669
+ const src = join8(sourceDir, entry.name);
8670
+ if (!existsSync11(join8(src, "SKILL.md"))) {
8652
8671
  continue;
8653
8672
  }
8654
- const dest = join7(targetDir, entry.name);
8673
+ const dest = join8(targetDir, entry.name);
8655
8674
  if (!force && existsSync11(dest)) {
8656
8675
  continue;
8657
8676
  }
@@ -8670,11 +8689,11 @@ var WorkspaceManager = class {
8670
8689
  const require3 = createRequire2(import.meta.url);
8671
8690
  const entry = require3.resolve("@nextclaw/core");
8672
8691
  const pkgRoot = resolve11(dirname3(entry), "..");
8673
- const distSkills = join7(pkgRoot, "dist", "skills");
8692
+ const distSkills = join8(pkgRoot, "dist", "skills");
8674
8693
  if (existsSync11(distSkills)) {
8675
8694
  return distSkills;
8676
8695
  }
8677
- const srcSkills = join7(pkgRoot, "src", "agent", "skills");
8696
+ const srcSkills = join8(pkgRoot, "src", "agent", "skills");
8678
8697
  if (existsSync11(srcSkills)) {
8679
8698
  return srcSkills;
8680
8699
  }
@@ -8690,7 +8709,7 @@ var WorkspaceManager = class {
8690
8709
  }
8691
8710
  const cliDir = resolve11(fileURLToPath4(new URL(".", import.meta.url)));
8692
8711
  const pkgRoot = resolve11(cliDir, "..", "..");
8693
- const candidates = [join7(pkgRoot, "templates")];
8712
+ const candidates = [join8(pkgRoot, "templates")];
8694
8713
  for (const candidate of candidates) {
8695
8714
  if (existsSync11(candidate)) {
8696
8715
  return candidate;
@@ -8699,8 +8718,8 @@ var WorkspaceManager = class {
8699
8718
  return null;
8700
8719
  }
8701
8720
  getBridgeDir() {
8702
- const userBridge = join7(getDataDir8(), "bridge");
8703
- if (existsSync11(join7(userBridge, "dist", "index.js"))) {
8721
+ const userBridge = join8(getDataDir8(), "bridge");
8722
+ if (existsSync11(join8(userBridge, "dist", "index.js"))) {
8704
8723
  return userBridge;
8705
8724
  }
8706
8725
  if (!which("npm")) {
@@ -8709,12 +8728,12 @@ var WorkspaceManager = class {
8709
8728
  }
8710
8729
  const cliDir = resolve11(fileURLToPath4(new URL(".", import.meta.url)));
8711
8730
  const pkgRoot = resolve11(cliDir, "..", "..");
8712
- const pkgBridge = join7(pkgRoot, "bridge");
8713
- const srcBridge = join7(pkgRoot, "..", "..", "bridge");
8731
+ const pkgBridge = join8(pkgRoot, "bridge");
8732
+ const srcBridge = join8(pkgRoot, "..", "..", "bridge");
8714
8733
  let source = null;
8715
- if (existsSync11(join7(pkgBridge, "package.json"))) {
8734
+ if (existsSync11(join8(pkgBridge, "package.json"))) {
8716
8735
  source = pkgBridge;
8717
- } else if (existsSync11(join7(srcBridge, "package.json"))) {
8736
+ } else if (existsSync11(join8(srcBridge, "package.json"))) {
8718
8737
  source = srcBridge;
8719
8738
  }
8720
8739
  if (!source) {
@@ -9009,7 +9028,7 @@ var CliRuntime = class {
9009
9028
  }
9010
9029
  const config2 = loadConfig15();
9011
9030
  const workspaceSetting = config2.agents.defaults.workspace;
9012
- const workspacePath = !workspaceSetting || workspaceSetting === DEFAULT_WORKSPACE_PATH ? join8(getDataDir9(), DEFAULT_WORKSPACE_DIR) : expandHome2(workspaceSetting);
9031
+ const workspacePath = !workspaceSetting || workspaceSetting === DEFAULT_WORKSPACE_PATH ? join9(getDataDir9(), DEFAULT_WORKSPACE_DIR) : expandHome2(workspaceSetting);
9013
9032
  const workspaceExisted = existsSync12(workspacePath);
9014
9033
  mkdirSync7(workspacePath, { recursive: true });
9015
9034
  const templateResult = this.workspaceManager.createWorkspaceTemplates(
@@ -9202,7 +9221,7 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
9202
9221
  `${this.logo} Interactive mode (type exit or Ctrl+C to quit)
9203
9222
  `
9204
9223
  );
9205
- const historyFile = join8(getDataDir9(), "history", "cli_history");
9224
+ const historyFile = join9(getDataDir9(), "history", "cli_history");
9206
9225
  const historyDir = resolve12(historyFile, "..");
9207
9226
  mkdirSync7(historyDir, { recursive: true });
9208
9227
  const history = existsSync12(historyFile) ? readFileSync10(historyFile, "utf-8").split("\n").filter(Boolean) : [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nextclaw",
3
- "version": "0.13.10",
3
+ "version": "0.13.11",
4
4
  "description": "Lightweight personal AI assistant with CLI, multi-provider routing, and channel integrations.",
5
5
  "private": false,
6
6
  "type": "module",
@@ -35,20 +35,30 @@
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
+ },
38
48
  "dependencies": {
39
49
  "chokidar": "^3.6.0",
40
50
  "commander": "^12.1.0",
41
51
  "yaml": "^2.8.1",
42
- "@nextclaw/core": "0.9.5",
43
- "@nextclaw/mcp": "0.1.10",
44
- "@nextclaw/ncp": "0.3.1",
45
- "@nextclaw/ncp-mcp": "0.1.10",
46
- "@nextclaw/ncp-agent-runtime": "0.2.1",
47
- "@nextclaw/ncp-toolkit": "0.4.1",
48
- "@nextclaw/remote": "0.1.6",
49
- "@nextclaw/runtime": "0.2.5",
50
- "@nextclaw/openclaw-compat": "0.3.8",
51
- "@nextclaw/server": "0.10.10"
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:*"
52
62
  },
53
63
  "devDependencies": {
54
64
  "@types/node": "^20.17.6",
@@ -57,14 +67,5 @@
57
67
  "tsx": "^4.19.2",
58
68
  "typescript": "^5.6.3",
59
69
  "vitest": "^2.1.2"
60
- },
61
- "scripts": {
62
- "dev": "tsx watch --tsconfig tsconfig.json src/cli/index.ts",
63
- "dev:build": "tsx src/cli/index.ts",
64
- "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",
65
- "start": "node dist/cli.js",
66
- "lint": "eslint .",
67
- "tsc": "tsc -p tsconfig.json",
68
- "test": "vitest"
69
70
  }
70
- }
71
+ }
@@ -0,0 +1 @@
1
+ import{r as v,j as a,ax as Z,J as ee,e as F,K as ae,af as te,aS as se,aT as ne,aU as le,D as re,s as oe,a7 as ce,v as ie}from"./vendor-CwsIoNvJ.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-CeRbsQ90.js";import{L as he}from"./label-CCSffS1D.js";import{S as fe}from"./switch-B-_SrMSL.js";import{S as J}from"./status-dot-Fz9-eKsl.js";import{L as K}from"./LogoBadge-D7j1al-w.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-6Tm1ZHfS.js";import{P as Ce,a as Ne}from"./page-layout-ud8wZ8gX.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 Te(t,m){const i=m.toLowerCase(),r=t[i];return r?`/logos/${r}`:null}function Y(t){return Te(Ie,t)}const B=[{value:"pairing",label:"pairing"},{value:"allowlist",label:"allowlist"},{value:"open",label:"open"},{value:"disabled",label:"disabled"}],R=[{value:"open",label:"open"},{value:"allowlist",label:"allowlist"},{value:"disabled",label:"disabled"}],Fe=[{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 G(){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:R},{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:Fe},{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:R},{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?G()[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),T=P?z(P):void 0;v.useEffect(()=>{if(k){g({...k});const s={};(t?G()[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{F.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?F.success(l.message||e("success")):F.error(l.message||e("error"))}catch(n){const l=n instanceof Error?n.message:String(n);F.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(K,{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")}),T&&a.jsxs("a",{href:T,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(J,{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 Je(){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),T=(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(K,{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:T})]})]}),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(J,{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{Je as ChannelsList};