nextclaw 0.9.9 → 0.9.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +181 -19
- package/package.json +2 -2
- package/templates/USAGE.md +9 -0
- package/ui-dist/assets/ChannelsList-Dz8AGmaQ.js +1 -0
- package/ui-dist/assets/{ChatPage-Def8_fbf.js → ChatPage-BXDyt7BL.js} +21 -21
- package/ui-dist/assets/DocBrowser-CkKvzF7m.js +1 -0
- package/ui-dist/assets/{LogoBadge-uiBOKAEe.js → LogoBadge-C_ygxoGB.js} +1 -1
- package/ui-dist/assets/{MarketplacePage-BwMsA6VY.js → MarketplacePage-DEvRs-Jc.js} +2 -2
- package/ui-dist/assets/ModelConfig-BGfliN2Z.js +1 -0
- package/ui-dist/assets/ProvidersList-BHLGLSvs.js +1 -0
- package/ui-dist/assets/RuntimeConfig-Clltld_h.js +1 -0
- package/ui-dist/assets/{SecretsConfig-BLZW7-5k.js → SecretsConfig-CaJLf7oJ.js} +2 -2
- package/ui-dist/assets/SessionsConfig-3QF7K9wm.js +2 -0
- package/ui-dist/assets/{card-BoxPL3fs.js → card-DXo3NsaB.js} +1 -1
- package/ui-dist/assets/index-CGo5Vnh0.js +7 -0
- package/ui-dist/assets/input-CzTldMKo.js +1 -0
- package/ui-dist/assets/{label-BdIFsV9G.js → label-De__vsU7.js} +1 -1
- package/ui-dist/assets/{page-layout-BdhEwv_X.js → page-layout-BOgLC2tK.js} +1 -1
- package/ui-dist/assets/{session-run-status-DJ7s-TnE.js → session-run-status-DQVCDxTb.js} +2 -2
- package/ui-dist/assets/{switch-DD9iXp2E.js → switch-pMrS4heA.js} +1 -1
- package/ui-dist/assets/{tabs-custom-DPMQcAvE.js → tabs-custom-DhOxWfCb.js} +1 -1
- package/ui-dist/assets/{useConfirmDialog-D0WoeDcH.js → useConfirmDialog-CseKBGh5.js} +2 -2
- package/ui-dist/assets/{vendor-CzIVZvq9.js → vendor-D33xZtEC.js} +6 -6
- package/ui-dist/index.html +2 -2
- package/ui-dist/assets/ChannelsList-CrQ3OXby.js +0 -1
- package/ui-dist/assets/DocBrowser-Dg-b4Atq.js +0 -1
- package/ui-dist/assets/ModelConfig-DVsQVvIt.js +0 -1
- package/ui-dist/assets/ProvidersList-BSJGEhJe.js +0 -1
- package/ui-dist/assets/RuntimeConfig-CZpxTqCn.js +0 -1
- package/ui-dist/assets/SessionsConfig-H_gq5Wtk.js +0 -2
- package/ui-dist/assets/index-Cwtv_w6q.js +0 -2
- package/ui-dist/assets/useConfig-BiE7PGOv.js +0 -6
package/dist/cli/index.js
CHANGED
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
resolvePluginChannelMessageToolHints as resolvePluginChannelMessageToolHints2,
|
|
27
27
|
setPluginRuntimeBridge as setPluginRuntimeBridge2
|
|
28
28
|
} from "@nextclaw/openclaw-compat";
|
|
29
|
-
import { existsSync as existsSync10, mkdirSync as mkdirSync6, readFileSync as readFileSync8, writeFileSync as
|
|
29
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync6, readFileSync as readFileSync8, writeFileSync as writeFileSync6 } from "fs";
|
|
30
30
|
import { join as join7, resolve as resolve9 } from "path";
|
|
31
31
|
import { createInterface as createInterface2 } from "readline";
|
|
32
32
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
@@ -1831,8 +1831,8 @@ import { join as join3 } from "path";
|
|
|
1831
1831
|
var CronCommands = class {
|
|
1832
1832
|
cronList(opts) {
|
|
1833
1833
|
const storePath = join3(getDataDir3(), "cron", "jobs.json");
|
|
1834
|
-
const
|
|
1835
|
-
const jobs =
|
|
1834
|
+
const service2 = new CronService(storePath);
|
|
1835
|
+
const jobs = service2.listJobs(Boolean(opts.all));
|
|
1836
1836
|
if (!jobs.length) {
|
|
1837
1837
|
console.log("No scheduled jobs.");
|
|
1838
1838
|
return;
|
|
@@ -1851,7 +1851,7 @@ var CronCommands = class {
|
|
|
1851
1851
|
}
|
|
1852
1852
|
cronAdd(opts) {
|
|
1853
1853
|
const storePath = join3(getDataDir3(), "cron", "jobs.json");
|
|
1854
|
-
const
|
|
1854
|
+
const service2 = new CronService(storePath);
|
|
1855
1855
|
let schedule = null;
|
|
1856
1856
|
if (opts.every) {
|
|
1857
1857
|
schedule = { kind: "every", everyMs: Number(opts.every) * 1e3 };
|
|
@@ -1864,7 +1864,7 @@ var CronCommands = class {
|
|
|
1864
1864
|
console.error("Error: Must specify --every, --cron, or --at");
|
|
1865
1865
|
return;
|
|
1866
1866
|
}
|
|
1867
|
-
const job =
|
|
1867
|
+
const job = service2.addJob({
|
|
1868
1868
|
name: opts.name,
|
|
1869
1869
|
schedule,
|
|
1870
1870
|
message: opts.message,
|
|
@@ -1876,8 +1876,8 @@ var CronCommands = class {
|
|
|
1876
1876
|
}
|
|
1877
1877
|
cronRemove(jobId) {
|
|
1878
1878
|
const storePath = join3(getDataDir3(), "cron", "jobs.json");
|
|
1879
|
-
const
|
|
1880
|
-
if (
|
|
1879
|
+
const service2 = new CronService(storePath);
|
|
1880
|
+
if (service2.removeJob(jobId)) {
|
|
1881
1881
|
console.log(`\u2713 Removed job ${jobId}`);
|
|
1882
1882
|
} else {
|
|
1883
1883
|
console.log(`Job ${jobId} not found`);
|
|
@@ -1885,8 +1885,8 @@ var CronCommands = class {
|
|
|
1885
1885
|
}
|
|
1886
1886
|
cronEnable(jobId, opts) {
|
|
1887
1887
|
const storePath = join3(getDataDir3(), "cron", "jobs.json");
|
|
1888
|
-
const
|
|
1889
|
-
const job =
|
|
1888
|
+
const service2 = new CronService(storePath);
|
|
1889
|
+
const job = service2.enableJob(jobId, !opts.disable);
|
|
1890
1890
|
if (job) {
|
|
1891
1891
|
console.log(`\u2713 Job '${job.name}' ${opts.disable ? "disabled" : "enabled"}`);
|
|
1892
1892
|
} else {
|
|
@@ -1895,8 +1895,8 @@ var CronCommands = class {
|
|
|
1895
1895
|
}
|
|
1896
1896
|
async cronRun(jobId, opts) {
|
|
1897
1897
|
const storePath = join3(getDataDir3(), "cron", "jobs.json");
|
|
1898
|
-
const
|
|
1899
|
-
const ok = await
|
|
1898
|
+
const service2 = new CronService(storePath);
|
|
1899
|
+
const ok = await service2.runJob(jobId, Boolean(opts.force));
|
|
1900
1900
|
console.log(ok ? "\u2713 Job executed" : `Failed to run job ${jobId}`);
|
|
1901
1901
|
}
|
|
1902
1902
|
};
|
|
@@ -2252,11 +2252,12 @@ import {
|
|
|
2252
2252
|
stopPluginChannelGateways
|
|
2253
2253
|
} from "@nextclaw/openclaw-compat";
|
|
2254
2254
|
import { startUiServer } from "@nextclaw/server";
|
|
2255
|
-
import { appendFileSync, closeSync, cpSync, existsSync as existsSync8, mkdirSync as mkdirSync4, openSync, rmSync as rmSync3 } from "fs";
|
|
2255
|
+
import { appendFileSync, closeSync, cpSync, existsSync as existsSync8, mkdirSync as mkdirSync4, openSync, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "fs";
|
|
2256
2256
|
import { dirname, isAbsolute as isAbsolute2, join as join5, relative, resolve as resolve7 } from "path";
|
|
2257
|
-
import { spawn as spawn2 } from "child_process";
|
|
2257
|
+
import { spawn as spawn2, spawnSync as spawnSync4 } from "child_process";
|
|
2258
2258
|
import { request as httpRequest } from "http";
|
|
2259
2259
|
import { request as httpsRequest } from "https";
|
|
2260
|
+
import { homedir, userInfo } from "os";
|
|
2260
2261
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2261
2262
|
import chokidar from "chokidar";
|
|
2262
2263
|
|
|
@@ -4034,6 +4035,85 @@ var ServiceCommands = class {
|
|
|
4034
4035
|
clearServiceState();
|
|
4035
4036
|
console.log(`\u2713 ${APP_NAME2} stopped`);
|
|
4036
4037
|
}
|
|
4038
|
+
async installSystemdService(options) {
|
|
4039
|
+
if (process.platform !== "linux") {
|
|
4040
|
+
console.error("Error: systemd installation is only supported on Linux.");
|
|
4041
|
+
return;
|
|
4042
|
+
}
|
|
4043
|
+
if (typeof process.getuid === "function" && process.getuid() !== 0) {
|
|
4044
|
+
console.error("Error: Run this command as root (for example: sudo nextclaw service install-systemd).");
|
|
4045
|
+
return;
|
|
4046
|
+
}
|
|
4047
|
+
const serviceName = this.resolveSystemdServiceName(options.name);
|
|
4048
|
+
const config2 = loadConfig6();
|
|
4049
|
+
const uiConfig = resolveUiConfig(config2, { enabled: true, host: "0.0.0.0" });
|
|
4050
|
+
const uiPort = this.parseSystemdUiPort(options.uiPort, uiConfig.port);
|
|
4051
|
+
if (uiPort === null) {
|
|
4052
|
+
console.error("Error: Invalid --ui-port. Provide a positive integer.");
|
|
4053
|
+
return;
|
|
4054
|
+
}
|
|
4055
|
+
const systemctlAvailable = this.runSystemCommand("systemctl", ["--version"]);
|
|
4056
|
+
if (!systemctlAvailable.ok) {
|
|
4057
|
+
console.error("Error: systemctl is not available on this machine.");
|
|
4058
|
+
return;
|
|
4059
|
+
}
|
|
4060
|
+
const runUser = this.resolveSystemdRunUser();
|
|
4061
|
+
const runHome = this.resolveSystemdRunHome(runUser);
|
|
4062
|
+
const servicePath = `/etc/systemd/system/${serviceName}.service`;
|
|
4063
|
+
const cliPath = fileURLToPath2(new URL("../index.js", import.meta.url));
|
|
4064
|
+
const execArgs = [process.execPath, ...process.execArgv, cliPath, "serve", "--ui-port", String(uiPort)];
|
|
4065
|
+
const unit = this.buildSystemdUnit({
|
|
4066
|
+
runUser,
|
|
4067
|
+
runHome,
|
|
4068
|
+
execArgs
|
|
4069
|
+
});
|
|
4070
|
+
writeFileSync4(servicePath, unit, "utf-8");
|
|
4071
|
+
const daemonReload = this.runSystemCommand("systemctl", ["daemon-reload"]);
|
|
4072
|
+
if (!daemonReload.ok) {
|
|
4073
|
+
console.error(`Error: Failed to reload systemd. ${daemonReload.stderr}`.trim());
|
|
4074
|
+
return;
|
|
4075
|
+
}
|
|
4076
|
+
const enableStart = this.runSystemCommand("systemctl", ["enable", "--now", `${serviceName}.service`]);
|
|
4077
|
+
if (!enableStart.ok) {
|
|
4078
|
+
console.error(`Error: Failed to enable/start ${serviceName}.service. ${enableStart.stderr}`.trim());
|
|
4079
|
+
return;
|
|
4080
|
+
}
|
|
4081
|
+
const active = this.runSystemCommand("systemctl", ["is-active", `${serviceName}.service`]);
|
|
4082
|
+
if (!active.ok || active.stdout.trim() !== "active") {
|
|
4083
|
+
console.error(`Error: ${serviceName}.service is not active. ${active.stderr || active.stdout}`.trim());
|
|
4084
|
+
return;
|
|
4085
|
+
}
|
|
4086
|
+
console.log(`\u2713 Installed systemd service: ${serviceName}.service`);
|
|
4087
|
+
console.log(`Run user: ${runUser}`);
|
|
4088
|
+
console.log(`UI port: ${uiPort}`);
|
|
4089
|
+
console.log(`Unit file: ${servicePath}`);
|
|
4090
|
+
console.log(`Health: http://127.0.0.1:${uiPort}/api/health`);
|
|
4091
|
+
console.log(`Logs: journalctl -u ${serviceName}.service -f`);
|
|
4092
|
+
}
|
|
4093
|
+
async uninstallSystemdService(options) {
|
|
4094
|
+
if (process.platform !== "linux") {
|
|
4095
|
+
console.error("Error: systemd removal is only supported on Linux.");
|
|
4096
|
+
return;
|
|
4097
|
+
}
|
|
4098
|
+
if (typeof process.getuid === "function" && process.getuid() !== 0) {
|
|
4099
|
+
console.error("Error: Run this command as root.");
|
|
4100
|
+
return;
|
|
4101
|
+
}
|
|
4102
|
+
const serviceName = this.resolveSystemdServiceName(options.name);
|
|
4103
|
+
const servicePath = `/etc/systemd/system/${serviceName}.service`;
|
|
4104
|
+
if (!existsSync8(servicePath)) {
|
|
4105
|
+
console.error(`Error: ${servicePath} does not exist.`);
|
|
4106
|
+
return;
|
|
4107
|
+
}
|
|
4108
|
+
this.runSystemCommand("systemctl", ["disable", "--now", `${serviceName}.service`]);
|
|
4109
|
+
rmSync3(servicePath, { force: true });
|
|
4110
|
+
const daemonReload = this.runSystemCommand("systemctl", ["daemon-reload"]);
|
|
4111
|
+
if (!daemonReload.ok) {
|
|
4112
|
+
console.error(`Warning: Removed unit file but failed to reload systemd. ${daemonReload.stderr}`.trim());
|
|
4113
|
+
return;
|
|
4114
|
+
}
|
|
4115
|
+
console.log(`\u2713 Removed systemd service: ${serviceName}.service`);
|
|
4116
|
+
}
|
|
4037
4117
|
async waitForBackgroundServiceReady(params) {
|
|
4038
4118
|
const startedAt = Date.now();
|
|
4039
4119
|
let lastProbeError = null;
|
|
@@ -4064,6 +4144,78 @@ var ServiceCommands = class {
|
|
|
4064
4144
|
const resolved = fromOverride ?? fromEnv ?? fallback;
|
|
4065
4145
|
return Math.max(3e3, resolved);
|
|
4066
4146
|
}
|
|
4147
|
+
resolveSystemdServiceName(rawName) {
|
|
4148
|
+
const trimmed = rawName?.trim() || APP_NAME2;
|
|
4149
|
+
return trimmed.endsWith(".service") ? trimmed.slice(0, -".service".length) : trimmed;
|
|
4150
|
+
}
|
|
4151
|
+
parseSystemdUiPort(rawPort, fallbackPort) {
|
|
4152
|
+
if (rawPort === void 0 || rawPort === null || rawPort === "") {
|
|
4153
|
+
return fallbackPort;
|
|
4154
|
+
}
|
|
4155
|
+
const parsed = Number(rawPort);
|
|
4156
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
4157
|
+
return null;
|
|
4158
|
+
}
|
|
4159
|
+
return parsed;
|
|
4160
|
+
}
|
|
4161
|
+
resolveSystemdRunUser() {
|
|
4162
|
+
const sudoUser = process.env.SUDO_USER?.trim();
|
|
4163
|
+
if (sudoUser && sudoUser !== "root") {
|
|
4164
|
+
return sudoUser;
|
|
4165
|
+
}
|
|
4166
|
+
return userInfo().username;
|
|
4167
|
+
}
|
|
4168
|
+
resolveSystemdRunHome(runUser) {
|
|
4169
|
+
const passwd = this.runSystemCommand("getent", ["passwd", runUser]);
|
|
4170
|
+
if (passwd.ok) {
|
|
4171
|
+
const fields = passwd.stdout.trim().split(":");
|
|
4172
|
+
if (fields.length >= 6 && fields[5]) {
|
|
4173
|
+
return fields[5];
|
|
4174
|
+
}
|
|
4175
|
+
}
|
|
4176
|
+
return process.env.HOME?.trim() || homedir();
|
|
4177
|
+
}
|
|
4178
|
+
buildSystemdUnit(params) {
|
|
4179
|
+
const execStart = params.execArgs.map((arg) => this.escapeSystemdArg(arg)).join(" ");
|
|
4180
|
+
return [
|
|
4181
|
+
"[Unit]",
|
|
4182
|
+
`Description=${APP_NAME2} gateway + UI`,
|
|
4183
|
+
"After=network-online.target",
|
|
4184
|
+
"Wants=network-online.target",
|
|
4185
|
+
"",
|
|
4186
|
+
"[Service]",
|
|
4187
|
+
"Type=simple",
|
|
4188
|
+
`User=${params.runUser}`,
|
|
4189
|
+
`WorkingDirectory=${params.runHome}`,
|
|
4190
|
+
`Environment=HOME=${params.runHome}`,
|
|
4191
|
+
"Environment=NODE_ENV=production",
|
|
4192
|
+
`ExecStart=${execStart}`,
|
|
4193
|
+
"Restart=always",
|
|
4194
|
+
"RestartSec=3",
|
|
4195
|
+
"TimeoutStopSec=20",
|
|
4196
|
+
"",
|
|
4197
|
+
"[Install]",
|
|
4198
|
+
"WantedBy=multi-user.target",
|
|
4199
|
+
""
|
|
4200
|
+
].join("\n");
|
|
4201
|
+
}
|
|
4202
|
+
escapeSystemdArg(value) {
|
|
4203
|
+
if (/^[A-Za-z0-9_./:@%+=,-]+$/.test(value)) {
|
|
4204
|
+
return value;
|
|
4205
|
+
}
|
|
4206
|
+
return `"${value.replaceAll("\\", "\\\\").replaceAll('"', '\\"')}"`;
|
|
4207
|
+
}
|
|
4208
|
+
runSystemCommand(command, args) {
|
|
4209
|
+
const result = spawnSync4(command, args, {
|
|
4210
|
+
encoding: "utf-8",
|
|
4211
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
4212
|
+
});
|
|
4213
|
+
return {
|
|
4214
|
+
ok: result.status === 0,
|
|
4215
|
+
stdout: result.stdout ?? "",
|
|
4216
|
+
stderr: result.stderr ?? ""
|
|
4217
|
+
};
|
|
4218
|
+
}
|
|
4067
4219
|
appendStartupStage(logPath, message) {
|
|
4068
4220
|
try {
|
|
4069
4221
|
appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] [startup] ${message}
|
|
@@ -4226,6 +4378,7 @@ var ServiceCommands = class {
|
|
|
4226
4378
|
host: uiConfig.host,
|
|
4227
4379
|
port: uiConfig.port,
|
|
4228
4380
|
configPath: getConfigPath3(),
|
|
4381
|
+
productVersion: getPackageVersion(),
|
|
4229
4382
|
staticDir: uiStaticDir ?? void 0,
|
|
4230
4383
|
cronService,
|
|
4231
4384
|
marketplace: {
|
|
@@ -4610,12 +4763,12 @@ ${stderr}`.trim();
|
|
|
4610
4763
|
};
|
|
4611
4764
|
|
|
4612
4765
|
// src/cli/workspace.ts
|
|
4613
|
-
import { cpSync as cpSync2, existsSync as existsSync9, mkdirSync as mkdirSync5, readFileSync as readFileSync7, readdirSync as readdirSync2, rmSync as rmSync4, writeFileSync as
|
|
4766
|
+
import { cpSync as cpSync2, existsSync as existsSync9, mkdirSync as mkdirSync5, readFileSync as readFileSync7, readdirSync as readdirSync2, rmSync as rmSync4, writeFileSync as writeFileSync5 } from "fs";
|
|
4614
4767
|
import { createRequire } from "module";
|
|
4615
4768
|
import { dirname as dirname2, join as join6, resolve as resolve8 } from "path";
|
|
4616
4769
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
4617
4770
|
import { APP_NAME as APP_NAME3, getDataDir as getDataDir7 } from "@nextclaw/core";
|
|
4618
|
-
import { spawnSync as
|
|
4771
|
+
import { spawnSync as spawnSync5 } from "child_process";
|
|
4619
4772
|
var WorkspaceManager = class {
|
|
4620
4773
|
constructor(logo) {
|
|
4621
4774
|
this.logo = logo;
|
|
@@ -4654,7 +4807,7 @@ var WorkspaceManager = class {
|
|
|
4654
4807
|
const raw = readFileSync7(templatePath, "utf-8");
|
|
4655
4808
|
const content = raw.replace(/\$\{APP_NAME\}/g, APP_NAME3);
|
|
4656
4809
|
mkdirSync5(dirname2(filePath), { recursive: true });
|
|
4657
|
-
|
|
4810
|
+
writeFileSync5(filePath, content);
|
|
4658
4811
|
created.push(entry.target);
|
|
4659
4812
|
}
|
|
4660
4813
|
const memoryDir = join6(workspace, "memory");
|
|
@@ -4762,7 +4915,7 @@ var WorkspaceManager = class {
|
|
|
4762
4915
|
recursive: true,
|
|
4763
4916
|
filter: (src) => !src.includes("node_modules") && !src.includes("dist")
|
|
4764
4917
|
});
|
|
4765
|
-
const install =
|
|
4918
|
+
const install = spawnSync5("npm", ["install"], { cwd: userBridge, stdio: "pipe" });
|
|
4766
4919
|
if (install.status !== 0) {
|
|
4767
4920
|
console.error(`Bridge install failed: ${install.status ?? 1}`);
|
|
4768
4921
|
if (install.stderr) {
|
|
@@ -4770,7 +4923,7 @@ var WorkspaceManager = class {
|
|
|
4770
4923
|
}
|
|
4771
4924
|
process.exit(1);
|
|
4772
4925
|
}
|
|
4773
|
-
const build =
|
|
4926
|
+
const build = spawnSync5("npm", ["run", "build"], { cwd: userBridge, stdio: "pipe" });
|
|
4774
4927
|
if (build.status !== 0) {
|
|
4775
4928
|
console.error(`Bridge build failed: ${build.status ?? 1}`);
|
|
4776
4929
|
if (build.stderr) {
|
|
@@ -5140,6 +5293,12 @@ ${this.logo} ${APP_NAME4} is ready! (${source})`);
|
|
|
5140
5293
|
async stop() {
|
|
5141
5294
|
await this.serviceCommands.stopService();
|
|
5142
5295
|
}
|
|
5296
|
+
async serviceInstallSystemd(opts) {
|
|
5297
|
+
await this.serviceCommands.installSystemdService(opts);
|
|
5298
|
+
}
|
|
5299
|
+
async serviceUninstallSystemd(opts) {
|
|
5300
|
+
await this.serviceCommands.uninstallSystemdService(opts);
|
|
5301
|
+
}
|
|
5143
5302
|
async agent(opts) {
|
|
5144
5303
|
const configPath = getConfigPath4();
|
|
5145
5304
|
const config2 = resolveConfigSecrets3(loadConfig7(), { configPath });
|
|
@@ -5222,7 +5381,7 @@ ${this.logo} ${APP_NAME4} is ready! (${source})`);
|
|
|
5222
5381
|
const merged = history.concat(
|
|
5223
5382
|
rl.history ?? []
|
|
5224
5383
|
);
|
|
5225
|
-
|
|
5384
|
+
writeFileSync6(historyFile, merged.join("\n"));
|
|
5226
5385
|
process.exit(0);
|
|
5227
5386
|
});
|
|
5228
5387
|
let running = true;
|
|
@@ -5402,6 +5561,9 @@ program.command("start").description(`Start the ${APP_NAME5} gateway + UI in the
|
|
|
5402
5561
|
program.command("restart").description(`Restart the ${APP_NAME5} background service`).option("--ui-port <port>", "UI port").option("--start-timeout <ms>", "Maximum wait time for startup readiness in milliseconds").option("--open", "Open browser after restart", false).action(async (opts) => runtime.restart(opts));
|
|
5403
5562
|
program.command("serve").description(`Run the ${APP_NAME5} gateway + UI in the foreground`).option("--ui-port <port>", "UI port").option("--open", "Open browser after start", false).action(async (opts) => runtime.serve(opts));
|
|
5404
5563
|
program.command("stop").description(`Stop the ${APP_NAME5} background service`).action(async () => runtime.stop());
|
|
5564
|
+
var service = program.command("service").description("Manage OS service integration");
|
|
5565
|
+
service.command("install-systemd").description(`Install a systemd unit for ${APP_NAME5} on Linux servers`).option("--name <name>", "Systemd unit name", APP_NAME5).option("--ui-port <port>", "UI port").action(async (opts) => runtime.serviceInstallSystemd(opts));
|
|
5566
|
+
service.command("uninstall-systemd").description(`Remove the systemd unit for ${APP_NAME5}`).option("--name <name>", "Systemd unit name", APP_NAME5).action(async (opts) => runtime.serviceUninstallSystemd(opts));
|
|
5405
5567
|
program.command("agent").description("Interact with the agent directly").option("-m, --message <message>", "Message to send to the agent").option("-s, --session <session>", "Session ID", "cli:default").option("--model <model>", "Session model override for this run").option("--no-markdown", "Disable Markdown rendering").action(async (opts) => runtime.agent(opts));
|
|
5406
5568
|
program.command("update").description(`Update ${APP_NAME5}`).option("--timeout <ms>", "Update command timeout in milliseconds").action(async (opts) => runtime.update(opts));
|
|
5407
5569
|
var registerClawHubInstall = (cmd) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nextclaw",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.10",
|
|
4
4
|
"description": "Lightweight personal AI assistant with CLI, multi-provider routing, and channel integrations.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"commander": "^12.1.0",
|
|
41
41
|
"@nextclaw/core": "^0.7.1",
|
|
42
42
|
"@nextclaw/runtime": "^0.1.1",
|
|
43
|
-
"@nextclaw/server": "^0.6.
|
|
43
|
+
"@nextclaw/server": "^0.6.4",
|
|
44
44
|
"@nextclaw/openclaw-compat": "^0.2.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
package/templates/USAGE.md
CHANGED
|
@@ -418,6 +418,8 @@ Created under the workspace:
|
|
|
418
418
|
| `nextclaw start` | Start gateway + UI in the background |
|
|
419
419
|
| `nextclaw restart` | Restart the background service with optional start flags |
|
|
420
420
|
| `nextclaw stop` | Stop the background service |
|
|
421
|
+
| `sudo nextclaw service install-systemd` | Install a managed Linux `systemd` service for public/server deployment |
|
|
422
|
+
| `sudo nextclaw service uninstall-systemd` | Remove the managed Linux `systemd` service |
|
|
421
423
|
| `nextclaw ui` | Start UI and gateway in the foreground |
|
|
422
424
|
| `nextclaw gateway` | Start gateway only (for channels) |
|
|
423
425
|
| `nextclaw serve` | Run gateway + UI in the foreground (no background) |
|
|
@@ -458,6 +460,13 @@ Gateway options (when running `nextclaw gateway` or `nextclaw start`):
|
|
|
458
460
|
|
|
459
461
|
If service is already running, new UI port flags do not hot-apply; use `nextclaw restart ...` to apply them.
|
|
460
462
|
|
|
463
|
+
Linux server deployment tip:
|
|
464
|
+
|
|
465
|
+
- If you put Nginx/Caddy/Traefik in front of NextClaw, do not rely on a one-time `nextclaw start` only.
|
|
466
|
+
- `nextclaw start` is a background convenience command, not a crash/reboot supervisor.
|
|
467
|
+
- On Linux servers, install a managed unit with `sudo nextclaw service install-systemd` so the UI/API comes back automatically after reboot or unexpected exit.
|
|
468
|
+
- Verify with `systemctl status nextclaw`, `journalctl -u nextclaw -f`, and `curl http://127.0.0.1:18791/api/health`.
|
|
469
|
+
|
|
461
470
|
Status/diagnostics tips:
|
|
462
471
|
|
|
463
472
|
- `nextclaw status` shows runtime truth (process + health + config summary).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as v,j as a,ax as Z,z as ee,d as T,K as ae,a9 as te,aL as se,aM as ne,aN as le,w as re,a1 as oe,aw as ce,q as ie}from"./vendor-D33xZtEC.js";import{t as e,c as I,H as me,u as q,a as $,b as H,J as pe,K as de,S as be,e as ue,f as xe,g as ye,h as ge}from"./index-CGo5Vnh0.js";import{B as E,P as he,a as fe}from"./page-layout-BOgLC2tK.js";import{I as D}from"./input-CzTldMKo.js";import{L as we}from"./label-De__vsU7.js";import{S as ve}from"./switch-pMrS4heA.js";import{C as je,a as ke,L as K,S as J,c as Se,b as Ce}from"./LogoBadge-C_ygxoGB.js";import{h as _}from"./config-hints-CApS3K_7.js";import{T as Ne}from"./tabs-custom-DhOxWfCb.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"}],R=[{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 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: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: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),F=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{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:je,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:ke,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")}),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(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(we,{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(ve,{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 He(){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(he,{className:"xl:flex xl:h-full xl:min-h-0 xl:flex-col xl:pb-0",children:[a.jsx(fe,{title:e("channelsPageTitle"),description:e("channelsPageDescription")}),a.jsxs("div",{className:I(Ce,"xl:min-h-0 xl:flex-1"),children:[a.jsxs("section",{className:Se,children:[a.jsx("div",{className:"border-b border-gray-100 px-4 pt-4",children:a.jsx(Ne,{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(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: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(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{He as ChannelsList};
|