nextclaw 0.33.1 → 0.34.0
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 +183 -11
- package/dist/cli/app/index.js.map +1 -1
- package/package.json +13 -12
- package/resources/USAGE.md +29 -0
- package/resources/apps/nextclaw-personal-organizer/manifest.json +1 -1
- package/resources/apps/nextclaw-personal-organizer/panels/nextclaw-personal-organizer-calendar.panel/assets/app.js +8 -0
- package/resources/apps/nextclaw-personal-organizer/panels/nextclaw-personal-organizer-calendar.panel/assets/icon.svg +6 -0
- package/resources/apps/nextclaw-personal-organizer/panels/nextclaw-personal-organizer-calendar.panel/assets/style.css +2 -0
- package/resources/apps/nextclaw-personal-organizer/panels/nextclaw-personal-organizer-calendar.panel/index.html +10 -21
- package/resources/apps/nextclaw-personal-organizer/panels/nextclaw-personal-organizer-calendar.panel/panel-app.json +4 -4
- package/resources/apps/nextclaw-personal-organizer/panels/nextclaw-personal-organizer-todos.panel/assets/app.js +8 -0
- package/resources/apps/nextclaw-personal-organizer/panels/nextclaw-personal-organizer-todos.panel/assets/icon.svg +4 -0
- package/resources/apps/nextclaw-personal-organizer/panels/nextclaw-personal-organizer-todos.panel/assets/style.css +2 -0
- package/resources/apps/nextclaw-personal-organizer/panels/nextclaw-personal-organizer-todos.panel/index.html +10 -40
- package/resources/apps/nextclaw-personal-organizer/panels/nextclaw-personal-organizer-todos.panel/panel-app.json +4 -4
- package/resources/apps/nextclaw-personal-organizer/service-components/nextclaw-personal-organizer-data/index.mjs +44 -18
- package/ui-dist/assets/{appearance-settings-page-DlGXLgff.js → appearance-settings-page-Bpd2RhK5.js} +1 -1
- package/ui-dist/assets/{channels-list-page-BEEk4Uc9.js → channels-list-page-CTblam4c.js} +2 -2
- package/ui-dist/assets/chat-page-Bg3_X8G9.js +1 -0
- package/ui-dist/assets/{desktop-update-config--zagjHic.js → desktop-update-config-D9AyIhJZ.js} +1 -1
- package/ui-dist/assets/index-VQAVqwG8.js +109 -0
- package/ui-dist/assets/{model-config-page-rrhFaque.js → model-config-page-B8Aubkwx.js} +1 -1
- package/ui-dist/assets/{provider-scoped-model-input-CFsfWEt9.js → provider-scoped-model-input-BRnIH-5O.js} +1 -1
- package/ui-dist/assets/providers-config-page-0r9AZNNZ.js +1 -0
- package/ui-dist/assets/remote-DQzE55WW.js +1 -0
- package/ui-dist/assets/runtime-config-page-BgeYpvMK.js +1 -0
- package/ui-dist/assets/{search-config-page-B3fvzMd1.js → search-config-page-CzNzLyd0.js} +1 -1
- package/ui-dist/assets/{secrets-config-page-ClwTxtXd.js → secrets-config-page-C4k3ik0v.js} +2 -2
- package/ui-dist/index.html +1 -1
- package/ui-dist/assets/chat-page-DUQXXqQm.js +0 -1
- package/ui-dist/assets/index-Ba_o5fu9.js +0 -109
- package/ui-dist/assets/providers-config-page-D-TYFZsF.js +0 -1
- package/ui-dist/assets/remote-BwVv_Qq-.js +0 -1
- package/ui-dist/assets/runtime-config-page-Br9j9Vxe.js +0 -1
package/dist/cli/app/index.js
CHANGED
|
@@ -7,11 +7,13 @@ import { constants, existsSync, mkdirSync, readFileSync, writeFileSync } from "n
|
|
|
7
7
|
import { randomBytes } from "node:crypto";
|
|
8
8
|
import { execFile } from "node:child_process";
|
|
9
9
|
import path, { join, resolve } from "node:path";
|
|
10
|
+
import { tmpdir } from "node:os";
|
|
10
11
|
import "@nextclaw/server";
|
|
11
12
|
import { NextclawDistributionService, NextclawServiceRuntime, readLearningLoopRuntimeConfig } from "@nextclaw/service";
|
|
13
|
+
import { access, mkdtemp, readFile, rm, stat } from "node:fs/promises";
|
|
12
14
|
import { McpServiceAppRuntimeService, buildServiceActionId, getServiceAppManifestPath, mergeServiceAppRuntimeActions, readServiceAppManifest } from "@nextclaw/kernel";
|
|
13
|
-
import { access, readFile, stat } from "node:fs/promises";
|
|
14
15
|
import { promisify } from "node:util";
|
|
16
|
+
import { AppPublishService, AppPublishValidationService } from "@nextclaw/app-runtime";
|
|
15
17
|
var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
16
18
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
17
19
|
//#endregion
|
|
@@ -3641,13 +3643,14 @@ var ServiceAppDevService = class {
|
|
|
3641
3643
|
if (!loaded) return this.buildDevReport(appPath, void 0, [], issues);
|
|
3642
3644
|
if (this.hasErrors(issues)) return this.buildDevReport(appPath, this.toServiceAppRecord(appPath, loaded.manifest, this.idleRuntimeStatus), [], issues);
|
|
3643
3645
|
const runtime = this.createRuntimeService();
|
|
3646
|
+
const dataDirectory = await this.createDevDataDirectory();
|
|
3644
3647
|
try {
|
|
3645
|
-
const startRecord = this.toServiceAppRecord(appPath, loaded.manifest, runtime);
|
|
3648
|
+
const startRecord = this.toServiceAppRecord(appPath, loaded.manifest, runtime, dataDirectory);
|
|
3646
3649
|
const runtimeActions = await runtime.listActions({
|
|
3647
3650
|
app: startRecord,
|
|
3648
3651
|
manifest: loaded.manifest
|
|
3649
3652
|
});
|
|
3650
|
-
const record = this.toServiceAppRecord(appPath, loaded.manifest, runtime);
|
|
3653
|
+
const record = this.toServiceAppRecord(appPath, loaded.manifest, runtime, dataDirectory);
|
|
3651
3654
|
const actions = mergeServiceAppRuntimeActions({
|
|
3652
3655
|
record,
|
|
3653
3656
|
manifest: loaded.manifest,
|
|
@@ -3656,7 +3659,14 @@ var ServiceAppDevService = class {
|
|
|
3656
3659
|
this.collectRuntimeIssues(record, actions, issues);
|
|
3657
3660
|
return this.buildDevReport(appPath, record, actions, issues);
|
|
3658
3661
|
} finally {
|
|
3659
|
-
|
|
3662
|
+
try {
|
|
3663
|
+
await runtime.dispose();
|
|
3664
|
+
} finally {
|
|
3665
|
+
await rm(dataDirectory, {
|
|
3666
|
+
recursive: true,
|
|
3667
|
+
force: true
|
|
3668
|
+
});
|
|
3669
|
+
}
|
|
3660
3670
|
}
|
|
3661
3671
|
};
|
|
3662
3672
|
call = async (target, actionName, input) => {
|
|
@@ -3676,18 +3686,19 @@ var ServiceAppDevService = class {
|
|
|
3676
3686
|
return this.buildCallReport(appPath, record, void 0, void 0, issues);
|
|
3677
3687
|
}
|
|
3678
3688
|
const runtime = this.createRuntimeService();
|
|
3689
|
+
const dataDirectory = await this.createDevDataDirectory();
|
|
3679
3690
|
try {
|
|
3680
|
-
const record = this.toServiceAppRecord(appPath, loaded.manifest, runtime);
|
|
3691
|
+
const record = this.toServiceAppRecord(appPath, loaded.manifest, runtime, dataDirectory);
|
|
3681
3692
|
const result = await runtime.invokeAction({
|
|
3682
3693
|
app: record,
|
|
3683
3694
|
manifest: loaded.manifest,
|
|
3684
3695
|
actionName: action,
|
|
3685
3696
|
input
|
|
3686
3697
|
});
|
|
3687
|
-
const nextRecord = this.toServiceAppRecord(appPath, loaded.manifest, runtime);
|
|
3698
|
+
const nextRecord = this.toServiceAppRecord(appPath, loaded.manifest, runtime, dataDirectory);
|
|
3688
3699
|
return this.buildCallReport(appPath, nextRecord, buildServiceActionId(loaded.manifest.id, action), result, issues);
|
|
3689
3700
|
} catch (error) {
|
|
3690
|
-
const record = this.toServiceAppRecord(appPath, loaded.manifest, runtime);
|
|
3701
|
+
const record = this.toServiceAppRecord(appPath, loaded.manifest, runtime, dataDirectory);
|
|
3691
3702
|
issues.push({
|
|
3692
3703
|
severity: "error",
|
|
3693
3704
|
code: "service.runtime.callFailed",
|
|
@@ -3695,7 +3706,14 @@ var ServiceAppDevService = class {
|
|
|
3695
3706
|
});
|
|
3696
3707
|
return this.buildCallReport(appPath, record, buildServiceActionId(loaded.manifest.id, action), void 0, issues);
|
|
3697
3708
|
} finally {
|
|
3698
|
-
|
|
3709
|
+
try {
|
|
3710
|
+
await runtime.dispose();
|
|
3711
|
+
} finally {
|
|
3712
|
+
await rm(dataDirectory, {
|
|
3713
|
+
recursive: true,
|
|
3714
|
+
force: true
|
|
3715
|
+
});
|
|
3716
|
+
}
|
|
3699
3717
|
}
|
|
3700
3718
|
};
|
|
3701
3719
|
loadServiceApp = async (appPath, issues) => {
|
|
@@ -3727,7 +3745,8 @@ var ServiceAppDevService = class {
|
|
|
3727
3745
|
return resolveConfigSecrets(loadConfig(configPath), { configPath });
|
|
3728
3746
|
};
|
|
3729
3747
|
idleRuntimeStatus = { getStatus: () => ({ status: "idle" }) };
|
|
3730
|
-
|
|
3748
|
+
createDevDataDirectory = async () => await mkdtemp(path.join(tmpdir(), "nextclaw-service-app-dev-data-"));
|
|
3749
|
+
toServiceAppRecord = (dirPath, manifest, runtime, dataDirectory) => {
|
|
3731
3750
|
const runtimeStatus = runtime.getStatus(manifest.id);
|
|
3732
3751
|
const record = {
|
|
3733
3752
|
id: manifest.id,
|
|
@@ -3739,7 +3758,8 @@ var ServiceAppDevService = class {
|
|
|
3739
3758
|
cwd: dirPath,
|
|
3740
3759
|
enabled: manifest.enabled,
|
|
3741
3760
|
protocol: manifest.protocol,
|
|
3742
|
-
status: manifest.enabled ? runtimeStatus.status : "stopped"
|
|
3761
|
+
status: manifest.enabled ? runtimeStatus.status : "stopped",
|
|
3762
|
+
dataDirectory
|
|
3743
3763
|
};
|
|
3744
3764
|
if (manifest.description) record.description = manifest.description;
|
|
3745
3765
|
if (runtimeStatus.lastError) record.lastError = runtimeStatus.lastError;
|
|
@@ -4588,13 +4608,165 @@ var AppRestartCommandController = class {
|
|
|
4588
4608
|
};
|
|
4589
4609
|
};
|
|
4590
4610
|
//#endregion
|
|
4611
|
+
//#region src/cli/app/services/app-publishing.service.ts
|
|
4612
|
+
var AppPublishingService = class {
|
|
4613
|
+
constructor(validationService = new AppPublishValidationService(), publishService = new AppPublishService()) {
|
|
4614
|
+
this.validationService = validationService;
|
|
4615
|
+
this.publishService = publishService;
|
|
4616
|
+
}
|
|
4617
|
+
validate = async (params) => {
|
|
4618
|
+
const result = await this.validationService.validate({
|
|
4619
|
+
appDirectory: params.appDirectory,
|
|
4620
|
+
metadataPath: params.metadataPath,
|
|
4621
|
+
mode: "bundle"
|
|
4622
|
+
});
|
|
4623
|
+
if (result.profile !== "components") throw new Error("nextclaw app publish 只支持由 Panel App 或 Service App 组成的 schema v2 Mini App。");
|
|
4624
|
+
if (result.distributionMode !== "bundle") throw new Error("NextClaw Mini App 只支持 bundle 分发。");
|
|
4625
|
+
return result;
|
|
4626
|
+
};
|
|
4627
|
+
publish = async (params) => {
|
|
4628
|
+
const validation = await this.validate(params);
|
|
4629
|
+
if (validation.warnings.length > 0 && !params.allowWarnings) {
|
|
4630
|
+
const warningList = validation.warnings.map((warning) => `[${warning.code}] ${warning.message}`).join("; ");
|
|
4631
|
+
throw new Error(`发布校验包含警告:${warningList}。确认后可使用 --allow-warnings 继续。`);
|
|
4632
|
+
}
|
|
4633
|
+
const tempDirectory = await mkdtemp(path.join(tmpdir(), "nextclaw-app-publish-"));
|
|
4634
|
+
try {
|
|
4635
|
+
const result = await this.publishService.publish({
|
|
4636
|
+
appDirectory: params.appDirectory,
|
|
4637
|
+
metadataPath: params.metadataPath,
|
|
4638
|
+
bundleOutputPath: path.join(tempDirectory, "artifact.napp"),
|
|
4639
|
+
mode: "bundle"
|
|
4640
|
+
});
|
|
4641
|
+
const { item } = result;
|
|
4642
|
+
return {
|
|
4643
|
+
validation,
|
|
4644
|
+
publish: {
|
|
4645
|
+
created: result.created,
|
|
4646
|
+
item: {
|
|
4647
|
+
slug: item.slug,
|
|
4648
|
+
appId: item.appId,
|
|
4649
|
+
ownerScope: item.ownerScope,
|
|
4650
|
+
appName: item.appName,
|
|
4651
|
+
publishStatus: item.publishStatus,
|
|
4652
|
+
name: item.name,
|
|
4653
|
+
latestVersion: item.latestVersion,
|
|
4654
|
+
webUrl: item.publishStatus === "published" ? item.webUrl : void 0
|
|
4655
|
+
},
|
|
4656
|
+
fileCount: result.fileCount
|
|
4657
|
+
}
|
|
4658
|
+
};
|
|
4659
|
+
} catch (error) {
|
|
4660
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4661
|
+
throw new Error(message.replace(/缺少 marketplace publish token。请先登录 NextClaw,或传入 --token。?/g, "发布需要 NextClaw 平台登录态。请先运行 nextclaw login。").replace(/,或传入 --token。?/g, "。"));
|
|
4662
|
+
} finally {
|
|
4663
|
+
await rm(tempDirectory, {
|
|
4664
|
+
recursive: true,
|
|
4665
|
+
force: true
|
|
4666
|
+
});
|
|
4667
|
+
}
|
|
4668
|
+
};
|
|
4669
|
+
};
|
|
4670
|
+
//#endregion
|
|
4671
|
+
//#region src/cli/app/controllers/app-publish-command.controller.ts
|
|
4672
|
+
const PLATFORM_APPS_URL = "https://platform.nextclaw.io/apps";
|
|
4673
|
+
var AppPublishCommandController = class {
|
|
4674
|
+
constructor(appPublishingService = new AppPublishingService()) {
|
|
4675
|
+
this.appPublishingService = appPublishingService;
|
|
4676
|
+
}
|
|
4677
|
+
publish = async (target, options) => {
|
|
4678
|
+
const { allowWarnings, json, meta } = options;
|
|
4679
|
+
try {
|
|
4680
|
+
const result = await this.appPublishingService.publish({
|
|
4681
|
+
appDirectory: target,
|
|
4682
|
+
metadataPath: meta,
|
|
4683
|
+
allowWarnings
|
|
4684
|
+
});
|
|
4685
|
+
process.stdout.write(json ? `${JSON.stringify({
|
|
4686
|
+
ok: true,
|
|
4687
|
+
...result
|
|
4688
|
+
}, null, 2)}\n` : this.format(result));
|
|
4689
|
+
} catch (error) {
|
|
4690
|
+
this.writeError(error, Boolean(json));
|
|
4691
|
+
process.exitCode = 1;
|
|
4692
|
+
}
|
|
4693
|
+
};
|
|
4694
|
+
format = (result) => {
|
|
4695
|
+
const { item } = result.publish;
|
|
4696
|
+
if (item.publishStatus === "pending") return [
|
|
4697
|
+
`Submitted ${item.name} (${item.appId}) ${item.latestVersion} for review.`,
|
|
4698
|
+
"Status: pending",
|
|
4699
|
+
"The app will appear in the App Marketplace after approval.",
|
|
4700
|
+
`Manage submissions: ${PLATFORM_APPS_URL}`,
|
|
4701
|
+
""
|
|
4702
|
+
].join("\n");
|
|
4703
|
+
return [
|
|
4704
|
+
`${result.publish.created ? "Published" : "Updated"} ${item.name} (${item.appId}) ${item.latestVersion}.`,
|
|
4705
|
+
"Status: published",
|
|
4706
|
+
item.webUrl ? `Details: ${item.webUrl}` : "",
|
|
4707
|
+
`Manage apps: ${PLATFORM_APPS_URL}`,
|
|
4708
|
+
""
|
|
4709
|
+
].filter((line, index, lines) => line || index === lines.length - 1).join("\n");
|
|
4710
|
+
};
|
|
4711
|
+
writeError = (error, json) => {
|
|
4712
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4713
|
+
process.stdout.write(json ? `${JSON.stringify({
|
|
4714
|
+
ok: false,
|
|
4715
|
+
error: { message }
|
|
4716
|
+
}, null, 2)}\n` : `Mini App publish failed: ${message}\n`);
|
|
4717
|
+
};
|
|
4718
|
+
};
|
|
4719
|
+
//#endregion
|
|
4720
|
+
//#region src/cli/app/controllers/app-validate-publish-command.controller.ts
|
|
4721
|
+
var AppValidatePublishCommandController = class {
|
|
4722
|
+
constructor(appPublishingService = new AppPublishingService()) {
|
|
4723
|
+
this.appPublishingService = appPublishingService;
|
|
4724
|
+
}
|
|
4725
|
+
validate = async (target, options) => {
|
|
4726
|
+
try {
|
|
4727
|
+
const validation = await this.appPublishingService.validate({
|
|
4728
|
+
appDirectory: target,
|
|
4729
|
+
metadataPath: options.meta
|
|
4730
|
+
});
|
|
4731
|
+
process.stdout.write(options.json ? `${JSON.stringify({
|
|
4732
|
+
ok: true,
|
|
4733
|
+
validation
|
|
4734
|
+
}, null, 2)}\n` : this.format(validation));
|
|
4735
|
+
} catch (error) {
|
|
4736
|
+
this.writeError(error, Boolean(options.json));
|
|
4737
|
+
process.exitCode = 1;
|
|
4738
|
+
}
|
|
4739
|
+
};
|
|
4740
|
+
format = (validation) => {
|
|
4741
|
+
const lines = [
|
|
4742
|
+
`Mini App publish validation passed: ${validation.appId}@${validation.version}`,
|
|
4743
|
+
`Components: ${validation.componentCount ?? 0}`,
|
|
4744
|
+
`Bundle size: ${validation.bundleSizeBytes} bytes`,
|
|
4745
|
+
`Metadata: ${validation.metadataPath}`
|
|
4746
|
+
];
|
|
4747
|
+
for (const warning of validation.warnings) lines.push(`Warning [${warning.code}]: ${warning.message}`);
|
|
4748
|
+
return `${lines.join("\n")}\n`;
|
|
4749
|
+
};
|
|
4750
|
+
writeError = (error, json) => {
|
|
4751
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4752
|
+
process.stdout.write(json ? `${JSON.stringify({
|
|
4753
|
+
ok: false,
|
|
4754
|
+
error: { message }
|
|
4755
|
+
}, null, 2)}\n` : `Mini App publish validation failed: ${message}\n`);
|
|
4756
|
+
};
|
|
4757
|
+
};
|
|
4758
|
+
//#endregion
|
|
4591
4759
|
//#region src/cli/app/register-app-commands.ts
|
|
4592
4760
|
function registerAppCommands(program) {
|
|
4593
|
-
const app = program.command("app").description("
|
|
4761
|
+
const app = program.command("app").description("Develop, validate, and publish NextClaw apps");
|
|
4594
4762
|
const appCheck = new AppCheckCommandController();
|
|
4595
4763
|
const appDev = new AppDevCommandController();
|
|
4596
4764
|
const appCall = new AppCallCommandController();
|
|
4597
4765
|
const appRestart = new AppRestartCommandController();
|
|
4766
|
+
const appValidatePublish = new AppValidatePublishCommandController();
|
|
4767
|
+
const appPublish = new AppPublishCommandController();
|
|
4768
|
+
app.command("validate-publish <app-dir>").description("Validate a NextClaw Mini App before Marketplace submission").option("--meta <path>", "Use a custom marketplace metadata file").option("--json", "Output JSON", false).action(async (target, opts) => appValidatePublish.validate(target, opts));
|
|
4769
|
+
app.command("publish <app-dir>").description("Submit a NextClaw Mini App to the App Marketplace").option("--meta <path>", "Use a custom marketplace metadata file").option("--allow-warnings", "Submit after reviewing validation warnings", false).option("--json", "Output JSON", false).action(async (target, opts) => appPublish.publish(target, opts));
|
|
4598
4770
|
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));
|
|
4599
4771
|
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));
|
|
4600
4772
|
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));
|