@clawos-dev/clawd 0.2.460 → 0.2.461
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/app-builder-plugin/mcp-server.cjs +115 -1
- package/dist/cli.cjs +1242 -608
- package/dist/dispatch/mcp-server.cjs +38 -0
- package/dist/share-md-viewer-error.html +1 -1
- package/dist/share-md-viewer.html +1 -1
- package/dist/share-ui/assets/{guest-CC5Z0Nwd.js → guest-0upTtqLX.js} +114 -114
- package/dist/share-ui/assets/guest-B3t_VaRM.css +32 -0
- package/dist/share-ui/guest.html +2 -2
- package/package.json +1 -1
- package/dist/share-ui/assets/guest-GnZTCQ46.css +0 -32
|
@@ -6893,6 +6893,7 @@ __export(mcp_server_exports, {
|
|
|
6893
6893
|
handleCreateProject: () => handleCreateProject,
|
|
6894
6894
|
handleListProjects: () => handleListProjects,
|
|
6895
6895
|
handlePublish: () => handlePublish,
|
|
6896
|
+
handleRemoveProject: () => handleRemoveProject,
|
|
6896
6897
|
handleReportStage: () => handleReportStage,
|
|
6897
6898
|
handleSetProdUrl: () => handleSetProdUrl,
|
|
6898
6899
|
handleStartDevServer: () => handleStartDevServer,
|
|
@@ -21361,6 +21362,19 @@ var DeployGapSchema = external_exports.object({
|
|
|
21361
21362
|
// 建议补的依赖:`cli:python3` 这种。拿不准就不给,让人自己决定。
|
|
21362
21363
|
suggest: external_exports.string().optional()
|
|
21363
21364
|
}).strict();
|
|
21365
|
+
var DeployPlacementSchema = external_exports.object({
|
|
21366
|
+
/** gateway 的公网地址(入口 A 直接 POST 它;入口 B 由设备目录下发 ws 地址) */
|
|
21367
|
+
gatewayUrl: external_exports.string().min(1),
|
|
21368
|
+
/** 服务设备 id:别人的 clawd 用 `device:connect { deviceId }` 就能连上,本机侧零改动 */
|
|
21369
|
+
serviceDeviceId: external_exports.string().min(1),
|
|
21370
|
+
/** 这次登记为正式的镜像 tag(= 试装通过的那个) */
|
|
21371
|
+
image: external_exports.string().min(1),
|
|
21372
|
+
/** 使用者自带的凭据名字(= 单据里 fulfillment 选了 'user' 的那些)。**只有名字** */
|
|
21373
|
+
userSecrets: external_exports.array(external_exports.string()).default([]),
|
|
21374
|
+
/** 是否进公共设备目录。false = 只有拿到 deviceId 的人连得上 */
|
|
21375
|
+
publicDirectory: external_exports.boolean(),
|
|
21376
|
+
deployedAt: external_exports.number()
|
|
21377
|
+
}).strict();
|
|
21364
21378
|
var DeployReceiptSchema = external_exports.object({
|
|
21365
21379
|
deployId: external_exports.string().min(1),
|
|
21366
21380
|
personaId: external_exports.string().min(1),
|
|
@@ -21386,6 +21400,23 @@ var DeployReceiptSchema = external_exports.object({
|
|
|
21386
21400
|
fulfillment: external_exports.record(external_exports.string(), FulfillmentSchema).default({}),
|
|
21387
21401
|
/** 试装失败时的缺口清单;成功或没试装过是空数组 */
|
|
21388
21402
|
gaps: external_exports.array(DeployGapSchema).default([]),
|
|
21403
|
+
/** 试装跑到第几轮了(每次 deploy:trial +1,上限 TRIAL_ROUND_MAX)。重扫清零 */
|
|
21404
|
+
trialRound: external_exports.number().default(0),
|
|
21405
|
+
/**
|
|
21406
|
+
* 试装当前在哪一步的一句人话(「在构镜像」「冒烟任务跑起来了」)。
|
|
21407
|
+
* 单据页要的是「到哪一步了」,不是逐 token 的过程——过程在 gateway 的任务台账里。
|
|
21408
|
+
*/
|
|
21409
|
+
trialStage: external_exports.string().optional(),
|
|
21410
|
+
/**
|
|
21411
|
+
* 上一次试装通过的时刻。**deploy:deploy 的前置**——没试装过不让部署,那正是试装存在的理由。
|
|
21412
|
+
* 试装通过后单据回 `ready` 而不是直接 `deployed`:试装的产物是一个用完即弃的镜像,
|
|
21413
|
+
* 部署的产物是一个别人能派活的服务,中间那次决定得留给人。
|
|
21414
|
+
*/
|
|
21415
|
+
trialPassedAt: external_exports.number().optional(),
|
|
21416
|
+
/** 试装通过的那个镜像 tag;deploy:deploy 登记的就是它,不重新构一遍 */
|
|
21417
|
+
trialImage: external_exports.string().optional(),
|
|
21418
|
+
/** 部署落点(status 是 deployed 才有) */
|
|
21419
|
+
placement: DeployPlacementSchema.optional(),
|
|
21389
21420
|
// 扫描 / 试装失败的原因(status 是 scanFailed / failed 时才有意义)
|
|
21390
21421
|
error: external_exports.string().optional(),
|
|
21391
21422
|
createdAt: external_exports.number(),
|
|
@@ -23929,6 +23960,14 @@ var METHOD_DOCS = {
|
|
|
23929
23960
|
summary: "butler \u6536\u5C3E\uFF1A\u7ED9\u51FA\u5192\u70DF\u4EFB\u52A1\u4E0E\u5B58\u7591\u9879\uFF0C\u5355\u636E\u4ECE scanning \u8F6C draft\u3002\u6CA1\u8C03\u5230\u5B83\u5C31\u7B49\u4E8E\u6CA1\u626B\u5B8C\u2014\u2014butler \u4F1A\u8BDD\u7ED3\u675F\u65F6\u5355\u636E\u8FD8\u505C\u5728 scanning\uFF0Cdaemon \u636E\u6B64\u5224 scanFailed\uFF1Bowner-only",
|
|
23930
23961
|
args: DeployFinishScanArgsSchema
|
|
23931
23962
|
},
|
|
23963
|
+
"deploy:trial": {
|
|
23964
|
+
summary: "\u8D77\u4E00\u6B21\u8BD5\u88C5\uFF1A**\u4E00\u6B21\u5E26\u81EA\u6BC1\u7684\u771F\u90E8\u7F72**\u2014\u2014\u6309\u5355\u636E\u7684\u6E05\u5355\u6784\u955C\u50CF \u2192 \u63A8\u8FDB k3s \u2192 \u7ECF gateway \u6295\u5582\u5355\u636E\u4E0A\u90A3\u6761\u5192\u70DF\u4EFB\u52A1 \u2192 \u8BA9 persona \u7528\u81EA\u5DF1\u7684\u65B9\u5F0F\u5E72 \u2192 \u8DD1\u5B8C\u8BA9\u5B83\u628A\u5EFA\u51FA\u6765\u7684\u4E1C\u897F\u62C6\u6389\u3002\u524D\u7F6E\u662F `ready`\uFF08\u5C65\u7EA6\u90FD\u9009\u4E86\u3001\u9009\u4E86\u300C\u6211\u6765\u63D0\u4F9B\u300D\u7684\u51ED\u636E\u90FD\u586B\u9F50\u4E86\uFF09\uFF0C\u7F3A\u54EA\u6761\u4F1A\u5728\u9519\u8BEF\u91CC\u70B9\u540D\uFF1B\u8DD1\u51E0\u5341\u5206\u949F\uFF0C\u6240\u4EE5 RPC \u79D2\u56DE `trialing` \u6001\u5355\u636E\uFF0C\u7ED3\u679C\u7531\u540E\u53F0\u56DE\u5199\uFF08UI \u8F6E\u8BE2\uFF09\u3002\u901A\u8FC7 \u2192 \u56DE `ready` \u5E76\u8BB0\u4E0B trialPassedAt\uFF08\u90E8\u7F72\u662F\u4EBA\u7684\u7B2C\u4E8C\u6B21\u51B3\u5B9A\uFF09\uFF1B\u6CA1\u8FC7 \u2192 `failed` + gaps\uFF08agent \u7684\u4EBA\u8BDD\u9519\u56E0\uFF09\uFF0C\u6539\u5B8C\u6E05\u5355\u518D\u8C03\u4E00\u6B21\u5373\u53EF\u3002\u8F6E\u6B21\u6709\u4E0A\u9650\uFF1Bowner-only",
|
|
23965
|
+
args: DeployIdArgsSchema
|
|
23966
|
+
},
|
|
23967
|
+
"deploy:deploy": {
|
|
23968
|
+
summary: "\u628A\u8BD5\u88C5\u901A\u8FC7\u7684\u90A3\u4E2A\u955C\u50CF\u5728 gateway \u767B\u8BB0\u4E3A**\u6B63\u5F0F**\u90E8\u7F72\uFF1A\u4E4B\u540E\u522B\u4EBA\u7684 clawd \u6D3E\u6D3B\u7ED9\u8FD9\u4E2A\u670D\u52A1\u8BBE\u5907\uFF0C\u8D77\u7684\u5C31\u662F\u5B83\u3002\u524D\u7F6E\u662F\u8BD5\u88C5\u901A\u8FC7\u8FC7\uFF08\u6CA1\u9A8C\u8FC7\u4E0D\u8BA9\u53D1\uFF0C\u90A3\u6B63\u662F\u8BD5\u88C5\u5B58\u5728\u7684\u7406\u7531\uFF09\u3002\u56DE\u6765\u7684\u5355\u636E\u5E26 placement\u2014\u2014\u4E91\u4E0A\u5730\u5740 / \u670D\u52A1\u8BBE\u5907 id / \u8C01\u53EF\u8C03\u7528 / \u4F7F\u7528\u8005\u9700\u81EA\u5E26\u54EA\u4E9B\u51ED\u636E\uFF1Bowner-only",
|
|
23969
|
+
args: DeployIdArgsSchema
|
|
23970
|
+
},
|
|
23932
23971
|
"deploy:remove": {
|
|
23933
23972
|
summary: "\u5220\u6389\u4E00\u5F20\u90E8\u7F72\u5355\uFF0C\u8FDE\u5E26\u6E05\u6389\u5B83\u7684\u5168\u90E8\u51ED\u636E\u503C\uFF08\u503C\u4E0D\u8BE5\u6BD4\u5355\u636E\u6D3B\u5F97\u4E45\uFF09\uFF1Bowner-only",
|
|
23934
23973
|
args: DeployIdArgsSchema
|
|
@@ -24673,6 +24712,9 @@ var ProjectStore = class {
|
|
|
24673
24712
|
}
|
|
24674
24713
|
};
|
|
24675
24714
|
|
|
24715
|
+
// src/app-builder-plugin/core.ts
|
|
24716
|
+
var import_node_child_process3 = require("child_process");
|
|
24717
|
+
|
|
24676
24718
|
// src/app-builder-plugin/publish-registry.ts
|
|
24677
24719
|
var import_node_crypto = require("crypto");
|
|
24678
24720
|
var PublishJobRegistry = class {
|
|
@@ -25085,6 +25127,38 @@ async function createProjectOnDisk(args) {
|
|
|
25085
25127
|
}
|
|
25086
25128
|
return { project, projectDir: store.projectDir(name) };
|
|
25087
25129
|
}
|
|
25130
|
+
var REMOVE_TIMEOUT_MS = 10 * 6e4;
|
|
25131
|
+
async function runRemoveExtension(args) {
|
|
25132
|
+
const spawnFn = args.spawnImpl ?? import_node_child_process3.spawn;
|
|
25133
|
+
return await new Promise((resolve, reject) => {
|
|
25134
|
+
const child = spawnFn("bash", [args.script, args.projectDir, args.personaRoot], {
|
|
25135
|
+
// 凭据在 process.env 里(gateway → MCP server 的 per-server env → 本进程)
|
|
25136
|
+
env: process.env,
|
|
25137
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
25138
|
+
});
|
|
25139
|
+
let stdout = "";
|
|
25140
|
+
let stderr = "";
|
|
25141
|
+
child.stdout?.on("data", (d) => {
|
|
25142
|
+
stdout += d.toString("utf8");
|
|
25143
|
+
});
|
|
25144
|
+
child.stderr?.on("data", (d) => {
|
|
25145
|
+
stderr += d.toString("utf8");
|
|
25146
|
+
});
|
|
25147
|
+
const timer = setTimeout(() => {
|
|
25148
|
+
child.kill("SIGKILL");
|
|
25149
|
+
reject(new Error(`remove-extension timeout (>${REMOVE_TIMEOUT_MS}ms): ${args.projectDir}`));
|
|
25150
|
+
}, REMOVE_TIMEOUT_MS);
|
|
25151
|
+
child.on("error", (err) => {
|
|
25152
|
+
clearTimeout(timer);
|
|
25153
|
+
reject(new Error(`remove-extension spawn failed: ${err.message}`));
|
|
25154
|
+
});
|
|
25155
|
+
child.on("exit", (code) => {
|
|
25156
|
+
clearTimeout(timer);
|
|
25157
|
+
args.logger?.info("app-builder.remove.exit", { projectDir: args.projectDir, code });
|
|
25158
|
+
resolve({ code, stdout, stderr });
|
|
25159
|
+
});
|
|
25160
|
+
});
|
|
25161
|
+
}
|
|
25088
25162
|
|
|
25089
25163
|
// src/app-builder-plugin/mcp-server.ts
|
|
25090
25164
|
var LOG_PATH = process.env.CLAWD_APP_BUILDER_LOG;
|
|
@@ -25117,7 +25191,8 @@ function readEnv(env = process.env) {
|
|
|
25117
25191
|
...env.CLAWD_APP_BUILDER_TEMPLATE_DIR ? { templateDir: env.CLAWD_APP_BUILDER_TEMPLATE_DIR } : {},
|
|
25118
25192
|
...env.CLAWD_APP_BUILDER_SCAFFOLD_SCRIPT ? { scaffoldScript: env.CLAWD_APP_BUILDER_SCAFFOLD_SCRIPT } : {},
|
|
25119
25193
|
...env.CLAWD_APP_BUILDER_PUBLISH_SCRIPT ? { publishScript: env.CLAWD_APP_BUILDER_PUBLISH_SCRIPT } : {},
|
|
25120
|
-
...env.CLAWD_APP_BUILDER_PERSONA_ROOT ? { personaRoot: env.CLAWD_APP_BUILDER_PERSONA_ROOT } : {}
|
|
25194
|
+
...env.CLAWD_APP_BUILDER_PERSONA_ROOT ? { personaRoot: env.CLAWD_APP_BUILDER_PERSONA_ROOT } : {},
|
|
25195
|
+
...env.CLAWD_APP_BUILDER_REMOVE_SCRIPT ? { removeScript: env.CLAWD_APP_BUILDER_REMOVE_SCRIPT } : {}
|
|
25121
25196
|
};
|
|
25122
25197
|
}
|
|
25123
25198
|
function hasDaemon(env) {
|
|
@@ -25278,6 +25353,35 @@ ${outcome.errorSummary}`));
|
|
|
25278
25353
|
}
|
|
25279
25354
|
return await done;
|
|
25280
25355
|
}
|
|
25356
|
+
async function handleRemoveProject(input, ctx) {
|
|
25357
|
+
if (hasDaemon(ctx.env)) {
|
|
25358
|
+
return fail(
|
|
25359
|
+
'removeProject is cloud-only. On this host run the script yourself:\n bash "$HOME/.clawd/deploy-kit/scripts/remove-extension.sh" <projectDir> <personaRoot>'
|
|
25360
|
+
);
|
|
25361
|
+
}
|
|
25362
|
+
const { removeScript, personaRoot } = ctx.env;
|
|
25363
|
+
if (!removeScript) {
|
|
25364
|
+
return fail("removeProject: no daemon, and CLAWD_APP_BUILDER_REMOVE_SCRIPT is not set.");
|
|
25365
|
+
}
|
|
25366
|
+
const store = storeOf(ctx.env);
|
|
25367
|
+
try {
|
|
25368
|
+
const projectDir = store.projectDir(input.name);
|
|
25369
|
+
const r = await runRemoveExtension({
|
|
25370
|
+
script: removeScript,
|
|
25371
|
+
projectDir,
|
|
25372
|
+
personaRoot: personaRoot ?? "",
|
|
25373
|
+
logger: { info: (m, i) => log(m, i), warn: (m, i) => log(m, i) }
|
|
25374
|
+
});
|
|
25375
|
+
const text = `exit=${r.code}
|
|
25376
|
+
--- stdout ---
|
|
25377
|
+
${r.stdout}
|
|
25378
|
+
--- stderr ---
|
|
25379
|
+
${r.stderr}`;
|
|
25380
|
+
return r.code === 0 ? ok(text) : fail(text);
|
|
25381
|
+
} catch (err) {
|
|
25382
|
+
return fail(`removeProject failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
25383
|
+
}
|
|
25384
|
+
}
|
|
25281
25385
|
function registerTools(server, ctx) {
|
|
25282
25386
|
server.registerTool(
|
|
25283
25387
|
"createProject",
|
|
@@ -25353,6 +25457,15 @@ function registerTools(server, ctx) {
|
|
|
25353
25457
|
},
|
|
25354
25458
|
async (input) => handlePublish(input, ctx)
|
|
25355
25459
|
);
|
|
25460
|
+
server.registerTool(
|
|
25461
|
+
"removeProject",
|
|
25462
|
+
{
|
|
25463
|
+
title: "Tear down a published project",
|
|
25464
|
+
description: "Tear down everything a published project created (FC function / trigger / custom domain, plus the DROP statements for its Supabase tables). Cloud-only: on a host with a local daemon this returns the shell command to run yourself instead. Returns the script output verbatim \u2014 read it, it may ask you to run a few DROPs through the supabase MCP to finish the job.",
|
|
25465
|
+
inputSchema: { name: external_exports.string().min(1).describe("project name") }
|
|
25466
|
+
},
|
|
25467
|
+
async (input) => handleRemoveProject(input, ctx)
|
|
25468
|
+
);
|
|
25356
25469
|
}
|
|
25357
25470
|
async function main() {
|
|
25358
25471
|
const env = readEnv();
|
|
@@ -25379,6 +25492,7 @@ if (isMainModule) {
|
|
|
25379
25492
|
handleCreateProject,
|
|
25380
25493
|
handleListProjects,
|
|
25381
25494
|
handlePublish,
|
|
25495
|
+
handleRemoveProject,
|
|
25382
25496
|
handleReportStage,
|
|
25383
25497
|
handleSetProdUrl,
|
|
25384
25498
|
handleStartDevServer,
|