@clawos-dev/clawd 0.2.489 → 0.2.490
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 +36 -3
- package/dist/cli.cjs +88 -15
- package/dist/dispatch/mcp-server.cjs +36 -3
- package/dist/persona-defaults/persona-clawd-butler/.claude/skills/scan-persona-for-deploy/SKILL.md +14 -2
- package/dist/share-md-viewer-error.html +1 -1
- package/dist/share-md-viewer.html +1 -1
- package/dist/share-ui/assets/guest-BVnHMXcA.css +32 -0
- package/dist/share-ui/assets/{guest-YvAFFMko.js → guest-XUxeACMw.js} +153 -143
- package/dist/share-ui/guest.html +2 -2
- package/package.json +1 -1
- package/dist/share-ui/assets/guest-Dznm1HrZ.css +0 -32
|
@@ -21317,10 +21317,22 @@ var EnvSecretSchema = external_exports.object({
|
|
|
21317
21317
|
var EnvAssetSchema = external_exports.object({
|
|
21318
21318
|
name: external_exports.string().min(1)
|
|
21319
21319
|
});
|
|
21320
|
+
var ConnectorNameSchema = external_exports.string().regex(/^[a-z0-9-]+$/, "\u8FDE\u63A5\u5668\u540D\u53EA\u80FD\u662F\u5C0F\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u548C\u77ED\u6A2A\u7EBF");
|
|
21321
|
+
var EnvConnectorSchema = external_exports.object({ name: ConnectorNameSchema });
|
|
21320
21322
|
var MANIFEST_BODY = {
|
|
21321
21323
|
clis: external_exports.array(EnvCliSchema),
|
|
21322
21324
|
secrets: external_exports.array(EnvSecretSchema),
|
|
21323
|
-
assets: external_exports.array(EnvAssetSchema)
|
|
21325
|
+
assets: external_exports.array(EnvAssetSchema),
|
|
21326
|
+
/**
|
|
21327
|
+
* 装了哪些连接器(design 2026-09-09-cloud-connector-credentials §7.1)。**字符串数组**,
|
|
21328
|
+
* 是四段里唯一不是 `{name}` 对象数组的一段:连接器没有任何附加属性,包一层对象只是多一层壳。
|
|
21329
|
+
*
|
|
21330
|
+
* 不复用 secrets:那段说的是「需要一份值,由部署者填」,这里没有值要填;
|
|
21331
|
+
* 不从 clis 推断:lark-cli 在底座里,每个 persona 都有它,推不出任何东西。
|
|
21332
|
+
*
|
|
21333
|
+
* **缺省空而不是必填**:本机上已有的单据不用为此重扫一遍;没声明就是没装,扫描器照样会报。
|
|
21334
|
+
*/
|
|
21335
|
+
connectors: external_exports.array(ConnectorNameSchema).default([])
|
|
21324
21336
|
};
|
|
21325
21337
|
var EnvManifestBodySchema = external_exports.object(MANIFEST_BODY);
|
|
21326
21338
|
var EnvironmentManifestSchema = external_exports.object({
|
|
@@ -21453,8 +21465,9 @@ var DeployRerunJobArgsSchema = external_exports.object({
|
|
|
21453
21465
|
}).strict();
|
|
21454
21466
|
var DeployReportFindingArgsSchema = external_exports.object({
|
|
21455
21467
|
personaId: external_exports.string().min(1),
|
|
21456
|
-
kind: external_exports.enum(["cli", "secret", "asset"]),
|
|
21468
|
+
kind: external_exports.enum(["cli", "secret", "asset", "connector"]),
|
|
21457
21469
|
// 该条目在 manifest 对应数组里的内容(形状随 kind 变,handler 按 kind 收窄校验)
|
|
21470
|
+
// connector 的 item 只有 name,落进清单时只留名字(manifest.connectors 是字符串数组)
|
|
21458
21471
|
item: external_exports.record(external_exports.string(), external_exports.unknown()),
|
|
21459
21472
|
// 这条发现的来历(一句人话 + 原文出处),形状同 EnvEvidence,target 由 handler 从 kind+name 派生
|
|
21460
21473
|
evidence: external_exports.object({
|
|
@@ -21750,6 +21763,16 @@ var DispatchRecordSchema = external_exports.object({
|
|
|
21750
21763
|
sourceSessionId: external_exports.string().min(1),
|
|
21751
21764
|
sourcePersonaId: external_exports.string().min(1).optional(),
|
|
21752
21765
|
targetPersonaId: external_exports.string().min(1),
|
|
21766
|
+
/**
|
|
21767
|
+
* 跨设备派活时 B 所在的设备(`DispatchRunArgs.targetDeviceId`),A 端台账记「我派给了谁的机器」。
|
|
21768
|
+
*
|
|
21769
|
+
* **缺省即本机**,与入参侧用 `undefined` 表示本机是同一条口径——不引第二种表示法。
|
|
21770
|
+
* 存量台账行没有这个字段,消费方(dispatch 卡片的归属带)据此只显示 persona、不显示设备。
|
|
21771
|
+
*
|
|
21772
|
+
* B 端自己的台账行**不会**有它:peer-forward 转发时故意 strip 掉(B 据此判定本地执行),
|
|
21773
|
+
* 那条行记的是 B 视角的本地 dispatch。
|
|
21774
|
+
*/
|
|
21775
|
+
targetDeviceId: external_exports.string().min(1).optional(),
|
|
21753
21776
|
/** B 的 sessionId;registerBSession 后回填 */
|
|
21754
21777
|
workerSessionId: external_exports.string().min(1).optional(),
|
|
21755
21778
|
/** 任务摘要;截断(≤500 字符)在 daemon store.add 处保证 */
|
|
@@ -21776,7 +21799,17 @@ var DispatchRecordSchema = external_exports.object({
|
|
|
21776
21799
|
deliveredAt: external_exports.string().min(1).optional()
|
|
21777
21800
|
});
|
|
21778
21801
|
var DispatchListArgsSchema = external_exports.object({
|
|
21779
|
-
sourceSessionId: external_exports.string().min(1).optional()
|
|
21802
|
+
sourceSessionId: external_exports.string().min(1).optional(),
|
|
21803
|
+
/**
|
|
21804
|
+
* 「**这条会话卷入的**所有台账行」:`sourceSessionId === it || workerSessionId === it`。
|
|
21805
|
+
*
|
|
21806
|
+
* 为什么不复用 `sourceSessionId`:一条会话既可能是派活方(在自己这儿看回报卡),也可能是
|
|
21807
|
+
* 干活方(在 worker 会话里看任务包),后者用 sourceSessionId 过滤一条也查不到。UI 的
|
|
21808
|
+
* dispatch 卡片要的正是「跟我这条会话有关的全部 dispatch」,一次调用答完,不必拉全量再本地筛。
|
|
21809
|
+
*
|
|
21810
|
+
* 与 `sourceSessionId` 同时给时两个条件都要满足(AND),但调用方没有这么用的场景。
|
|
21811
|
+
*/
|
|
21812
|
+
relatedSessionId: external_exports.string().min(1).optional()
|
|
21780
21813
|
});
|
|
21781
21814
|
var DispatchListResultSchema = external_exports.object({
|
|
21782
21815
|
records: external_exports.array(DispatchRecordSchema)
|
package/dist/cli.cjs
CHANGED
|
@@ -5951,7 +5951,7 @@ var init_contact_handshake = __esm({
|
|
|
5951
5951
|
});
|
|
5952
5952
|
|
|
5953
5953
|
// ../protocol/src/environment-schemas.ts
|
|
5954
|
-
var EnvCliSchema, EnvSecretSchema, EnvAssetSchema, MANIFEST_BODY, EnvManifestBodySchema, EnvironmentManifestSchema, EnvEvidenceSchema;
|
|
5954
|
+
var EnvCliSchema, EnvSecretSchema, EnvAssetSchema, ConnectorNameSchema, EnvConnectorSchema, MANIFEST_BODY, EnvManifestBodySchema, EnvironmentManifestSchema, EnvEvidenceSchema;
|
|
5955
5955
|
var init_environment_schemas = __esm({
|
|
5956
5956
|
"../protocol/src/environment-schemas.ts"() {
|
|
5957
5957
|
"use strict";
|
|
@@ -5993,10 +5993,22 @@ var init_environment_schemas = __esm({
|
|
|
5993
5993
|
EnvAssetSchema = external_exports.object({
|
|
5994
5994
|
name: external_exports.string().min(1)
|
|
5995
5995
|
});
|
|
5996
|
+
ConnectorNameSchema = external_exports.string().regex(/^[a-z0-9-]+$/, "\u8FDE\u63A5\u5668\u540D\u53EA\u80FD\u662F\u5C0F\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u548C\u77ED\u6A2A\u7EBF");
|
|
5997
|
+
EnvConnectorSchema = external_exports.object({ name: ConnectorNameSchema });
|
|
5996
5998
|
MANIFEST_BODY = {
|
|
5997
5999
|
clis: external_exports.array(EnvCliSchema),
|
|
5998
6000
|
secrets: external_exports.array(EnvSecretSchema),
|
|
5999
|
-
assets: external_exports.array(EnvAssetSchema)
|
|
6001
|
+
assets: external_exports.array(EnvAssetSchema),
|
|
6002
|
+
/**
|
|
6003
|
+
* 装了哪些连接器(design 2026-09-09-cloud-connector-credentials §7.1)。**字符串数组**,
|
|
6004
|
+
* 是四段里唯一不是 `{name}` 对象数组的一段:连接器没有任何附加属性,包一层对象只是多一层壳。
|
|
6005
|
+
*
|
|
6006
|
+
* 不复用 secrets:那段说的是「需要一份值,由部署者填」,这里没有值要填;
|
|
6007
|
+
* 不从 clis 推断:lark-cli 在底座里,每个 persona 都有它,推不出任何东西。
|
|
6008
|
+
*
|
|
6009
|
+
* **缺省空而不是必填**:本机上已有的单据不用为此重扫一遍;没声明就是没装,扫描器照样会报。
|
|
6010
|
+
*/
|
|
6011
|
+
connectors: external_exports.array(ConnectorNameSchema).default([])
|
|
6000
6012
|
};
|
|
6001
6013
|
EnvManifestBodySchema = external_exports.object(MANIFEST_BODY);
|
|
6002
6014
|
EnvironmentManifestSchema = external_exports.object({
|
|
@@ -6148,8 +6160,9 @@ var init_deploy_schemas = __esm({
|
|
|
6148
6160
|
}).strict();
|
|
6149
6161
|
DeployReportFindingArgsSchema = external_exports.object({
|
|
6150
6162
|
personaId: external_exports.string().min(1),
|
|
6151
|
-
kind: external_exports.enum(["cli", "secret", "asset"]),
|
|
6163
|
+
kind: external_exports.enum(["cli", "secret", "asset", "connector"]),
|
|
6152
6164
|
// 该条目在 manifest 对应数组里的内容(形状随 kind 变,handler 按 kind 收窄校验)
|
|
6165
|
+
// connector 的 item 只有 name,落进清单时只留名字(manifest.connectors 是字符串数组)
|
|
6153
6166
|
item: external_exports.record(external_exports.string(), external_exports.unknown()),
|
|
6154
6167
|
// 这条发现的来历(一句人话 + 原文出处),形状同 EnvEvidence,target 由 handler 从 kind+name 派生
|
|
6155
6168
|
evidence: external_exports.object({
|
|
@@ -6494,6 +6507,16 @@ var init_dispatch = __esm({
|
|
|
6494
6507
|
sourceSessionId: external_exports.string().min(1),
|
|
6495
6508
|
sourcePersonaId: external_exports.string().min(1).optional(),
|
|
6496
6509
|
targetPersonaId: external_exports.string().min(1),
|
|
6510
|
+
/**
|
|
6511
|
+
* 跨设备派活时 B 所在的设备(`DispatchRunArgs.targetDeviceId`),A 端台账记「我派给了谁的机器」。
|
|
6512
|
+
*
|
|
6513
|
+
* **缺省即本机**,与入参侧用 `undefined` 表示本机是同一条口径——不引第二种表示法。
|
|
6514
|
+
* 存量台账行没有这个字段,消费方(dispatch 卡片的归属带)据此只显示 persona、不显示设备。
|
|
6515
|
+
*
|
|
6516
|
+
* B 端自己的台账行**不会**有它:peer-forward 转发时故意 strip 掉(B 据此判定本地执行),
|
|
6517
|
+
* 那条行记的是 B 视角的本地 dispatch。
|
|
6518
|
+
*/
|
|
6519
|
+
targetDeviceId: external_exports.string().min(1).optional(),
|
|
6497
6520
|
/** B 的 sessionId;registerBSession 后回填 */
|
|
6498
6521
|
workerSessionId: external_exports.string().min(1).optional(),
|
|
6499
6522
|
/** 任务摘要;截断(≤500 字符)在 daemon store.add 处保证 */
|
|
@@ -6520,7 +6543,17 @@ var init_dispatch = __esm({
|
|
|
6520
6543
|
deliveredAt: external_exports.string().min(1).optional()
|
|
6521
6544
|
});
|
|
6522
6545
|
DispatchListArgsSchema = external_exports.object({
|
|
6523
|
-
sourceSessionId: external_exports.string().min(1).optional()
|
|
6546
|
+
sourceSessionId: external_exports.string().min(1).optional(),
|
|
6547
|
+
/**
|
|
6548
|
+
* 「**这条会话卷入的**所有台账行」:`sourceSessionId === it || workerSessionId === it`。
|
|
6549
|
+
*
|
|
6550
|
+
* 为什么不复用 `sourceSessionId`:一条会话既可能是派活方(在自己这儿看回报卡),也可能是
|
|
6551
|
+
* 干活方(在 worker 会话里看任务包),后者用 sourceSessionId 过滤一条也查不到。UI 的
|
|
6552
|
+
* dispatch 卡片要的正是「跟我这条会话有关的全部 dispatch」,一次调用答完,不必拉全量再本地筛。
|
|
6553
|
+
*
|
|
6554
|
+
* 与 `sourceSessionId` 同时给时两个条件都要满足(AND),但调用方没有这么用的场景。
|
|
6555
|
+
*/
|
|
6556
|
+
relatedSessionId: external_exports.string().min(1).optional()
|
|
6524
6557
|
});
|
|
6525
6558
|
DispatchListResultSchema = external_exports.object({
|
|
6526
6559
|
records: external_exports.array(DispatchRecordSchema)
|
|
@@ -53667,6 +53700,7 @@ var PersonaDispatchManager = class {
|
|
|
53667
53700
|
sourceSessionId: args.sourceSessionId,
|
|
53668
53701
|
...args.sourcePersonaId ? { sourcePersonaId: args.sourcePersonaId } : {},
|
|
53669
53702
|
targetPersonaId: args.targetPersona,
|
|
53703
|
+
...args.targetDeviceId ? { targetDeviceId: args.targetDeviceId } : {},
|
|
53670
53704
|
taskText: args.taskText,
|
|
53671
53705
|
...args.taskBrief ? { taskBrief: args.taskBrief } : {},
|
|
53672
53706
|
...args.meta ? { meta: args.meta } : {}
|
|
@@ -53784,6 +53818,7 @@ function createDispatchStore(deps) {
|
|
|
53784
53818
|
sourceSessionId: input.sourceSessionId,
|
|
53785
53819
|
...input.sourcePersonaId ? { sourcePersonaId: input.sourcePersonaId } : {},
|
|
53786
53820
|
targetPersonaId: input.targetPersonaId,
|
|
53821
|
+
...input.targetDeviceId ? { targetDeviceId: input.targetDeviceId } : {},
|
|
53787
53822
|
taskText: input.taskText.slice(0, TASK_TEXT_MAX),
|
|
53788
53823
|
...input.taskBrief ? { taskBrief: input.taskBrief } : {},
|
|
53789
53824
|
// 新开 dispatch = 第 1 轮;续派在 handler 里 +1
|
|
@@ -53805,7 +53840,9 @@ function createDispatchStore(deps) {
|
|
|
53805
53840
|
return merged;
|
|
53806
53841
|
}
|
|
53807
53842
|
function list(filter) {
|
|
53808
|
-
return records.filter((r) => !filter?.sourceSessionId || r.sourceSessionId === filter.sourceSessionId).
|
|
53843
|
+
return records.filter((r) => !filter?.sourceSessionId || r.sourceSessionId === filter.sourceSessionId).filter(
|
|
53844
|
+
(r) => !filter?.relatedSessionId || r.sourceSessionId === filter.relatedSessionId || r.workerSessionId === filter.relatedSessionId
|
|
53845
|
+
).slice().sort((a, b2) => a.createdAt < b2.createdAt ? 1 : a.createdAt > b2.createdAt ? -1 : 0);
|
|
53809
53846
|
}
|
|
53810
53847
|
function markInterruptedAsFailed(nowIso3) {
|
|
53811
53848
|
let touched = false;
|
|
@@ -54993,11 +55030,16 @@ async function writeScan(dir, scan) {
|
|
|
54993
55030
|
await writeJson(import_node_path31.default.join(dir, SCAN_FILE), DeployScanSchema.parse(scan));
|
|
54994
55031
|
}
|
|
54995
55032
|
function emptyDeployFile() {
|
|
54996
|
-
return { version: 1, manifest: { version: 1, clis: [], secrets: [], assets: [] } };
|
|
55033
|
+
return { version: 1, manifest: { version: 1, clis: [], secrets: [], assets: [], connectors: [] } };
|
|
54997
55034
|
}
|
|
55035
|
+
var FINDING_SCHEMAS = {
|
|
55036
|
+
cli: EnvCliSchema,
|
|
55037
|
+
secret: EnvSecretSchema,
|
|
55038
|
+
asset: EnvAssetSchema,
|
|
55039
|
+
connector: EnvConnectorSchema
|
|
55040
|
+
};
|
|
54998
55041
|
function parseFinding(kind, item) {
|
|
54999
|
-
const
|
|
55000
|
-
const parsed = schema.safeParse(item);
|
|
55042
|
+
const parsed = FINDING_SCHEMAS[kind].safeParse(item);
|
|
55001
55043
|
if (!parsed.success) {
|
|
55002
55044
|
const first = parsed.error.issues[0];
|
|
55003
55045
|
throw new Error(`${kind} \u6761\u76EE\u4E0D\u5408\u6CD5\uFF1A${first ? `${first.path.join(".")} ${first.message}` : ""}`);
|
|
@@ -55005,6 +55047,11 @@ function parseFinding(kind, item) {
|
|
|
55005
55047
|
return parsed.data;
|
|
55006
55048
|
}
|
|
55007
55049
|
function upsertFinding(file, kind, item) {
|
|
55050
|
+
if (kind === "connector") {
|
|
55051
|
+
const have = file.manifest.connectors;
|
|
55052
|
+
const connectors = have.includes(item.name) ? have : [...have, item.name];
|
|
55053
|
+
return { ...file, manifest: { ...file.manifest, connectors } };
|
|
55054
|
+
}
|
|
55008
55055
|
const key = kind === "cli" ? "clis" : kind === "secret" ? "secrets" : "assets";
|
|
55009
55056
|
const list = [...file.manifest[key]];
|
|
55010
55057
|
const idx = list.findIndex((x) => x.name === item.name);
|
|
@@ -55091,6 +55138,10 @@ var L = [
|
|
|
55091
55138
|
// smoke 与 deploy 都要:smoke 得用正式那份模型探活,否则验的不是将要上线的东西。
|
|
55092
55139
|
" model: ${{ steps.plan.outputs.model }}",
|
|
55093
55140
|
" effort: ${{ steps.plan.outputs.effort }}",
|
|
55141
|
+
// 装了哪些连接器(JSON 数组)。gateway 按它决定要不要为任务签工牌、把授权链接拼进 prompt
|
|
55142
|
+
//(design 2026-09-09-cloud-connector-credentials)。名字形状在 deploy-file.mjs 卡死成 [a-z0-9-],
|
|
55143
|
+
// 所以下面单引号包住直接拼进命令行是安全的。
|
|
55144
|
+
" connectors: ${{ steps.plan.outputs.connectors }}",
|
|
55094
55145
|
" steps:",
|
|
55095
55146
|
" - name: Checkout persona",
|
|
55096
55147
|
" uses: actions/checkout@v4",
|
|
@@ -55213,6 +55264,7 @@ var L = [
|
|
|
55213
55264
|
" --persona-id '${{ needs.build.outputs.persona_id }}' \\",
|
|
55214
55265
|
" --model '${{ needs.build.outputs.model }}' \\",
|
|
55215
55266
|
" --effort '${{ needs.build.outputs.effort }}' \\",
|
|
55267
|
+
" --connectors '${{ needs.build.outputs.connectors }}' \\",
|
|
55216
55268
|
" --run-number '${{ github.run_number }}'",
|
|
55217
55269
|
"",
|
|
55218
55270
|
" deploy:",
|
|
@@ -55242,7 +55294,8 @@ var L = [
|
|
|
55242
55294
|
" --image '${{ needs.build.outputs.image }}' \\",
|
|
55243
55295
|
" --persona-id '${{ needs.build.outputs.persona_id }}' \\",
|
|
55244
55296
|
" --model '${{ needs.build.outputs.model }}' \\",
|
|
55245
|
-
" --effort '${{ needs.build.outputs.effort }}'",
|
|
55297
|
+
" --effort '${{ needs.build.outputs.effort }}' \\",
|
|
55298
|
+
" --connectors '${{ needs.build.outputs.connectors }}'",
|
|
55246
55299
|
""
|
|
55247
55300
|
];
|
|
55248
55301
|
var WORKFLOW_TEMPLATE = L.join("\n");
|
|
@@ -56848,9 +56901,10 @@ function canAccessPersona(grants, personaId2, action) {
|
|
|
56848
56901
|
|
|
56849
56902
|
// src/handlers/persona-dispatch.ts
|
|
56850
56903
|
init_claude();
|
|
56851
|
-
function buildFollowUpTaskPack(dispatchId, prompt, round) {
|
|
56904
|
+
function buildFollowUpTaskPack(dispatchId, prompt, round, from) {
|
|
56852
56905
|
return formatDispatchTaskEnvelope({
|
|
56853
56906
|
dispatchId,
|
|
56907
|
+
...from ? { from } : {},
|
|
56854
56908
|
round,
|
|
56855
56909
|
detail: [
|
|
56856
56910
|
`[Follow-up instruction for dispatch ${dispatchId}]`,
|
|
@@ -56876,6 +56930,7 @@ function buildPersonaDispatchHandlers(deps) {
|
|
|
56876
56930
|
});
|
|
56877
56931
|
}
|
|
56878
56932
|
const args = DispatchRunArgsSchema.parse(rest);
|
|
56933
|
+
const sourcePersonaId = deps.getSessionPersonaId?.(sourceSessionId);
|
|
56879
56934
|
if (args.tool !== void 0 && ctx?.principal.kind === "guest") {
|
|
56880
56935
|
throw new ClawdError(
|
|
56881
56936
|
ERROR_CODES.UNAUTHORIZED,
|
|
@@ -56931,7 +56986,14 @@ function buildPersonaDispatchHandlers(deps) {
|
|
|
56931
56986
|
});
|
|
56932
56987
|
const ok = deps.sendFollowUp(
|
|
56933
56988
|
rec4.workerSessionId,
|
|
56934
|
-
buildFollowUpTaskPack(
|
|
56989
|
+
buildFollowUpTaskPack(
|
|
56990
|
+
args.dispatchId,
|
|
56991
|
+
args.prompt,
|
|
56992
|
+
nextRound,
|
|
56993
|
+
// 台账行里有就用台账的(本机派活一律有),没有再现查一次:老台账行是在
|
|
56994
|
+
// sourcePersonaId 有写入点之前落的,那些行只能靠现查补上。
|
|
56995
|
+
rec4.sourcePersonaId ?? deps.getSessionPersonaId?.(sourceSessionId)
|
|
56996
|
+
),
|
|
56935
56997
|
// 来源分型(L2):续派并进 dispatch-task;realtime 侧靠这个 meta 打标,
|
|
56936
56998
|
// history 侧靠 classifyUserMessage 从信封解出同值。
|
|
56937
56999
|
"dispatch-task"
|
|
@@ -56997,6 +57059,10 @@ function buildPersonaDispatchHandlers(deps) {
|
|
|
56997
57059
|
const { dispatchId: dispatchId2 } = mgr.start({
|
|
56998
57060
|
sourceSessionId,
|
|
56999
57061
|
targetPersona,
|
|
57062
|
+
...sourcePersonaId ? { sourcePersonaId } : {},
|
|
57063
|
+
// A 端台账记「我派给了谁的机器」:worker 会话在对端,本机点不进去,卡片的归属带
|
|
57064
|
+
// 靠这个字段说出「在哪台机器上」而不是干瞪眼(design §4 跨设备那一行)。
|
|
57065
|
+
targetDeviceId: args.targetDeviceId,
|
|
57000
57066
|
taskText: args.prompt,
|
|
57001
57067
|
...args.brief ? { taskBrief: args.brief } : {},
|
|
57002
57068
|
...args.meta ? { meta: args.meta } : {}
|
|
@@ -57070,6 +57136,9 @@ function buildPersonaDispatchHandlers(deps) {
|
|
|
57070
57136
|
const { dispatchId } = mgr.start({
|
|
57071
57137
|
sourceSessionId,
|
|
57072
57138
|
targetPersona,
|
|
57139
|
+
// 「这活谁派的」的真源。schema 里早就有这个字段,本次之前没有任何写入点——
|
|
57140
|
+
// 于是 worker 会话的 dispatch 卡片永远查不到派活方(归属带只能退回信封)。
|
|
57141
|
+
...sourcePersonaId ? { sourcePersonaId } : {},
|
|
57073
57142
|
taskText: args.prompt,
|
|
57074
57143
|
...args.brief ? { taskBrief: args.brief } : {},
|
|
57075
57144
|
...args.meta ? { meta: args.meta } : {}
|
|
@@ -57136,9 +57205,10 @@ function buildPersonaDispatchHandlers(deps) {
|
|
|
57136
57205
|
const list = async (frame) => {
|
|
57137
57206
|
const { type: _t, requestId: _r, ...rest } = frame;
|
|
57138
57207
|
const args = DispatchListArgsSchema.parse(rest);
|
|
57139
|
-
const records = deps.store.list(
|
|
57140
|
-
args.sourceSessionId ? { sourceSessionId: args.sourceSessionId } :
|
|
57141
|
-
|
|
57208
|
+
const records = deps.store.list({
|
|
57209
|
+
...args.sourceSessionId ? { sourceSessionId: args.sourceSessionId } : {},
|
|
57210
|
+
...args.relatedSessionId ? { relatedSessionId: args.relatedSessionId } : {}
|
|
57211
|
+
});
|
|
57142
57212
|
return {
|
|
57143
57213
|
response: { type: "personaDispatch:list:ok", records }
|
|
57144
57214
|
};
|
|
@@ -65464,7 +65534,7 @@ function computeMethodAccess(args) {
|
|
|
65464
65534
|
}
|
|
65465
65535
|
|
|
65466
65536
|
// src/version.ts
|
|
65467
|
-
var version = "0.2.
|
|
65537
|
+
var version = "0.2.490".length > 0 ? "0.2.490" : "dev";
|
|
65468
65538
|
|
|
65469
65539
|
// src/cli-probe/probe.ts
|
|
65470
65540
|
var fs72 = __toESM(require("fs"), 1);
|
|
@@ -70582,6 +70652,9 @@ async function startDaemon(config) {
|
|
|
70582
70652
|
},
|
|
70583
70653
|
// 续派(spec 2026-07-21):任务包注入 worker session,复用投递同款注入路径。
|
|
70584
70654
|
sendFollowUp: (workerSessionId, text, meta) => manager.injectIntoSession(workerSessionId, text, meta),
|
|
70655
|
+
// 「这活是谁派的」:台账 sourcePersonaId + 续派包信封 from 都吃它。与首发任务包在
|
|
70656
|
+
// SessionManager 那侧的反查(buildDispatchTaskPack 的 from)是同一个字段、同一个查法。
|
|
70657
|
+
getSessionPersonaId: (sessionId) => manager.findOwnedSession(sessionId)?.ownerPersonaId,
|
|
70585
70658
|
logger,
|
|
70586
70659
|
spawnB: async (args) => {
|
|
70587
70660
|
logger.info("dispatch.spawnB.start", {
|
|
@@ -21310,10 +21310,22 @@ var EnvSecretSchema = external_exports.object({
|
|
|
21310
21310
|
var EnvAssetSchema = external_exports.object({
|
|
21311
21311
|
name: external_exports.string().min(1)
|
|
21312
21312
|
});
|
|
21313
|
+
var ConnectorNameSchema = external_exports.string().regex(/^[a-z0-9-]+$/, "\u8FDE\u63A5\u5668\u540D\u53EA\u80FD\u662F\u5C0F\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u548C\u77ED\u6A2A\u7EBF");
|
|
21314
|
+
var EnvConnectorSchema = external_exports.object({ name: ConnectorNameSchema });
|
|
21313
21315
|
var MANIFEST_BODY = {
|
|
21314
21316
|
clis: external_exports.array(EnvCliSchema),
|
|
21315
21317
|
secrets: external_exports.array(EnvSecretSchema),
|
|
21316
|
-
assets: external_exports.array(EnvAssetSchema)
|
|
21318
|
+
assets: external_exports.array(EnvAssetSchema),
|
|
21319
|
+
/**
|
|
21320
|
+
* 装了哪些连接器(design 2026-09-09-cloud-connector-credentials §7.1)。**字符串数组**,
|
|
21321
|
+
* 是四段里唯一不是 `{name}` 对象数组的一段:连接器没有任何附加属性,包一层对象只是多一层壳。
|
|
21322
|
+
*
|
|
21323
|
+
* 不复用 secrets:那段说的是「需要一份值,由部署者填」,这里没有值要填;
|
|
21324
|
+
* 不从 clis 推断:lark-cli 在底座里,每个 persona 都有它,推不出任何东西。
|
|
21325
|
+
*
|
|
21326
|
+
* **缺省空而不是必填**:本机上已有的单据不用为此重扫一遍;没声明就是没装,扫描器照样会报。
|
|
21327
|
+
*/
|
|
21328
|
+
connectors: external_exports.array(ConnectorNameSchema).default([])
|
|
21317
21329
|
};
|
|
21318
21330
|
var EnvManifestBodySchema = external_exports.object(MANIFEST_BODY);
|
|
21319
21331
|
var EnvironmentManifestSchema = external_exports.object({
|
|
@@ -21446,8 +21458,9 @@ var DeployRerunJobArgsSchema = external_exports.object({
|
|
|
21446
21458
|
}).strict();
|
|
21447
21459
|
var DeployReportFindingArgsSchema = external_exports.object({
|
|
21448
21460
|
personaId: external_exports.string().min(1),
|
|
21449
|
-
kind: external_exports.enum(["cli", "secret", "asset"]),
|
|
21461
|
+
kind: external_exports.enum(["cli", "secret", "asset", "connector"]),
|
|
21450
21462
|
// 该条目在 manifest 对应数组里的内容(形状随 kind 变,handler 按 kind 收窄校验)
|
|
21463
|
+
// connector 的 item 只有 name,落进清单时只留名字(manifest.connectors 是字符串数组)
|
|
21451
21464
|
item: external_exports.record(external_exports.string(), external_exports.unknown()),
|
|
21452
21465
|
// 这条发现的来历(一句人话 + 原文出处),形状同 EnvEvidence,target 由 handler 从 kind+name 派生
|
|
21453
21466
|
evidence: external_exports.object({
|
|
@@ -21743,6 +21756,16 @@ var DispatchRecordSchema = external_exports.object({
|
|
|
21743
21756
|
sourceSessionId: external_exports.string().min(1),
|
|
21744
21757
|
sourcePersonaId: external_exports.string().min(1).optional(),
|
|
21745
21758
|
targetPersonaId: external_exports.string().min(1),
|
|
21759
|
+
/**
|
|
21760
|
+
* 跨设备派活时 B 所在的设备(`DispatchRunArgs.targetDeviceId`),A 端台账记「我派给了谁的机器」。
|
|
21761
|
+
*
|
|
21762
|
+
* **缺省即本机**,与入参侧用 `undefined` 表示本机是同一条口径——不引第二种表示法。
|
|
21763
|
+
* 存量台账行没有这个字段,消费方(dispatch 卡片的归属带)据此只显示 persona、不显示设备。
|
|
21764
|
+
*
|
|
21765
|
+
* B 端自己的台账行**不会**有它:peer-forward 转发时故意 strip 掉(B 据此判定本地执行),
|
|
21766
|
+
* 那条行记的是 B 视角的本地 dispatch。
|
|
21767
|
+
*/
|
|
21768
|
+
targetDeviceId: external_exports.string().min(1).optional(),
|
|
21746
21769
|
/** B 的 sessionId;registerBSession 后回填 */
|
|
21747
21770
|
workerSessionId: external_exports.string().min(1).optional(),
|
|
21748
21771
|
/** 任务摘要;截断(≤500 字符)在 daemon store.add 处保证 */
|
|
@@ -21769,7 +21792,17 @@ var DispatchRecordSchema = external_exports.object({
|
|
|
21769
21792
|
deliveredAt: external_exports.string().min(1).optional()
|
|
21770
21793
|
});
|
|
21771
21794
|
var DispatchListArgsSchema = external_exports.object({
|
|
21772
|
-
sourceSessionId: external_exports.string().min(1).optional()
|
|
21795
|
+
sourceSessionId: external_exports.string().min(1).optional(),
|
|
21796
|
+
/**
|
|
21797
|
+
* 「**这条会话卷入的**所有台账行」:`sourceSessionId === it || workerSessionId === it`。
|
|
21798
|
+
*
|
|
21799
|
+
* 为什么不复用 `sourceSessionId`:一条会话既可能是派活方(在自己这儿看回报卡),也可能是
|
|
21800
|
+
* 干活方(在 worker 会话里看任务包),后者用 sourceSessionId 过滤一条也查不到。UI 的
|
|
21801
|
+
* dispatch 卡片要的正是「跟我这条会话有关的全部 dispatch」,一次调用答完,不必拉全量再本地筛。
|
|
21802
|
+
*
|
|
21803
|
+
* 与 `sourceSessionId` 同时给时两个条件都要满足(AND),但调用方没有这么用的场景。
|
|
21804
|
+
*/
|
|
21805
|
+
relatedSessionId: external_exports.string().min(1).optional()
|
|
21773
21806
|
});
|
|
21774
21807
|
var DispatchListResultSchema = external_exports.object({
|
|
21775
21808
|
records: external_exports.array(DispatchRecordSchema)
|
package/dist/persona-defaults/persona-clawd-butler/.claude/skills/scan-persona-for-deploy/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: scan-persona-for-deploy
|
|
3
|
-
description: 老板要把某个 persona 发布到云上时触发——把这个 persona
|
|
3
|
+
description: 老板要把某个 persona 发布到云上时触发——把这个 persona 读一遍,弄清它挪到一台干净的云上机器要预备什么(命令行工具、凭据、随行资产、连接器),边查边填进它的部署文件。收到形如「扫描 persona-xxx 的部署环境,personaId=persona-xxx」的任务时使用。只负责扫,不负责部署。
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# 扫 persona 的上云环境
|
|
@@ -35,7 +35,7 @@ description: 老板要把某个 persona 发布到云上时触发——把这个
|
|
|
35
35
|
```
|
|
36
36
|
call({ method: "deploy:reportFinding", args: {
|
|
37
37
|
personaId: "<任务里给的>",
|
|
38
|
-
kind: "cli" | "secret" | "asset",
|
|
38
|
+
kind: "cli" | "secret" | "asset" | "connector",
|
|
39
39
|
item: { ... }, // 见下面各类的字段
|
|
40
40
|
evidence: { reason: "...", file: "...", quote: "..." }
|
|
41
41
|
}})
|
|
@@ -99,6 +99,18 @@ call({ method: "deploy:reportFinding", args: {
|
|
|
99
99
|
- 判据往往落在「这个动作在云上由谁提供」。persona 在本机走 daemon 提供的 MCP 干的活,
|
|
100
100
|
云上容器里没有 daemon,靠的就是那份随行资产。
|
|
101
101
|
|
|
102
|
+
### kind: "connector" —— 以用户本人身份操作的第三方
|
|
103
|
+
|
|
104
|
+
`item` 字段只有 `name`(小写字母、数字、短横线)。目前能声明的只有 `feishu`。
|
|
105
|
+
|
|
106
|
+
判据:**persona 里出现「以用户本人身份操作某个第三方」的动作**就报——查他的日程、发他的消息、
|
|
107
|
+
读他的文档,这类活在云上要先拿到他本人的授权,授权由云上的连接器完成,不是部署者填一份凭据就能代替的。
|
|
108
|
+
|
|
109
|
+
- 跟 `secret` 的区别:`secret` 是「部署者出一份值,全体使用者共用」;`connector` 是「每个使用者各自授权一次」。
|
|
110
|
+
一个 persona 用 `lark-cli … --as user` 操作飞书,报的是 `connector: feishu`,**不要**再给它报一条飞书的 `secret`。
|
|
111
|
+
- 跟 `cli` 的区别:`lark-cli` 这个工具本身在底座镜像里,不用报 `cli`;报 `connector` 说的是「它要用谁的身份」。
|
|
112
|
+
- `evidence.quote` 引 skill 里带 `--as user` 的那类命令行就够。
|
|
113
|
+
|
|
102
114
|
### evidence —— 每条的来历
|
|
103
115
|
|
|
104
116
|
- `reason`:**一句人话**,说清「为什么需要它 + 你从哪看出来的」,写给不熟悉这个 persona 的人看。
|