nextclaw 0.21.6 → 0.21.7
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/app/index.js +174 -5
- package/dist/cli/app/index.js.map +1 -1
- package/package.json +16 -16
- package/resources/USAGE.md +2 -0
- package/ui-dist/assets/{api-DmxQnm30.js → api-D0hARyyl.js} +1 -1
- package/ui-dist/assets/app-presenter-provider-C7EsUuEJ.js +3 -0
- package/ui-dist/assets/arrow-left-CzSkR5L6.js +1 -0
- package/ui-dist/assets/book-open-DmeQPqkd.js +1 -0
- package/ui-dist/assets/{channels-list-page-D-WYFmcG.js → channels-list-page-B0yiiH01.js} +2 -2
- package/ui-dist/assets/chat-page-ChPjx_X9.js +105 -0
- package/ui-dist/assets/{config-split-page-CdJEkWxv.js → config-split-page-BzfZSyAr.js} +1 -1
- package/ui-dist/assets/{confirm-dialog-BWRNsRgb.js → confirm-dialog-CTcaBp-8.js} +1 -1
- package/ui-dist/assets/desktop-update-config-CExpdkqD.js +1 -0
- package/ui-dist/assets/{dist-CyWdaJvr.js → dist-C59BKqbX.js} +1 -1
- package/ui-dist/assets/{dist-DzM2ZEVN.js → dist-Di6EHp2x.js} +1 -1
- package/ui-dist/assets/{doc-browser-DewXa6oX.js → doc-browser-EZbnEcdk.js} +1 -1
- package/ui-dist/assets/doc-browser-XIwe1Tg-.js +1 -0
- package/ui-dist/assets/{doc-browser-context-CpL2m4Sp.js → doc-browser-context-BzEA1lm1.js} +1 -1
- package/ui-dist/assets/{ellipsis-BDgTYNDX.js → ellipsis-hXUNwi63.js} +1 -1
- package/ui-dist/assets/{es2015-WqekV0OK.js → es2015-CJlVSTh-.js} +1 -1
- package/ui-dist/assets/{external-link-BLjo8z2a.js → external-link-J0fCK-vu.js} +1 -1
- package/ui-dist/assets/host-capabilities-DjiRQ0Q9.js +1 -0
- package/ui-dist/assets/index-DfZTO6Pi.js +101 -0
- package/ui-dist/assets/index-mIb_YMrc.css +1 -0
- package/ui-dist/assets/{key-round-Du8x3sWa.js → key-round-BzYZ0Nno.js} +1 -1
- package/ui-dist/assets/loader-circle-BbdIlBbQ.js +1 -0
- package/ui-dist/assets/mcp-marketplace-page-L22aCzHX.js +40 -0
- package/ui-dist/assets/mcp-marketplace-page-f80Jmv37.js +1 -0
- package/ui-dist/assets/model-config-DkD7vSQT.js +1 -0
- package/ui-dist/assets/{notice-card-3a7FmAz-.js → notice-card-CD9Ok62G.js} +1 -1
- package/ui-dist/assets/play-DHuSeKs8.js +1 -0
- package/ui-dist/assets/plus-DrV685KC.js +1 -0
- package/ui-dist/assets/{popover-BlJLguiZ.js → popover-CoBu3mbV.js} +1 -1
- package/ui-dist/assets/{provider-scoped-model-input-IMD4W0jD.js → provider-scoped-model-input-DZlmTCJU.js} +1 -1
- package/ui-dist/assets/providers-list-CVkWiqIy.js +1 -0
- package/ui-dist/assets/{react-BVjl1ZaK.js → react-C7HsxuKH.js} +1 -1
- package/ui-dist/assets/{refresh-cw-DFR87zei.js → refresh-cw-CVo4nWpq.js} +1 -1
- package/ui-dist/assets/remote-Bznw9iji.js +1 -0
- package/ui-dist/assets/rotate-cw-CXDpRO6D.js +1 -0
- package/ui-dist/assets/{runtime-config-page-DzbTVebD.js → runtime-config-page-5IycbIxs.js} +1 -1
- package/ui-dist/assets/{save-BDmIlHvN.js → save-Z1QTovIt.js} +1 -1
- package/ui-dist/assets/search-8nY6PGm0.js +1 -0
- package/ui-dist/assets/{search-config-CJ6OPxAf.js → search-config-DEH80WkC.js} +1 -1
- package/ui-dist/assets/{secrets-config-CYOHWL7P.js → secrets-config-Gzo5nDJG.js} +1 -1
- package/ui-dist/assets/{status-dot-SVPjIyG5.js → status-dot-C1-FKgvv.js} +1 -1
- package/ui-dist/assets/{tabs-Czd2mj6z.js → tabs-BqkKwx1R.js} +1 -1
- package/ui-dist/assets/{tabs-custom-Ix4nkp2h.js → tabs-custom-DOkaJZmt.js} +1 -1
- package/ui-dist/assets/{tag-chip-Cdwb3JSH.js → tag-chip-3kpiMTST.js} +1 -1
- package/ui-dist/assets/{tooltip-CKGxLGnG.js → tooltip-Bw-mXQAM.js} +1 -1
- package/ui-dist/assets/{trash-2-yLA8BEcE.js → trash-2-CmIwAJIT.js} +1 -1
- package/ui-dist/assets/x-CSRTOZnM.js +1 -0
- package/ui-dist/index.html +27 -25
- package/ui-dist/assets/app-presenter-provider-CDSjiqfE.js +0 -3
- package/ui-dist/assets/arrow-left-Dd45Mvr1.js +0 -1
- package/ui-dist/assets/chat-page-D1X8YNTC.js +0 -105
- package/ui-dist/assets/desktop-update-config-DOi5R1fX.js +0 -1
- package/ui-dist/assets/doc-browser-D5FJcAyz.js +0 -1
- package/ui-dist/assets/index-Q891JiF_.css +0 -1
- package/ui-dist/assets/index-ZDJP_uJc.js +0 -101
- package/ui-dist/assets/loader-circle-Dz4FssYC.js +0 -1
- package/ui-dist/assets/mcp-marketplace-page-LmMhKH5a.js +0 -1
- package/ui-dist/assets/mcp-marketplace-page-RqISBSqO.js +0 -40
- package/ui-dist/assets/model-config-JUsW1Khb.js +0 -1
- package/ui-dist/assets/play-BziM-Y34.js +0 -1
- package/ui-dist/assets/plus-DrpyArC8.js +0 -1
- package/ui-dist/assets/providers-list-BsDpxNzy.js +0 -1
- package/ui-dist/assets/remote-DjhVMpVd.js +0 -1
- package/ui-dist/assets/rotate-cw-DMBnsYKm.js +0 -1
- package/ui-dist/assets/search-CjHGYvTI.js +0 -1
- package/ui-dist/assets/x-dpDISboO.js +0 -1
- /package/ui-dist/assets/{config-hints-Ceiol9x4.js → config-hints-fGnUjDe9.js} +0 -0
- /package/ui-dist/assets/{provider-models-C_yOh6DE.js → provider-models-C9VRroK3.js} +0 -0
package/dist/cli/app/index.js
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { t as createNextclawDistribution } from "../../nextclaw-distribution.utils-BJZhAnGk.js";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
|
-
import { APP_NAME, APP_TAGLINE, getConfigPath, loadConfig, resolveConfigSecrets } from "@nextclaw/core";
|
|
4
|
+
import { APP_NAME, APP_TAGLINE, getConfigPath, getDataDir, getRunPath, loadConfig, resolveConfigSecrets } from "@nextclaw/core";
|
|
5
5
|
import { Command } from "commander";
|
|
6
|
-
import { constants } from "node:fs";
|
|
7
|
-
import path from "node:path";
|
|
6
|
+
import { constants, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
7
|
+
import path, { join, resolve } from "node:path";
|
|
8
8
|
import "@nextclaw/server";
|
|
9
9
|
import { NextclawDistributionService, NextclawServiceRuntime, readLearningLoopRuntimeConfig } from "@nextclaw/service";
|
|
10
10
|
import { McpServiceAppRuntimeService, buildServiceActionId, getServiceAppManifestPath, mergeServiceAppRuntimeActions, readServiceAppManifest } from "@nextclaw/kernel";
|
|
11
11
|
import { access, readFile, stat } from "node:fs/promises";
|
|
12
12
|
import { execFile } from "node:child_process";
|
|
13
13
|
import { promisify } from "node:util";
|
|
14
|
+
import { randomBytes } from "node:crypto";
|
|
14
15
|
var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
15
16
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
16
17
|
//#endregion
|
|
@@ -2017,7 +2018,7 @@ var require_websocket = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
2017
2018
|
const http$1 = __require("http");
|
|
2018
2019
|
const net = __require("net");
|
|
2019
2020
|
const tls = __require("tls");
|
|
2020
|
-
const { randomBytes, createHash: createHash$1 } = __require("crypto");
|
|
2021
|
+
const { randomBytes: randomBytes$1, createHash: createHash$1 } = __require("crypto");
|
|
2021
2022
|
const { Duplex: Duplex$2, Readable } = __require("stream");
|
|
2022
2023
|
const { URL: URL$1 } = __require("url");
|
|
2023
2024
|
const PerMessageDeflate = require_permessage_deflate();
|
|
@@ -2572,7 +2573,7 @@ var require_websocket = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
2572
2573
|
}
|
|
2573
2574
|
}
|
|
2574
2575
|
const defaultPort = isSecure ? 443 : 80;
|
|
2575
|
-
const key = randomBytes(16).toString("base64");
|
|
2576
|
+
const key = randomBytes$1(16).toString("base64");
|
|
2576
2577
|
const request = isSecure ? https.request : http$1.request;
|
|
2577
2578
|
const protocolSet = /* @__PURE__ */ new Set();
|
|
2578
2579
|
let perMessageDeflate;
|
|
@@ -4416,15 +4417,183 @@ var AppDevCommandController = class {
|
|
|
4416
4417
|
};
|
|
4417
4418
|
};
|
|
4418
4419
|
//#endregion
|
|
4420
|
+
//#region src/cli/app/services/service-app-live-runtime.service.ts
|
|
4421
|
+
function readErrorMessage(error) {
|
|
4422
|
+
if (error instanceof Error && error.message.trim().length > 0) return error.message.trim();
|
|
4423
|
+
return String(error ?? "unknown error");
|
|
4424
|
+
}
|
|
4425
|
+
var ServiceAppLiveRuntimeService = class {
|
|
4426
|
+
constructor(params = {}) {
|
|
4427
|
+
this.params = params;
|
|
4428
|
+
}
|
|
4429
|
+
restart = async (appId) => {
|
|
4430
|
+
const target = appId.trim();
|
|
4431
|
+
const issues = [];
|
|
4432
|
+
if (!target) {
|
|
4433
|
+
issues.push({
|
|
4434
|
+
severity: "error",
|
|
4435
|
+
code: "service.id.invalid",
|
|
4436
|
+
message: "Service App id is required."
|
|
4437
|
+
});
|
|
4438
|
+
return {
|
|
4439
|
+
ok: false,
|
|
4440
|
+
target,
|
|
4441
|
+
issues
|
|
4442
|
+
};
|
|
4443
|
+
}
|
|
4444
|
+
const apiClient = this.createApiClient();
|
|
4445
|
+
if (!apiClient) {
|
|
4446
|
+
issues.push({
|
|
4447
|
+
severity: "error",
|
|
4448
|
+
code: "service.runtime.notRunning",
|
|
4449
|
+
message: "NextClaw UI runtime is not running; start NextClaw before restarting a live Service App."
|
|
4450
|
+
});
|
|
4451
|
+
return {
|
|
4452
|
+
ok: false,
|
|
4453
|
+
target,
|
|
4454
|
+
issues
|
|
4455
|
+
};
|
|
4456
|
+
}
|
|
4457
|
+
try {
|
|
4458
|
+
return {
|
|
4459
|
+
ok: true,
|
|
4460
|
+
target,
|
|
4461
|
+
app: await apiClient.request({
|
|
4462
|
+
path: `/api/service-apps/${encodeURIComponent(target)}/restart`,
|
|
4463
|
+
method: "POST"
|
|
4464
|
+
}),
|
|
4465
|
+
issues
|
|
4466
|
+
};
|
|
4467
|
+
} catch (error) {
|
|
4468
|
+
issues.push({
|
|
4469
|
+
severity: "error",
|
|
4470
|
+
code: "service.runtime.restartFailed",
|
|
4471
|
+
message: readErrorMessage(error)
|
|
4472
|
+
});
|
|
4473
|
+
return {
|
|
4474
|
+
ok: false,
|
|
4475
|
+
target,
|
|
4476
|
+
issues
|
|
4477
|
+
};
|
|
4478
|
+
}
|
|
4479
|
+
};
|
|
4480
|
+
createApiClient = () => {
|
|
4481
|
+
if (this.params.createApiClient) return this.params.createApiClient();
|
|
4482
|
+
const apiBase = resolveLocalUiApiBase();
|
|
4483
|
+
return apiBase ? new LocalUiApiClient(apiBase) : null;
|
|
4484
|
+
};
|
|
4485
|
+
};
|
|
4486
|
+
var LocalUiApiClient = class {
|
|
4487
|
+
cookie;
|
|
4488
|
+
constructor(apiBase) {
|
|
4489
|
+
this.apiBase = apiBase;
|
|
4490
|
+
}
|
|
4491
|
+
request = async (params) => {
|
|
4492
|
+
const { body, method, path } = params;
|
|
4493
|
+
const cookie = await this.getCookie();
|
|
4494
|
+
const headers = {};
|
|
4495
|
+
if (body) headers["Content-Type"] = "application/json";
|
|
4496
|
+
if (cookie) headers.Cookie = cookie;
|
|
4497
|
+
const requestInit = {
|
|
4498
|
+
method: method ?? "GET",
|
|
4499
|
+
headers
|
|
4500
|
+
};
|
|
4501
|
+
if (body) requestInit.body = JSON.stringify(body);
|
|
4502
|
+
const response = await fetch(`${this.apiBase}${path}`, requestInit);
|
|
4503
|
+
if (!response.ok) throw new Error(`api request failed with status ${response.status}`);
|
|
4504
|
+
const payload = await response.json();
|
|
4505
|
+
if (!payload.ok) throw new Error(payload.error?.message ?? "api request failed");
|
|
4506
|
+
return payload.data;
|
|
4507
|
+
};
|
|
4508
|
+
getCookie = async () => {
|
|
4509
|
+
if (this.cookie !== void 0) return this.cookie;
|
|
4510
|
+
const response = await fetch(`${this.apiBase}/api/auth/bridge`, {
|
|
4511
|
+
method: "POST",
|
|
4512
|
+
headers: { "x-nextclaw-ui-bridge-secret": ensureUiBridgeSecret() }
|
|
4513
|
+
});
|
|
4514
|
+
if (!response.ok) throw new Error(`bridge auth failed with status ${response.status}`);
|
|
4515
|
+
const payload = await response.json();
|
|
4516
|
+
if (!payload.ok) throw new Error(payload.error?.message ?? "bridge auth failed");
|
|
4517
|
+
this.cookie = typeof payload.data.cookie === "string" && payload.data.cookie.trim().length > 0 ? payload.data.cookie.trim() : null;
|
|
4518
|
+
return this.cookie;
|
|
4519
|
+
};
|
|
4520
|
+
};
|
|
4521
|
+
function resolveLocalUiApiBase() {
|
|
4522
|
+
const state = readRunningRuntimeState(resolve(getRunPath(), "ui-runtime.json")) ?? readRunningRuntimeState(resolve(getRunPath(), "service.json"));
|
|
4523
|
+
if (!state) return null;
|
|
4524
|
+
if (typeof state.uiUrl === "string" && state.uiUrl.trim().length > 0) return state.uiUrl.replace(/\/+$/, "");
|
|
4525
|
+
if (typeof state.apiUrl === "string" && state.apiUrl.trim().length > 0) return state.apiUrl.replace(/\/api\/?$/, "").replace(/\/+$/, "");
|
|
4526
|
+
return null;
|
|
4527
|
+
}
|
|
4528
|
+
function readRunningRuntimeState(statePath) {
|
|
4529
|
+
if (!existsSync(statePath)) return null;
|
|
4530
|
+
try {
|
|
4531
|
+
const state = JSON.parse(readFileSync(statePath, "utf-8"));
|
|
4532
|
+
return typeof state.pid === "number" && isProcessRunning(state.pid) ? state : null;
|
|
4533
|
+
} catch {
|
|
4534
|
+
return null;
|
|
4535
|
+
}
|
|
4536
|
+
}
|
|
4537
|
+
function isProcessRunning(pid) {
|
|
4538
|
+
try {
|
|
4539
|
+
process.kill(pid, 0);
|
|
4540
|
+
return true;
|
|
4541
|
+
} catch {
|
|
4542
|
+
return false;
|
|
4543
|
+
}
|
|
4544
|
+
}
|
|
4545
|
+
function ensureUiBridgeSecret() {
|
|
4546
|
+
const dirPath = join(getDataDir(), "remote");
|
|
4547
|
+
const secretPath = join(dirPath, "ui-bridge-secret");
|
|
4548
|
+
if (existsSync(secretPath)) {
|
|
4549
|
+
const existing = readFileSync(secretPath, "utf-8").trim();
|
|
4550
|
+
if (existing.length > 0) return existing;
|
|
4551
|
+
}
|
|
4552
|
+
mkdirSync(dirPath, { recursive: true });
|
|
4553
|
+
const secret = randomBytes(24).toString("hex");
|
|
4554
|
+
writeFileSync(secretPath, `${secret}\n`, "utf-8");
|
|
4555
|
+
return secret;
|
|
4556
|
+
}
|
|
4557
|
+
//#endregion
|
|
4558
|
+
//#region src/cli/app/controllers/app-restart-command.controller.ts
|
|
4559
|
+
var AppRestartCommandController = class {
|
|
4560
|
+
constructor(liveRuntimeService = new ServiceAppLiveRuntimeService()) {
|
|
4561
|
+
this.liveRuntimeService = liveRuntimeService;
|
|
4562
|
+
}
|
|
4563
|
+
restart = async (appId, options) => {
|
|
4564
|
+
const report = await this.liveRuntimeService.restart(appId);
|
|
4565
|
+
process.stdout.write(options.json ? `${JSON.stringify(report, null, 2)}\n` : this.format(report));
|
|
4566
|
+
if (!report.ok) process.exitCode = 1;
|
|
4567
|
+
};
|
|
4568
|
+
format = (report) => {
|
|
4569
|
+
return [
|
|
4570
|
+
report.ok ? `NextClaw service app restart passed: ${report.target}\n` : `NextClaw service app restart failed: ${report.target || "(empty)"}\n`,
|
|
4571
|
+
report.app ? [
|
|
4572
|
+
`App: ${report.app.title} (${report.app.id})`,
|
|
4573
|
+
`Status: ${report.app.status}`,
|
|
4574
|
+
report.app.lastError ? `Last error: ${report.app.lastError}` : ""
|
|
4575
|
+
].filter(Boolean).join("\n") : "",
|
|
4576
|
+
this.formatIssueSection("Errors", report.issues.filter((issue) => issue.severity === "error")),
|
|
4577
|
+
this.formatIssueSection("Warnings", report.issues.filter((issue) => issue.severity === "warning"))
|
|
4578
|
+
].filter(Boolean).join("\n");
|
|
4579
|
+
};
|
|
4580
|
+
formatIssueSection = (title, issues) => {
|
|
4581
|
+
if (issues.length === 0) return "";
|
|
4582
|
+
return `${title}:\n${issues.flatMap((issue) => [`- [${issue.code}] ${issue.message}`, issue.fixHint ? ` Fix: ${issue.fixHint}` : ""].filter(Boolean)).join("\n")}\n`;
|
|
4583
|
+
};
|
|
4584
|
+
};
|
|
4585
|
+
//#endregion
|
|
4419
4586
|
//#region src/cli/app/register-app-commands.ts
|
|
4420
4587
|
function registerAppCommands(program) {
|
|
4421
4588
|
const app = program.command("app").description("Inspect and validate lightweight NextClaw apps");
|
|
4422
4589
|
const appCheck = new AppCheckCommandController();
|
|
4423
4590
|
const appDev = new AppDevCommandController();
|
|
4424
4591
|
const appCall = new AppCallCommandController();
|
|
4592
|
+
const appRestart = new AppRestartCommandController();
|
|
4425
4593
|
app.command("check <app-dir>").description("Check a Panel App or Service App directory").option("--json", "Output JSON", false).action(async (target, opts) => appCheck.check(target, opts));
|
|
4426
4594
|
app.command("dev <service-app-dir>").description("Start a Service App through the real runtime and inspect its actions").option("--json", "Output JSON", false).action(async (target, opts) => appDev.dev(target, opts));
|
|
4427
4595
|
app.command("call <service-app-dir> <action-name>").description("Call a Service App action through the real runtime").option("--input <json>", "JSON object input for the action").option("--json", "Output JSON", false).action(async (target, actionName, opts) => appCall.call(target, actionName, opts));
|
|
4596
|
+
app.command("restart <app-id>").description("Restart a live Service App runtime in the running NextClaw UI").option("--json", "Output JSON", false).action(async (appId, opts) => appRestart.restart(appId, opts));
|
|
4428
4597
|
}
|
|
4429
4598
|
//#endregion
|
|
4430
4599
|
//#region src/cli/app/index.ts
|