nextclaw 0.13.13 → 0.13.15
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 +55 -79
- package/package.json +8 -8
- package/ui-dist/assets/ChannelsList-Byfj2R01.js +1 -0
- package/ui-dist/assets/ChatPage-DM1ewbWf.js +38 -0
- package/ui-dist/assets/DocBrowser-BLv77lJ0.js +1 -0
- package/ui-dist/assets/LogoBadge-D7j1al-w.js +1 -0
- package/ui-dist/assets/MarketplacePage-DuskLKYh.js +49 -0
- package/ui-dist/assets/McpMarketplacePage-DpMjaD3m.js +40 -0
- package/ui-dist/assets/ModelConfig-ubaecweS.js +1 -0
- package/ui-dist/assets/ProvidersList-w8MJH2LI.js +1 -0
- package/ui-dist/assets/RemoteAccessPage-D79_5Kbn.js +1 -0
- package/ui-dist/assets/RuntimeConfig-BbX4yFKy.js +1 -0
- package/ui-dist/assets/SearchConfig-BmmmeyJd.js +1 -0
- package/ui-dist/assets/SecretsConfig-CWG8J01H.js +3 -0
- package/ui-dist/assets/SessionsConfig-D-vg_Lgv.js +2 -0
- package/ui-dist/assets/chat-message-CGXiVhyN.js +3 -0
- package/ui-dist/assets/config-hints-CApS3K_7.js +1 -0
- package/ui-dist/assets/config-layout-BHnOoweL.js +1 -0
- package/ui-dist/assets/index-COrhpAdh.css +1 -0
- package/ui-dist/assets/index-CeRbsQ90.js +8 -0
- package/ui-dist/assets/index-Ct7FQpxN.js +1 -0
- package/ui-dist/assets/label-CCSffS1D.js +1 -0
- package/ui-dist/assets/marketplace-localization-Dk31LJJJ.js +1 -0
- package/ui-dist/assets/page-layout-ud8wZ8gX.js +1 -0
- package/ui-dist/assets/popover-Bfoe6YBX.js +1 -0
- package/ui-dist/assets/provider-models-D3B_xWXx.js +1 -0
- package/ui-dist/assets/security-config-DJJUCMov.js +1 -0
- package/ui-dist/assets/skeleton-IOOTmHzP.js +1 -0
- package/ui-dist/assets/status-dot-Fz9-eKsl.js +1 -0
- package/ui-dist/assets/switch-B-_SrMSL.js +1 -0
- package/ui-dist/assets/tabs-custom-6Tm1ZHfS.js +1 -0
- package/ui-dist/assets/useConfirmDialog-BeOW2bOI.js +5 -0
- package/ui-dist/assets/vendor-CwsIoNvJ.js +442 -0
- package/ui-dist/index.html +18 -0
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
|
|
32
|
+
import { join as join8, 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";
|
|
@@ -864,29 +864,14 @@ async function waitForExit(pid, timeoutMs) {
|
|
|
864
864
|
return !isProcessRunning(pid);
|
|
865
865
|
}
|
|
866
866
|
function resolveUiStaticDir() {
|
|
867
|
-
const candidates = [];
|
|
868
867
|
const envDir = process.env.NEXTCLAW_UI_STATIC_DIR;
|
|
869
868
|
if (envDir) {
|
|
870
|
-
|
|
869
|
+
return existsSync4(join2(envDir, "index.html")) ? envDir : null;
|
|
871
870
|
}
|
|
872
871
|
const cliDir = resolve4(fileURLToPath(new URL(".", import.meta.url)));
|
|
873
872
|
const pkgRoot = resolve4(cliDir, "..", "..");
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
candidates.push(join2(pkgRoot, "..", "ui-dist"));
|
|
877
|
-
candidates.push(join2(pkgRoot, "..", "ui"));
|
|
878
|
-
const cwd = process.cwd();
|
|
879
|
-
candidates.push(join2(cwd, "packages", "nextclaw-ui", "dist"));
|
|
880
|
-
candidates.push(join2(cwd, "nextclaw-ui", "dist"));
|
|
881
|
-
candidates.push(join2(pkgRoot, "..", "nextclaw-ui", "dist"));
|
|
882
|
-
candidates.push(join2(pkgRoot, "..", "..", "packages", "nextclaw-ui", "dist"));
|
|
883
|
-
candidates.push(join2(pkgRoot, "..", "..", "nextclaw-ui", "dist"));
|
|
884
|
-
for (const dir of candidates) {
|
|
885
|
-
if (existsSync4(join2(dir, "index.html"))) {
|
|
886
|
-
return dir;
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
return null;
|
|
873
|
+
const bundledDir = join2(pkgRoot, "ui-dist");
|
|
874
|
+
return existsSync4(join2(bundledDir, "index.html")) ? bundledDir : null;
|
|
890
875
|
}
|
|
891
876
|
function openBrowser(url) {
|
|
892
877
|
const platform = process.platform;
|
|
@@ -3415,7 +3400,7 @@ var RemoteCommands = class {
|
|
|
3415
3400
|
// src/cli/commands/diagnostics.ts
|
|
3416
3401
|
import { createServer as createNetServer } from "net";
|
|
3417
3402
|
import { existsSync as existsSync6, readFileSync as readFileSync6 } from "fs";
|
|
3418
|
-
import {
|
|
3403
|
+
import { resolve as resolve8 } from "path";
|
|
3419
3404
|
import {
|
|
3420
3405
|
APP_NAME as APP_NAME2,
|
|
3421
3406
|
getConfigPath as getConfigPath5,
|
|
@@ -3556,11 +3541,6 @@ var DiagnosticsCommands = class {
|
|
|
3556
3541
|
status: report.workspaceExists ? "pass" : "warn",
|
|
3557
3542
|
detail: report.workspacePath
|
|
3558
3543
|
},
|
|
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
|
-
},
|
|
3564
3544
|
{
|
|
3565
3545
|
name: "service-state",
|
|
3566
3546
|
status: report.process.staleState ? "fail" : report.process.running ? "pass" : "warn",
|
|
@@ -3629,8 +3609,6 @@ var DiagnosticsCommands = class {
|
|
|
3629
3609
|
const configuredUi = resolveUiConfig(config2, { enabled: true, host: config2.ui.host, port: config2.ui.port });
|
|
3630
3610
|
const configuredUiUrl = resolveUiApiBase(configuredUi.host, configuredUi.port);
|
|
3631
3611
|
const configuredApiUrl = `${configuredUiUrl}/api`;
|
|
3632
|
-
const resolvedStaticDir = serviceState?.uiStaticDir ?? resolveUiStaticDir();
|
|
3633
|
-
const indexHtmlPresent = Boolean(resolvedStaticDir && existsSync6(join4(resolvedStaticDir, "index.html")));
|
|
3634
3612
|
const managedUiUrl = serviceState?.uiUrl ?? null;
|
|
3635
3613
|
const managedApiUrl = serviceState?.apiUrl ?? null;
|
|
3636
3614
|
const managedHealth = running && managedApiUrl ? await this.probeApiHealth(`${managedApiUrl}/health`) : { state: "unreachable", detail: "service not running" };
|
|
@@ -3665,10 +3643,6 @@ var DiagnosticsCommands = class {
|
|
|
3665
3643
|
providers,
|
|
3666
3644
|
serviceStatePath,
|
|
3667
3645
|
serviceStateExists: existsSync6(serviceStatePath),
|
|
3668
|
-
uiAssets: {
|
|
3669
|
-
resolvedStaticDir,
|
|
3670
|
-
indexHtmlPresent
|
|
3671
|
-
},
|
|
3672
3646
|
fixActions,
|
|
3673
3647
|
process: {
|
|
3674
3648
|
managedByState,
|
|
@@ -3768,11 +3742,7 @@ var DiagnosticsCommands = class {
|
|
|
3768
3742
|
params.issues.push("A service appears healthy on configured API endpoint, but state is missing/stale.");
|
|
3769
3743
|
params.recommendations.push("Another process may be occupying the UI port; stop it or use --ui-port with a free port.");
|
|
3770
3744
|
}
|
|
3771
|
-
if (params.
|
|
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)) {
|
|
3745
|
+
if (!params.providers.some((provider) => provider.configured)) {
|
|
3776
3746
|
params.recommendations.push("Configure at least one provider API key in UI or config before expecting agent replies.");
|
|
3777
3747
|
}
|
|
3778
3748
|
}
|
|
@@ -3822,7 +3792,7 @@ import {
|
|
|
3822
3792
|
} from "@nextclaw/openclaw-compat";
|
|
3823
3793
|
import { startUiServer } from "@nextclaw/server";
|
|
3824
3794
|
import { appendFileSync, closeSync, cpSync as cpSync2, existsSync as existsSync10, mkdirSync as mkdirSync5, openSync } from "fs";
|
|
3825
|
-
import { dirname as dirname2, join as
|
|
3795
|
+
import { dirname as dirname2, join as join6, resolve as resolve10 } from "path";
|
|
3826
3796
|
import { spawn as spawn3 } from "child_process";
|
|
3827
3797
|
import { request as httpRequest } from "http";
|
|
3828
3798
|
import { request as httpsRequest } from "https";
|
|
@@ -4303,7 +4273,7 @@ var MissingProvider = class extends LLMProvider {
|
|
|
4303
4273
|
// src/cli/commands/service-marketplace-installer.ts
|
|
4304
4274
|
import { getWorkspacePath as getWorkspacePath5, loadConfig as loadConfig12 } from "@nextclaw/core";
|
|
4305
4275
|
import { existsSync as existsSync8, rmSync as rmSync4 } from "fs";
|
|
4306
|
-
import { join as
|
|
4276
|
+
import { join as join4 } from "path";
|
|
4307
4277
|
|
|
4308
4278
|
// src/cli/commands/service-marketplace-helpers.ts
|
|
4309
4279
|
var containsAbsoluteFsPath = (line) => {
|
|
@@ -4506,7 +4476,7 @@ var ServiceMarketplaceInstaller = class {
|
|
|
4506
4476
|
}
|
|
4507
4477
|
async uninstallSkill(slug) {
|
|
4508
4478
|
const workspace = getWorkspacePath5(loadConfig12().agents.defaults.workspace);
|
|
4509
|
-
const targetDir =
|
|
4479
|
+
const targetDir = join4(workspace, "skills", slug);
|
|
4510
4480
|
if (!existsSync8(targetDir)) {
|
|
4511
4481
|
throw new Error(`Skill not installed in workspace: ${slug}`);
|
|
4512
4482
|
}
|
|
@@ -6499,7 +6469,7 @@ async function createUiNcpAgent(params) {
|
|
|
6499
6469
|
// src/cli/commands/service-remote-runtime.ts
|
|
6500
6470
|
import { RemoteServiceModule } from "@nextclaw/remote";
|
|
6501
6471
|
function createManagedRemoteModule(params) {
|
|
6502
|
-
if (!params.
|
|
6472
|
+
if (!params.config.ui.enabled) {
|
|
6503
6473
|
return null;
|
|
6504
6474
|
}
|
|
6505
6475
|
return new RemoteServiceModule({
|
|
@@ -6523,7 +6493,6 @@ function writeInitialManagedServiceState(params) {
|
|
|
6523
6493
|
uiHost: params.snapshot.uiHost,
|
|
6524
6494
|
uiPort: params.snapshot.uiPort,
|
|
6525
6495
|
logPath: params.snapshot.logPath,
|
|
6526
|
-
uiStaticDir: params.snapshot.uiStaticDir ?? null,
|
|
6527
6496
|
startupLastProbeError: null,
|
|
6528
6497
|
startupTimeoutMs: params.readinessTimeoutMs,
|
|
6529
6498
|
startupCheckedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -6540,7 +6509,6 @@ function writeReadyManagedServiceState(params) {
|
|
|
6540
6509
|
uiHost: params.snapshot.uiHost,
|
|
6541
6510
|
uiPort: params.snapshot.uiPort,
|
|
6542
6511
|
logPath: params.snapshot.logPath,
|
|
6543
|
-
uiStaticDir: params.snapshot.uiStaticDir ?? currentState?.uiStaticDir ?? null,
|
|
6544
6512
|
startupState: params.readiness.ready ? "ready" : "degraded",
|
|
6545
6513
|
startupLastProbeError: params.readiness.lastProbeError,
|
|
6546
6514
|
startupTimeoutMs: params.readinessTimeoutMs,
|
|
@@ -6872,13 +6840,13 @@ function createRemoteAccessHost(params) {
|
|
|
6872
6840
|
|
|
6873
6841
|
// src/cli/commands/ui-chat-run-coordinator.ts
|
|
6874
6842
|
import { existsSync as existsSync9, mkdirSync as mkdirSync4, readdirSync as readdirSync2, readFileSync as readFileSync8, writeFileSync as writeFileSync4 } from "fs";
|
|
6875
|
-
import { join as
|
|
6843
|
+
import { join as join5 } from "path";
|
|
6876
6844
|
import {
|
|
6877
6845
|
getDataDir as getDataDir6,
|
|
6878
6846
|
parseAgentScopedSessionKey as parseAgentScopedSessionKey2,
|
|
6879
6847
|
safeFilename
|
|
6880
6848
|
} from "@nextclaw/core";
|
|
6881
|
-
var RUNS_DIR =
|
|
6849
|
+
var RUNS_DIR = join5(getDataDir6(), "runs");
|
|
6882
6850
|
var NON_TERMINAL_STATES = /* @__PURE__ */ new Set(["queued", "running"]);
|
|
6883
6851
|
var DEFAULT_SESSION_TYPE = "native";
|
|
6884
6852
|
var SESSION_TYPE_METADATA_KEY = "session_type";
|
|
@@ -7404,7 +7372,7 @@ var UiChatRunCoordinator = class {
|
|
|
7404
7372
|
};
|
|
7405
7373
|
}
|
|
7406
7374
|
getRunPath(runId) {
|
|
7407
|
-
return
|
|
7375
|
+
return join5(RUNS_DIR, `${safeFilename(runId)}.json`);
|
|
7408
7376
|
}
|
|
7409
7377
|
persistRun(run) {
|
|
7410
7378
|
const persisted = {
|
|
@@ -7433,7 +7401,7 @@ var UiChatRunCoordinator = class {
|
|
|
7433
7401
|
if (!entry.isFile() || !entry.name.endsWith(".json")) {
|
|
7434
7402
|
continue;
|
|
7435
7403
|
}
|
|
7436
|
-
const path2 =
|
|
7404
|
+
const path2 = join5(RUNS_DIR, entry.name);
|
|
7437
7405
|
try {
|
|
7438
7406
|
const parsed = JSON.parse(readFileSync8(path2, "utf-8"));
|
|
7439
7407
|
const runId = readOptionalString(parsed.runId);
|
|
@@ -7539,7 +7507,7 @@ var ServiceCommands = class {
|
|
|
7539
7507
|
});
|
|
7540
7508
|
const sessionManager = new SessionManager(workspace);
|
|
7541
7509
|
let pluginGatewayHandles = [];
|
|
7542
|
-
const cronStorePath =
|
|
7510
|
+
const cronStorePath = join6(getDataDir7(), "cron", "jobs.json");
|
|
7543
7511
|
const cron2 = new CronService2(cronStorePath);
|
|
7544
7512
|
const uiConfig = resolveUiConfig(config2, options.uiOverrides);
|
|
7545
7513
|
const uiStaticDir = options.uiStaticDir === void 0 ? resolveUiStaticDir() : options.uiStaticDir;
|
|
@@ -7722,7 +7690,7 @@ var ServiceCommands = class {
|
|
|
7722
7690
|
accountId
|
|
7723
7691
|
})
|
|
7724
7692
|
);
|
|
7725
|
-
const remoteModule = createManagedRemoteModule({ config: config2,
|
|
7693
|
+
const remoteModule = createManagedRemoteModule({ config: config2, localOrigin });
|
|
7726
7694
|
await startGatewaySupportServices({
|
|
7727
7695
|
cronJobs: cron2.status().jobs,
|
|
7728
7696
|
remoteModule,
|
|
@@ -7935,15 +7903,23 @@ var ServiceCommands = class {
|
|
|
7935
7903
|
if (existing) {
|
|
7936
7904
|
clearServiceState();
|
|
7937
7905
|
}
|
|
7938
|
-
const logPath = resolveServiceLogPath();
|
|
7939
|
-
const logDir = resolve10(logPath, "..");
|
|
7940
|
-
mkdirSync5(logDir, { recursive: true });
|
|
7941
|
-
const staticDirDescription = staticDir ? `staticDir=${staticDir}` : "staticDir=<missing>";
|
|
7942
|
-
this.appendStartupStage(logPath, `ui asset resolution: ${staticDirDescription}`);
|
|
7943
7906
|
if (!staticDir) {
|
|
7944
|
-
console.
|
|
7907
|
+
return void (process.exitCode = 1, console.error(`Error: ${APP_NAME3} UI frontend bundle not found. Reinstall or rebuild ${APP_NAME3}. For dev-only overrides, set NEXTCLAW_UI_STATIC_DIR to a built frontend directory.`));
|
|
7945
7908
|
}
|
|
7946
7909
|
const healthUrl = `${apiUrl}/health`;
|
|
7910
|
+
const portPreflight = await this.checkUiPortPreflight({
|
|
7911
|
+
host: uiConfig.host,
|
|
7912
|
+
port: uiConfig.port,
|
|
7913
|
+
healthUrl
|
|
7914
|
+
});
|
|
7915
|
+
if (!portPreflight.ok) {
|
|
7916
|
+
console.error(`Error: Cannot start ${APP_NAME3} because UI port ${uiConfig.port} is already occupied.`);
|
|
7917
|
+
console.error(portPreflight.message);
|
|
7918
|
+
return;
|
|
7919
|
+
}
|
|
7920
|
+
const logPath = resolveServiceLogPath();
|
|
7921
|
+
const logDir = resolve10(logPath, "..");
|
|
7922
|
+
mkdirSync5(logDir, { recursive: true });
|
|
7947
7923
|
const logFd = openSync(logPath, "a");
|
|
7948
7924
|
const readinessTimeoutMs = this.resolveStartupTimeoutMs(options.startupTimeoutMs);
|
|
7949
7925
|
const quickPhaseTimeoutMs = Math.min(8e3, readinessTimeoutMs);
|
|
@@ -7977,7 +7953,7 @@ var ServiceCommands = class {
|
|
|
7977
7953
|
writeInitialManagedServiceState({
|
|
7978
7954
|
config: config2,
|
|
7979
7955
|
readinessTimeoutMs,
|
|
7980
|
-
snapshot: { pid: child.pid, uiUrl, apiUrl, uiHost: uiConfig.host, uiPort: uiConfig.port, logPath
|
|
7956
|
+
snapshot: { pid: child.pid, uiUrl, apiUrl, uiHost: uiConfig.host, uiPort: uiConfig.port, logPath }
|
|
7981
7957
|
});
|
|
7982
7958
|
this.appendStartupStage(logPath, `health probe started: ${healthUrl} (phase=quick, timeoutMs=${quickPhaseTimeoutMs})`);
|
|
7983
7959
|
let readiness = await this.waitForBackgroundServiceReady({
|
|
@@ -8505,8 +8481,8 @@ var ServiceCommands = class {
|
|
|
8505
8481
|
}
|
|
8506
8482
|
installBuiltinMarketplaceSkill(slug, force) {
|
|
8507
8483
|
const workspace = getWorkspacePath9(loadConfig14().agents.defaults.workspace);
|
|
8508
|
-
const destination =
|
|
8509
|
-
const destinationSkillFile =
|
|
8484
|
+
const destination = join6(workspace, "skills", slug);
|
|
8485
|
+
const destinationSkillFile = join6(destination, "SKILL.md");
|
|
8510
8486
|
if (existsSync10(destinationSkillFile) && !force) {
|
|
8511
8487
|
return {
|
|
8512
8488
|
message: `${slug} is already installed`
|
|
@@ -8522,7 +8498,7 @@ var ServiceCommands = class {
|
|
|
8522
8498
|
}
|
|
8523
8499
|
return null;
|
|
8524
8500
|
}
|
|
8525
|
-
mkdirSync5(
|
|
8501
|
+
mkdirSync5(join6(workspace, "skills"), { recursive: true });
|
|
8526
8502
|
cpSync2(dirname2(builtin.path), destination, { recursive: true, force: true });
|
|
8527
8503
|
return {
|
|
8528
8504
|
message: `Installed skill: ${slug}`
|
|
@@ -8584,7 +8560,7 @@ ${stderr}`.trim();
|
|
|
8584
8560
|
// src/cli/workspace.ts
|
|
8585
8561
|
import { cpSync as cpSync3, existsSync as existsSync11, mkdirSync as mkdirSync6, readFileSync as readFileSync9, readdirSync as readdirSync3, rmSync as rmSync5, writeFileSync as writeFileSync5 } from "fs";
|
|
8586
8562
|
import { createRequire as createRequire2 } from "module";
|
|
8587
|
-
import { dirname as dirname3, join as
|
|
8563
|
+
import { dirname as dirname3, join as join7, resolve as resolve11 } from "path";
|
|
8588
8564
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
8589
8565
|
import { APP_NAME as APP_NAME4, getDataDir as getDataDir8 } from "@nextclaw/core";
|
|
8590
8566
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
@@ -8614,11 +8590,11 @@ var WorkspaceManager = class {
|
|
|
8614
8590
|
{ source: "memory/MEMORY.md", target: "memory/MEMORY.md" }
|
|
8615
8591
|
];
|
|
8616
8592
|
for (const entry of templateFiles) {
|
|
8617
|
-
const filePath =
|
|
8593
|
+
const filePath = join7(workspace, entry.target);
|
|
8618
8594
|
if (!force && existsSync11(filePath)) {
|
|
8619
8595
|
continue;
|
|
8620
8596
|
}
|
|
8621
|
-
const templatePath =
|
|
8597
|
+
const templatePath = join7(templateDir, entry.source);
|
|
8622
8598
|
if (!existsSync11(templatePath)) {
|
|
8623
8599
|
console.warn(`Warning: Template file missing: ${templatePath}`);
|
|
8624
8600
|
continue;
|
|
@@ -8629,15 +8605,15 @@ var WorkspaceManager = class {
|
|
|
8629
8605
|
writeFileSync5(filePath, content);
|
|
8630
8606
|
created.push(entry.target);
|
|
8631
8607
|
}
|
|
8632
|
-
const memoryDir =
|
|
8608
|
+
const memoryDir = join7(workspace, "memory");
|
|
8633
8609
|
if (!existsSync11(memoryDir)) {
|
|
8634
8610
|
mkdirSync6(memoryDir, { recursive: true });
|
|
8635
|
-
created.push(
|
|
8611
|
+
created.push(join7("memory", ""));
|
|
8636
8612
|
}
|
|
8637
|
-
const skillsDir =
|
|
8613
|
+
const skillsDir = join7(workspace, "skills");
|
|
8638
8614
|
if (!existsSync11(skillsDir)) {
|
|
8639
8615
|
mkdirSync6(skillsDir, { recursive: true });
|
|
8640
|
-
created.push(
|
|
8616
|
+
created.push(join7("skills", ""));
|
|
8641
8617
|
}
|
|
8642
8618
|
const seeded = this.seedBuiltinSkills(skillsDir, { force });
|
|
8643
8619
|
if (seeded > 0) {
|
|
@@ -8656,11 +8632,11 @@ var WorkspaceManager = class {
|
|
|
8656
8632
|
if (!entry.isDirectory()) {
|
|
8657
8633
|
continue;
|
|
8658
8634
|
}
|
|
8659
|
-
const src =
|
|
8660
|
-
if (!existsSync11(
|
|
8635
|
+
const src = join7(sourceDir, entry.name);
|
|
8636
|
+
if (!existsSync11(join7(src, "SKILL.md"))) {
|
|
8661
8637
|
continue;
|
|
8662
8638
|
}
|
|
8663
|
-
const dest =
|
|
8639
|
+
const dest = join7(targetDir, entry.name);
|
|
8664
8640
|
if (!force && existsSync11(dest)) {
|
|
8665
8641
|
continue;
|
|
8666
8642
|
}
|
|
@@ -8679,11 +8655,11 @@ var WorkspaceManager = class {
|
|
|
8679
8655
|
const require3 = createRequire2(import.meta.url);
|
|
8680
8656
|
const entry = require3.resolve("@nextclaw/core");
|
|
8681
8657
|
const pkgRoot = resolve11(dirname3(entry), "..");
|
|
8682
|
-
const distSkills =
|
|
8658
|
+
const distSkills = join7(pkgRoot, "dist", "skills");
|
|
8683
8659
|
if (existsSync11(distSkills)) {
|
|
8684
8660
|
return distSkills;
|
|
8685
8661
|
}
|
|
8686
|
-
const srcSkills =
|
|
8662
|
+
const srcSkills = join7(pkgRoot, "src", "agent", "skills");
|
|
8687
8663
|
if (existsSync11(srcSkills)) {
|
|
8688
8664
|
return srcSkills;
|
|
8689
8665
|
}
|
|
@@ -8699,7 +8675,7 @@ var WorkspaceManager = class {
|
|
|
8699
8675
|
}
|
|
8700
8676
|
const cliDir = resolve11(fileURLToPath4(new URL(".", import.meta.url)));
|
|
8701
8677
|
const pkgRoot = resolve11(cliDir, "..", "..");
|
|
8702
|
-
const candidates = [
|
|
8678
|
+
const candidates = [join7(pkgRoot, "templates")];
|
|
8703
8679
|
for (const candidate of candidates) {
|
|
8704
8680
|
if (existsSync11(candidate)) {
|
|
8705
8681
|
return candidate;
|
|
@@ -8708,8 +8684,8 @@ var WorkspaceManager = class {
|
|
|
8708
8684
|
return null;
|
|
8709
8685
|
}
|
|
8710
8686
|
getBridgeDir() {
|
|
8711
|
-
const userBridge =
|
|
8712
|
-
if (existsSync11(
|
|
8687
|
+
const userBridge = join7(getDataDir8(), "bridge");
|
|
8688
|
+
if (existsSync11(join7(userBridge, "dist", "index.js"))) {
|
|
8713
8689
|
return userBridge;
|
|
8714
8690
|
}
|
|
8715
8691
|
if (!which("npm")) {
|
|
@@ -8718,12 +8694,12 @@ var WorkspaceManager = class {
|
|
|
8718
8694
|
}
|
|
8719
8695
|
const cliDir = resolve11(fileURLToPath4(new URL(".", import.meta.url)));
|
|
8720
8696
|
const pkgRoot = resolve11(cliDir, "..", "..");
|
|
8721
|
-
const pkgBridge =
|
|
8722
|
-
const srcBridge =
|
|
8697
|
+
const pkgBridge = join7(pkgRoot, "bridge");
|
|
8698
|
+
const srcBridge = join7(pkgRoot, "..", "..", "bridge");
|
|
8723
8699
|
let source = null;
|
|
8724
|
-
if (existsSync11(
|
|
8700
|
+
if (existsSync11(join7(pkgBridge, "package.json"))) {
|
|
8725
8701
|
source = pkgBridge;
|
|
8726
|
-
} else if (existsSync11(
|
|
8702
|
+
} else if (existsSync11(join7(srcBridge, "package.json"))) {
|
|
8727
8703
|
source = srcBridge;
|
|
8728
8704
|
}
|
|
8729
8705
|
if (!source) {
|
|
@@ -9018,7 +8994,7 @@ var CliRuntime = class {
|
|
|
9018
8994
|
}
|
|
9019
8995
|
const config2 = loadConfig15();
|
|
9020
8996
|
const workspaceSetting = config2.agents.defaults.workspace;
|
|
9021
|
-
const workspacePath = !workspaceSetting || workspaceSetting === DEFAULT_WORKSPACE_PATH ?
|
|
8997
|
+
const workspacePath = !workspaceSetting || workspaceSetting === DEFAULT_WORKSPACE_PATH ? join8(getDataDir9(), DEFAULT_WORKSPACE_DIR) : expandHome2(workspaceSetting);
|
|
9022
8998
|
const workspaceExisted = existsSync12(workspacePath);
|
|
9023
8999
|
mkdirSync7(workspacePath, { recursive: true });
|
|
9024
9000
|
const templateResult = this.workspaceManager.createWorkspaceTemplates(
|
|
@@ -9211,7 +9187,7 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
|
|
|
9211
9187
|
`${this.logo} Interactive mode (type exit or Ctrl+C to quit)
|
|
9212
9188
|
`
|
|
9213
9189
|
);
|
|
9214
|
-
const historyFile =
|
|
9190
|
+
const historyFile = join8(getDataDir9(), "history", "cli_history");
|
|
9215
9191
|
const historyDir = resolve12(historyFile, "..");
|
|
9216
9192
|
mkdirSync7(historyDir, { recursive: true });
|
|
9217
9193
|
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.
|
|
3
|
+
"version": "0.13.15",
|
|
4
4
|
"description": "Lightweight personal AI assistant with CLI, multi-provider routing, and channel integrations.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -39,16 +39,16 @@
|
|
|
39
39
|
"chokidar": "^3.6.0",
|
|
40
40
|
"commander": "^12.1.0",
|
|
41
41
|
"yaml": "^2.8.1",
|
|
42
|
-
"@nextclaw/ncp": "0.3.1",
|
|
43
|
-
"@nextclaw/ncp-agent-runtime": "0.2.1",
|
|
44
42
|
"@nextclaw/core": "0.9.5",
|
|
45
|
-
"@nextclaw/
|
|
46
|
-
"@nextclaw/
|
|
43
|
+
"@nextclaw/ncp": "0.3.1",
|
|
44
|
+
"@nextclaw/server": "0.10.11",
|
|
47
45
|
"@nextclaw/ncp-toolkit": "0.4.1",
|
|
48
|
-
"@nextclaw/
|
|
46
|
+
"@nextclaw/ncp-agent-runtime": "0.2.1",
|
|
49
47
|
"@nextclaw/runtime": "0.2.5",
|
|
50
|
-
"@nextclaw/
|
|
51
|
-
"@nextclaw/
|
|
48
|
+
"@nextclaw/openclaw-compat": "0.3.8",
|
|
49
|
+
"@nextclaw/mcp": "0.1.11",
|
|
50
|
+
"@nextclaw/remote": "0.1.7",
|
|
51
|
+
"@nextclaw/ncp-mcp": "0.1.11"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@types/node": "^20.17.6",
|
|
@@ -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};
|