@clawos-dev/clawd 0.2.445 → 0.2.446
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.cjs +1208 -541
- package/dist/dispatch/mcp-server.cjs +198 -0
- package/dist/persona-defaults/persona-clawd-butler/.claude/skills/scan-persona-for-deploy/SKILL.md +134 -0
- package/dist/share-md-viewer-error.html +1 -1
- package/dist/share-md-viewer.html +1 -1
- package/dist/share-ui/assets/{guest-Cn0m2N_c.js → guest-ChNRpL1J.js} +132 -132
- package/dist/share-ui/assets/guest-DgGpoVf5.css +32 -0
- package/dist/share-ui/guest.html +2 -2
- package/package.json +1 -1
- package/dist/share-ui/assets/guest-DISx208T.css +0 -32
package/dist/cli.cjs
CHANGED
|
@@ -450,8 +450,8 @@ var init_parseUtil = __esm({
|
|
|
450
450
|
init_errors();
|
|
451
451
|
init_en();
|
|
452
452
|
makeIssue = (params) => {
|
|
453
|
-
const { data, path:
|
|
454
|
-
const fullPath = [...
|
|
453
|
+
const { data, path: path93, errorMaps, issueData } = params;
|
|
454
|
+
const fullPath = [...path93, ...issueData.path || []];
|
|
455
455
|
const fullIssue = {
|
|
456
456
|
...issueData,
|
|
457
457
|
path: fullPath
|
|
@@ -762,11 +762,11 @@ var init_types = __esm({
|
|
|
762
762
|
init_parseUtil();
|
|
763
763
|
init_util();
|
|
764
764
|
ParseInputLazyPath = class {
|
|
765
|
-
constructor(parent, value,
|
|
765
|
+
constructor(parent, value, path93, key) {
|
|
766
766
|
this._cachedPath = [];
|
|
767
767
|
this.parent = parent;
|
|
768
768
|
this.data = value;
|
|
769
|
-
this._path =
|
|
769
|
+
this._path = path93;
|
|
770
770
|
this._key = key;
|
|
771
771
|
}
|
|
772
772
|
get path() {
|
|
@@ -5950,6 +5950,187 @@ var init_contact_handshake = __esm({
|
|
|
5950
5950
|
}
|
|
5951
5951
|
});
|
|
5952
5952
|
|
|
5953
|
+
// ../protocol/src/environment-schemas.ts
|
|
5954
|
+
var EnvCliSchema, EnvSecretSchema, EnvAssetSchema, MANIFEST_BODY, EnvManifestBodySchema, EnvironmentManifestSchema, EnvEvidenceSchema;
|
|
5955
|
+
var init_environment_schemas = __esm({
|
|
5956
|
+
"../protocol/src/environment-schemas.ts"() {
|
|
5957
|
+
"use strict";
|
|
5958
|
+
init_zod();
|
|
5959
|
+
EnvCliSchema = external_exports.object({
|
|
5960
|
+
// 可执行文件名,装配后要能在 PATH 里直接调到('aliyun' / 's' / 'pnpm' / 'python3')
|
|
5961
|
+
name: external_exports.string().min(1),
|
|
5962
|
+
/**
|
|
5963
|
+
* 从哪装,约定 `<kind>:<ref>`:`npm:@serverless-devs/s` / `github:aliyun/aliyun-cli` /
|
|
5964
|
+
* `apt:python3`。
|
|
5965
|
+
*
|
|
5966
|
+
* **不是装饰字段,是构建器的必需输入**:可执行名往往推不出安装源——Serverless Devs 的命令
|
|
5967
|
+
* 就叫单个字母 `s`,没人能从 's' 猜到要 `npm i -g @serverless-devs/s`;`aliyun` 也不在
|
|
5968
|
+
* apt 源里,得从 GitHub release 拉 tarball。扫描器读 ensure-toolchain.sh 的时候本来就看见
|
|
5969
|
+
* 了这些,顺手带出来即可。
|
|
5970
|
+
*
|
|
5971
|
+
* 它同时解决人的阅读问题:单据上只写一个 `s`,看的人不知道那是什么东西。
|
|
5972
|
+
*
|
|
5973
|
+
* 允许缺省:扫描器拿不准安装源时不该编一个(编错了构建期才炸,还查不出来源)。缺省时构建
|
|
5974
|
+
* 器会失败或猜错,试装当场暴露——这跟整体「宁可让试装发现,不要靠猜」的取向一致。
|
|
5975
|
+
*
|
|
5976
|
+
* 只给一个源,不给平台回落链:本地那套 brew → GitHub → npm 的三级兜底是
|
|
5977
|
+
* ensure-toolchain.sh 的事,云上只构一个镜像、一个基础环境,多给反而要求构建器做选择。
|
|
5978
|
+
*/
|
|
5979
|
+
from: external_exports.string().optional(),
|
|
5980
|
+
// 精确版本;缺省 = 不挑版本,装配器自选
|
|
5981
|
+
version: external_exports.string().optional(),
|
|
5982
|
+
// 版本下限('20.6' 这种)。与 version 的区别:version 是「就要这个」,min 是「不低于」。
|
|
5983
|
+
// 两者都缺省即完全不约束。
|
|
5984
|
+
min: external_exports.string().optional()
|
|
5985
|
+
});
|
|
5986
|
+
EnvSecretSchema = external_exports.object({
|
|
5987
|
+
// 凭据的命名引用('aliyun-ak' / 'supabase-shared')。部署时按这个名字去解析实际的值。
|
|
5988
|
+
name: external_exports.string().min(1),
|
|
5989
|
+
// 解析出的值注入到哪些环境变量。一份凭据可含多个字段(AK 是 id+secret 两个,
|
|
5990
|
+
// supabase 是 url/anon/service-role/jwt 四个),所以是数组不是单值。
|
|
5991
|
+
env: external_exports.array(external_exports.string().min(1)).min(1)
|
|
5992
|
+
});
|
|
5993
|
+
EnvAssetSchema = external_exports.object({
|
|
5994
|
+
name: external_exports.string().min(1)
|
|
5995
|
+
});
|
|
5996
|
+
MANIFEST_BODY = {
|
|
5997
|
+
clis: external_exports.array(EnvCliSchema),
|
|
5998
|
+
secrets: external_exports.array(EnvSecretSchema),
|
|
5999
|
+
assets: external_exports.array(EnvAssetSchema)
|
|
6000
|
+
};
|
|
6001
|
+
EnvManifestBodySchema = external_exports.object(MANIFEST_BODY);
|
|
6002
|
+
EnvironmentManifestSchema = external_exports.object({
|
|
6003
|
+
// 格式版本。manifest 要跨进程(daemon 扫 → 镜像构建器读)也跨时间(部署记录留档),
|
|
6004
|
+
// 加字段兼容但改语义不兼容,留一个显式版本位。
|
|
6005
|
+
version: external_exports.literal(1),
|
|
6006
|
+
...MANIFEST_BODY
|
|
6007
|
+
}).strict();
|
|
6008
|
+
EnvEvidenceSchema = external_exports.object({
|
|
6009
|
+
// 这条证据支持的是哪一项:`${kind}:${name}`,如 'cli:aliyun' / 'secret:aliyun-ak'
|
|
6010
|
+
target: external_exports.string().min(1),
|
|
6011
|
+
// 一句人话:为什么需要它 + 从哪看出来的。单据默认显示这句。
|
|
6012
|
+
reason: external_exports.string().min(1),
|
|
6013
|
+
// persona 目录内的相对路径('CLAUDE.md' / '.claude/skills/foo/SKILL.md')
|
|
6014
|
+
file: external_exports.string().min(1),
|
|
6015
|
+
// 原文摘录(一两句即可,不是整段)。默认收起,起疑时才看。
|
|
6016
|
+
//
|
|
6017
|
+
// **自由文本,schema 守不住凭据值**:这里只验得了非空,而 agent 被要求「引原文不要转述」,
|
|
6018
|
+
// 引到 `KEY=值` 那行是迟早的事。落盘前由 daemon 的 deploy/redact.ts 涂抹(reason 同理)。
|
|
6019
|
+
quote: external_exports.string().min(1)
|
|
6020
|
+
});
|
|
6021
|
+
}
|
|
6022
|
+
});
|
|
6023
|
+
|
|
6024
|
+
// ../protocol/src/deploy-schemas.ts
|
|
6025
|
+
var FulfillmentSchema, DeployStatusSchema, DeployGapSchema, DeployReceiptSchema, DeployStartArgsSchema, DeployIdArgsSchema, DeployPatchArgsSchema, DeployPutSecretArgsSchema, DeployReportFindingArgsSchema, DeployFinishScanArgsSchema, DeploySecretStatusSchema, DeployReceiptViewSchema, DeployListResultSchema;
|
|
6026
|
+
var init_deploy_schemas = __esm({
|
|
6027
|
+
"../protocol/src/deploy-schemas.ts"() {
|
|
6028
|
+
"use strict";
|
|
6029
|
+
init_zod();
|
|
6030
|
+
init_environment_schemas();
|
|
6031
|
+
FulfillmentSchema = external_exports.enum(["deployer", "user"]);
|
|
6032
|
+
DeployStatusSchema = external_exports.enum([
|
|
6033
|
+
"scanning",
|
|
6034
|
+
"scanFailed",
|
|
6035
|
+
"draft",
|
|
6036
|
+
"ready",
|
|
6037
|
+
"trialing",
|
|
6038
|
+
"failed",
|
|
6039
|
+
"deployed"
|
|
6040
|
+
]);
|
|
6041
|
+
DeployGapSchema = external_exports.object({
|
|
6042
|
+
// agent 的自然语言错因,如「我要解析 aliyun 的 JSON 输出,但容器里没有 python3」
|
|
6043
|
+
errorText: external_exports.string().min(1),
|
|
6044
|
+
// 原始输出片段,给人自己判断用
|
|
6045
|
+
raw: external_exports.string().optional(),
|
|
6046
|
+
// 建议补的依赖:`cli:python3` 这种。拿不准就不给,让人自己决定。
|
|
6047
|
+
suggest: external_exports.string().optional()
|
|
6048
|
+
}).strict();
|
|
6049
|
+
DeployReceiptSchema = external_exports.object({
|
|
6050
|
+
deployId: external_exports.string().min(1),
|
|
6051
|
+
personaId: external_exports.string().min(1),
|
|
6052
|
+
status: DeployStatusSchema,
|
|
6053
|
+
/**
|
|
6054
|
+
* 干这次扫描的 butler 会话 id。单据上「看它怎么干的」入口靠它把工作过程调出来。
|
|
6055
|
+
*
|
|
6056
|
+
* 扫描不是 daemon 里一个闷头跑的黑盒进程,是 persona-butler 的一次真实会话——用户能翻
|
|
6057
|
+
* 看它读了哪些文件、搜了什么。这条也顺带解决「它到底有没有上网查」这类问题:不用另造
|
|
6058
|
+
* 探针去抓证据,看一眼就知道。
|
|
6059
|
+
*/
|
|
6060
|
+
scanSessionId: external_exports.string().optional(),
|
|
6061
|
+
// 扫描产物;scanning / scanFailed 时还没有
|
|
6062
|
+
manifest: EnvironmentManifestSchema.optional(),
|
|
6063
|
+
evidence: external_exports.array(EnvEvidenceSchema).optional(),
|
|
6064
|
+
smokeTask: external_exports.string().optional(),
|
|
6065
|
+
notes: external_exports.array(external_exports.string()).default([]),
|
|
6066
|
+
/**
|
|
6067
|
+
* 每条凭据的履约选择:secret name → 'deployer' | 'user'。
|
|
6068
|
+
* **只记「谁出」,不记值。** 没做选择的凭据不在这个 map 里(缺席即未定),
|
|
6069
|
+
* 用缺席而不是 'unset' 枚举值表达未定,省掉一个下游要处处判的第三态。
|
|
6070
|
+
*/
|
|
6071
|
+
fulfillment: external_exports.record(external_exports.string(), FulfillmentSchema).default({}),
|
|
6072
|
+
/** 试装失败时的缺口清单;成功或没试装过是空数组 */
|
|
6073
|
+
gaps: external_exports.array(DeployGapSchema).default([]),
|
|
6074
|
+
// 扫描 / 试装失败的原因(status 是 scanFailed / failed 时才有意义)
|
|
6075
|
+
error: external_exports.string().optional(),
|
|
6076
|
+
createdAt: external_exports.number(),
|
|
6077
|
+
updatedAt: external_exports.number()
|
|
6078
|
+
}).strict();
|
|
6079
|
+
DeployStartArgsSchema = external_exports.object({
|
|
6080
|
+
personaId: external_exports.string().min(1)
|
|
6081
|
+
}).strict();
|
|
6082
|
+
DeployIdArgsSchema = external_exports.object({
|
|
6083
|
+
deployId: external_exports.string().min(1)
|
|
6084
|
+
}).strict();
|
|
6085
|
+
DeployPatchArgsSchema = external_exports.object({
|
|
6086
|
+
deployId: external_exports.string().min(1),
|
|
6087
|
+
patch: external_exports.object({
|
|
6088
|
+
fulfillment: external_exports.record(external_exports.string(), FulfillmentSchema).optional(),
|
|
6089
|
+
smokeTask: external_exports.string().min(1).optional(),
|
|
6090
|
+
// 人工补依赖(试装失败后补 python3 这种);整份替换 manifest
|
|
6091
|
+
manifest: EnvironmentManifestSchema.optional()
|
|
6092
|
+
}).strict()
|
|
6093
|
+
}).strict();
|
|
6094
|
+
DeployPutSecretArgsSchema = external_exports.object({
|
|
6095
|
+
deployId: external_exports.string().min(1),
|
|
6096
|
+
// 对应 manifest.secrets[].name
|
|
6097
|
+
name: external_exports.string().min(1),
|
|
6098
|
+
// 环境变量名 → 值。key 必须是该 secret 声明过的 env 之一,handler 校验。
|
|
6099
|
+
values: external_exports.record(external_exports.string(), external_exports.string())
|
|
6100
|
+
}).strict();
|
|
6101
|
+
DeployReportFindingArgsSchema = external_exports.object({
|
|
6102
|
+
deployId: external_exports.string().min(1),
|
|
6103
|
+
kind: external_exports.enum(["cli", "secret", "asset"]),
|
|
6104
|
+
// 该条目在 manifest 对应数组里的内容(形状随 kind 变,handler 按 kind 收窄校验)
|
|
6105
|
+
item: external_exports.record(external_exports.string(), external_exports.unknown()),
|
|
6106
|
+
// 这条发现的来历(一句人话 + 原文出处),形状同 EnvEvidence,target 由 handler 从 kind+name 派生
|
|
6107
|
+
evidence: external_exports.object({
|
|
6108
|
+
reason: external_exports.string().min(1),
|
|
6109
|
+
file: external_exports.string().min(1),
|
|
6110
|
+
quote: external_exports.string().min(1)
|
|
6111
|
+
})
|
|
6112
|
+
}).strict();
|
|
6113
|
+
DeployFinishScanArgsSchema = external_exports.object({
|
|
6114
|
+
deployId: external_exports.string().min(1),
|
|
6115
|
+
smokeTask: external_exports.string().min(1),
|
|
6116
|
+
notes: external_exports.array(external_exports.string()).default([])
|
|
6117
|
+
}).strict();
|
|
6118
|
+
DeploySecretStatusSchema = external_exports.object({
|
|
6119
|
+
name: external_exports.string(),
|
|
6120
|
+
// 该 secret 声明的 env 里已有值的个数
|
|
6121
|
+
filled: external_exports.number(),
|
|
6122
|
+
total: external_exports.number()
|
|
6123
|
+
}).strict();
|
|
6124
|
+
DeployReceiptViewSchema = external_exports.object({
|
|
6125
|
+
receipt: DeployReceiptSchema,
|
|
6126
|
+
secretStatus: external_exports.array(DeploySecretStatusSchema)
|
|
6127
|
+
}).strict();
|
|
6128
|
+
DeployListResultSchema = external_exports.object({
|
|
6129
|
+
receipts: external_exports.array(DeployReceiptSchema)
|
|
6130
|
+
}).strict();
|
|
6131
|
+
}
|
|
6132
|
+
});
|
|
6133
|
+
|
|
5953
6134
|
// ../protocol/src/contact-remote-access.ts
|
|
5954
6135
|
var ContactSetRemoteAccessArgsSchema, ContactSetRemoteAccessOkSchema, ContactRemoteAccessUpdatedFrameSchema;
|
|
5955
6136
|
var init_contact_remote_access = __esm({
|
|
@@ -8410,6 +8591,7 @@ var init_methods = __esm({
|
|
|
8410
8591
|
init_esm();
|
|
8411
8592
|
init_attachment_schemas();
|
|
8412
8593
|
init_contact_handshake();
|
|
8594
|
+
init_deploy_schemas();
|
|
8413
8595
|
init_contact_remote_access();
|
|
8414
8596
|
init_contact();
|
|
8415
8597
|
init_feishu_auth();
|
|
@@ -8613,6 +8795,38 @@ var init_methods = __esm({
|
|
|
8613
8795
|
summary: "\u8BFB\u6587\u4EF6\u5185\u5BB9\uFF1Bguest \u8DEF\u5F84\u8FB9\u754C\u4E0E workspace:list \u540C",
|
|
8614
8796
|
args: WorkspaceReadArgs
|
|
8615
8797
|
},
|
|
8798
|
+
"deploy:start": {
|
|
8799
|
+
summary: "\u5BF9\u67D0\u4E2A persona \u53D1\u8D77\u4E00\u6B21\u4E0A\u4E91\u90E8\u7F72\uFF1A\u5EFA\u5355\u636E\u5E76**\u5F02\u6B65**\u8D77\u73AF\u5883\u626B\u63CF\u3002\u7ACB\u523B\u8FD4\u56DE scanning \u6001\u5355\u636E\uFF0C\u626B\u63CF\u8981\u8DD1\u51E0\u5206\u949F\u3001\u626B\u5B8C\u7531\u540E\u53F0\u56DE\u5199\uFF1Bowner-only",
|
|
8800
|
+
args: DeployStartArgsSchema
|
|
8801
|
+
},
|
|
8802
|
+
"deploy:list": {
|
|
8803
|
+
summary: "\u5217\u51FA\u5168\u90E8\u90E8\u7F72\u5355\uFF08\u65B0\u7684\u5728\u524D\uFF09\uFF1Bowner-only\u3002\u65E0\u53C2\u6570",
|
|
8804
|
+
args: NO_ARGS
|
|
8805
|
+
},
|
|
8806
|
+
"deploy:get": {
|
|
8807
|
+
summary: "\u53D6\u4E00\u5F20\u90E8\u7F72\u5355 + \u6BCF\u6761\u51ED\u636E\u7684\u586B\u5199\u8FDB\u5EA6\u3002**\u8FDB\u5EA6\u53EA\u6709\u4E2A\u6570\u4E0D\u542B\u503C**\u2014\u2014\u51ED\u636E\u503C\u4E0D\u7ECF\u8FC7\u8FD9\u6761\u8DEF\uFF1Bowner-only",
|
|
8808
|
+
args: DeployIdArgsSchema
|
|
8809
|
+
},
|
|
8810
|
+
"deploy:patch": {
|
|
8811
|
+
summary: "\u7F16\u8F91\u90E8\u7F72\u5355\uFF1A\u9009\u5C65\u7EA6\uFF08\u8C01\u51FA\u8FD9\u6761\u51ED\u636E\uFF09/ \u6539\u5192\u70DF\u4EFB\u52A1 / \u624B\u5DE5\u8865\u4F9D\u8D56\u3002**\u4E0D\u80FD\u4ECE\u8FD9\u91CC\u4F20\u51ED\u636E\u7684\u503C**\uFF08\u503C\u8D70 deploy:putSecret\uFF09\uFF1B\u5C65\u7EA6\u540D\u5FC5\u987B\u662F\u6E05\u5355\u91CC\u58F0\u660E\u8FC7\u7684\u51ED\u636E\uFF1Bowner-only",
|
|
8812
|
+
args: DeployPatchArgsSchema
|
|
8813
|
+
},
|
|
8814
|
+
"deploy:putSecret": {
|
|
8815
|
+
summary: "\u5F55\u5165\u4E00\u6761\u51ED\u636E\u7684\u503C\u3002**\u8FD9\u662F\u503C\u552F\u4E00\u7684\u5165\u53E3**\uFF1A\u5165\u53C2\u4E0D\u8FDB\u65E5\u5FD7\u3001\u54CD\u5E94\u53EA\u56DE\u586B\u5199\u8FDB\u5EA6\u4E0D\u56DE\u663E\u503C\u3002env \u540D\u5FC5\u987B\u662F\u8BE5\u51ED\u636E\u5728\u6E05\u5355\u91CC\u58F0\u660E\u8FC7\u7684\uFF0C\u5426\u5219\u503C\u5B58\u4E86\u4E5F\u6C38\u8FDC\u6CE8\u5165\u4E0D\u5230\uFF1Bowner-only",
|
|
8816
|
+
args: DeployPutSecretArgsSchema
|
|
8817
|
+
},
|
|
8818
|
+
"deploy:reportFinding": {
|
|
8819
|
+
summary: "\u626B\u63CF\u4E2D\u7684 butler \u9010\u6761\u4E0A\u62A5\u4E00\u4E2A\u53D1\u73B0\uFF08cli / secret / asset\uFF09\u3002**\u8FB9\u626B\u8FB9\u62A5**\uFF0C\u5355\u636E\u9875\u968F\u4E4B\u4E00\u70B9\u70B9\u586B\u5145\uFF1B\u540C (kind,name) \u91CD\u590D\u4E0A\u62A5\u5373\u8986\u76D6\u3002owner-only\u2014\u2014butler \u4F1A\u8BDD\u672C\u8EAB\u8DD1\u5728 owner \u6A21\u5F0F",
|
|
8820
|
+
args: DeployReportFindingArgsSchema
|
|
8821
|
+
},
|
|
8822
|
+
"deploy:finishScan": {
|
|
8823
|
+
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",
|
|
8824
|
+
args: DeployFinishScanArgsSchema
|
|
8825
|
+
},
|
|
8826
|
+
"deploy:remove": {
|
|
8827
|
+
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",
|
|
8828
|
+
args: DeployIdArgsSchema
|
|
8829
|
+
},
|
|
8616
8830
|
"shift:list": {
|
|
8617
8831
|
summary: "\u5217\u51FA owner \u7684\u5168\u90E8 shift\uFF08\u6392\u73ED\uFF09\uFF0C\u7ED9 UI \u65E5\u5386\u6E32\u67D3\u7528\uFF1Bowner-only",
|
|
8618
8832
|
args: NO_ARGS
|
|
@@ -9119,7 +9333,9 @@ var init_errors2 = __esm({
|
|
|
9119
9333
|
DISPATCH_NOT_FOUND: "DISPATCH_NOT_FOUND",
|
|
9120
9334
|
// persona:get 查不到该 personaId,或 guest ctx 查非 public / 无 read grant 的 persona
|
|
9121
9335
|
// (与 DISPATCH_NOT_FOUND 同款:越权与未知 id 同码,不泄露存在性)。
|
|
9122
|
-
PERSONA_NOT_FOUND: "PERSONA_NOT_FOUND"
|
|
9336
|
+
PERSONA_NOT_FOUND: "PERSONA_NOT_FOUND",
|
|
9337
|
+
// deploy:* 查不到该部署单(persona 上云的单据)。同上口径:未知 id 与越权同码。
|
|
9338
|
+
DEPLOY_NOT_FOUND: "DEPLOY_NOT_FOUND"
|
|
9123
9339
|
};
|
|
9124
9340
|
ClawdError = class extends Error {
|
|
9125
9341
|
constructor(code, message) {
|
|
@@ -9295,6 +9511,8 @@ var init_runtime = __esm({
|
|
|
9295
9511
|
init_errors2();
|
|
9296
9512
|
init_schemas();
|
|
9297
9513
|
init_frames();
|
|
9514
|
+
init_environment_schemas();
|
|
9515
|
+
init_deploy_schemas();
|
|
9298
9516
|
init_persona_schemas();
|
|
9299
9517
|
init_persona_mode();
|
|
9300
9518
|
init_attachment_schemas();
|
|
@@ -9593,8 +9811,8 @@ var require_req = __commonJS({
|
|
|
9593
9811
|
if (req.originalUrl) {
|
|
9594
9812
|
_req.url = req.originalUrl;
|
|
9595
9813
|
} else {
|
|
9596
|
-
const
|
|
9597
|
-
_req.url = typeof
|
|
9814
|
+
const path93 = req.path;
|
|
9815
|
+
_req.url = typeof path93 === "string" ? path93 : req.url ? req.url.path || req.url : void 0;
|
|
9598
9816
|
}
|
|
9599
9817
|
if (req.query) {
|
|
9600
9818
|
_req.query = req.query;
|
|
@@ -9759,14 +9977,14 @@ var require_redact = __commonJS({
|
|
|
9759
9977
|
}
|
|
9760
9978
|
return obj;
|
|
9761
9979
|
}
|
|
9762
|
-
function parsePath(
|
|
9980
|
+
function parsePath(path93) {
|
|
9763
9981
|
const parts = [];
|
|
9764
9982
|
let current = "";
|
|
9765
9983
|
let inBrackets = false;
|
|
9766
9984
|
let inQuotes = false;
|
|
9767
9985
|
let quoteChar = "";
|
|
9768
|
-
for (let i = 0; i <
|
|
9769
|
-
const char =
|
|
9986
|
+
for (let i = 0; i < path93.length; i++) {
|
|
9987
|
+
const char = path93[i];
|
|
9770
9988
|
if (!inBrackets && char === ".") {
|
|
9771
9989
|
if (current) {
|
|
9772
9990
|
parts.push(current);
|
|
@@ -9897,10 +10115,10 @@ var require_redact = __commonJS({
|
|
|
9897
10115
|
return current;
|
|
9898
10116
|
}
|
|
9899
10117
|
function redactPaths(obj, paths, censor, remove = false) {
|
|
9900
|
-
for (const
|
|
9901
|
-
const parts = parsePath(
|
|
10118
|
+
for (const path93 of paths) {
|
|
10119
|
+
const parts = parsePath(path93);
|
|
9902
10120
|
if (parts.includes("*")) {
|
|
9903
|
-
redactWildcardPath(obj, parts, censor,
|
|
10121
|
+
redactWildcardPath(obj, parts, censor, path93, remove);
|
|
9904
10122
|
} else {
|
|
9905
10123
|
if (remove) {
|
|
9906
10124
|
removeKey(obj, parts);
|
|
@@ -9985,8 +10203,8 @@ var require_redact = __commonJS({
|
|
|
9985
10203
|
}
|
|
9986
10204
|
} else {
|
|
9987
10205
|
if (afterWildcard.includes("*")) {
|
|
9988
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
9989
|
-
const fullPath = [...pathArray.slice(0, pathLength), ...
|
|
10206
|
+
const wrappedCensor = typeof censor === "function" ? (value, path93) => {
|
|
10207
|
+
const fullPath = [...pathArray.slice(0, pathLength), ...path93];
|
|
9990
10208
|
return censor(value, fullPath);
|
|
9991
10209
|
} : censor;
|
|
9992
10210
|
redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
|
|
@@ -10021,8 +10239,8 @@ var require_redact = __commonJS({
|
|
|
10021
10239
|
return null;
|
|
10022
10240
|
}
|
|
10023
10241
|
const pathStructure = /* @__PURE__ */ new Map();
|
|
10024
|
-
for (const
|
|
10025
|
-
const parts = parsePath(
|
|
10242
|
+
for (const path93 of pathsToClone) {
|
|
10243
|
+
const parts = parsePath(path93);
|
|
10026
10244
|
let current = pathStructure;
|
|
10027
10245
|
for (let i = 0; i < parts.length; i++) {
|
|
10028
10246
|
const part = parts[i];
|
|
@@ -10074,24 +10292,24 @@ var require_redact = __commonJS({
|
|
|
10074
10292
|
}
|
|
10075
10293
|
return cloneSelectively(obj, pathStructure);
|
|
10076
10294
|
}
|
|
10077
|
-
function validatePath(
|
|
10078
|
-
if (typeof
|
|
10295
|
+
function validatePath(path93) {
|
|
10296
|
+
if (typeof path93 !== "string") {
|
|
10079
10297
|
throw new Error("Paths must be (non-empty) strings");
|
|
10080
10298
|
}
|
|
10081
|
-
if (
|
|
10299
|
+
if (path93 === "") {
|
|
10082
10300
|
throw new Error("Invalid redaction path ()");
|
|
10083
10301
|
}
|
|
10084
|
-
if (
|
|
10085
|
-
throw new Error(`Invalid redaction path (${
|
|
10302
|
+
if (path93.includes("..")) {
|
|
10303
|
+
throw new Error(`Invalid redaction path (${path93})`);
|
|
10086
10304
|
}
|
|
10087
|
-
if (
|
|
10088
|
-
throw new Error(`Invalid redaction path (${
|
|
10305
|
+
if (path93.includes(",")) {
|
|
10306
|
+
throw new Error(`Invalid redaction path (${path93})`);
|
|
10089
10307
|
}
|
|
10090
10308
|
let bracketCount = 0;
|
|
10091
10309
|
let inQuotes = false;
|
|
10092
10310
|
let quoteChar = "";
|
|
10093
|
-
for (let i = 0; i <
|
|
10094
|
-
const char =
|
|
10311
|
+
for (let i = 0; i < path93.length; i++) {
|
|
10312
|
+
const char = path93[i];
|
|
10095
10313
|
if ((char === '"' || char === "'") && bracketCount > 0) {
|
|
10096
10314
|
if (!inQuotes) {
|
|
10097
10315
|
inQuotes = true;
|
|
@@ -10105,20 +10323,20 @@ var require_redact = __commonJS({
|
|
|
10105
10323
|
} else if (char === "]" && !inQuotes) {
|
|
10106
10324
|
bracketCount--;
|
|
10107
10325
|
if (bracketCount < 0) {
|
|
10108
|
-
throw new Error(`Invalid redaction path (${
|
|
10326
|
+
throw new Error(`Invalid redaction path (${path93})`);
|
|
10109
10327
|
}
|
|
10110
10328
|
}
|
|
10111
10329
|
}
|
|
10112
10330
|
if (bracketCount !== 0) {
|
|
10113
|
-
throw new Error(`Invalid redaction path (${
|
|
10331
|
+
throw new Error(`Invalid redaction path (${path93})`);
|
|
10114
10332
|
}
|
|
10115
10333
|
}
|
|
10116
10334
|
function validatePaths(paths) {
|
|
10117
10335
|
if (!Array.isArray(paths)) {
|
|
10118
10336
|
throw new TypeError("paths must be an array");
|
|
10119
10337
|
}
|
|
10120
|
-
for (const
|
|
10121
|
-
validatePath(
|
|
10338
|
+
for (const path93 of paths) {
|
|
10339
|
+
validatePath(path93);
|
|
10122
10340
|
}
|
|
10123
10341
|
}
|
|
10124
10342
|
function slowRedact(options = {}) {
|
|
@@ -10286,8 +10504,8 @@ var require_redaction = __commonJS({
|
|
|
10286
10504
|
if (shape[k2] === null) {
|
|
10287
10505
|
o[k2] = (value) => topCensor(value, [k2]);
|
|
10288
10506
|
} else {
|
|
10289
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
10290
|
-
return censor(value, [k2, ...
|
|
10507
|
+
const wrappedCensor = typeof censor === "function" ? (value, path93) => {
|
|
10508
|
+
return censor(value, [k2, ...path93]);
|
|
10291
10509
|
} : censor;
|
|
10292
10510
|
o[k2] = Redact({
|
|
10293
10511
|
paths: shape[k2],
|
|
@@ -10505,10 +10723,10 @@ var require_atomic_sleep = __commonJS({
|
|
|
10505
10723
|
var require_sonic_boom = __commonJS({
|
|
10506
10724
|
"../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
|
|
10507
10725
|
"use strict";
|
|
10508
|
-
var
|
|
10726
|
+
var fs82 = require("fs");
|
|
10509
10727
|
var EventEmitter3 = require("events");
|
|
10510
10728
|
var inherits = require("util").inherits;
|
|
10511
|
-
var
|
|
10729
|
+
var path93 = require("path");
|
|
10512
10730
|
var sleep2 = require_atomic_sleep();
|
|
10513
10731
|
var assert = require("assert");
|
|
10514
10732
|
var BUSY_WRITE_TIMEOUT = 100;
|
|
@@ -10562,20 +10780,20 @@ var require_sonic_boom = __commonJS({
|
|
|
10562
10780
|
const mode = sonic.mode;
|
|
10563
10781
|
if (sonic.sync) {
|
|
10564
10782
|
try {
|
|
10565
|
-
if (sonic.mkdir)
|
|
10566
|
-
const fd =
|
|
10783
|
+
if (sonic.mkdir) fs82.mkdirSync(path93.dirname(file), { recursive: true });
|
|
10784
|
+
const fd = fs82.openSync(file, flags, mode);
|
|
10567
10785
|
fileOpened(null, fd);
|
|
10568
10786
|
} catch (err) {
|
|
10569
10787
|
fileOpened(err);
|
|
10570
10788
|
throw err;
|
|
10571
10789
|
}
|
|
10572
10790
|
} else if (sonic.mkdir) {
|
|
10573
|
-
|
|
10791
|
+
fs82.mkdir(path93.dirname(file), { recursive: true }, (err) => {
|
|
10574
10792
|
if (err) return fileOpened(err);
|
|
10575
|
-
|
|
10793
|
+
fs82.open(file, flags, mode, fileOpened);
|
|
10576
10794
|
});
|
|
10577
10795
|
} else {
|
|
10578
|
-
|
|
10796
|
+
fs82.open(file, flags, mode, fileOpened);
|
|
10579
10797
|
}
|
|
10580
10798
|
}
|
|
10581
10799
|
function SonicBoom(opts) {
|
|
@@ -10616,8 +10834,8 @@ var require_sonic_boom = __commonJS({
|
|
|
10616
10834
|
this.flush = flushBuffer;
|
|
10617
10835
|
this.flushSync = flushBufferSync;
|
|
10618
10836
|
this._actualWrite = actualWriteBuffer;
|
|
10619
|
-
fsWriteSync = () =>
|
|
10620
|
-
fsWrite = () =>
|
|
10837
|
+
fsWriteSync = () => fs82.writeSync(this.fd, this._writingBuf);
|
|
10838
|
+
fsWrite = () => fs82.write(this.fd, this._writingBuf, this.release);
|
|
10621
10839
|
} else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
|
|
10622
10840
|
this._writingBuf = "";
|
|
10623
10841
|
this.write = write;
|
|
@@ -10626,15 +10844,15 @@ var require_sonic_boom = __commonJS({
|
|
|
10626
10844
|
this._actualWrite = actualWrite;
|
|
10627
10845
|
fsWriteSync = () => {
|
|
10628
10846
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
10629
|
-
return
|
|
10847
|
+
return fs82.writeSync(this.fd, this._writingBuf);
|
|
10630
10848
|
}
|
|
10631
|
-
return
|
|
10849
|
+
return fs82.writeSync(this.fd, this._writingBuf, "utf8");
|
|
10632
10850
|
};
|
|
10633
10851
|
fsWrite = () => {
|
|
10634
10852
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
10635
|
-
return
|
|
10853
|
+
return fs82.write(this.fd, this._writingBuf, this.release);
|
|
10636
10854
|
}
|
|
10637
|
-
return
|
|
10855
|
+
return fs82.write(this.fd, this._writingBuf, "utf8", this.release);
|
|
10638
10856
|
};
|
|
10639
10857
|
} else {
|
|
10640
10858
|
throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
|
|
@@ -10691,7 +10909,7 @@ var require_sonic_boom = __commonJS({
|
|
|
10691
10909
|
}
|
|
10692
10910
|
}
|
|
10693
10911
|
if (this._fsync) {
|
|
10694
|
-
|
|
10912
|
+
fs82.fsyncSync(this.fd);
|
|
10695
10913
|
}
|
|
10696
10914
|
const len = this._len;
|
|
10697
10915
|
if (this._reopening) {
|
|
@@ -10805,7 +11023,7 @@ var require_sonic_boom = __commonJS({
|
|
|
10805
11023
|
const onDrain = () => {
|
|
10806
11024
|
if (!this._fsync) {
|
|
10807
11025
|
try {
|
|
10808
|
-
|
|
11026
|
+
fs82.fsync(this.fd, (err) => {
|
|
10809
11027
|
this._flushPending = false;
|
|
10810
11028
|
cb(err);
|
|
10811
11029
|
});
|
|
@@ -10907,7 +11125,7 @@ var require_sonic_boom = __commonJS({
|
|
|
10907
11125
|
const fd = this.fd;
|
|
10908
11126
|
this.once("ready", () => {
|
|
10909
11127
|
if (fd !== this.fd) {
|
|
10910
|
-
|
|
11128
|
+
fs82.close(fd, (err) => {
|
|
10911
11129
|
if (err) {
|
|
10912
11130
|
return this.emit("error", err);
|
|
10913
11131
|
}
|
|
@@ -10956,7 +11174,7 @@ var require_sonic_boom = __commonJS({
|
|
|
10956
11174
|
buf = this._bufs[0];
|
|
10957
11175
|
}
|
|
10958
11176
|
try {
|
|
10959
|
-
const n = Buffer.isBuffer(buf) ?
|
|
11177
|
+
const n = Buffer.isBuffer(buf) ? fs82.writeSync(this.fd, buf) : fs82.writeSync(this.fd, buf, "utf8");
|
|
10960
11178
|
const releasedBufObj = releaseWritingBuf(buf, this._len, n);
|
|
10961
11179
|
buf = releasedBufObj.writingBuf;
|
|
10962
11180
|
this._len = releasedBufObj.len;
|
|
@@ -10972,7 +11190,7 @@ var require_sonic_boom = __commonJS({
|
|
|
10972
11190
|
}
|
|
10973
11191
|
}
|
|
10974
11192
|
try {
|
|
10975
|
-
|
|
11193
|
+
fs82.fsyncSync(this.fd);
|
|
10976
11194
|
} catch {
|
|
10977
11195
|
}
|
|
10978
11196
|
}
|
|
@@ -10993,7 +11211,7 @@ var require_sonic_boom = __commonJS({
|
|
|
10993
11211
|
buf = mergeBuf(this._bufs[0], this._lens[0]);
|
|
10994
11212
|
}
|
|
10995
11213
|
try {
|
|
10996
|
-
const n =
|
|
11214
|
+
const n = fs82.writeSync(this.fd, buf);
|
|
10997
11215
|
buf = buf.subarray(n);
|
|
10998
11216
|
this._len = Math.max(this._len - n, 0);
|
|
10999
11217
|
if (buf.length <= 0) {
|
|
@@ -11021,13 +11239,13 @@ var require_sonic_boom = __commonJS({
|
|
|
11021
11239
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
|
|
11022
11240
|
if (this.sync) {
|
|
11023
11241
|
try {
|
|
11024
|
-
const written = Buffer.isBuffer(this._writingBuf) ?
|
|
11242
|
+
const written = Buffer.isBuffer(this._writingBuf) ? fs82.writeSync(this.fd, this._writingBuf) : fs82.writeSync(this.fd, this._writingBuf, "utf8");
|
|
11025
11243
|
release(null, written);
|
|
11026
11244
|
} catch (err) {
|
|
11027
11245
|
release(err);
|
|
11028
11246
|
}
|
|
11029
11247
|
} else {
|
|
11030
|
-
|
|
11248
|
+
fs82.write(this.fd, this._writingBuf, release);
|
|
11031
11249
|
}
|
|
11032
11250
|
}
|
|
11033
11251
|
function actualWriteBuffer() {
|
|
@@ -11036,7 +11254,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11036
11254
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
|
|
11037
11255
|
if (this.sync) {
|
|
11038
11256
|
try {
|
|
11039
|
-
const written =
|
|
11257
|
+
const written = fs82.writeSync(this.fd, this._writingBuf);
|
|
11040
11258
|
release(null, written);
|
|
11041
11259
|
} catch (err) {
|
|
11042
11260
|
release(err);
|
|
@@ -11045,7 +11263,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11045
11263
|
if (kCopyBuffer) {
|
|
11046
11264
|
this._writingBuf = Buffer.from(this._writingBuf);
|
|
11047
11265
|
}
|
|
11048
|
-
|
|
11266
|
+
fs82.write(this.fd, this._writingBuf, release);
|
|
11049
11267
|
}
|
|
11050
11268
|
}
|
|
11051
11269
|
function actualClose(sonic) {
|
|
@@ -11061,12 +11279,12 @@ var require_sonic_boom = __commonJS({
|
|
|
11061
11279
|
sonic._lens = [];
|
|
11062
11280
|
assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
|
|
11063
11281
|
try {
|
|
11064
|
-
|
|
11282
|
+
fs82.fsync(sonic.fd, closeWrapped);
|
|
11065
11283
|
} catch {
|
|
11066
11284
|
}
|
|
11067
11285
|
function closeWrapped() {
|
|
11068
11286
|
if (sonic.fd !== 1 && sonic.fd !== 2) {
|
|
11069
|
-
|
|
11287
|
+
fs82.close(sonic.fd, done);
|
|
11070
11288
|
} else {
|
|
11071
11289
|
done();
|
|
11072
11290
|
}
|
|
@@ -14201,11 +14419,11 @@ var init_lib = __esm({
|
|
|
14201
14419
|
}
|
|
14202
14420
|
}
|
|
14203
14421
|
},
|
|
14204
|
-
addToPath: function addToPath(
|
|
14205
|
-
var last =
|
|
14422
|
+
addToPath: function addToPath(path93, added, removed, oldPosInc, options) {
|
|
14423
|
+
var last = path93.lastComponent;
|
|
14206
14424
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
14207
14425
|
return {
|
|
14208
|
-
oldPos:
|
|
14426
|
+
oldPos: path93.oldPos + oldPosInc,
|
|
14209
14427
|
lastComponent: {
|
|
14210
14428
|
count: last.count + 1,
|
|
14211
14429
|
added,
|
|
@@ -14215,7 +14433,7 @@ var init_lib = __esm({
|
|
|
14215
14433
|
};
|
|
14216
14434
|
} else {
|
|
14217
14435
|
return {
|
|
14218
|
-
oldPos:
|
|
14436
|
+
oldPos: path93.oldPos + oldPosInc,
|
|
14219
14437
|
lastComponent: {
|
|
14220
14438
|
count: 1,
|
|
14221
14439
|
added,
|
|
@@ -14797,10 +15015,10 @@ function attachmentToHistoryMessage(o, ts) {
|
|
|
14797
15015
|
const memories = raw.map((m2) => {
|
|
14798
15016
|
if (!m2 || typeof m2 !== "object") return null;
|
|
14799
15017
|
const rec4 = m2;
|
|
14800
|
-
const
|
|
15018
|
+
const path93 = typeof rec4.path === "string" ? rec4.path : null;
|
|
14801
15019
|
const content = typeof rec4.content === "string" ? rec4.content : null;
|
|
14802
|
-
if (!
|
|
14803
|
-
const entry = { path:
|
|
15020
|
+
if (!path93 || content == null) return null;
|
|
15021
|
+
const entry = { path: path93, content };
|
|
14804
15022
|
if (typeof rec4.mtimeMs === "number") entry.mtimeMs = rec4.mtimeMs;
|
|
14805
15023
|
return entry;
|
|
14806
15024
|
}).filter((m2) => m2 !== null);
|
|
@@ -15666,10 +15884,10 @@ function parseAttachment(obj) {
|
|
|
15666
15884
|
const memories = raw.map((m2) => {
|
|
15667
15885
|
if (!m2 || typeof m2 !== "object") return null;
|
|
15668
15886
|
const rec4 = m2;
|
|
15669
|
-
const
|
|
15887
|
+
const path93 = typeof rec4.path === "string" ? rec4.path : null;
|
|
15670
15888
|
const content = typeof rec4.content === "string" ? rec4.content : null;
|
|
15671
|
-
if (!
|
|
15672
|
-
const out = { path:
|
|
15889
|
+
if (!path93 || content == null) return null;
|
|
15890
|
+
const out = { path: path93, content };
|
|
15673
15891
|
if (typeof rec4.mtimeMs === "number") out.mtimeMs = rec4.mtimeMs;
|
|
15674
15892
|
return out;
|
|
15675
15893
|
}).filter((m2) => m2 !== null);
|
|
@@ -36643,8 +36861,8 @@ var require_utils = __commonJS({
|
|
|
36643
36861
|
var result = transform[inputType][outputType](input);
|
|
36644
36862
|
return result;
|
|
36645
36863
|
};
|
|
36646
|
-
exports2.resolve = function(
|
|
36647
|
-
var parts =
|
|
36864
|
+
exports2.resolve = function(path93) {
|
|
36865
|
+
var parts = path93.split("/");
|
|
36648
36866
|
var result = [];
|
|
36649
36867
|
for (var index = 0; index < parts.length; index++) {
|
|
36650
36868
|
var part = parts[index];
|
|
@@ -42497,18 +42715,18 @@ var require_object = __commonJS({
|
|
|
42497
42715
|
var object = new ZipObject(name, zipObjectContent, o);
|
|
42498
42716
|
this.files[name] = object;
|
|
42499
42717
|
};
|
|
42500
|
-
var parentFolder = function(
|
|
42501
|
-
if (
|
|
42502
|
-
|
|
42718
|
+
var parentFolder = function(path93) {
|
|
42719
|
+
if (path93.slice(-1) === "/") {
|
|
42720
|
+
path93 = path93.substring(0, path93.length - 1);
|
|
42503
42721
|
}
|
|
42504
|
-
var lastSlash =
|
|
42505
|
-
return lastSlash > 0 ?
|
|
42722
|
+
var lastSlash = path93.lastIndexOf("/");
|
|
42723
|
+
return lastSlash > 0 ? path93.substring(0, lastSlash) : "";
|
|
42506
42724
|
};
|
|
42507
|
-
var forceTrailingSlash = function(
|
|
42508
|
-
if (
|
|
42509
|
-
|
|
42725
|
+
var forceTrailingSlash = function(path93) {
|
|
42726
|
+
if (path93.slice(-1) !== "/") {
|
|
42727
|
+
path93 += "/";
|
|
42510
42728
|
}
|
|
42511
|
-
return
|
|
42729
|
+
return path93;
|
|
42512
42730
|
};
|
|
42513
42731
|
var folderAdd = function(name, createFolders) {
|
|
42514
42732
|
createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
|
|
@@ -43510,7 +43728,7 @@ var require_lib3 = __commonJS({
|
|
|
43510
43728
|
// src/run-case/recorder.ts
|
|
43511
43729
|
function startRunCaseRecorder(opts) {
|
|
43512
43730
|
const now = opts.now ?? Date.now;
|
|
43513
|
-
const dir =
|
|
43731
|
+
const dir = import_node_path75.default.dirname(opts.recordPath);
|
|
43514
43732
|
let stream = null;
|
|
43515
43733
|
let closing = false;
|
|
43516
43734
|
let closedSettled = false;
|
|
@@ -43550,12 +43768,12 @@ function startRunCaseRecorder(opts) {
|
|
|
43550
43768
|
};
|
|
43551
43769
|
return { tap, close, closed };
|
|
43552
43770
|
}
|
|
43553
|
-
var import_node_fs54,
|
|
43771
|
+
var import_node_fs54, import_node_path75;
|
|
43554
43772
|
var init_recorder = __esm({
|
|
43555
43773
|
"src/run-case/recorder.ts"() {
|
|
43556
43774
|
"use strict";
|
|
43557
43775
|
import_node_fs54 = __toESM(require("fs"), 1);
|
|
43558
|
-
|
|
43776
|
+
import_node_path75 = __toESM(require("path"), 1);
|
|
43559
43777
|
}
|
|
43560
43778
|
});
|
|
43561
43779
|
|
|
@@ -43598,7 +43816,7 @@ var init_wire = __esm({
|
|
|
43598
43816
|
// src/run-case/controller.ts
|
|
43599
43817
|
async function runController(opts) {
|
|
43600
43818
|
const now = opts.now ?? Date.now;
|
|
43601
|
-
const cwd = opts.cwd ?? (0, import_node_fs55.mkdtempSync)(
|
|
43819
|
+
const cwd = opts.cwd ?? (0, import_node_fs55.mkdtempSync)(import_node_path76.default.join(import_node_os27.default.tmpdir(), "clawd-runcase-"));
|
|
43602
43820
|
const ownsCwd = opts.cwd === void 0;
|
|
43603
43821
|
const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
|
|
43604
43822
|
const spawnCtx = { cwd };
|
|
@@ -43765,13 +43983,13 @@ async function runController(opts) {
|
|
|
43765
43983
|
}
|
|
43766
43984
|
return exitCode ?? 0;
|
|
43767
43985
|
}
|
|
43768
|
-
var import_node_fs55, import_node_os27,
|
|
43986
|
+
var import_node_fs55, import_node_os27, import_node_path76;
|
|
43769
43987
|
var init_controller = __esm({
|
|
43770
43988
|
"src/run-case/controller.ts"() {
|
|
43771
43989
|
"use strict";
|
|
43772
43990
|
import_node_fs55 = require("fs");
|
|
43773
43991
|
import_node_os27 = __toESM(require("os"), 1);
|
|
43774
|
-
|
|
43992
|
+
import_node_path76 = __toESM(require("path"), 1);
|
|
43775
43993
|
init_claude();
|
|
43776
43994
|
init_stdout_splitter();
|
|
43777
43995
|
init_permission_stdio();
|
|
@@ -44046,7 +44264,7 @@ Env (advanced):
|
|
|
44046
44264
|
`;
|
|
44047
44265
|
|
|
44048
44266
|
// src/index.ts
|
|
44049
|
-
var
|
|
44267
|
+
var import_node_path74 = __toESM(require("path"), 1);
|
|
44050
44268
|
var import_node_fs53 = __toESM(require("fs"), 1);
|
|
44051
44269
|
var import_node_os26 = __toESM(require("os"), 1);
|
|
44052
44270
|
var import_node_crypto22 = require("crypto");
|
|
@@ -51189,8 +51407,8 @@ function turnStartInput(text) {
|
|
|
51189
51407
|
const items = [];
|
|
51190
51408
|
let leftover = text;
|
|
51191
51409
|
for (const m2 of text.matchAll(SKILL_RE)) {
|
|
51192
|
-
const [marker, name,
|
|
51193
|
-
items.push({ type: "skill", name, path:
|
|
51410
|
+
const [marker, name, path93] = m2;
|
|
51411
|
+
items.push({ type: "skill", name, path: path93 });
|
|
51194
51412
|
leftover = leftover.replace(marker, "");
|
|
51195
51413
|
}
|
|
51196
51414
|
for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
|
|
@@ -54110,6 +54328,391 @@ function buildShiftInternalHandlers(deps) {
|
|
|
54110
54328
|
};
|
|
54111
54329
|
}
|
|
54112
54330
|
|
|
54331
|
+
// src/handlers/deploy.ts
|
|
54332
|
+
init_protocol();
|
|
54333
|
+
|
|
54334
|
+
// src/deploy/redact.ts
|
|
54335
|
+
var SECRET_KEY_HINT = /(KEY|TOKEN|SECRET|PASSWORD|PASSWD|PWD|CREDENTIAL|AKID|ACCESS_?ID)/i;
|
|
54336
|
+
var KNOWN_SECRET_SHAPES = [
|
|
54337
|
+
/LTAI[A-Za-z0-9]{6,}/,
|
|
54338
|
+
/eyJ[A-Za-z0-9_-]{10,}/,
|
|
54339
|
+
/sk-[A-Za-z0-9_-]{16,}/,
|
|
54340
|
+
/gh[pousr]_[A-Za-z0-9]{20,}/,
|
|
54341
|
+
/AKIA[A-Z0-9]{12,}/
|
|
54342
|
+
];
|
|
54343
|
+
var BARE_SECRET = new RegExp(KNOWN_SECRET_SHAPES.map((re) => re.source).join("|"), "g");
|
|
54344
|
+
var REDACTED = "<\u5DF2\u7565\u53BB>";
|
|
54345
|
+
function isPlaceholder(value) {
|
|
54346
|
+
return value.length === 0 || value === REDACTED || /^\$\{?[A-Za-z_]/.test(value) || // ${VAR} / $VAR
|
|
54347
|
+
/^["']?[<(]/.test(value) || // <your-key> / (填这里)
|
|
54348
|
+
/^["']?(your|xxx+|todo|placeholder|change[-_]?me|填)/i.test(value);
|
|
54349
|
+
}
|
|
54350
|
+
var ASSIGNMENT = /((?:export\s+)?)(["']?)([A-Za-z_][A-Za-z0-9_.-]*)\2(\s*[:=]\s*)(["']?)([^\s"'`,;)\]}]+)/g;
|
|
54351
|
+
function redactSecretValues(text) {
|
|
54352
|
+
const byAssignment = text.replace(
|
|
54353
|
+
ASSIGNMENT,
|
|
54354
|
+
(whole, exp, kq, key, sep4, vq, value) => {
|
|
54355
|
+
if (isPlaceholder(value)) return whole;
|
|
54356
|
+
const looksSecret = SECRET_KEY_HINT.test(key) || KNOWN_SECRET_SHAPES.some((re) => re.test(value));
|
|
54357
|
+
return looksSecret ? `${exp}${kq}${key}${kq}${sep4}${vq}${REDACTED}` : whole;
|
|
54358
|
+
}
|
|
54359
|
+
);
|
|
54360
|
+
return byAssignment.replace(BARE_SECRET, REDACTED);
|
|
54361
|
+
}
|
|
54362
|
+
function redactEvidence(evidence) {
|
|
54363
|
+
return {
|
|
54364
|
+
...evidence,
|
|
54365
|
+
reason: redactSecretValues(evidence.reason),
|
|
54366
|
+
quote: redactSecretValues(evidence.quote)
|
|
54367
|
+
};
|
|
54368
|
+
}
|
|
54369
|
+
|
|
54370
|
+
// src/handlers/deploy.ts
|
|
54371
|
+
function ensureOwner(ctx) {
|
|
54372
|
+
if (!ctx || ctx.principal.kind !== "owner") {
|
|
54373
|
+
throw new ClawdError(ERROR_CODES.UNAUTHORIZED, "UNAUTHORIZED: deploy:* requires owner ctx");
|
|
54374
|
+
}
|
|
54375
|
+
}
|
|
54376
|
+
function mustGet(deps, deployId) {
|
|
54377
|
+
const receipt = deps.receipts.get(deployId);
|
|
54378
|
+
if (!receipt) throw new ClawdError(ERROR_CODES.DEPLOY_NOT_FOUND, `DEPLOY_NOT_FOUND: \u6CA1\u6709\u8FD9\u5F20\u90E8\u7F72\u5355\uFF08${deployId}\uFF09`);
|
|
54379
|
+
return receipt;
|
|
54380
|
+
}
|
|
54381
|
+
function mustBeScanning(receipt, method) {
|
|
54382
|
+
if (receipt.status !== "scanning") {
|
|
54383
|
+
throw new ClawdError(
|
|
54384
|
+
ERROR_CODES.VALIDATION_ERROR,
|
|
54385
|
+
`VALIDATION_ERROR: ${method} \u53EA\u5728\u626B\u63CF\u671F\u53EF\u7528\uFF08\u5F53\u524D ${receipt.status}\uFF09`
|
|
54386
|
+
);
|
|
54387
|
+
}
|
|
54388
|
+
return receipt;
|
|
54389
|
+
}
|
|
54390
|
+
function secretStatusOf(deps, receipt) {
|
|
54391
|
+
const declared = receipt.manifest?.secrets ?? [];
|
|
54392
|
+
return declared.map((s) => ({
|
|
54393
|
+
name: s.name,
|
|
54394
|
+
// 只看部署级:使用者自带的那部分由使用者各自绑定,不在部署者这张单据的进度里
|
|
54395
|
+
filled: deps.secrets.filledKeys(receipt.deployId, s.name).length,
|
|
54396
|
+
total: s.env.length
|
|
54397
|
+
}));
|
|
54398
|
+
}
|
|
54399
|
+
function buildDeployHandlers(deps) {
|
|
54400
|
+
const view = (receipt) => ({
|
|
54401
|
+
response: { type: "deploy:receipt", receipt, secretStatus: secretStatusOf(deps, receipt) }
|
|
54402
|
+
});
|
|
54403
|
+
const start = async (frame, _client, ctx) => {
|
|
54404
|
+
ensureOwner(ctx);
|
|
54405
|
+
const args = parseArgs2(DeployStartArgsSchema, frame, "deploy:start");
|
|
54406
|
+
if (!deps.hasPersona(args.personaId)) {
|
|
54407
|
+
throw new ClawdError(ERROR_CODES.PERSONA_NOT_FOUND, `PERSONA_NOT_FOUND: \u6CA1\u6709\u8FD9\u4E2A persona\uFF08${args.personaId}\uFF09`);
|
|
54408
|
+
}
|
|
54409
|
+
const inFlight = deps.receipts.list().find((r) => r.personaId === args.personaId && r.status === "scanning");
|
|
54410
|
+
if (inFlight) return view(inFlight);
|
|
54411
|
+
const receipt = deps.receipts.create({
|
|
54412
|
+
deployId: deps.genId(),
|
|
54413
|
+
personaId: args.personaId,
|
|
54414
|
+
status: "scanning"
|
|
54415
|
+
});
|
|
54416
|
+
const scanSessionId = deps.startScan(receipt.deployId, args.personaId);
|
|
54417
|
+
if (scanSessionId) deps.receipts.update(receipt.deployId, { scanSessionId });
|
|
54418
|
+
return view(deps.receipts.get(receipt.deployId) ?? receipt);
|
|
54419
|
+
};
|
|
54420
|
+
const list = async (_frame, _client, ctx) => {
|
|
54421
|
+
ensureOwner(ctx);
|
|
54422
|
+
return { response: { type: "deploy:list", receipts: deps.receipts.list() } };
|
|
54423
|
+
};
|
|
54424
|
+
const get = async (frame, _client, ctx) => {
|
|
54425
|
+
ensureOwner(ctx);
|
|
54426
|
+
const args = parseArgs2(DeployIdArgsSchema, frame, "deploy:get");
|
|
54427
|
+
return view(mustGet(deps, args.deployId));
|
|
54428
|
+
};
|
|
54429
|
+
const patch = async (frame, _client, ctx) => {
|
|
54430
|
+
ensureOwner(ctx);
|
|
54431
|
+
const args = parseArgs2(DeployPatchArgsSchema, frame, "deploy:patch");
|
|
54432
|
+
const receipt = mustGet(deps, args.deployId);
|
|
54433
|
+
if (args.patch.fulfillment) {
|
|
54434
|
+
const declared = new Set((args.patch.manifest ?? receipt.manifest)?.secrets.map((s) => s.name) ?? []);
|
|
54435
|
+
for (const name of Object.keys(args.patch.fulfillment)) {
|
|
54436
|
+
if (!declared.has(name)) {
|
|
54437
|
+
throw new ClawdError(
|
|
54438
|
+
ERROR_CODES.VALIDATION_ERROR,
|
|
54439
|
+
`VALIDATION_ERROR: \u6E05\u5355\u91CC\u6CA1\u6709\u53EB\u300C${name}\u300D\u7684\u51ED\u636E`
|
|
54440
|
+
);
|
|
54441
|
+
}
|
|
54442
|
+
}
|
|
54443
|
+
}
|
|
54444
|
+
const next = deps.receipts.update(args.deployId, args.patch);
|
|
54445
|
+
return view(next ?? receipt);
|
|
54446
|
+
};
|
|
54447
|
+
const putSecret = async (frame, _client, ctx) => {
|
|
54448
|
+
ensureOwner(ctx);
|
|
54449
|
+
const args = parseArgs2(DeployPutSecretArgsSchema, frame, "deploy:putSecret");
|
|
54450
|
+
const receipt = mustGet(deps, args.deployId);
|
|
54451
|
+
const declared = receipt.manifest?.secrets.find((s) => s.name === args.name);
|
|
54452
|
+
if (!declared) {
|
|
54453
|
+
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `VALIDATION_ERROR: \u6E05\u5355\u91CC\u6CA1\u6709\u53EB\u300C${args.name}\u300D\u7684\u51ED\u636E`);
|
|
54454
|
+
}
|
|
54455
|
+
const allowed = new Set(declared.env);
|
|
54456
|
+
for (const key of Object.keys(args.values)) {
|
|
54457
|
+
if (!allowed.has(key)) {
|
|
54458
|
+
throw new ClawdError(
|
|
54459
|
+
ERROR_CODES.VALIDATION_ERROR,
|
|
54460
|
+
`VALIDATION_ERROR: \u300C${args.name}\u300D\u6CA1\u6709\u58F0\u660E\u73AF\u5883\u53D8\u91CF ${key}`
|
|
54461
|
+
);
|
|
54462
|
+
}
|
|
54463
|
+
}
|
|
54464
|
+
deps.secrets.put({ deployId: args.deployId, name: args.name, values: args.values });
|
|
54465
|
+
return view(receipt);
|
|
54466
|
+
};
|
|
54467
|
+
const reportFinding = async (frame, _client, ctx) => {
|
|
54468
|
+
ensureOwner(ctx);
|
|
54469
|
+
const args = parseArgs2(DeployReportFindingArgsSchema, frame, "deploy:reportFinding");
|
|
54470
|
+
const receipt = mustBeScanning(mustGet(deps, args.deployId), "deploy:reportFinding");
|
|
54471
|
+
const schema = args.kind === "cli" ? EnvCliSchema : args.kind === "secret" ? EnvSecretSchema : EnvAssetSchema;
|
|
54472
|
+
const parsed = schema.safeParse(args.item);
|
|
54473
|
+
if (!parsed.success) {
|
|
54474
|
+
const first = parsed.error.issues[0];
|
|
54475
|
+
throw new ClawdError(
|
|
54476
|
+
ERROR_CODES.VALIDATION_ERROR,
|
|
54477
|
+
`VALIDATION_ERROR: ${args.kind} \u6761\u76EE\u4E0D\u5408\u6CD5\uFF1A${first ? `${first.path.join(".")} ${first.message}` : ""}`
|
|
54478
|
+
);
|
|
54479
|
+
}
|
|
54480
|
+
const item = parsed.data;
|
|
54481
|
+
const base = receipt.manifest ?? { version: 1, clis: [], secrets: [], assets: [] };
|
|
54482
|
+
const key = args.kind === "cli" ? "clis" : args.kind === "secret" ? "secrets" : "assets";
|
|
54483
|
+
const list2 = [...base[key]];
|
|
54484
|
+
const idx = list2.findIndex((x) => x.name === item.name);
|
|
54485
|
+
if (idx === -1) list2.push(item);
|
|
54486
|
+
else list2[idx] = item;
|
|
54487
|
+
const target = `${args.kind}:${item.name}`;
|
|
54488
|
+
const evidence = [
|
|
54489
|
+
...(receipt.evidence ?? []).filter((e) => e.target !== target),
|
|
54490
|
+
redactEvidence({ target, ...args.evidence })
|
|
54491
|
+
];
|
|
54492
|
+
const next = deps.receipts.update(args.deployId, {
|
|
54493
|
+
manifest: { ...base, [key]: list2 },
|
|
54494
|
+
evidence
|
|
54495
|
+
});
|
|
54496
|
+
return view(next ?? receipt);
|
|
54497
|
+
};
|
|
54498
|
+
const finishScan = async (frame, _client, ctx) => {
|
|
54499
|
+
ensureOwner(ctx);
|
|
54500
|
+
const args = parseArgs2(DeployFinishScanArgsSchema, frame, "deploy:finishScan");
|
|
54501
|
+
mustBeScanning(mustGet(deps, args.deployId), "deploy:finishScan");
|
|
54502
|
+
const next = deps.receipts.update(args.deployId, {
|
|
54503
|
+
status: "draft",
|
|
54504
|
+
smokeTask: args.smokeTask ? redactSecretValues(args.smokeTask) : args.smokeTask,
|
|
54505
|
+
notes: args.notes?.map(redactSecretValues),
|
|
54506
|
+
error: void 0
|
|
54507
|
+
});
|
|
54508
|
+
return view(next);
|
|
54509
|
+
};
|
|
54510
|
+
const remove = async (frame, _client, ctx) => {
|
|
54511
|
+
ensureOwner(ctx);
|
|
54512
|
+
const args = parseArgs2(DeployIdArgsSchema, frame, "deploy:remove");
|
|
54513
|
+
mustGet(deps, args.deployId);
|
|
54514
|
+
deps.receipts.remove(args.deployId);
|
|
54515
|
+
deps.secrets.removeDeploy(args.deployId);
|
|
54516
|
+
return { response: { type: "deploy:remove", deployId: args.deployId } };
|
|
54517
|
+
};
|
|
54518
|
+
return {
|
|
54519
|
+
"deploy:start": start,
|
|
54520
|
+
"deploy:list": list,
|
|
54521
|
+
"deploy:get": get,
|
|
54522
|
+
"deploy:patch": patch,
|
|
54523
|
+
"deploy:putSecret": putSecret,
|
|
54524
|
+
"deploy:reportFinding": reportFinding,
|
|
54525
|
+
"deploy:finishScan": finishScan,
|
|
54526
|
+
"deploy:remove": remove
|
|
54527
|
+
};
|
|
54528
|
+
}
|
|
54529
|
+
|
|
54530
|
+
// src/deploy/receipt-store.ts
|
|
54531
|
+
var import_promises4 = __toESM(require("fs/promises"), 1);
|
|
54532
|
+
var import_node_path28 = __toESM(require("path"), 1);
|
|
54533
|
+
init_protocol();
|
|
54534
|
+
function createReceiptStore(deps) {
|
|
54535
|
+
let receipts = [];
|
|
54536
|
+
let flushTimer = null;
|
|
54537
|
+
async function load() {
|
|
54538
|
+
let raw;
|
|
54539
|
+
try {
|
|
54540
|
+
raw = await import_promises4.default.readFile(deps.filePath, "utf8");
|
|
54541
|
+
} catch (err) {
|
|
54542
|
+
if (err.code === "ENOENT") {
|
|
54543
|
+
receipts = [];
|
|
54544
|
+
return;
|
|
54545
|
+
}
|
|
54546
|
+
throw err;
|
|
54547
|
+
}
|
|
54548
|
+
const parsed = JSON.parse(raw);
|
|
54549
|
+
if (parsed.version !== 1) throw new Error(`deploy.json: unsupported version ${parsed.version}`);
|
|
54550
|
+
receipts = (parsed.receipts ?? []).map((r) => DeployReceiptSchema.parse(r));
|
|
54551
|
+
}
|
|
54552
|
+
async function flushNow() {
|
|
54553
|
+
if (flushTimer) {
|
|
54554
|
+
clearTimeout(flushTimer);
|
|
54555
|
+
flushTimer = null;
|
|
54556
|
+
}
|
|
54557
|
+
const content = { version: 1, receipts };
|
|
54558
|
+
await import_promises4.default.mkdir(import_node_path28.default.dirname(deps.filePath), { recursive: true });
|
|
54559
|
+
const tmp = `${deps.filePath}.tmp-${process.pid}-${deps.now()}`;
|
|
54560
|
+
await import_promises4.default.writeFile(tmp, JSON.stringify(content, null, 2), { encoding: "utf8", mode: 384 });
|
|
54561
|
+
await import_promises4.default.rename(tmp, deps.filePath);
|
|
54562
|
+
}
|
|
54563
|
+
function scheduleFlush() {
|
|
54564
|
+
if (flushTimer) return;
|
|
54565
|
+
flushTimer = setTimeout(() => {
|
|
54566
|
+
flushTimer = null;
|
|
54567
|
+
flushNow().catch((err) => deps.onFlushError?.(err));
|
|
54568
|
+
}, STORE_FLUSH_DEBOUNCE_MS);
|
|
54569
|
+
}
|
|
54570
|
+
return {
|
|
54571
|
+
load,
|
|
54572
|
+
flushNow,
|
|
54573
|
+
create(input) {
|
|
54574
|
+
const ts = deps.now();
|
|
54575
|
+
const receipt = {
|
|
54576
|
+
deployId: input.deployId,
|
|
54577
|
+
personaId: input.personaId,
|
|
54578
|
+
status: input.status,
|
|
54579
|
+
notes: [],
|
|
54580
|
+
fulfillment: {},
|
|
54581
|
+
gaps: [],
|
|
54582
|
+
createdAt: ts,
|
|
54583
|
+
updatedAt: ts
|
|
54584
|
+
};
|
|
54585
|
+
receipts.push(receipt);
|
|
54586
|
+
scheduleFlush();
|
|
54587
|
+
return receipt;
|
|
54588
|
+
},
|
|
54589
|
+
update(deployId, patch) {
|
|
54590
|
+
const idx = receipts.findIndex((r) => r.deployId === deployId);
|
|
54591
|
+
if (idx === -1) return void 0;
|
|
54592
|
+
const next = DeployReceiptSchema.parse({ ...receipts[idx], ...patch, updatedAt: deps.now() });
|
|
54593
|
+
receipts[idx] = next;
|
|
54594
|
+
scheduleFlush();
|
|
54595
|
+
return next;
|
|
54596
|
+
},
|
|
54597
|
+
get(deployId) {
|
|
54598
|
+
return receipts.find((r) => r.deployId === deployId);
|
|
54599
|
+
},
|
|
54600
|
+
list() {
|
|
54601
|
+
return [...receipts].sort((a, b2) => b2.createdAt - a.createdAt);
|
|
54602
|
+
},
|
|
54603
|
+
remove(deployId) {
|
|
54604
|
+
const idx = receipts.findIndex((r) => r.deployId === deployId);
|
|
54605
|
+
if (idx === -1) return false;
|
|
54606
|
+
receipts.splice(idx, 1);
|
|
54607
|
+
scheduleFlush();
|
|
54608
|
+
return true;
|
|
54609
|
+
}
|
|
54610
|
+
};
|
|
54611
|
+
}
|
|
54612
|
+
|
|
54613
|
+
// src/deploy/secret-store.ts
|
|
54614
|
+
var import_promises5 = __toESM(require("fs/promises"), 1);
|
|
54615
|
+
var import_node_path29 = __toESM(require("path"), 1);
|
|
54616
|
+
function createSecretStore(deps) {
|
|
54617
|
+
let entries = [];
|
|
54618
|
+
let flushTimer = null;
|
|
54619
|
+
const sameScope = (e, deployId, name, userId) => e.deployId === deployId && e.name === name && (e.userId ?? void 0) === (userId ?? void 0);
|
|
54620
|
+
async function load() {
|
|
54621
|
+
let raw;
|
|
54622
|
+
try {
|
|
54623
|
+
raw = await import_promises5.default.readFile(deps.filePath, "utf8");
|
|
54624
|
+
} catch (err) {
|
|
54625
|
+
if (err.code === "ENOENT") {
|
|
54626
|
+
entries = [];
|
|
54627
|
+
return;
|
|
54628
|
+
}
|
|
54629
|
+
throw err;
|
|
54630
|
+
}
|
|
54631
|
+
const parsed = JSON.parse(raw);
|
|
54632
|
+
if (parsed.version !== 1) throw new Error(`deploy-secrets.json: unsupported version ${parsed.version}`);
|
|
54633
|
+
entries = parsed.entries ?? [];
|
|
54634
|
+
}
|
|
54635
|
+
async function flushNow() {
|
|
54636
|
+
if (flushTimer) {
|
|
54637
|
+
clearTimeout(flushTimer);
|
|
54638
|
+
flushTimer = null;
|
|
54639
|
+
}
|
|
54640
|
+
const content = { version: 1, entries };
|
|
54641
|
+
await import_promises5.default.mkdir(import_node_path29.default.dirname(deps.filePath), { recursive: true });
|
|
54642
|
+
const tmp = `${deps.filePath}.tmp-${process.pid}-${deps.now()}`;
|
|
54643
|
+
await import_promises5.default.writeFile(tmp, JSON.stringify(content, null, 2), { encoding: "utf8", mode: 384 });
|
|
54644
|
+
await import_promises5.default.rename(tmp, deps.filePath);
|
|
54645
|
+
}
|
|
54646
|
+
function scheduleFlush() {
|
|
54647
|
+
if (flushTimer) return;
|
|
54648
|
+
flushTimer = setTimeout(() => {
|
|
54649
|
+
flushTimer = null;
|
|
54650
|
+
flushNow().catch((err) => deps.onFlushError?.(err));
|
|
54651
|
+
}, STORE_FLUSH_DEBOUNCE_MS);
|
|
54652
|
+
}
|
|
54653
|
+
return {
|
|
54654
|
+
load,
|
|
54655
|
+
flushNow,
|
|
54656
|
+
put(entry) {
|
|
54657
|
+
const idx = entries.findIndex((e) => sameScope(e, entry.deployId, entry.name, entry.userId));
|
|
54658
|
+
if (idx === -1) {
|
|
54659
|
+
entries.push({ ...entry, updatedAt: deps.now() });
|
|
54660
|
+
} else {
|
|
54661
|
+
entries[idx] = {
|
|
54662
|
+
...entries[idx],
|
|
54663
|
+
values: { ...entries[idx].values, ...entry.values },
|
|
54664
|
+
updatedAt: deps.now()
|
|
54665
|
+
};
|
|
54666
|
+
}
|
|
54667
|
+
scheduleFlush();
|
|
54668
|
+
},
|
|
54669
|
+
resolve(deployId, userId) {
|
|
54670
|
+
const out = {};
|
|
54671
|
+
for (const e of entries) {
|
|
54672
|
+
if (e.deployId !== deployId || e.userId !== void 0) continue;
|
|
54673
|
+
Object.assign(out, e.values);
|
|
54674
|
+
}
|
|
54675
|
+
if (userId !== void 0) {
|
|
54676
|
+
for (const e of entries) {
|
|
54677
|
+
if (e.deployId !== deployId || e.userId !== userId) continue;
|
|
54678
|
+
Object.assign(out, e.values);
|
|
54679
|
+
}
|
|
54680
|
+
}
|
|
54681
|
+
return out;
|
|
54682
|
+
},
|
|
54683
|
+
filledKeys(deployId, name, userId) {
|
|
54684
|
+
const e = entries.find((x) => sameScope(x, deployId, name, userId));
|
|
54685
|
+
if (!e) return [];
|
|
54686
|
+
return Object.keys(e.values).filter((k2) => e.values[k2].length > 0);
|
|
54687
|
+
},
|
|
54688
|
+
removeDeploy(deployId) {
|
|
54689
|
+
const before = entries.length;
|
|
54690
|
+
entries = entries.filter((e) => e.deployId !== deployId);
|
|
54691
|
+
const removed = before - entries.length;
|
|
54692
|
+
if (removed > 0) scheduleFlush();
|
|
54693
|
+
return removed;
|
|
54694
|
+
}
|
|
54695
|
+
};
|
|
54696
|
+
}
|
|
54697
|
+
|
|
54698
|
+
// src/deploy/scan-task.ts
|
|
54699
|
+
var BUTLER_PERSONA_ID = "persona-clawd-butler";
|
|
54700
|
+
var SCANNABLE_ASSETS = ["deploy-kit"];
|
|
54701
|
+
function settleEndedScan(outcome, current) {
|
|
54702
|
+
if (current?.status !== "scanning") return void 0;
|
|
54703
|
+
return {
|
|
54704
|
+
status: "scanFailed",
|
|
54705
|
+
error: "error" in outcome ? outcome.error : "butler \u4F1A\u8BDD\u7ED3\u675F\u4E86\u4F46\u6CA1\u6709\u8C03 finishScan"
|
|
54706
|
+
};
|
|
54707
|
+
}
|
|
54708
|
+
function reconcileInterruptedScans(deps) {
|
|
54709
|
+
const stale = deps.list().filter((r) => r.status === "scanning");
|
|
54710
|
+
for (const r of stale) {
|
|
54711
|
+
deps.update(r.deployId, { status: "scanFailed", error: "daemon \u91CD\u542F\uFF0C\u626B\u63CF\u4F1A\u8BDD\u5DF2\u4E2D\u65AD\u2014\u2014\u8BF7\u91CD\u65B0\u626B\u63CF" });
|
|
54712
|
+
}
|
|
54713
|
+
return stale.map((r) => r.deployId);
|
|
54714
|
+
}
|
|
54715
|
+
|
|
54113
54716
|
// src/handlers/lark-bot.ts
|
|
54114
54717
|
init_protocol();
|
|
54115
54718
|
var PROVISION_ERROR_SET = new Set(LARK_BOT_PROVISION_ERROR_REASONS);
|
|
@@ -54498,9 +55101,9 @@ async function refreshTunnelUrlOnStartup(deps) {
|
|
|
54498
55101
|
|
|
54499
55102
|
// src/lark-bot-connector/binding-store.ts
|
|
54500
55103
|
var import_node_fs26 = __toESM(require("fs"), 1);
|
|
54501
|
-
var
|
|
55104
|
+
var import_node_path30 = __toESM(require("path"), 1);
|
|
54502
55105
|
function createLarkBotBindingStore(personaRoot) {
|
|
54503
|
-
const filePath = (personaId2) =>
|
|
55106
|
+
const filePath = (personaId2) => import_node_path30.default.join(personaRoot, safeFileName(personaId2), ".clawd", "lark-bot.json");
|
|
54504
55107
|
const read = (personaId2) => {
|
|
54505
55108
|
const file = filePath(personaId2);
|
|
54506
55109
|
if (!import_node_fs26.default.existsSync(file)) return null;
|
|
@@ -54514,7 +55117,7 @@ function createLarkBotBindingStore(personaRoot) {
|
|
|
54514
55117
|
};
|
|
54515
55118
|
const write = (personaId2, meta) => {
|
|
54516
55119
|
const file = filePath(personaId2);
|
|
54517
|
-
import_node_fs26.default.mkdirSync(
|
|
55120
|
+
import_node_fs26.default.mkdirSync(import_node_path30.default.dirname(file), { recursive: true });
|
|
54518
55121
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
54519
55122
|
import_node_fs26.default.writeFileSync(tmp, JSON.stringify(meta, null, 2), { mode: 384 });
|
|
54520
55123
|
import_node_fs26.default.renameSync(tmp, file);
|
|
@@ -54682,7 +55285,7 @@ function createLarkBotCloudClient(opts) {
|
|
|
54682
55285
|
|
|
54683
55286
|
// src/lark-bot-connector/chat-router.ts
|
|
54684
55287
|
var import_node_fs27 = __toESM(require("fs"), 1);
|
|
54685
|
-
var
|
|
55288
|
+
var import_node_path31 = __toESM(require("path"), 1);
|
|
54686
55289
|
init_protocol();
|
|
54687
55290
|
var ERROR_REPLY_TEXT = "\u5904\u7406\u51FA\u9519\u4E86\uFF0C\u8BF7\u91CD\u8BD5";
|
|
54688
55291
|
var LOCAL_TURN_RETRIES = 2;
|
|
@@ -54749,7 +55352,7 @@ function createLarkChatRouter(deps) {
|
|
|
54749
55352
|
}
|
|
54750
55353
|
const dir = deps.mediaRootFor(env.chatId);
|
|
54751
55354
|
import_node_fs27.default.mkdirSync(dir, { recursive: true });
|
|
54752
|
-
const p2 =
|
|
55355
|
+
const p2 = import_node_path31.default.join(dir, `${safeMediaName(ownerMessageId)}-${i}.${ext}`);
|
|
54753
55356
|
import_node_fs27.default.writeFileSync(p2, r.data);
|
|
54754
55357
|
lines.push(`[\u56FE\u7247: ${p2}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
|
|
54755
55358
|
} catch (err) {
|
|
@@ -54772,7 +55375,7 @@ function createLarkChatRouter(deps) {
|
|
|
54772
55375
|
}
|
|
54773
55376
|
const dir = deps.mediaRootFor(env.chatId);
|
|
54774
55377
|
import_node_fs27.default.mkdirSync(dir, { recursive: true });
|
|
54775
|
-
const p2 =
|
|
55378
|
+
const p2 = import_node_path31.default.join(dir, `${safeMediaName(ownerMessageId)}-${i}-${safeAttachmentName(f.name)}`);
|
|
54776
55379
|
import_node_fs27.default.writeFileSync(p2, r.data);
|
|
54777
55380
|
lines.push(`[\u6587\u4EF6: ${p2}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
|
|
54778
55381
|
} catch (err) {
|
|
@@ -55862,7 +56465,7 @@ var CodexHistoryReader = class {
|
|
|
55862
56465
|
};
|
|
55863
56466
|
|
|
55864
56467
|
// src/tools/codex-skills.ts
|
|
55865
|
-
var
|
|
56468
|
+
var import_node_path32 = __toESM(require("path"), 1);
|
|
55866
56469
|
function str3(v2) {
|
|
55867
56470
|
return typeof v2 === "string" ? v2 : void 0;
|
|
55868
56471
|
}
|
|
@@ -55877,13 +56480,13 @@ function mapSkillsListResponse(res) {
|
|
|
55877
56480
|
const r = s ?? {};
|
|
55878
56481
|
const name = str3(r.name);
|
|
55879
56482
|
if (!name) continue;
|
|
55880
|
-
const
|
|
56483
|
+
const path93 = str3(r.path);
|
|
55881
56484
|
const description = str3(r.description);
|
|
55882
56485
|
const isPlugin = name.includes(":");
|
|
55883
56486
|
out.push({
|
|
55884
56487
|
name,
|
|
55885
56488
|
source: isPlugin ? "plugin" : "project",
|
|
55886
|
-
...
|
|
56489
|
+
...path93 ? { path: path93 } : {},
|
|
55887
56490
|
...description ? { description } : {},
|
|
55888
56491
|
...isPlugin ? { plugin: name.split(":")[0] } : {}
|
|
55889
56492
|
});
|
|
@@ -55899,14 +56502,14 @@ async function listCodexSkills(cwd, deps = {}) {
|
|
|
55899
56502
|
// 先写 extraRoots 再写 list(stdio 按写入顺序处理,fire-and-forget 不 await 回包;
|
|
55900
56503
|
// codex-session.ts ready 序列同款,两处保持一致)。失败不阻塞 list。
|
|
55901
56504
|
beforeRequest: (client) => {
|
|
55902
|
-
void client.request("skills/extraRoots/set", { extraRoots: [
|
|
56505
|
+
void client.request("skills/extraRoots/set", { extraRoots: [import_node_path32.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
|
|
55903
56506
|
}
|
|
55904
56507
|
});
|
|
55905
56508
|
return mapSkillsListResponse(res);
|
|
55906
56509
|
}
|
|
55907
56510
|
|
|
55908
56511
|
// src/tools/codex-turn-context.ts
|
|
55909
|
-
var
|
|
56512
|
+
var import_promises6 = __toESM(require("fs/promises"), 1);
|
|
55910
56513
|
function parseTurnContextFromRollout(raw) {
|
|
55911
56514
|
const lines = raw.split("\n");
|
|
55912
56515
|
for (let i = lines.length - 1; i >= 0; i--) {
|
|
@@ -55941,7 +56544,7 @@ async function readCodexTurnContext(args, deps = {}) {
|
|
|
55941
56544
|
);
|
|
55942
56545
|
const rolloutPath = str4(rec3(res?.thread)?.path);
|
|
55943
56546
|
if (!rolloutPath) return null;
|
|
55944
|
-
return parseTurnContextFromRollout(await
|
|
56547
|
+
return parseTurnContextFromRollout(await import_promises6.default.readFile(rolloutPath, "utf8"));
|
|
55945
56548
|
}
|
|
55946
56549
|
function createCodexResolvedMetaHydrator(deps) {
|
|
55947
56550
|
const fetchedThreadIds = /* @__PURE__ */ new Set();
|
|
@@ -55986,14 +56589,14 @@ function str4(v2) {
|
|
|
55986
56589
|
// src/workspace/browser.ts
|
|
55987
56590
|
var import_node_fs28 = __toESM(require("fs"), 1);
|
|
55988
56591
|
var import_node_os8 = __toESM(require("os"), 1);
|
|
55989
|
-
var
|
|
56592
|
+
var import_node_path33 = __toESM(require("path"), 1);
|
|
55990
56593
|
init_protocol();
|
|
55991
56594
|
var MAX_FILE_BYTES2 = 2 * 1024 * 1024;
|
|
55992
56595
|
function resolveInsideCwd(cwd, subpath) {
|
|
55993
|
-
const absCwd =
|
|
55994
|
-
const joined =
|
|
55995
|
-
const rel =
|
|
55996
|
-
if (rel.startsWith("..") ||
|
|
56596
|
+
const absCwd = import_node_path33.default.resolve(cwd);
|
|
56597
|
+
const joined = import_node_path33.default.resolve(absCwd, subpath ?? ".");
|
|
56598
|
+
const rel = import_node_path33.default.relative(absCwd, joined);
|
|
56599
|
+
if (rel.startsWith("..") || import_node_path33.default.isAbsolute(rel)) {
|
|
55997
56600
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
|
|
55998
56601
|
}
|
|
55999
56602
|
return joined;
|
|
@@ -56024,7 +56627,7 @@ var WorkspaceBrowser = class {
|
|
|
56024
56627
|
mtime: ""
|
|
56025
56628
|
};
|
|
56026
56629
|
try {
|
|
56027
|
-
const st = import_node_fs28.default.statSync(
|
|
56630
|
+
const st = import_node_fs28.default.statSync(import_node_path33.default.join(full, d.name));
|
|
56028
56631
|
entry.mtime = new Date(st.mtimeMs).toISOString();
|
|
56029
56632
|
if (d.isFile()) entry.size = st.size;
|
|
56030
56633
|
} catch {
|
|
@@ -56071,7 +56674,7 @@ var WorkspaceBrowser = class {
|
|
|
56071
56674
|
// src/skills/agents-scanner.ts
|
|
56072
56675
|
var import_node_fs29 = __toESM(require("fs"), 1);
|
|
56073
56676
|
var import_node_os9 = __toESM(require("os"), 1);
|
|
56074
|
-
var
|
|
56677
|
+
var import_node_path34 = __toESM(require("path"), 1);
|
|
56075
56678
|
var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
|
|
56076
56679
|
function isDirLikeSync2(p2) {
|
|
56077
56680
|
try {
|
|
@@ -56109,10 +56712,10 @@ function scanAgentsDir(dir, source, seen, out) {
|
|
|
56109
56712
|
}
|
|
56110
56713
|
for (const ent of entries) {
|
|
56111
56714
|
if (!ent.name.endsWith(".md")) continue;
|
|
56112
|
-
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(
|
|
56715
|
+
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path34.default.join(dir, ent.name)))) {
|
|
56113
56716
|
continue;
|
|
56114
56717
|
}
|
|
56115
|
-
const filePath =
|
|
56718
|
+
const filePath = import_node_path34.default.join(dir, ent.name);
|
|
56116
56719
|
const baseName = ent.name.replace(/\.md$/, "");
|
|
56117
56720
|
if (seen.has(baseName)) continue;
|
|
56118
56721
|
seen.add(baseName);
|
|
@@ -56135,7 +56738,7 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
56135
56738
|
return;
|
|
56136
56739
|
}
|
|
56137
56740
|
for (const ent of entries) {
|
|
56138
|
-
const childPath =
|
|
56741
|
+
const childPath = import_node_path34.default.join(dir, ent.name);
|
|
56139
56742
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
|
|
56140
56743
|
walk2(childPath, [...namespaces, ent.name]);
|
|
56141
56744
|
continue;
|
|
@@ -56160,9 +56763,9 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
56160
56763
|
walk2(root, []);
|
|
56161
56764
|
}
|
|
56162
56765
|
function readInstalledPlugins2(home) {
|
|
56163
|
-
const pluginsDir =
|
|
56164
|
-
const v2 =
|
|
56165
|
-
const v1 =
|
|
56766
|
+
const pluginsDir = import_node_path34.default.join(home, ".claude", "plugins");
|
|
56767
|
+
const v2 = import_node_path34.default.join(pluginsDir, "installed_plugins_v2.json");
|
|
56768
|
+
const v1 = import_node_path34.default.join(pluginsDir, "installed_plugins.json");
|
|
56166
56769
|
let raw = null;
|
|
56167
56770
|
for (const candidate of [v2, v1]) {
|
|
56168
56771
|
try {
|
|
@@ -56191,19 +56794,19 @@ function readInstalledPlugins2(home) {
|
|
|
56191
56794
|
return out;
|
|
56192
56795
|
}
|
|
56193
56796
|
function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
|
|
56194
|
-
let cur =
|
|
56195
|
-
const fsRoot =
|
|
56797
|
+
let cur = import_node_path34.default.resolve(startCwd);
|
|
56798
|
+
const fsRoot = import_node_path34.default.parse(cur).root;
|
|
56196
56799
|
while (true) {
|
|
56197
|
-
scanAgentsDir(
|
|
56800
|
+
scanAgentsDir(import_node_path34.default.join(cur, ".claude", "agents"), "project", seen, out);
|
|
56198
56801
|
let hasGit = false;
|
|
56199
56802
|
try {
|
|
56200
|
-
hasGit = import_node_fs29.default.existsSync(
|
|
56803
|
+
hasGit = import_node_fs29.default.existsSync(import_node_path34.default.join(cur, ".git"));
|
|
56201
56804
|
} catch {
|
|
56202
56805
|
}
|
|
56203
56806
|
if (hasGit) return;
|
|
56204
56807
|
if (cur === home) return;
|
|
56205
56808
|
if (cur === fsRoot) return;
|
|
56206
|
-
const parent =
|
|
56809
|
+
const parent = import_node_path34.default.dirname(cur);
|
|
56207
56810
|
if (parent === cur) return;
|
|
56208
56811
|
cur = parent;
|
|
56209
56812
|
}
|
|
@@ -56238,7 +56841,7 @@ var AgentsScanner = class {
|
|
|
56238
56841
|
}
|
|
56239
56842
|
const fsBlock = [];
|
|
56240
56843
|
scanAgentsDir(
|
|
56241
|
-
|
|
56844
|
+
import_node_path34.default.join(this.home, ".claude", "agents"),
|
|
56242
56845
|
"global",
|
|
56243
56846
|
seen,
|
|
56244
56847
|
fsBlock
|
|
@@ -56252,7 +56855,7 @@ var AgentsScanner = class {
|
|
|
56252
56855
|
...this.extraPluginRoots
|
|
56253
56856
|
];
|
|
56254
56857
|
for (const { name, root } of plugins) {
|
|
56255
|
-
const agentsRoot =
|
|
56858
|
+
const agentsRoot = import_node_path34.default.join(root, "agents");
|
|
56256
56859
|
scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
|
|
56257
56860
|
}
|
|
56258
56861
|
return [...builtinBlock, ...fsBlock];
|
|
@@ -56262,13 +56865,13 @@ var AgentsScanner = class {
|
|
|
56262
56865
|
// src/observer/session-observer.ts
|
|
56263
56866
|
var import_node_fs31 = __toESM(require("fs"), 1);
|
|
56264
56867
|
var import_node_os11 = __toESM(require("os"), 1);
|
|
56265
|
-
var
|
|
56868
|
+
var import_node_path36 = __toESM(require("path"), 1);
|
|
56266
56869
|
init_claude_history();
|
|
56267
56870
|
|
|
56268
56871
|
// src/observer/subagent-meta-observer.ts
|
|
56269
56872
|
var import_node_fs30 = __toESM(require("fs"), 1);
|
|
56270
56873
|
var import_node_os10 = __toESM(require("os"), 1);
|
|
56271
|
-
var
|
|
56874
|
+
var import_node_path35 = __toESM(require("path"), 1);
|
|
56272
56875
|
init_claude_history();
|
|
56273
56876
|
var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
|
|
56274
56877
|
var SubagentMetaObserver = class {
|
|
@@ -56281,7 +56884,7 @@ var SubagentMetaObserver = class {
|
|
|
56281
56884
|
watches = /* @__PURE__ */ new Map();
|
|
56282
56885
|
// public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
|
|
56283
56886
|
resolveSubagentDir(cwd, toolSessionId) {
|
|
56284
|
-
return
|
|
56887
|
+
return import_node_path35.default.join(
|
|
56285
56888
|
this.home,
|
|
56286
56889
|
".claude",
|
|
56287
56890
|
"projects",
|
|
@@ -56337,7 +56940,7 @@ var SubagentMetaObserver = class {
|
|
|
56337
56940
|
if (!m2) return;
|
|
56338
56941
|
const agentId = m2[1];
|
|
56339
56942
|
if (w2.emitted.has(agentId)) return;
|
|
56340
|
-
const file =
|
|
56943
|
+
const file = import_node_path35.default.join(w2.dirPath, name);
|
|
56341
56944
|
let raw;
|
|
56342
56945
|
try {
|
|
56343
56946
|
raw = import_node_fs30.default.readFileSync(file, "utf8");
|
|
@@ -56397,7 +57000,7 @@ var SessionObserver = class {
|
|
|
56397
57000
|
metaObserver;
|
|
56398
57001
|
resolveJsonlPath(cwd, toolSessionId, override) {
|
|
56399
57002
|
if (override) return override;
|
|
56400
|
-
return
|
|
57003
|
+
return import_node_path36.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
|
|
56401
57004
|
}
|
|
56402
57005
|
start(args) {
|
|
56403
57006
|
this.stop(args.sessionId);
|
|
@@ -56423,10 +57026,10 @@ var SessionObserver = class {
|
|
|
56423
57026
|
lastDeriveMs: 0
|
|
56424
57027
|
};
|
|
56425
57028
|
try {
|
|
56426
|
-
import_node_fs31.default.mkdirSync(
|
|
57029
|
+
import_node_fs31.default.mkdirSync(import_node_path36.default.dirname(filePath), { recursive: true });
|
|
56427
57030
|
} catch {
|
|
56428
57031
|
}
|
|
56429
|
-
w2.watcher = import_node_fs31.default.watch(
|
|
57032
|
+
w2.watcher = import_node_fs31.default.watch(import_node_path36.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
|
|
56430
57033
|
if (!changedName || !w2.filePath.endsWith(changedName)) return;
|
|
56431
57034
|
this.poll(w2);
|
|
56432
57035
|
});
|
|
@@ -56523,7 +57126,7 @@ var SessionObserver = class {
|
|
|
56523
57126
|
const now = Date.now();
|
|
56524
57127
|
if (now - w2.lastRelocateScanMs < 1e3) return;
|
|
56525
57128
|
w2.lastRelocateScanMs = now;
|
|
56526
|
-
const projectsRoot =
|
|
57129
|
+
const projectsRoot = import_node_path36.default.join(this.home, ".claude", "projects");
|
|
56527
57130
|
const found = findTranscriptByToolSessionId(projectsRoot, w2.toolSessionId);
|
|
56528
57131
|
if (!found || found === w2.filePath) return;
|
|
56529
57132
|
try {
|
|
@@ -56532,7 +57135,7 @@ var SessionObserver = class {
|
|
|
56532
57135
|
}
|
|
56533
57136
|
w2.filePath = found;
|
|
56534
57137
|
try {
|
|
56535
|
-
w2.watcher = import_node_fs31.default.watch(
|
|
57138
|
+
w2.watcher = import_node_fs31.default.watch(import_node_path36.default.dirname(found), { persistent: false }, (_event, changedName) => {
|
|
56536
57139
|
if (!changedName || !w2.filePath.endsWith(changedName)) return;
|
|
56537
57140
|
this.poll(w2);
|
|
56538
57141
|
});
|
|
@@ -56655,7 +57258,7 @@ function listRegistered() {
|
|
|
56655
57258
|
var import_node_child_process8 = require("child_process");
|
|
56656
57259
|
var import_node_fs32 = __toESM(require("fs"), 1);
|
|
56657
57260
|
var import_node_os12 = __toESM(require("os"), 1);
|
|
56658
|
-
var
|
|
57261
|
+
var import_node_path37 = __toESM(require("path"), 1);
|
|
56659
57262
|
var TITLE_GEN_DIR_PREFIX = "clawd-title-";
|
|
56660
57263
|
var TITLE_MODEL_BY_TOOL = {
|
|
56661
57264
|
claude: "haiku",
|
|
@@ -56726,7 +57329,7 @@ async function generateSessionTitle(tool, firstMessage, deps = {}) {
|
|
|
56726
57329
|
if (!text) return null;
|
|
56727
57330
|
let workDir;
|
|
56728
57331
|
try {
|
|
56729
|
-
workDir = import_node_fs32.default.mkdtempSync(
|
|
57332
|
+
workDir = import_node_fs32.default.mkdtempSync(import_node_path37.default.join(import_node_os12.default.tmpdir(), TITLE_GEN_DIR_PREFIX));
|
|
56730
57333
|
} catch {
|
|
56731
57334
|
return null;
|
|
56732
57335
|
}
|
|
@@ -56736,8 +57339,8 @@ async function generateSessionTitle(tool, firstMessage, deps = {}) {
|
|
|
56736
57339
|
} catch {
|
|
56737
57340
|
}
|
|
56738
57341
|
};
|
|
56739
|
-
const outFile =
|
|
56740
|
-
const schemaFile =
|
|
57342
|
+
const outFile = import_node_path37.default.join(workDir, `codex-title-${process.pid}-${++outFileSeq}-${Date.now()}.txt`);
|
|
57343
|
+
const schemaFile = import_node_path37.default.join(workDir, "title-schema.json");
|
|
56741
57344
|
if (tool === "codex") {
|
|
56742
57345
|
try {
|
|
56743
57346
|
import_node_fs32.default.writeFileSync(schemaFile, CODEX_TITLE_SCHEMA);
|
|
@@ -57491,8 +58094,8 @@ async function authenticate(token, deps) {
|
|
|
57491
58094
|
}
|
|
57492
58095
|
|
|
57493
58096
|
// src/legacy-cleanup.ts
|
|
57494
|
-
var
|
|
57495
|
-
var
|
|
58097
|
+
var fs43 = __toESM(require("fs/promises"), 1);
|
|
58098
|
+
var path45 = __toESM(require("path"), 1);
|
|
57496
58099
|
var LEGACY_FILES = [
|
|
57497
58100
|
"personal-capability.json",
|
|
57498
58101
|
"received-capabilities.json",
|
|
@@ -57501,9 +58104,9 @@ var LEGACY_FILES = [
|
|
|
57501
58104
|
async function cleanupLegacyCapabilityFiles(dataDir, logger) {
|
|
57502
58105
|
const removed = [];
|
|
57503
58106
|
for (const name of LEGACY_FILES) {
|
|
57504
|
-
const p2 =
|
|
58107
|
+
const p2 = path45.join(dataDir, name);
|
|
57505
58108
|
try {
|
|
57506
|
-
await
|
|
58109
|
+
await fs43.unlink(p2);
|
|
57507
58110
|
removed.push(name);
|
|
57508
58111
|
logger.debug("legacy capability file removed", { file: name });
|
|
57509
58112
|
} catch (err) {
|
|
@@ -57515,13 +58118,13 @@ async function cleanupLegacyCapabilityFiles(dataDir, logger) {
|
|
|
57515
58118
|
}
|
|
57516
58119
|
|
|
57517
58120
|
// src/inbox/inbox-store.ts
|
|
57518
|
-
var
|
|
57519
|
-
var
|
|
58121
|
+
var fs44 = __toESM(require("fs"), 1);
|
|
58122
|
+
var path46 = __toESM(require("path"), 1);
|
|
57520
58123
|
var INBOX_SUBDIR = "inbox";
|
|
57521
58124
|
var InboxStore = class {
|
|
57522
58125
|
constructor(dataDir) {
|
|
57523
58126
|
this.dataDir = dataDir;
|
|
57524
|
-
|
|
58127
|
+
fs44.mkdirSync(this.dirPath(), { recursive: true });
|
|
57525
58128
|
}
|
|
57526
58129
|
dataDir;
|
|
57527
58130
|
/**
|
|
@@ -57533,7 +58136,7 @@ var InboxStore = class {
|
|
|
57533
58136
|
const file = this.filePath(peerDeviceId);
|
|
57534
58137
|
let raw;
|
|
57535
58138
|
try {
|
|
57536
|
-
raw =
|
|
58139
|
+
raw = fs44.readFileSync(file, "utf8");
|
|
57537
58140
|
} catch (err) {
|
|
57538
58141
|
if (err?.code === "ENOENT") return [];
|
|
57539
58142
|
return [];
|
|
@@ -57549,7 +58152,7 @@ var InboxStore = class {
|
|
|
57549
58152
|
const dir = this.dirPath();
|
|
57550
58153
|
let entries;
|
|
57551
58154
|
try {
|
|
57552
|
-
entries =
|
|
58155
|
+
entries = fs44.readdirSync(dir);
|
|
57553
58156
|
} catch (err) {
|
|
57554
58157
|
if (err?.code === "ENOENT") return [];
|
|
57555
58158
|
return [];
|
|
@@ -57565,9 +58168,9 @@ var InboxStore = class {
|
|
|
57565
58168
|
if (existing.some((m2) => m2.id === message.id)) return;
|
|
57566
58169
|
const file = this.filePath(message.peerDeviceId);
|
|
57567
58170
|
const line = JSON.stringify(message) + "\n";
|
|
57568
|
-
|
|
58171
|
+
fs44.appendFileSync(file, line, { mode: 384 });
|
|
57569
58172
|
try {
|
|
57570
|
-
|
|
58173
|
+
fs44.chmodSync(file, 384);
|
|
57571
58174
|
} catch {
|
|
57572
58175
|
}
|
|
57573
58176
|
}
|
|
@@ -57597,7 +58200,7 @@ var InboxStore = class {
|
|
|
57597
58200
|
removeByPeerDeviceId(peerDeviceId) {
|
|
57598
58201
|
const file = this.filePath(peerDeviceId);
|
|
57599
58202
|
try {
|
|
57600
|
-
|
|
58203
|
+
fs44.unlinkSync(file);
|
|
57601
58204
|
} catch (err) {
|
|
57602
58205
|
if (err?.code === "ENOENT") return;
|
|
57603
58206
|
}
|
|
@@ -57606,18 +58209,18 @@ var InboxStore = class {
|
|
|
57606
58209
|
const file = this.filePath(peerDeviceId);
|
|
57607
58210
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
57608
58211
|
const content = messages.map((m2) => JSON.stringify(m2)).join("\n") + (messages.length > 0 ? "\n" : "");
|
|
57609
|
-
|
|
57610
|
-
|
|
58212
|
+
fs44.writeFileSync(tmp, content, { mode: 384 });
|
|
58213
|
+
fs44.renameSync(tmp, file);
|
|
57611
58214
|
try {
|
|
57612
|
-
|
|
58215
|
+
fs44.chmodSync(file, 384);
|
|
57613
58216
|
} catch {
|
|
57614
58217
|
}
|
|
57615
58218
|
}
|
|
57616
58219
|
dirPath() {
|
|
57617
|
-
return
|
|
58220
|
+
return path46.join(this.dataDir, INBOX_SUBDIR);
|
|
57618
58221
|
}
|
|
57619
58222
|
filePath(peerDeviceId) {
|
|
57620
|
-
return
|
|
58223
|
+
return path46.join(this.dirPath(), `${peerDeviceId}.jsonl`);
|
|
57621
58224
|
}
|
|
57622
58225
|
};
|
|
57623
58226
|
function parseAllLines(raw) {
|
|
@@ -57705,8 +58308,8 @@ var InboxManager = class {
|
|
|
57705
58308
|
};
|
|
57706
58309
|
|
|
57707
58310
|
// src/state/contact-store.ts
|
|
57708
|
-
var
|
|
57709
|
-
var
|
|
58311
|
+
var fs45 = __toESM(require("fs"), 1);
|
|
58312
|
+
var path47 = __toESM(require("path"), 1);
|
|
57710
58313
|
var FILE_NAME = "contacts.json";
|
|
57711
58314
|
var ContactStore = class {
|
|
57712
58315
|
constructor(dataDir) {
|
|
@@ -57716,10 +58319,10 @@ var ContactStore = class {
|
|
|
57716
58319
|
contacts = /* @__PURE__ */ new Map();
|
|
57717
58320
|
load() {
|
|
57718
58321
|
this.contacts.clear();
|
|
57719
|
-
const file =
|
|
58322
|
+
const file = path47.join(this.dataDir, FILE_NAME);
|
|
57720
58323
|
let raw;
|
|
57721
58324
|
try {
|
|
57722
|
-
raw =
|
|
58325
|
+
raw = fs45.readFileSync(file, "utf8");
|
|
57723
58326
|
} catch (err) {
|
|
57724
58327
|
if (err?.code !== "ENOENT") this.renameBak(file);
|
|
57725
58328
|
return;
|
|
@@ -57800,20 +58403,20 @@ var ContactStore = class {
|
|
|
57800
58403
|
return true;
|
|
57801
58404
|
}
|
|
57802
58405
|
flush() {
|
|
57803
|
-
const file =
|
|
58406
|
+
const file = path47.join(this.dataDir, FILE_NAME);
|
|
57804
58407
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
57805
58408
|
const content = JSON.stringify(
|
|
57806
58409
|
{ contacts: Array.from(this.contacts.values()) },
|
|
57807
58410
|
null,
|
|
57808
58411
|
2
|
|
57809
58412
|
);
|
|
57810
|
-
|
|
57811
|
-
|
|
57812
|
-
|
|
58413
|
+
fs45.mkdirSync(this.dataDir, { recursive: true });
|
|
58414
|
+
fs45.writeFileSync(tmp, content, { mode: 384 });
|
|
58415
|
+
fs45.renameSync(tmp, file);
|
|
57813
58416
|
}
|
|
57814
58417
|
renameBak(file) {
|
|
57815
58418
|
try {
|
|
57816
|
-
|
|
58419
|
+
fs45.renameSync(file, `${file}.bak`);
|
|
57817
58420
|
} catch {
|
|
57818
58421
|
}
|
|
57819
58422
|
}
|
|
@@ -57921,61 +58524,61 @@ async function connectRemote(args) {
|
|
|
57921
58524
|
}
|
|
57922
58525
|
|
|
57923
58526
|
// src/migrations/2026-05-20-flatten-sessions.ts
|
|
57924
|
-
var
|
|
57925
|
-
var
|
|
58527
|
+
var fs46 = __toESM(require("fs"), 1);
|
|
58528
|
+
var path48 = __toESM(require("path"), 1);
|
|
57926
58529
|
var MIGRATION_FLAG_NAME = ".migration.v1.done";
|
|
57927
58530
|
function migrateFlattenSessions(opts) {
|
|
57928
58531
|
const dataDir = opts.dataDir;
|
|
57929
58532
|
const now = opts.now ?? Date.now;
|
|
57930
|
-
const sessionsDir =
|
|
57931
|
-
const flagPath =
|
|
58533
|
+
const sessionsDir = path48.join(dataDir, "sessions");
|
|
58534
|
+
const flagPath = path48.join(sessionsDir, MIGRATION_FLAG_NAME);
|
|
57932
58535
|
if (existsSync3(flagPath)) {
|
|
57933
58536
|
return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
|
|
57934
58537
|
}
|
|
57935
58538
|
let movedBare = 0;
|
|
57936
58539
|
let movedVmOwner = 0;
|
|
57937
58540
|
let archivedListener = 0;
|
|
57938
|
-
const defaultDir =
|
|
58541
|
+
const defaultDir = path48.join(sessionsDir, "default");
|
|
57939
58542
|
if (existsSync3(defaultDir)) {
|
|
57940
58543
|
for (const entry of readdirSafe(defaultDir)) {
|
|
57941
58544
|
if (!entry.endsWith(".json")) continue;
|
|
57942
|
-
const src =
|
|
57943
|
-
const dst =
|
|
57944
|
-
|
|
58545
|
+
const src = path48.join(defaultDir, entry);
|
|
58546
|
+
const dst = path48.join(sessionsDir, entry);
|
|
58547
|
+
fs46.renameSync(src, dst);
|
|
57945
58548
|
movedBare += 1;
|
|
57946
58549
|
}
|
|
57947
58550
|
rmdirIfEmpty(defaultDir);
|
|
57948
58551
|
}
|
|
57949
58552
|
for (const pid of readdirSafe(sessionsDir)) {
|
|
57950
|
-
const personaDir =
|
|
58553
|
+
const personaDir = path48.join(sessionsDir, pid);
|
|
57951
58554
|
if (!isDir(personaDir)) continue;
|
|
57952
58555
|
if (pid === "default") continue;
|
|
57953
|
-
const ownerSrc =
|
|
58556
|
+
const ownerSrc = path48.join(personaDir, "owner");
|
|
57954
58557
|
if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
|
|
57955
|
-
const ownerDst =
|
|
57956
|
-
|
|
58558
|
+
const ownerDst = path48.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
|
|
58559
|
+
fs46.mkdirSync(ownerDst, { recursive: true });
|
|
57957
58560
|
for (const file of readdirSafe(ownerSrc)) {
|
|
57958
58561
|
if (!file.endsWith(".json")) continue;
|
|
57959
|
-
|
|
58562
|
+
fs46.renameSync(path48.join(ownerSrc, file), path48.join(ownerDst, file));
|
|
57960
58563
|
movedVmOwner += 1;
|
|
57961
58564
|
}
|
|
57962
58565
|
rmdirIfEmpty(ownerSrc);
|
|
57963
58566
|
}
|
|
57964
|
-
const listenerSrc =
|
|
58567
|
+
const listenerSrc = path48.join(personaDir, "listener");
|
|
57965
58568
|
if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
|
|
57966
|
-
const archiveDst =
|
|
57967
|
-
|
|
58569
|
+
const archiveDst = path48.join(dataDir, ".legacy", `listener-${pid}`);
|
|
58570
|
+
fs46.mkdirSync(archiveDst, { recursive: true });
|
|
57968
58571
|
for (const file of readdirSafe(listenerSrc)) {
|
|
57969
58572
|
if (!file.endsWith(".json")) continue;
|
|
57970
|
-
|
|
58573
|
+
fs46.renameSync(path48.join(listenerSrc, file), path48.join(archiveDst, file));
|
|
57971
58574
|
archivedListener += 1;
|
|
57972
58575
|
}
|
|
57973
58576
|
rmdirIfEmpty(listenerSrc);
|
|
57974
58577
|
}
|
|
57975
58578
|
rmdirIfEmpty(personaDir);
|
|
57976
58579
|
}
|
|
57977
|
-
|
|
57978
|
-
|
|
58580
|
+
fs46.mkdirSync(sessionsDir, { recursive: true });
|
|
58581
|
+
fs46.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
|
|
57979
58582
|
return {
|
|
57980
58583
|
skipped: false,
|
|
57981
58584
|
flagWritten: true,
|
|
@@ -57986,7 +58589,7 @@ function migrateFlattenSessions(opts) {
|
|
|
57986
58589
|
}
|
|
57987
58590
|
function existsSync3(p2) {
|
|
57988
58591
|
try {
|
|
57989
|
-
|
|
58592
|
+
fs46.statSync(p2);
|
|
57990
58593
|
return true;
|
|
57991
58594
|
} catch {
|
|
57992
58595
|
return false;
|
|
@@ -57994,61 +58597,61 @@ function existsSync3(p2) {
|
|
|
57994
58597
|
}
|
|
57995
58598
|
function isDir(p2) {
|
|
57996
58599
|
try {
|
|
57997
|
-
return
|
|
58600
|
+
return fs46.statSync(p2).isDirectory();
|
|
57998
58601
|
} catch {
|
|
57999
58602
|
return false;
|
|
58000
58603
|
}
|
|
58001
58604
|
}
|
|
58002
58605
|
function readdirSafe(p2) {
|
|
58003
58606
|
try {
|
|
58004
|
-
return
|
|
58607
|
+
return fs46.readdirSync(p2);
|
|
58005
58608
|
} catch {
|
|
58006
58609
|
return [];
|
|
58007
58610
|
}
|
|
58008
58611
|
}
|
|
58009
58612
|
function rmdirIfEmpty(p2) {
|
|
58010
58613
|
try {
|
|
58011
|
-
|
|
58614
|
+
fs46.rmdirSync(p2);
|
|
58012
58615
|
} catch {
|
|
58013
58616
|
}
|
|
58014
58617
|
}
|
|
58015
58618
|
|
|
58016
58619
|
// src/migrations/2026-08-18-drop-seeded-projects.ts
|
|
58017
|
-
var
|
|
58018
|
-
var
|
|
58620
|
+
var fs47 = __toESM(require("fs"), 1);
|
|
58621
|
+
var path49 = __toESM(require("path"), 1);
|
|
58019
58622
|
var DROP_SEEDED_PROJECTS_FLAG = ".projects-seed-dropped.v1.done";
|
|
58020
58623
|
function dropSeededProjects(opts) {
|
|
58021
|
-
|
|
58022
|
-
const flag =
|
|
58023
|
-
if (
|
|
58024
|
-
const file =
|
|
58624
|
+
fs47.mkdirSync(opts.dataDir, { recursive: true });
|
|
58625
|
+
const flag = path49.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
|
|
58626
|
+
if (fs47.existsSync(flag)) return { skipped: true, dropped: 0, backup: null };
|
|
58627
|
+
const file = path49.join(opts.dataDir, "projects.json");
|
|
58025
58628
|
let raw = null;
|
|
58026
58629
|
let dropped = 0;
|
|
58027
58630
|
try {
|
|
58028
|
-
raw =
|
|
58631
|
+
raw = fs47.readFileSync(file, "utf8");
|
|
58029
58632
|
dropped = JSON.parse(raw).projects?.length ?? 0;
|
|
58030
58633
|
} catch {
|
|
58031
58634
|
}
|
|
58032
58635
|
let backup = null;
|
|
58033
58636
|
if (raw != null && dropped > 0) {
|
|
58034
|
-
const dir =
|
|
58035
|
-
|
|
58036
|
-
backup =
|
|
58037
|
-
|
|
58637
|
+
const dir = path49.join(opts.dataDir, "backups");
|
|
58638
|
+
fs47.mkdirSync(dir, { recursive: true });
|
|
58639
|
+
backup = path49.join(dir, `projects.seed-dropped.${(opts.now ?? Date.now)()}.json`);
|
|
58640
|
+
fs47.writeFileSync(backup, raw);
|
|
58038
58641
|
}
|
|
58039
58642
|
if (raw != null || dropped > 0) {
|
|
58040
|
-
|
|
58643
|
+
fs47.writeFileSync(file, JSON.stringify({ projects: [] }, null, 2));
|
|
58041
58644
|
}
|
|
58042
|
-
|
|
58645
|
+
fs47.writeFileSync(flag, (/* @__PURE__ */ new Date()).toISOString());
|
|
58043
58646
|
return { skipped: false, dropped, backup };
|
|
58044
58647
|
}
|
|
58045
58648
|
|
|
58046
58649
|
// src/transport/http-router.ts
|
|
58047
58650
|
var import_node_fs34 = __toESM(require("fs"), 1);
|
|
58048
|
-
var
|
|
58651
|
+
var import_node_path41 = __toESM(require("path"), 1);
|
|
58049
58652
|
|
|
58050
58653
|
// src/attachment/mime.ts
|
|
58051
|
-
var
|
|
58654
|
+
var import_node_path38 = __toESM(require("path"), 1);
|
|
58052
58655
|
var TEXT_PLAIN = "text/plain; charset=utf-8";
|
|
58053
58656
|
var EXT_TO_NATIVE_MIME = {
|
|
58054
58657
|
// 图片
|
|
@@ -58155,7 +58758,7 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
58155
58758
|
".mk"
|
|
58156
58759
|
]);
|
|
58157
58760
|
function lookupMime(filePathOrName) {
|
|
58158
|
-
const ext =
|
|
58761
|
+
const ext = import_node_path38.default.extname(filePathOrName).toLowerCase();
|
|
58159
58762
|
if (EXT_TO_NATIVE_MIME[ext]) return EXT_TO_NATIVE_MIME[ext];
|
|
58160
58763
|
if (TEXT_EXTENSIONS.has(ext)) return TEXT_PLAIN;
|
|
58161
58764
|
return "application/octet-stream";
|
|
@@ -58226,9 +58829,9 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
|
|
|
58226
58829
|
|
|
58227
58830
|
// src/attachment/upload.ts
|
|
58228
58831
|
var import_node_fs33 = __toESM(require("fs"), 1);
|
|
58229
|
-
var
|
|
58832
|
+
var import_node_path39 = __toESM(require("path"), 1);
|
|
58230
58833
|
var import_node_crypto10 = __toESM(require("crypto"), 1);
|
|
58231
|
-
var
|
|
58834
|
+
var import_promises7 = require("stream/promises");
|
|
58232
58835
|
var UploadError = class extends Error {
|
|
58233
58836
|
constructor(code, message) {
|
|
58234
58837
|
super(message);
|
|
@@ -58238,14 +58841,14 @@ var UploadError = class extends Error {
|
|
|
58238
58841
|
code;
|
|
58239
58842
|
};
|
|
58240
58843
|
function assertValidFileName(fileName) {
|
|
58241
|
-
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !==
|
|
58844
|
+
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path39.default.basename(fileName)) {
|
|
58242
58845
|
throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
|
|
58243
58846
|
}
|
|
58244
58847
|
}
|
|
58245
58848
|
var HASH_PREFIX_LEN = 16;
|
|
58246
58849
|
async function writeUploadedAttachment(args) {
|
|
58247
58850
|
assertValidFileName(args.fileName);
|
|
58248
|
-
const attachmentsRoot =
|
|
58851
|
+
const attachmentsRoot = import_node_path39.default.join(args.baseDir, ".attachments");
|
|
58249
58852
|
try {
|
|
58250
58853
|
import_node_fs33.default.mkdirSync(attachmentsRoot, { recursive: true });
|
|
58251
58854
|
} catch (err) {
|
|
@@ -58253,12 +58856,12 @@ async function writeUploadedAttachment(args) {
|
|
|
58253
58856
|
}
|
|
58254
58857
|
const hasher = import_node_crypto10.default.createHash("sha256");
|
|
58255
58858
|
let actualSize = 0;
|
|
58256
|
-
const tmpPath =
|
|
58859
|
+
const tmpPath = import_node_path39.default.join(
|
|
58257
58860
|
attachmentsRoot,
|
|
58258
58861
|
`.upload-${process.pid}-${Date.now()}-${import_node_crypto10.default.randomBytes(4).toString("hex")}`
|
|
58259
58862
|
);
|
|
58260
58863
|
try {
|
|
58261
|
-
await (0,
|
|
58864
|
+
await (0, import_promises7.pipeline)(
|
|
58262
58865
|
args.body,
|
|
58263
58866
|
async function* (source) {
|
|
58264
58867
|
for await (const chunk of source) {
|
|
@@ -58288,7 +58891,7 @@ async function writeUploadedAttachment(args) {
|
|
|
58288
58891
|
);
|
|
58289
58892
|
}
|
|
58290
58893
|
const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
|
|
58291
|
-
const hashDir =
|
|
58894
|
+
const hashDir = import_node_path39.default.join(attachmentsRoot, attachmentId);
|
|
58292
58895
|
let finalFileName;
|
|
58293
58896
|
let hashDirExists = false;
|
|
58294
58897
|
try {
|
|
@@ -58306,7 +58909,7 @@ async function writeUploadedAttachment(args) {
|
|
|
58306
58909
|
try {
|
|
58307
58910
|
import_node_fs33.default.mkdirSync(hashDir, { recursive: true });
|
|
58308
58911
|
finalFileName = args.fileName;
|
|
58309
|
-
import_node_fs33.default.renameSync(tmpPath,
|
|
58912
|
+
import_node_fs33.default.renameSync(tmpPath, import_node_path39.default.join(hashDir, finalFileName));
|
|
58310
58913
|
} catch (err) {
|
|
58311
58914
|
try {
|
|
58312
58915
|
import_node_fs33.default.unlinkSync(tmpPath);
|
|
@@ -58315,7 +58918,7 @@ async function writeUploadedAttachment(args) {
|
|
|
58315
58918
|
throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
|
|
58316
58919
|
}
|
|
58317
58920
|
}
|
|
58318
|
-
const absPath =
|
|
58921
|
+
const absPath = import_node_path39.default.join(hashDir, finalFileName);
|
|
58319
58922
|
const relPath = absPath;
|
|
58320
58923
|
args.groupFileStore.upsert(args.scope, args.sessionId, {
|
|
58321
58924
|
relPath: absPath,
|
|
@@ -58329,8 +58932,8 @@ async function writeUploadedAttachment(args) {
|
|
|
58329
58932
|
}
|
|
58330
58933
|
|
|
58331
58934
|
// src/extension/import.ts
|
|
58332
|
-
var
|
|
58333
|
-
var
|
|
58935
|
+
var import_promises8 = __toESM(require("fs/promises"), 1);
|
|
58936
|
+
var import_node_path40 = __toESM(require("path"), 1);
|
|
58334
58937
|
var import_node_os13 = __toESM(require("os"), 1);
|
|
58335
58938
|
var import_jszip = __toESM(require_lib3(), 1);
|
|
58336
58939
|
var ImportError = class extends Error {
|
|
@@ -58348,7 +58951,7 @@ async function importZip(buf, root) {
|
|
|
58348
58951
|
throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
58349
58952
|
}
|
|
58350
58953
|
for (const name of Object.keys(zip.files)) {
|
|
58351
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
58954
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path40.default.isAbsolute(name)) {
|
|
58352
58955
|
throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
|
|
58353
58956
|
}
|
|
58354
58957
|
}
|
|
@@ -58381,33 +58984,33 @@ async function importZip(buf, root) {
|
|
|
58381
58984
|
);
|
|
58382
58985
|
}
|
|
58383
58986
|
}
|
|
58384
|
-
const destDir =
|
|
58987
|
+
const destDir = import_node_path40.default.join(root, manifest.id);
|
|
58385
58988
|
let destExists = false;
|
|
58386
58989
|
try {
|
|
58387
|
-
await
|
|
58990
|
+
await import_promises8.default.access(destDir);
|
|
58388
58991
|
destExists = true;
|
|
58389
58992
|
} catch {
|
|
58390
58993
|
}
|
|
58391
58994
|
if (destExists) {
|
|
58392
58995
|
throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
|
|
58393
58996
|
}
|
|
58394
|
-
const stage = await
|
|
58997
|
+
const stage = await import_promises8.default.mkdtemp(import_node_path40.default.join(import_node_os13.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
|
|
58395
58998
|
try {
|
|
58396
58999
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
58397
|
-
const dest =
|
|
59000
|
+
const dest = import_node_path40.default.join(stage, name);
|
|
58398
59001
|
if (entry.dir) {
|
|
58399
|
-
await
|
|
59002
|
+
await import_promises8.default.mkdir(dest, { recursive: true });
|
|
58400
59003
|
continue;
|
|
58401
59004
|
}
|
|
58402
|
-
await
|
|
59005
|
+
await import_promises8.default.mkdir(import_node_path40.default.dirname(dest), { recursive: true });
|
|
58403
59006
|
const content = await entry.async("nodebuffer");
|
|
58404
|
-
await
|
|
59007
|
+
await import_promises8.default.writeFile(dest, content);
|
|
58405
59008
|
}
|
|
58406
|
-
await
|
|
58407
|
-
await
|
|
59009
|
+
await import_promises8.default.mkdir(root, { recursive: true });
|
|
59010
|
+
await import_promises8.default.rename(stage, destDir);
|
|
58408
59011
|
return { extId: manifest.id };
|
|
58409
59012
|
} catch (e) {
|
|
58410
|
-
await
|
|
59013
|
+
await import_promises8.default.rm(stage, { recursive: true, force: true }).catch(() => {
|
|
58411
59014
|
});
|
|
58412
59015
|
throw e;
|
|
58413
59016
|
}
|
|
@@ -58429,7 +59032,7 @@ var SHARE_UI_ASSET_MIME = {
|
|
|
58429
59032
|
".wasm": "application/wasm"
|
|
58430
59033
|
};
|
|
58431
59034
|
function shareUiAssetMime(filePath) {
|
|
58432
|
-
const ext =
|
|
59035
|
+
const ext = import_node_path41.default.extname(filePath).toLowerCase();
|
|
58433
59036
|
return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
|
|
58434
59037
|
}
|
|
58435
59038
|
var AUTHED_RPC_ROUTE_PREFIX = "/rpc/";
|
|
@@ -58528,7 +59131,7 @@ function isValidUploadFileName(fileName) {
|
|
|
58528
59131
|
if (fileName === "." || fileName === "..") return false;
|
|
58529
59132
|
if (fileName.startsWith(".")) return false;
|
|
58530
59133
|
if (fileName.includes("/") || fileName.includes("\\")) return false;
|
|
58531
|
-
return fileName ===
|
|
59134
|
+
return fileName === import_node_path41.default.basename(fileName);
|
|
58532
59135
|
}
|
|
58533
59136
|
function createHttpRouter(deps) {
|
|
58534
59137
|
return async (req, res) => {
|
|
@@ -58764,7 +59367,7 @@ function createHttpRouter(deps) {
|
|
|
58764
59367
|
sendHtml(res, statusByCode[r.code], loader.renderErrorHtml(r.code, msgByCode[r.code]));
|
|
58765
59368
|
return true;
|
|
58766
59369
|
}
|
|
58767
|
-
sendHtml(res, 200, loader.renderViewerHtml(
|
|
59370
|
+
sendHtml(res, 200, loader.renderViewerHtml(import_node_path41.default.basename(r.absPath)));
|
|
58768
59371
|
return true;
|
|
58769
59372
|
}
|
|
58770
59373
|
const ctx = deps.authResolver.resolveFromHeader(
|
|
@@ -58885,7 +59488,7 @@ function createHttpRouter(deps) {
|
|
|
58885
59488
|
return true;
|
|
58886
59489
|
}
|
|
58887
59490
|
let absPath;
|
|
58888
|
-
if (
|
|
59491
|
+
if (import_node_path41.default.isAbsolute(pathParam)) {
|
|
58889
59492
|
absPath = pathParam;
|
|
58890
59493
|
} else if (deps.sessionStore) {
|
|
58891
59494
|
const file = deps.sessionStore.read(sid);
|
|
@@ -58893,7 +59496,7 @@ function createHttpRouter(deps) {
|
|
|
58893
59496
|
sendJson(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
|
|
58894
59497
|
return true;
|
|
58895
59498
|
}
|
|
58896
|
-
absPath =
|
|
59499
|
+
absPath = import_node_path41.default.join(file.cwd, pathParam);
|
|
58897
59500
|
} else {
|
|
58898
59501
|
sendJson(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
|
|
58899
59502
|
return true;
|
|
@@ -58995,7 +59598,7 @@ function streamFile(res, absPath, logger) {
|
|
|
58995
59598
|
return;
|
|
58996
59599
|
}
|
|
58997
59600
|
const mime = lookupMime(absPath);
|
|
58998
|
-
const basename2 =
|
|
59601
|
+
const basename2 = import_node_path41.default.basename(absPath);
|
|
58999
59602
|
res.writeHead(200, {
|
|
59000
59603
|
"Content-Type": mime,
|
|
59001
59604
|
"Content-Length": String(stat.size),
|
|
@@ -59013,7 +59616,7 @@ function streamFile(res, absPath, logger) {
|
|
|
59013
59616
|
|
|
59014
59617
|
// src/attachment/gc.ts
|
|
59015
59618
|
var import_node_fs35 = __toESM(require("fs"), 1);
|
|
59016
|
-
var
|
|
59619
|
+
var import_node_path42 = __toESM(require("path"), 1);
|
|
59017
59620
|
var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
|
|
59018
59621
|
function runAttachmentGc(args) {
|
|
59019
59622
|
const now = (args.now ?? Date.now)();
|
|
@@ -59022,12 +59625,12 @@ function runAttachmentGc(args) {
|
|
|
59022
59625
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
59023
59626
|
for (const entry of args.groupFileStore.list(scope, sessionId)) {
|
|
59024
59627
|
if (entry.stale) continue;
|
|
59025
|
-
if (
|
|
59628
|
+
if (import_node_path42.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
|
|
59026
59629
|
}
|
|
59027
59630
|
}
|
|
59028
59631
|
const visited = /* @__PURE__ */ new Set();
|
|
59029
59632
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
59030
|
-
const legacyDir = args.getSessionCwd?.(sessionId) ??
|
|
59633
|
+
const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path42.default.join(
|
|
59031
59634
|
args.dataDir,
|
|
59032
59635
|
"sessions",
|
|
59033
59636
|
...scopeSubPath(scope).map(safeFileName),
|
|
@@ -59040,7 +59643,7 @@ function runAttachmentGc(args) {
|
|
|
59040
59643
|
return true;
|
|
59041
59644
|
});
|
|
59042
59645
|
for (const rootDir of roots) {
|
|
59043
|
-
const attRoot =
|
|
59646
|
+
const attRoot = import_node_path42.default.join(rootDir, ".attachments");
|
|
59044
59647
|
let hashDirs;
|
|
59045
59648
|
try {
|
|
59046
59649
|
hashDirs = import_node_fs35.default.readdirSync(attRoot);
|
|
@@ -59050,7 +59653,7 @@ function runAttachmentGc(args) {
|
|
|
59050
59653
|
continue;
|
|
59051
59654
|
}
|
|
59052
59655
|
for (const hashDir of hashDirs) {
|
|
59053
|
-
const hashDirAbs =
|
|
59656
|
+
const hashDirAbs = import_node_path42.default.join(attRoot, hashDir);
|
|
59054
59657
|
let files;
|
|
59055
59658
|
try {
|
|
59056
59659
|
files = import_node_fs35.default.readdirSync(hashDirAbs);
|
|
@@ -59058,7 +59661,7 @@ function runAttachmentGc(args) {
|
|
|
59058
59661
|
continue;
|
|
59059
59662
|
}
|
|
59060
59663
|
for (const name of files) {
|
|
59061
|
-
const file =
|
|
59664
|
+
const file = import_node_path42.default.join(hashDirAbs, name);
|
|
59062
59665
|
let stat;
|
|
59063
59666
|
try {
|
|
59064
59667
|
stat = import_node_fs35.default.statSync(file);
|
|
@@ -59090,7 +59693,7 @@ function runAttachmentGc(args) {
|
|
|
59090
59693
|
|
|
59091
59694
|
// src/attachment/group.ts
|
|
59092
59695
|
var import_node_fs36 = __toESM(require("fs"), 1);
|
|
59093
|
-
var
|
|
59696
|
+
var import_node_path43 = __toESM(require("path"), 1);
|
|
59094
59697
|
var import_node_crypto11 = __toESM(require("crypto"), 1);
|
|
59095
59698
|
init_protocol();
|
|
59096
59699
|
var GroupFileStore = class {
|
|
@@ -59102,11 +59705,11 @@ var GroupFileStore = class {
|
|
|
59102
59705
|
this.logger = opts.logger;
|
|
59103
59706
|
}
|
|
59104
59707
|
rootForScope(scope) {
|
|
59105
|
-
return
|
|
59708
|
+
return import_node_path43.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
|
|
59106
59709
|
}
|
|
59107
59710
|
/** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
|
|
59108
59711
|
filePath(scope, sessionId) {
|
|
59109
|
-
return
|
|
59712
|
+
return import_node_path43.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
|
|
59110
59713
|
}
|
|
59111
59714
|
cacheKey(scope, sessionId) {
|
|
59112
59715
|
return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
|
|
@@ -59141,7 +59744,7 @@ var GroupFileStore = class {
|
|
|
59141
59744
|
}
|
|
59142
59745
|
writeFile(scope, sessionId, entries) {
|
|
59143
59746
|
const file = this.filePath(scope, sessionId);
|
|
59144
|
-
import_node_fs36.default.mkdirSync(
|
|
59747
|
+
import_node_fs36.default.mkdirSync(import_node_path43.default.dirname(file), { recursive: true });
|
|
59145
59748
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
59146
59749
|
import_node_fs36.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
|
|
59147
59750
|
import_node_fs36.default.renameSync(tmp, file);
|
|
@@ -59231,9 +59834,9 @@ var GroupFileStore = class {
|
|
|
59231
59834
|
|
|
59232
59835
|
// src/discovery/state-file.ts
|
|
59233
59836
|
var import_node_fs37 = __toESM(require("fs"), 1);
|
|
59234
|
-
var
|
|
59837
|
+
var import_node_path44 = __toESM(require("path"), 1);
|
|
59235
59838
|
function defaultStateFilePath(dataDir) {
|
|
59236
|
-
return
|
|
59839
|
+
return import_node_path44.default.join(dataDir, "state.json");
|
|
59237
59840
|
}
|
|
59238
59841
|
function isPidAlive(pid) {
|
|
59239
59842
|
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
@@ -59269,7 +59872,7 @@ var StateFileManager = class {
|
|
|
59269
59872
|
return { status: "stale", existing };
|
|
59270
59873
|
}
|
|
59271
59874
|
write(state) {
|
|
59272
|
-
import_node_fs37.default.mkdirSync(
|
|
59875
|
+
import_node_fs37.default.mkdirSync(import_node_path44.default.dirname(this.file), { recursive: true });
|
|
59273
59876
|
const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
|
|
59274
59877
|
import_node_fs37.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
|
|
59275
59878
|
import_node_fs37.default.renameSync(tmp, this.file);
|
|
@@ -59297,13 +59900,13 @@ function readSpawnedByDesktopFromEnv(env = process.env) {
|
|
|
59297
59900
|
|
|
59298
59901
|
// src/tunnel/tunnel-manager.ts
|
|
59299
59902
|
var import_node_fs41 = __toESM(require("fs"), 1);
|
|
59300
|
-
var
|
|
59903
|
+
var import_node_path48 = __toESM(require("path"), 1);
|
|
59301
59904
|
var import_node_crypto12 = __toESM(require("crypto"), 1);
|
|
59302
59905
|
var import_node_child_process11 = require("child_process");
|
|
59303
59906
|
|
|
59304
59907
|
// src/tunnel/tunnel-store.ts
|
|
59305
59908
|
var import_node_fs38 = __toESM(require("fs"), 1);
|
|
59306
|
-
var
|
|
59909
|
+
var import_node_path45 = __toESM(require("path"), 1);
|
|
59307
59910
|
var TunnelStore = class {
|
|
59308
59911
|
constructor(filePath) {
|
|
59309
59912
|
this.filePath = filePath;
|
|
@@ -59322,7 +59925,7 @@ var TunnelStore = class {
|
|
|
59322
59925
|
}
|
|
59323
59926
|
}
|
|
59324
59927
|
async set(v2) {
|
|
59325
|
-
const dir =
|
|
59928
|
+
const dir = import_node_path45.default.dirname(this.filePath);
|
|
59326
59929
|
await import_node_fs38.default.promises.mkdir(dir, { recursive: true });
|
|
59327
59930
|
const data = JSON.stringify(v2, null, 2);
|
|
59328
59931
|
const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
@@ -59434,10 +60037,10 @@ function escape(v2) {
|
|
|
59434
60037
|
// src/tunnel/frpc-binary.ts
|
|
59435
60038
|
var import_node_fs39 = __toESM(require("fs"), 1);
|
|
59436
60039
|
var import_node_os14 = __toESM(require("os"), 1);
|
|
59437
|
-
var
|
|
60040
|
+
var import_node_path46 = __toESM(require("path"), 1);
|
|
59438
60041
|
var import_node_child_process9 = require("child_process");
|
|
59439
60042
|
var import_node_stream3 = require("stream");
|
|
59440
|
-
var
|
|
60043
|
+
var import_promises9 = require("stream/promises");
|
|
59441
60044
|
var FRPC_VERSION = "0.68.0";
|
|
59442
60045
|
var UnsupportedPlatformError = class extends Error {
|
|
59443
60046
|
constructor(platform, arch) {
|
|
@@ -59473,13 +60076,13 @@ async function ensureFrpcBinary(opts) {
|
|
|
59473
60076
|
}
|
|
59474
60077
|
const version2 = opts.version ?? FRPC_VERSION;
|
|
59475
60078
|
const platform = opts.platform ?? detectPlatform();
|
|
59476
|
-
const binDir =
|
|
60079
|
+
const binDir = import_node_path46.default.join(opts.dataDir, "bin");
|
|
59477
60080
|
import_node_fs39.default.mkdirSync(binDir, { recursive: true });
|
|
59478
60081
|
cleanupStaleArtifacts(binDir);
|
|
59479
|
-
const stableBin =
|
|
60082
|
+
const stableBin = import_node_path46.default.join(binDir, "frpc");
|
|
59480
60083
|
if (import_node_fs39.default.existsSync(stableBin)) return stableBin;
|
|
59481
60084
|
const partialBin = `${stableBin}.partial`;
|
|
59482
|
-
const tarballPath =
|
|
60085
|
+
const tarballPath = import_node_path46.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
|
|
59483
60086
|
try {
|
|
59484
60087
|
const url = frpcDownloadUrl(version2, platform);
|
|
59485
60088
|
await downloadToFile(url, tarballPath, opts.fetchImpl);
|
|
@@ -59505,7 +60108,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
59505
60108
|
}
|
|
59506
60109
|
for (const name of entries) {
|
|
59507
60110
|
if (name.endsWith(".partial") || name.startsWith("extract-")) {
|
|
59508
|
-
const full =
|
|
60111
|
+
const full = import_node_path46.default.join(binDir, name);
|
|
59509
60112
|
try {
|
|
59510
60113
|
import_node_fs39.default.rmSync(full, { recursive: true, force: true });
|
|
59511
60114
|
} catch {
|
|
@@ -59528,10 +60131,10 @@ async function downloadToFile(url, dest, fetchImpl) {
|
|
|
59528
60131
|
}
|
|
59529
60132
|
const out = import_node_fs39.default.createWriteStream(dest);
|
|
59530
60133
|
const nodeStream = import_node_stream3.Readable.fromWeb(res.body);
|
|
59531
|
-
await (0,
|
|
60134
|
+
await (0, import_promises9.pipeline)(nodeStream, out);
|
|
59532
60135
|
}
|
|
59533
60136
|
async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
|
|
59534
|
-
const work =
|
|
60137
|
+
const work = import_node_path46.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
|
|
59535
60138
|
import_node_fs39.default.mkdirSync(work, { recursive: true });
|
|
59536
60139
|
try {
|
|
59537
60140
|
await new Promise((resolve9, reject) => {
|
|
@@ -59540,7 +60143,7 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
59540
60143
|
proc.on("exit", (code) => code === 0 ? resolve9() : reject(new Error(`tar exited ${code}`)));
|
|
59541
60144
|
});
|
|
59542
60145
|
const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
|
|
59543
|
-
const src =
|
|
60146
|
+
const src = import_node_path46.default.join(work, dirName, "frpc");
|
|
59544
60147
|
if (!import_node_fs39.default.existsSync(src)) {
|
|
59545
60148
|
throw new Error(`frpc not found inside tarball at ${src}`);
|
|
59546
60149
|
}
|
|
@@ -59552,10 +60155,10 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
59552
60155
|
|
|
59553
60156
|
// src/tunnel/frpc-process.ts
|
|
59554
60157
|
var import_node_fs40 = __toESM(require("fs"), 1);
|
|
59555
|
-
var
|
|
60158
|
+
var import_node_path47 = __toESM(require("path"), 1);
|
|
59556
60159
|
var import_node_child_process10 = require("child_process");
|
|
59557
60160
|
function frpcPidFilePath(dataDir) {
|
|
59558
|
-
return
|
|
60161
|
+
return import_node_path47.default.join(dataDir, "frpc.pid");
|
|
59559
60162
|
}
|
|
59560
60163
|
function writeFrpcPid(dataDir, pid) {
|
|
59561
60164
|
try {
|
|
@@ -59597,7 +60200,7 @@ function defaultSleep2(ms) {
|
|
|
59597
60200
|
}
|
|
59598
60201
|
async function killStaleFrpc(deps) {
|
|
59599
60202
|
const pidFile = frpcPidFilePath(deps.dataDir);
|
|
59600
|
-
const tomlPath =
|
|
60203
|
+
const tomlPath = import_node_path47.default.join(deps.dataDir, "frpc.toml");
|
|
59601
60204
|
const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
|
|
59602
60205
|
const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
|
|
59603
60206
|
const killPid = deps.killPidImpl ?? defaultKillPid;
|
|
@@ -59669,7 +60272,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
|
59669
60272
|
var TunnelManager = class {
|
|
59670
60273
|
constructor(deps) {
|
|
59671
60274
|
this.deps = deps;
|
|
59672
|
-
this.store = deps.store ?? new TunnelStore(
|
|
60275
|
+
this.store = deps.store ?? new TunnelStore(import_node_path48.default.join(deps.dataDir, "tunnel.json"));
|
|
59673
60276
|
this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
|
|
59674
60277
|
this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
|
|
59675
60278
|
}
|
|
@@ -59796,7 +60399,7 @@ var TunnelManager = class {
|
|
|
59796
60399
|
dataDir: this.deps.dataDir,
|
|
59797
60400
|
override: this.deps.frpcBinaryOverride ?? void 0
|
|
59798
60401
|
});
|
|
59799
|
-
const tomlPath =
|
|
60402
|
+
const tomlPath = import_node_path48.default.join(this.deps.dataDir, "frpc.toml");
|
|
59800
60403
|
const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto12.default.randomBytes(3).toString("hex")}`;
|
|
59801
60404
|
const toml = buildFrpcToml({
|
|
59802
60405
|
serverAddr: t.frpsHost,
|
|
@@ -59811,9 +60414,9 @@ var TunnelManager = class {
|
|
|
59811
60414
|
const proc = (this.deps.spawnImpl ?? import_node_child_process11.spawn)(frpcBin, ["-c", tomlPath], {
|
|
59812
60415
|
stdio: ["ignore", "pipe", "pipe"]
|
|
59813
60416
|
});
|
|
59814
|
-
const logDir =
|
|
60417
|
+
const logDir = import_node_path48.default.join(this.deps.dataDir, "log");
|
|
59815
60418
|
import_node_fs41.default.mkdirSync(logDir, { recursive: true });
|
|
59816
|
-
const logFilePath =
|
|
60419
|
+
const logFilePath = import_node_path48.default.join(logDir, "frpc.log");
|
|
59817
60420
|
const logStream = import_node_fs41.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
|
|
59818
60421
|
logStream.on("error", () => {
|
|
59819
60422
|
});
|
|
@@ -59897,15 +60500,15 @@ async function waitForFrpcReady(proc, timeoutMs) {
|
|
|
59897
60500
|
|
|
59898
60501
|
// src/tunnel/device-key.ts
|
|
59899
60502
|
var import_node_os15 = __toESM(require("os"), 1);
|
|
59900
|
-
var
|
|
60503
|
+
var import_node_path49 = __toESM(require("path"), 1);
|
|
59901
60504
|
var import_node_crypto13 = __toESM(require("crypto"), 1);
|
|
59902
60505
|
var DERIVE_SALT = "clawd-tunnel-device-v1";
|
|
59903
60506
|
function deriveStableDeviceKey(opts = {}) {
|
|
59904
60507
|
const hostname = opts.hostname ?? import_node_os15.default.hostname();
|
|
59905
60508
|
const uid = opts.uid ?? (typeof import_node_os15.default.userInfo === "function" ? import_node_os15.default.userInfo().uid : 0);
|
|
59906
60509
|
const home = opts.home ?? import_node_os15.default.homedir();
|
|
59907
|
-
const defaultDataDir =
|
|
59908
|
-
const normalizedDataDir = opts.dataDir ?
|
|
60510
|
+
const defaultDataDir = import_node_path49.default.resolve(import_node_path49.default.join(home, ".clawd"));
|
|
60511
|
+
const normalizedDataDir = opts.dataDir ? import_node_path49.default.resolve(opts.dataDir) : null;
|
|
59909
60512
|
const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
|
|
59910
60513
|
const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
|
|
59911
60514
|
return import_node_crypto13.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
|
|
@@ -59913,11 +60516,11 @@ function deriveStableDeviceKey(opts = {}) {
|
|
|
59913
60516
|
|
|
59914
60517
|
// src/auth-store.ts
|
|
59915
60518
|
var import_node_fs42 = __toESM(require("fs"), 1);
|
|
59916
|
-
var
|
|
60519
|
+
var import_node_path50 = __toESM(require("path"), 1);
|
|
59917
60520
|
var import_node_crypto14 = __toESM(require("crypto"), 1);
|
|
59918
60521
|
var AUTH_FILE_NAME = "auth.json";
|
|
59919
60522
|
function authFilePath(dataDir) {
|
|
59920
|
-
return
|
|
60523
|
+
return import_node_path50.default.join(dataDir, AUTH_FILE_NAME);
|
|
59921
60524
|
}
|
|
59922
60525
|
function loadOrCreateAuthFile(opts) {
|
|
59923
60526
|
const file = authFilePath(opts.dataDir);
|
|
@@ -59969,7 +60572,7 @@ function readAuthFile(file) {
|
|
|
59969
60572
|
}
|
|
59970
60573
|
}
|
|
59971
60574
|
function writeAuthFile(file, content) {
|
|
59972
|
-
import_node_fs42.default.mkdirSync(
|
|
60575
|
+
import_node_fs42.default.mkdirSync(import_node_path50.default.dirname(file), { recursive: true });
|
|
59973
60576
|
import_node_fs42.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
|
|
59974
60577
|
try {
|
|
59975
60578
|
import_node_fs42.default.chmodSync(file, 384);
|
|
@@ -59980,10 +60583,10 @@ function writeAuthFile(file, content) {
|
|
|
59980
60583
|
// src/owner-profile.ts
|
|
59981
60584
|
var import_node_fs43 = __toESM(require("fs"), 1);
|
|
59982
60585
|
var import_node_os16 = __toESM(require("os"), 1);
|
|
59983
|
-
var
|
|
60586
|
+
var import_node_path51 = __toESM(require("path"), 1);
|
|
59984
60587
|
var PROFILE_FILENAME = "profile.json";
|
|
59985
60588
|
function profilePath(dataDir) {
|
|
59986
|
-
return
|
|
60589
|
+
return import_node_path51.default.join(dataDir, PROFILE_FILENAME);
|
|
59987
60590
|
}
|
|
59988
60591
|
function loadOwnerProfile(dataDir) {
|
|
59989
60592
|
let raw;
|
|
@@ -60021,12 +60624,12 @@ function loadOwnerDisplayName(dataDir) {
|
|
|
60021
60624
|
|
|
60022
60625
|
// src/feishu-auth/owner-identity-store.ts
|
|
60023
60626
|
var import_node_fs44 = __toESM(require("fs"), 1);
|
|
60024
|
-
var
|
|
60627
|
+
var import_node_path52 = __toESM(require("path"), 1);
|
|
60025
60628
|
var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
|
|
60026
60629
|
var OwnerIdentityStore = class {
|
|
60027
60630
|
file;
|
|
60028
60631
|
constructor(dataDir) {
|
|
60029
|
-
this.file =
|
|
60632
|
+
this.file = import_node_path52.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
|
|
60030
60633
|
}
|
|
60031
60634
|
read() {
|
|
60032
60635
|
let raw;
|
|
@@ -60059,7 +60662,7 @@ var OwnerIdentityStore = class {
|
|
|
60059
60662
|
};
|
|
60060
60663
|
}
|
|
60061
60664
|
write(record3) {
|
|
60062
|
-
import_node_fs44.default.mkdirSync(
|
|
60665
|
+
import_node_fs44.default.mkdirSync(import_node_path52.default.dirname(this.file), { recursive: true });
|
|
60063
60666
|
import_node_fs44.default.writeFileSync(this.file, JSON.stringify(record3, null, 2), { mode: 384 });
|
|
60064
60667
|
try {
|
|
60065
60668
|
import_node_fs44.default.chmodSync(this.file, 384);
|
|
@@ -60205,9 +60808,9 @@ var CentralClientError = class extends Error {
|
|
|
60205
60808
|
code;
|
|
60206
60809
|
cause;
|
|
60207
60810
|
};
|
|
60208
|
-
async function centralRequest(opts,
|
|
60811
|
+
async function centralRequest(opts, path93, init) {
|
|
60209
60812
|
const f = opts.fetchImpl ?? globalThis.fetch;
|
|
60210
|
-
const url = `${opts.api.replace(/\/+$/, "")}${
|
|
60813
|
+
const url = `${opts.api.replace(/\/+$/, "")}${path93}`;
|
|
60211
60814
|
const ctrl = new AbortController();
|
|
60212
60815
|
const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
|
|
60213
60816
|
let res;
|
|
@@ -60461,7 +61064,7 @@ async function syncOrgMesh(deps) {
|
|
|
60461
61064
|
|
|
60462
61065
|
// src/handlers/device.ts
|
|
60463
61066
|
init_protocol();
|
|
60464
|
-
function
|
|
61067
|
+
function ensureOwner2(ctx) {
|
|
60465
61068
|
if (!ctx || ctx.principal.kind !== "owner") {
|
|
60466
61069
|
throw new ClawdError(ERROR_CODES.UNAUTHORIZED, "UNAUTHORIZED: device:* requires owner ctx");
|
|
60467
61070
|
}
|
|
@@ -60556,14 +61159,14 @@ function createConnectToDevice(deps) {
|
|
|
60556
61159
|
function buildDeviceHandlers(deps) {
|
|
60557
61160
|
const connectToDevice = createConnectToDevice(deps);
|
|
60558
61161
|
const list = async (_frame, _client, ctx) => {
|
|
60559
|
-
|
|
61162
|
+
ensureOwner2(ctx);
|
|
60560
61163
|
const devices = await deps.listDevices().catch(rethrowLoginExpired);
|
|
60561
61164
|
return {
|
|
60562
61165
|
response: { type: "device:list:ok", devices }
|
|
60563
61166
|
};
|
|
60564
61167
|
};
|
|
60565
61168
|
const connect = async (frame, _client, ctx) => {
|
|
60566
|
-
|
|
61169
|
+
ensureOwner2(ctx);
|
|
60567
61170
|
const { type: _t, requestId: _r, ...rest } = frame;
|
|
60568
61171
|
const args = DeviceConnectArgsSchema.parse(rest);
|
|
60569
61172
|
const contact = await connectToDevice(args);
|
|
@@ -60578,7 +61181,7 @@ function buildDeviceHandlers(deps) {
|
|
|
60578
61181
|
};
|
|
60579
61182
|
};
|
|
60580
61183
|
const connections = async (_frame, client, ctx) => {
|
|
60581
|
-
|
|
61184
|
+
ensureOwner2(ctx);
|
|
60582
61185
|
const entries = deps.listOwnerConnections();
|
|
60583
61186
|
return {
|
|
60584
61187
|
response: {
|
|
@@ -60644,8 +61247,8 @@ function verifyConnectToken(args) {
|
|
|
60644
61247
|
}
|
|
60645
61248
|
|
|
60646
61249
|
// src/feishu-auth/server-key.ts
|
|
60647
|
-
var
|
|
60648
|
-
var
|
|
61250
|
+
var fs61 = __toESM(require("fs"), 1);
|
|
61251
|
+
var path65 = __toESM(require("path"), 1);
|
|
60649
61252
|
var FILE_NAME2 = "server-signing-key.json";
|
|
60650
61253
|
var ServerKeyStore = class {
|
|
60651
61254
|
constructor(dataDir) {
|
|
@@ -60653,12 +61256,12 @@ var ServerKeyStore = class {
|
|
|
60653
61256
|
}
|
|
60654
61257
|
dataDir;
|
|
60655
61258
|
filePath() {
|
|
60656
|
-
return
|
|
61259
|
+
return path65.join(this.dataDir, FILE_NAME2);
|
|
60657
61260
|
}
|
|
60658
61261
|
/** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
|
|
60659
61262
|
read() {
|
|
60660
61263
|
try {
|
|
60661
|
-
const raw =
|
|
61264
|
+
const raw = fs61.readFileSync(this.filePath(), "utf8");
|
|
60662
61265
|
const parsed = JSON.parse(raw);
|
|
60663
61266
|
if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
|
|
60664
61267
|
return parsed.publicKeyPem;
|
|
@@ -60673,12 +61276,12 @@ var ServerKeyStore = class {
|
|
|
60673
61276
|
publicKeyPem,
|
|
60674
61277
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
60675
61278
|
};
|
|
60676
|
-
|
|
60677
|
-
|
|
61279
|
+
fs61.mkdirSync(this.dataDir, { recursive: true });
|
|
61280
|
+
fs61.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
|
|
60678
61281
|
}
|
|
60679
61282
|
clear() {
|
|
60680
61283
|
try {
|
|
60681
|
-
|
|
61284
|
+
fs61.unlinkSync(this.filePath());
|
|
60682
61285
|
} catch {
|
|
60683
61286
|
}
|
|
60684
61287
|
}
|
|
@@ -60688,7 +61291,7 @@ var ServerKeyStore = class {
|
|
|
60688
61291
|
init_protocol();
|
|
60689
61292
|
|
|
60690
61293
|
// src/handlers/index.ts
|
|
60691
|
-
var
|
|
61294
|
+
var import_node_path70 = __toESM(require("path"), 1);
|
|
60692
61295
|
|
|
60693
61296
|
// src/handlers/session.ts
|
|
60694
61297
|
init_protocol();
|
|
@@ -60696,7 +61299,7 @@ init_protocol();
|
|
|
60696
61299
|
// src/session/fork.ts
|
|
60697
61300
|
var import_node_fs45 = __toESM(require("fs"), 1);
|
|
60698
61301
|
var import_node_os17 = __toESM(require("os"), 1);
|
|
60699
|
-
var
|
|
61302
|
+
var import_node_path53 = __toESM(require("path"), 1);
|
|
60700
61303
|
var import_node_crypto16 = require("crypto");
|
|
60701
61304
|
init_claude_history();
|
|
60702
61305
|
function readJsonlEntries(file) {
|
|
@@ -60713,19 +61316,19 @@ function readJsonlEntries(file) {
|
|
|
60713
61316
|
return out;
|
|
60714
61317
|
}
|
|
60715
61318
|
function forkSession(input) {
|
|
60716
|
-
const baseDir = input.baseDir ??
|
|
60717
|
-
let projectDir =
|
|
60718
|
-
let sourceFile =
|
|
61319
|
+
const baseDir = input.baseDir ?? import_node_path53.default.join(import_node_os17.default.homedir(), ".claude");
|
|
61320
|
+
let projectDir = import_node_path53.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
|
|
61321
|
+
let sourceFile = import_node_path53.default.join(projectDir, `${input.toolSessionId}.jsonl`);
|
|
60719
61322
|
if (!import_node_fs45.default.existsSync(sourceFile)) {
|
|
60720
61323
|
const found = findTranscriptByToolSessionId(
|
|
60721
|
-
|
|
61324
|
+
import_node_path53.default.join(baseDir, "projects"),
|
|
60722
61325
|
input.toolSessionId
|
|
60723
61326
|
);
|
|
60724
61327
|
if (!found) {
|
|
60725
61328
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
60726
61329
|
}
|
|
60727
61330
|
sourceFile = found;
|
|
60728
|
-
projectDir =
|
|
61331
|
+
projectDir = import_node_path53.default.dirname(found);
|
|
60729
61332
|
}
|
|
60730
61333
|
const entries = readJsonlEntries(sourceFile);
|
|
60731
61334
|
const mainEntries = entries.filter((e) => e.isSidechain !== true);
|
|
@@ -60754,8 +61357,8 @@ function forkSession(input) {
|
|
|
60754
61357
|
}
|
|
60755
61358
|
forkedLines.push(JSON.stringify(forked));
|
|
60756
61359
|
}
|
|
60757
|
-
const outDir = input.targetCwd ?
|
|
60758
|
-
const forkedFilePath =
|
|
61360
|
+
const outDir = input.targetCwd ? import_node_path53.default.join(baseDir, "projects", cwdToHashDir(input.targetCwd)) : projectDir;
|
|
61361
|
+
const forkedFilePath = import_node_path53.default.join(outDir, `${forkedToolSessionId}.jsonl`);
|
|
60759
61362
|
import_node_fs45.default.mkdirSync(outDir, { recursive: true });
|
|
60760
61363
|
import_node_fs45.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
|
|
60761
61364
|
return { forkedToolSessionId, forkedFilePath };
|
|
@@ -60763,18 +61366,18 @@ function forkSession(input) {
|
|
|
60763
61366
|
|
|
60764
61367
|
// src/session/external-scan.ts
|
|
60765
61368
|
var import_node_fs46 = __toESM(require("fs"), 1);
|
|
60766
|
-
var
|
|
61369
|
+
var import_promises10 = __toESM(require("fs/promises"), 1);
|
|
60767
61370
|
var import_node_os18 = __toESM(require("os"), 1);
|
|
60768
|
-
var
|
|
61371
|
+
var import_node_path54 = __toESM(require("path"), 1);
|
|
60769
61372
|
var import_node_module = require("module");
|
|
60770
61373
|
var import_node_child_process12 = require("child_process");
|
|
60771
61374
|
var import_meta4 = {};
|
|
60772
61375
|
function defaultRoots() {
|
|
60773
61376
|
const home = import_node_os18.default.homedir();
|
|
60774
61377
|
return {
|
|
60775
|
-
claudeProjectsDir:
|
|
60776
|
-
codexDir:
|
|
60777
|
-
clawdDir:
|
|
61378
|
+
claudeProjectsDir: import_node_path54.default.join(home, ".claude", "projects"),
|
|
61379
|
+
codexDir: import_node_path54.default.join(home, ".codex"),
|
|
61380
|
+
clawdDir: import_node_path54.default.join(home, ".clawd")
|
|
60778
61381
|
};
|
|
60779
61382
|
}
|
|
60780
61383
|
function width(s) {
|
|
@@ -60802,7 +61405,7 @@ function toMs(v2) {
|
|
|
60802
61405
|
async function* jsonLines(file) {
|
|
60803
61406
|
let raw;
|
|
60804
61407
|
try {
|
|
60805
|
-
raw = await
|
|
61408
|
+
raw = await import_promises10.default.readFile(file, "utf8");
|
|
60806
61409
|
} catch {
|
|
60807
61410
|
return;
|
|
60808
61411
|
}
|
|
@@ -60842,13 +61445,13 @@ async function scanClaude(roots) {
|
|
|
60842
61445
|
if (!d.isDirectory()) continue;
|
|
60843
61446
|
let files;
|
|
60844
61447
|
try {
|
|
60845
|
-
files = import_node_fs46.default.readdirSync(
|
|
61448
|
+
files = import_node_fs46.default.readdirSync(import_node_path54.default.join(roots.claudeProjectsDir, d.name));
|
|
60846
61449
|
} catch {
|
|
60847
61450
|
continue;
|
|
60848
61451
|
}
|
|
60849
61452
|
for (const name of files) {
|
|
60850
61453
|
if (!name.endsWith(".jsonl")) continue;
|
|
60851
|
-
const file =
|
|
61454
|
+
const file = import_node_path54.default.join(roots.claudeProjectsDir, d.name, name);
|
|
60852
61455
|
let st;
|
|
60853
61456
|
try {
|
|
60854
61457
|
st = import_node_fs46.default.statSync(file);
|
|
@@ -60978,7 +61581,7 @@ async function codexFromRows(rows) {
|
|
|
60978
61581
|
async function scanCodex(roots) {
|
|
60979
61582
|
let dbs = [];
|
|
60980
61583
|
try {
|
|
60981
|
-
dbs = import_node_fs46.default.readdirSync(roots.codexDir).filter((n) => /^state_.*\.sqlite$/.test(n)).sort().map((n) =>
|
|
61584
|
+
dbs = import_node_fs46.default.readdirSync(roots.codexDir).filter((n) => /^state_.*\.sqlite$/.test(n)).sort().map((n) => import_node_path54.default.join(roots.codexDir, n));
|
|
60982
61585
|
} catch {
|
|
60983
61586
|
}
|
|
60984
61587
|
if (!dbs.length) return [];
|
|
@@ -60987,14 +61590,14 @@ async function scanCodex(roots) {
|
|
|
60987
61590
|
}
|
|
60988
61591
|
async function scanExternalSessions(rootsIn) {
|
|
60989
61592
|
const roots = { ...defaultRoots(), ...rootsIn };
|
|
60990
|
-
const personaRoot =
|
|
61593
|
+
const personaRoot = import_node_path54.default.join(roots.clawdDir, "personas");
|
|
60991
61594
|
const all = [...await scanClaude(roots), ...await scanCodex(roots)];
|
|
60992
61595
|
const out = [];
|
|
60993
61596
|
for (const c of all) {
|
|
60994
61597
|
if (c.skip) continue;
|
|
60995
61598
|
if (c.turns < 1) continue;
|
|
60996
61599
|
if (!c.cwd || !isDir2(c.cwd)) continue;
|
|
60997
|
-
if (c.cwd === roots.clawdDir || c.cwd === personaRoot || c.cwd.startsWith(personaRoot +
|
|
61600
|
+
if (c.cwd === roots.clawdDir || c.cwd === personaRoot || c.cwd.startsWith(personaRoot + import_node_path54.default.sep) || c.cwd.startsWith(roots.clawdDir + import_node_path54.default.sep)) {
|
|
60998
61601
|
continue;
|
|
60999
61602
|
}
|
|
61000
61603
|
out.push({
|
|
@@ -61012,12 +61615,12 @@ async function scanExternalSessions(rootsIn) {
|
|
|
61012
61615
|
|
|
61013
61616
|
// src/session/import-ledger.ts
|
|
61014
61617
|
var import_node_fs47 = __toESM(require("fs"), 1);
|
|
61015
|
-
var
|
|
61618
|
+
var import_node_path55 = __toESM(require("path"), 1);
|
|
61016
61619
|
var LEDGER_FILENAME = "session-import-ledger.json";
|
|
61017
61620
|
function readImportLedger(dataDir) {
|
|
61018
61621
|
try {
|
|
61019
61622
|
const parsed = JSON.parse(
|
|
61020
|
-
import_node_fs47.default.readFileSync(
|
|
61623
|
+
import_node_fs47.default.readFileSync(import_node_path55.default.join(dataDir, LEDGER_FILENAME), "utf8")
|
|
61021
61624
|
);
|
|
61022
61625
|
return Array.isArray(parsed) ? parsed : [];
|
|
61023
61626
|
} catch {
|
|
@@ -61025,7 +61628,7 @@ function readImportLedger(dataDir) {
|
|
|
61025
61628
|
}
|
|
61026
61629
|
}
|
|
61027
61630
|
function appendImportLedger(dataDir, entry) {
|
|
61028
|
-
const file =
|
|
61631
|
+
const file = import_node_path55.default.join(dataDir, LEDGER_FILENAME);
|
|
61029
61632
|
const entries = readImportLedger(dataDir);
|
|
61030
61633
|
entries.push(entry);
|
|
61031
61634
|
import_node_fs47.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
|
|
@@ -61033,7 +61636,7 @@ function appendImportLedger(dataDir, entry) {
|
|
|
61033
61636
|
|
|
61034
61637
|
// src/tools/transcript-search.ts
|
|
61035
61638
|
var import_node_fs48 = __toESM(require("fs"), 1);
|
|
61036
|
-
var
|
|
61639
|
+
var import_node_path56 = __toESM(require("path"), 1);
|
|
61037
61640
|
var SNIPPET_PAD = 60;
|
|
61038
61641
|
var INJECTED_ENVELOPE_RE = /^<(system-reminder|command-name|command-message|command-args|local-command-stdout|local-command-stderr|task-notification|user-prompt-submit-hook|environment_context|user_instructions)\b/;
|
|
61039
61642
|
var CODEX_WRAPPER_RE = /<(related-dir|environment_context|user_instructions)>[\s\S]*?<\/\1>/g;
|
|
@@ -61126,7 +61729,7 @@ function createCodexRolloutLocator(roots) {
|
|
|
61126
61729
|
return;
|
|
61127
61730
|
}
|
|
61128
61731
|
for (const entry of entries) {
|
|
61129
|
-
const full =
|
|
61732
|
+
const full = import_node_path56.default.join(dir, entry.name);
|
|
61130
61733
|
if (entry.isDirectory()) {
|
|
61131
61734
|
walk2(full, into);
|
|
61132
61735
|
continue;
|
|
@@ -61147,15 +61750,15 @@ function createCodexRolloutLocator(roots) {
|
|
|
61147
61750
|
// src/handlers/session.ts
|
|
61148
61751
|
init_protocol();
|
|
61149
61752
|
var import_node_os19 = __toESM(require("os"), 1);
|
|
61150
|
-
var
|
|
61753
|
+
var import_node_path57 = __toESM(require("path"), 1);
|
|
61151
61754
|
function canReadSearchHit(ctx, file) {
|
|
61152
61755
|
if (!ctx || ctx.principal.kind === "owner") return true;
|
|
61153
61756
|
return canAccessPersona(ctx.grants, file.ownerPersonaId, "read") && file.creatorPrincipalId === ctx.principal.id;
|
|
61154
61757
|
}
|
|
61155
61758
|
var DEFAULT_SEARCH_LIMIT = 9;
|
|
61156
61759
|
function codexRolloutRoots(dataDir) {
|
|
61157
|
-
const roots = [
|
|
61158
|
-
if (dataDir) roots.push(
|
|
61760
|
+
const roots = [import_node_path57.default.join(import_node_os19.default.homedir(), ".codex", "sessions")];
|
|
61761
|
+
if (dataDir) roots.push(import_node_path57.default.join(dataDir, "codex-home", "sessions"));
|
|
61159
61762
|
return roots;
|
|
61160
61763
|
}
|
|
61161
61764
|
function buildSessionHandlers(deps) {
|
|
@@ -61697,7 +62300,7 @@ function buildPermissionHandlers(deps) {
|
|
|
61697
62300
|
}
|
|
61698
62301
|
|
|
61699
62302
|
// src/handlers/history.ts
|
|
61700
|
-
var
|
|
62303
|
+
var path72 = __toESM(require("path"), 1);
|
|
61701
62304
|
init_protocol();
|
|
61702
62305
|
|
|
61703
62306
|
// src/session/recent-dirs.ts
|
|
@@ -61715,7 +62318,7 @@ function listRecentDirs(store, limit = 50) {
|
|
|
61715
62318
|
}
|
|
61716
62319
|
|
|
61717
62320
|
// src/permission/persona-paths.ts
|
|
61718
|
-
var
|
|
62321
|
+
var path71 = __toESM(require("path"), 1);
|
|
61719
62322
|
function getAllowedPersonaIds(grants, action) {
|
|
61720
62323
|
const ids = /* @__PURE__ */ new Set();
|
|
61721
62324
|
for (const g2 of grants) {
|
|
@@ -61728,42 +62331,42 @@ function getAllowedPersonaIds(grants, action) {
|
|
|
61728
62331
|
return ids;
|
|
61729
62332
|
}
|
|
61730
62333
|
function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
|
|
61731
|
-
const target =
|
|
62334
|
+
const target = path71.resolve(absPath);
|
|
61732
62335
|
if (userWorkDir) {
|
|
61733
|
-
const u =
|
|
61734
|
-
const usep = u.endsWith(
|
|
62336
|
+
const u = path71.resolve(userWorkDir);
|
|
62337
|
+
const usep = u.endsWith(path71.sep) ? "" : path71.sep;
|
|
61735
62338
|
if (target === u || target.startsWith(u + usep)) return true;
|
|
61736
62339
|
}
|
|
61737
|
-
const root =
|
|
61738
|
-
const sep4 = root.endsWith(
|
|
62340
|
+
const root = path71.resolve(personaRoot);
|
|
62341
|
+
const sep4 = root.endsWith(path71.sep) ? "" : path71.sep;
|
|
61739
62342
|
if (!target.startsWith(root + sep4)) return false;
|
|
61740
|
-
const rel =
|
|
62343
|
+
const rel = path71.relative(root, target);
|
|
61741
62344
|
if (!rel || rel.startsWith("..")) return false;
|
|
61742
|
-
const personaId2 = rel.split(
|
|
62345
|
+
const personaId2 = rel.split(path71.sep)[0];
|
|
61743
62346
|
if (!personaId2) return false;
|
|
61744
62347
|
const allowed = getAllowedPersonaIds(grants, action);
|
|
61745
62348
|
if (allowed === "*") return true;
|
|
61746
62349
|
return allowed.has(personaId2);
|
|
61747
62350
|
}
|
|
61748
62351
|
function personaIdFromPath(absPath, personaRoot) {
|
|
61749
|
-
const root =
|
|
61750
|
-
const target =
|
|
61751
|
-
const sep4 = root.endsWith(
|
|
62352
|
+
const root = path71.resolve(personaRoot);
|
|
62353
|
+
const target = path71.resolve(absPath);
|
|
62354
|
+
const sep4 = root.endsWith(path71.sep) ? "" : path71.sep;
|
|
61752
62355
|
if (!target.startsWith(root + sep4)) return null;
|
|
61753
|
-
const rel =
|
|
62356
|
+
const rel = path71.relative(root, target);
|
|
61754
62357
|
if (!rel || rel.startsWith("..")) return null;
|
|
61755
|
-
const id = rel.split(
|
|
62358
|
+
const id = rel.split(path71.sep)[0];
|
|
61756
62359
|
return id || null;
|
|
61757
62360
|
}
|
|
61758
62361
|
function isPathWithin(dir, absPath) {
|
|
61759
|
-
const d =
|
|
61760
|
-
const t =
|
|
61761
|
-
const sep4 = d.endsWith(
|
|
62362
|
+
const d = path71.resolve(dir);
|
|
62363
|
+
const t = path71.resolve(absPath);
|
|
62364
|
+
const sep4 = d.endsWith(path71.sep) ? "" : path71.sep;
|
|
61762
62365
|
return t === d || t.startsWith(d + sep4);
|
|
61763
62366
|
}
|
|
61764
62367
|
function isPathInGuestBoundary(personaRoot, personaId2, userWorkDir, absPath) {
|
|
61765
62368
|
if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
|
|
61766
|
-
return personaIdFromPath(
|
|
62369
|
+
return personaIdFromPath(path71.resolve(absPath), personaRoot) === personaId2;
|
|
61767
62370
|
}
|
|
61768
62371
|
|
|
61769
62372
|
// src/handlers/history.ts
|
|
@@ -61816,7 +62419,7 @@ function buildHistoryHandlers(deps) {
|
|
|
61816
62419
|
if (!pid) return false;
|
|
61817
62420
|
return isGuestPathAllowed(
|
|
61818
62421
|
ctx.grants,
|
|
61819
|
-
|
|
62422
|
+
path72.join(personaRoot, pid),
|
|
61820
62423
|
personaRoot,
|
|
61821
62424
|
"read",
|
|
61822
62425
|
userWorkDir
|
|
@@ -61828,7 +62431,7 @@ function buildHistoryHandlers(deps) {
|
|
|
61828
62431
|
};
|
|
61829
62432
|
const list = async (frame, _client, ctx) => {
|
|
61830
62433
|
const args = HistoryListArgs.parse(frame);
|
|
61831
|
-
assertGuestPath(ctx,
|
|
62434
|
+
assertGuestPath(ctx, path72.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
|
|
61832
62435
|
const sessions = await history.listSessions(args);
|
|
61833
62436
|
return { response: { type: "history:list", sessions } };
|
|
61834
62437
|
};
|
|
@@ -61876,14 +62479,14 @@ function buildHistoryHandlers(deps) {
|
|
|
61876
62479
|
};
|
|
61877
62480
|
const subagents = async (frame, _client, ctx) => {
|
|
61878
62481
|
const args = HistorySubagentsArgs.parse(frame);
|
|
61879
|
-
assertGuestPath(ctx,
|
|
62482
|
+
assertGuestPath(ctx, path72.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
|
|
61880
62483
|
assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagents");
|
|
61881
62484
|
const subs = await historyReaderForToolSession(args.toolSessionId).listSubagents(args);
|
|
61882
62485
|
return { response: { type: "history:subagents", subagents: subs } };
|
|
61883
62486
|
};
|
|
61884
62487
|
const subagentRead = async (frame, _client, ctx) => {
|
|
61885
62488
|
const args = HistorySubagentReadArgs.parse(frame);
|
|
61886
|
-
assertGuestPath(ctx,
|
|
62489
|
+
assertGuestPath(ctx, path72.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
|
|
61887
62490
|
assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagent-read");
|
|
61888
62491
|
const res = await historyReaderForToolSession(args.toolSessionId).readSubagent(args);
|
|
61889
62492
|
return { response: { type: "history:subagent-read", ...res } };
|
|
@@ -61893,7 +62496,7 @@ function buildHistoryHandlers(deps) {
|
|
|
61893
62496
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
61894
62497
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
61895
62498
|
const filtered = dirs.filter(
|
|
61896
|
-
(d) => isGuestPathAllowed(ctx.grants,
|
|
62499
|
+
(d) => isGuestPathAllowed(ctx.grants, path72.resolve(d.cwd), personaRoot, "read", userWorkDir)
|
|
61897
62500
|
);
|
|
61898
62501
|
return { response: { type: "history:recentDirs", dirs: filtered } };
|
|
61899
62502
|
}
|
|
@@ -61910,17 +62513,17 @@ function buildHistoryHandlers(deps) {
|
|
|
61910
62513
|
}
|
|
61911
62514
|
|
|
61912
62515
|
// src/handlers/projects.ts
|
|
61913
|
-
var
|
|
62516
|
+
var fs66 = __toESM(require("fs"), 1);
|
|
61914
62517
|
var os21 = __toESM(require("os"), 1);
|
|
61915
|
-
var
|
|
62518
|
+
var path73 = __toESM(require("path"), 1);
|
|
61916
62519
|
var import_node_child_process13 = require("child_process");
|
|
61917
62520
|
init_protocol();
|
|
61918
|
-
var DEFAULT_PROJECTS_ROOT =
|
|
62521
|
+
var DEFAULT_PROJECTS_ROOT = path73.join(os21.homedir(), "Documents", "ChatGPT");
|
|
61919
62522
|
function allocateDir(root, name) {
|
|
61920
|
-
let candidate =
|
|
62523
|
+
let candidate = path73.join(root, name);
|
|
61921
62524
|
let n = 2;
|
|
61922
|
-
while (
|
|
61923
|
-
candidate =
|
|
62525
|
+
while (fs66.existsSync(candidate)) {
|
|
62526
|
+
candidate = path73.join(root, `${name} ${n}`);
|
|
61924
62527
|
n += 1;
|
|
61925
62528
|
}
|
|
61926
62529
|
return candidate;
|
|
@@ -61948,7 +62551,7 @@ function buildProjectHandlers(deps) {
|
|
|
61948
62551
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, "project:reveal \u4EC5\u652F\u6301 macOS");
|
|
61949
62552
|
}
|
|
61950
62553
|
try {
|
|
61951
|
-
if (!
|
|
62554
|
+
if (!fs66.statSync(args.path).isDirectory()) throw new Error("not dir");
|
|
61952
62555
|
} catch {
|
|
61953
62556
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
|
|
61954
62557
|
}
|
|
@@ -61964,7 +62567,7 @@ function buildProjectHandlers(deps) {
|
|
|
61964
62567
|
let target;
|
|
61965
62568
|
if (args.path) {
|
|
61966
62569
|
try {
|
|
61967
|
-
if (!
|
|
62570
|
+
if (!fs66.statSync(args.path).isDirectory()) throw new Error("not dir");
|
|
61968
62571
|
} catch {
|
|
61969
62572
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
|
|
61970
62573
|
}
|
|
@@ -61972,15 +62575,15 @@ function buildProjectHandlers(deps) {
|
|
|
61972
62575
|
} else {
|
|
61973
62576
|
const name = args.name;
|
|
61974
62577
|
try {
|
|
61975
|
-
|
|
62578
|
+
fs66.mkdirSync(root, { recursive: true });
|
|
61976
62579
|
target = allocateDir(root, name);
|
|
61977
|
-
|
|
62580
|
+
fs66.mkdirSync(target);
|
|
61978
62581
|
} catch (err) {
|
|
61979
62582
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `\u521B\u5EFA\u9879\u76EE\u76EE\u5F55\u5931\u8D25: ${String(err)}`);
|
|
61980
62583
|
}
|
|
61981
62584
|
const git = (0, import_node_child_process13.spawnSync)("git", ["init"], { cwd: target, stdio: "ignore" });
|
|
61982
62585
|
if (git.status !== 0) {
|
|
61983
|
-
|
|
62586
|
+
fs66.rmSync(target, { recursive: true, force: true });
|
|
61984
62587
|
throw new ClawdError(
|
|
61985
62588
|
ERROR_CODES.INVALID_CWD,
|
|
61986
62589
|
`git init \u5931\u8D25\uFF08${git.error ? String(git.error) : `exit ${git.status}`}\uFF09: ${target}`
|
|
@@ -62005,7 +62608,7 @@ function buildProjectHandlers(deps) {
|
|
|
62005
62608
|
}
|
|
62006
62609
|
|
|
62007
62610
|
// src/handlers/workspace.ts
|
|
62008
|
-
var
|
|
62611
|
+
var path74 = __toESM(require("path"), 1);
|
|
62009
62612
|
var os22 = __toESM(require("os"), 1);
|
|
62010
62613
|
init_protocol();
|
|
62011
62614
|
init_protocol();
|
|
@@ -62047,22 +62650,22 @@ function buildWorkspaceHandlers(deps) {
|
|
|
62047
62650
|
const args = WorkspaceListArgs.parse(frame);
|
|
62048
62651
|
const isGuest = ctx?.principal.kind === "guest";
|
|
62049
62652
|
const fallbackCwd = isGuest && personaRoot ? personaRoot : os22.homedir();
|
|
62050
|
-
const resolvedCwd =
|
|
62051
|
-
const target = args.path ?
|
|
62653
|
+
const resolvedCwd = path74.resolve(args.cwd ?? fallbackCwd);
|
|
62654
|
+
const target = args.path ? path74.resolve(resolvedCwd, args.path) : resolvedCwd;
|
|
62052
62655
|
assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
|
|
62053
62656
|
const res = workspace.list({ ...args, cwd: resolvedCwd });
|
|
62054
62657
|
return { response: { type: "workspace:list", ...res } };
|
|
62055
62658
|
};
|
|
62056
62659
|
const read = async (frame, _client, ctx) => {
|
|
62057
62660
|
const args = WorkspaceReadArgs.parse(frame);
|
|
62058
|
-
const target =
|
|
62661
|
+
const target = path74.isAbsolute(args.path) ? path74.resolve(args.path) : path74.resolve(args.cwd, args.path);
|
|
62059
62662
|
assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
|
|
62060
62663
|
const res = workspace.read(args);
|
|
62061
62664
|
return { response: { type: "workspace:read", ...res } };
|
|
62062
62665
|
};
|
|
62063
62666
|
const skillsList = async (frame, _client, ctx) => {
|
|
62064
62667
|
const args = SkillsListArgs.parse(frame);
|
|
62065
|
-
const cwdAbs =
|
|
62668
|
+
const cwdAbs = path74.resolve(args.cwd);
|
|
62066
62669
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
|
|
62067
62670
|
const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
|
|
62068
62671
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
@@ -62074,7 +62677,7 @@ function buildWorkspaceHandlers(deps) {
|
|
|
62074
62677
|
};
|
|
62075
62678
|
const agentsList = async (frame, _client, ctx) => {
|
|
62076
62679
|
const args = AgentsListArgs.parse(frame);
|
|
62077
|
-
const cwdAbs =
|
|
62680
|
+
const cwdAbs = path74.resolve(args.cwd);
|
|
62078
62681
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
|
|
62079
62682
|
if (args.tool === "codex") {
|
|
62080
62683
|
return { response: { type: "agents:list", agents: [] } };
|
|
@@ -62096,18 +62699,18 @@ function buildWorkspaceHandlers(deps) {
|
|
|
62096
62699
|
}
|
|
62097
62700
|
|
|
62098
62701
|
// src/handlers/git.ts
|
|
62099
|
-
var
|
|
62702
|
+
var path76 = __toESM(require("path"), 1);
|
|
62100
62703
|
init_protocol();
|
|
62101
62704
|
init_protocol();
|
|
62102
62705
|
|
|
62103
62706
|
// src/workspace/git.ts
|
|
62104
62707
|
var import_node_child_process14 = require("child_process");
|
|
62105
62708
|
var import_node_fs49 = __toESM(require("fs"), 1);
|
|
62106
|
-
var
|
|
62709
|
+
var import_node_path58 = __toESM(require("path"), 1);
|
|
62107
62710
|
var import_node_util = require("util");
|
|
62108
62711
|
var pexec = (0, import_node_util.promisify)(import_node_child_process14.execFile);
|
|
62109
62712
|
function normalizePath(p2) {
|
|
62110
|
-
const resolved =
|
|
62713
|
+
const resolved = import_node_path58.default.resolve(p2);
|
|
62111
62714
|
try {
|
|
62112
62715
|
return import_node_fs49.default.realpathSync(resolved);
|
|
62113
62716
|
} catch {
|
|
@@ -62183,7 +62786,7 @@ async function listGitBranches(cwd) {
|
|
|
62183
62786
|
function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
|
|
62184
62787
|
if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
|
|
62185
62788
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
62186
|
-
if (!isGuestPathAllowed(ctx.grants,
|
|
62789
|
+
if (!isGuestPathAllowed(ctx.grants, path76.resolve(cwd), personaRoot, "read", userWorkDir)) {
|
|
62187
62790
|
throw new ClawdError(
|
|
62188
62791
|
ERROR_CODES.UNAUTHORIZED,
|
|
62189
62792
|
`guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
|
|
@@ -62438,7 +63041,7 @@ function upsertPeerContact(args) {
|
|
|
62438
63041
|
}
|
|
62439
63042
|
|
|
62440
63043
|
// src/handlers/contact.ts
|
|
62441
|
-
function
|
|
63044
|
+
function ensureOwner3(ctx) {
|
|
62442
63045
|
if (!ctx || ctx.principal.kind !== "owner") {
|
|
62443
63046
|
throw new ClawdError(
|
|
62444
63047
|
ERROR_CODES.UNAUTHORIZED,
|
|
@@ -62448,7 +63051,7 @@ function ensureOwner2(ctx) {
|
|
|
62448
63051
|
}
|
|
62449
63052
|
function buildContactHandlers(deps) {
|
|
62450
63053
|
const list = async (_frame, _client, ctx) => {
|
|
62451
|
-
|
|
63054
|
+
ensureOwner3(ctx);
|
|
62452
63055
|
return {
|
|
62453
63056
|
response: {
|
|
62454
63057
|
type: "contact:list:ok",
|
|
@@ -62457,7 +63060,7 @@ function buildContactHandlers(deps) {
|
|
|
62457
63060
|
};
|
|
62458
63061
|
};
|
|
62459
63062
|
const pin = async (frame, _client, ctx) => {
|
|
62460
|
-
|
|
63063
|
+
ensureOwner3(ctx);
|
|
62461
63064
|
const args = parseArgs2(ContactPinArgsSchema, frame, "contact:pin");
|
|
62462
63065
|
const pinnedAt = args.pinned ? deps.now() : null;
|
|
62463
63066
|
const hit = deps.store.setPin(args.deviceId, pinnedAt);
|
|
@@ -62481,7 +63084,7 @@ function buildContactHandlers(deps) {
|
|
|
62481
63084
|
};
|
|
62482
63085
|
};
|
|
62483
63086
|
const setNote = async (frame, _client, ctx) => {
|
|
62484
|
-
|
|
63087
|
+
ensureOwner3(ctx);
|
|
62485
63088
|
const args = parseArgs2(ContactSetNoteArgsSchema, frame, "contact:setNote");
|
|
62486
63089
|
const hit = deps.store.setNote(args.deviceId, args.note);
|
|
62487
63090
|
if (!hit) {
|
|
@@ -62504,13 +63107,13 @@ function buildContactHandlers(deps) {
|
|
|
62504
63107
|
};
|
|
62505
63108
|
};
|
|
62506
63109
|
const orgPeers = async (_frame, _client, ctx) => {
|
|
62507
|
-
|
|
63110
|
+
ensureOwner3(ctx);
|
|
62508
63111
|
return {
|
|
62509
63112
|
response: { type: "org:peers:ok", peers: getCachedOrgPeers() }
|
|
62510
63113
|
};
|
|
62511
63114
|
};
|
|
62512
63115
|
const remove = async (frame, _client, ctx) => {
|
|
62513
|
-
|
|
63116
|
+
ensureOwner3(ctx);
|
|
62514
63117
|
const args = parseArgs2(ContactRemoveArgsSchema, frame, "contact:remove");
|
|
62515
63118
|
deps.store.removeByDeviceId(args.deviceId);
|
|
62516
63119
|
deps.broadcast({
|
|
@@ -62584,7 +63187,7 @@ function buildContactHandlers(deps) {
|
|
|
62584
63187
|
|
|
62585
63188
|
// src/handlers/contact-remote-access.ts
|
|
62586
63189
|
init_protocol();
|
|
62587
|
-
function
|
|
63190
|
+
function ensureOwner4(ctx) {
|
|
62588
63191
|
if (!ctx || ctx.principal.kind !== "owner") {
|
|
62589
63192
|
throw new ClawdError(
|
|
62590
63193
|
ERROR_CODES.UNAUTHORIZED,
|
|
@@ -62594,7 +63197,7 @@ function ensureOwner3(ctx) {
|
|
|
62594
63197
|
}
|
|
62595
63198
|
function buildContactRemoteAccessHandlers(deps) {
|
|
62596
63199
|
const setRemoteAccess = async (frame, _client, ctx) => {
|
|
62597
|
-
|
|
63200
|
+
ensureOwner4(ctx);
|
|
62598
63201
|
const args = parseArgs2(ContactSetRemoteAccessArgsSchema, frame, "contact:setRemoteAccess");
|
|
62599
63202
|
const hit = deps.store.setRemoteAccess(args.deviceId, {
|
|
62600
63203
|
remoteAccessAllowed: args.remoteAccessAllowed
|
|
@@ -62773,6 +63376,16 @@ var METHOD_GRANT_MAP = {
|
|
|
62773
63376
|
// ---- visitor:* (访客名单,owner-only) ----
|
|
62774
63377
|
// owner 看完整访客名单(含没开会话的);guest 不可调(handler 内再 assertOwner 兜底)。
|
|
62775
63378
|
"visitor:list": ADMIN_ANY,
|
|
63379
|
+
// deploy:*(persona 上云的部署单):全部 owner-only。单据里有履约决策、凭据录入口,
|
|
63380
|
+
// guest 不该看见更不该动。
|
|
63381
|
+
"deploy:start": ADMIN_ANY,
|
|
63382
|
+
"deploy:list": ADMIN_ANY,
|
|
63383
|
+
"deploy:get": ADMIN_ANY,
|
|
63384
|
+
"deploy:patch": ADMIN_ANY,
|
|
63385
|
+
"deploy:putSecret": ADMIN_ANY,
|
|
63386
|
+
"deploy:reportFinding": ADMIN_ANY,
|
|
63387
|
+
"deploy:finishScan": ADMIN_ANY,
|
|
63388
|
+
"deploy:remove": ADMIN_ANY,
|
|
62776
63389
|
// ---- session:* / chat:* 业务方法(v2 Phase 8 两层模型)----
|
|
62777
63390
|
// dispatcher 不验资源,handler 内按 ctx + frame.args 反查 ownerPersonaId 调 assertGrant。
|
|
62778
63391
|
// owner 自动通过(ctx 自带 '*':'admin' grant 一切 match);guest 在被授权 persona 内可调。
|
|
@@ -63018,21 +63631,21 @@ function computeMethodAccess(args) {
|
|
|
63018
63631
|
}
|
|
63019
63632
|
|
|
63020
63633
|
// src/version.ts
|
|
63021
|
-
var version = "0.2.
|
|
63634
|
+
var version = "0.2.446".length > 0 ? "0.2.446" : "dev";
|
|
63022
63635
|
|
|
63023
63636
|
// src/cli-probe/probe.ts
|
|
63024
|
-
var
|
|
63025
|
-
var
|
|
63637
|
+
var fs68 = __toESM(require("fs"), 1);
|
|
63638
|
+
var path77 = __toESM(require("path"), 1);
|
|
63026
63639
|
var PKG_NAME = "@clawos-dev/clawd";
|
|
63027
63640
|
var BIN_NAME = "clawd";
|
|
63028
63641
|
var MAX_PARENT_HOPS = 5;
|
|
63029
63642
|
function probeGlobalCli(pathEnv) {
|
|
63030
63643
|
if (!pathEnv) return null;
|
|
63031
|
-
for (const dir of pathEnv.split(
|
|
63644
|
+
for (const dir of pathEnv.split(path77.delimiter)) {
|
|
63032
63645
|
if (!dir) continue;
|
|
63033
63646
|
let real;
|
|
63034
63647
|
try {
|
|
63035
|
-
real =
|
|
63648
|
+
real = fs68.realpathSync(path77.join(dir, BIN_NAME));
|
|
63036
63649
|
} catch {
|
|
63037
63650
|
continue;
|
|
63038
63651
|
}
|
|
@@ -63042,15 +63655,15 @@ function probeGlobalCli(pathEnv) {
|
|
|
63042
63655
|
return null;
|
|
63043
63656
|
}
|
|
63044
63657
|
function readOwnPackageVersion(entryPath) {
|
|
63045
|
-
let dir =
|
|
63658
|
+
let dir = path77.dirname(entryPath);
|
|
63046
63659
|
for (let i = 0; i < MAX_PARENT_HOPS; i++) {
|
|
63047
63660
|
try {
|
|
63048
|
-
const raw =
|
|
63661
|
+
const raw = fs68.readFileSync(path77.join(dir, "package.json"), "utf8");
|
|
63049
63662
|
const pkg = JSON.parse(raw);
|
|
63050
63663
|
if (pkg.name !== PKG_NAME) return null;
|
|
63051
63664
|
return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
|
|
63052
63665
|
} catch {
|
|
63053
|
-
const parent =
|
|
63666
|
+
const parent = path77.dirname(dir);
|
|
63054
63667
|
if (parent === dir) return null;
|
|
63055
63668
|
dir = parent;
|
|
63056
63669
|
}
|
|
@@ -63222,7 +63835,7 @@ function buildPersonaHandlers(deps) {
|
|
|
63222
63835
|
}
|
|
63223
63836
|
|
|
63224
63837
|
// src/handlers/attachment.ts
|
|
63225
|
-
var
|
|
63838
|
+
var import_node_path59 = __toESM(require("path"), 1);
|
|
63226
63839
|
init_protocol();
|
|
63227
63840
|
init_protocol();
|
|
63228
63841
|
var DEFAULT_TTL_SECONDS = 24 * 3600;
|
|
@@ -63302,12 +63915,12 @@ function buildAttachmentHandlers(deps) {
|
|
|
63302
63915
|
`session ${args.sessionId} scope unresolved`
|
|
63303
63916
|
);
|
|
63304
63917
|
}
|
|
63305
|
-
const cwdAbs =
|
|
63306
|
-
const candidateAbs =
|
|
63918
|
+
const cwdAbs = import_node_path59.default.resolve(sessionFile.cwd);
|
|
63919
|
+
const candidateAbs = import_node_path59.default.isAbsolute(args.relPath) ? import_node_path59.default.resolve(args.relPath) : import_node_path59.default.resolve(cwdAbs, args.relPath);
|
|
63307
63920
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
|
|
63308
63921
|
const entries = deps.groupFileStore.list(scope, args.sessionId);
|
|
63309
63922
|
const entry = entries.find((e) => {
|
|
63310
|
-
const storedAbs =
|
|
63923
|
+
const storedAbs = import_node_path59.default.isAbsolute(e.relPath) ? import_node_path59.default.resolve(e.relPath) : import_node_path59.default.resolve(cwdAbs, e.relPath);
|
|
63311
63924
|
return storedAbs === candidateAbs && !e.stale;
|
|
63312
63925
|
});
|
|
63313
63926
|
if (!entry) {
|
|
@@ -63332,7 +63945,7 @@ function buildAttachmentHandlers(deps) {
|
|
|
63332
63945
|
if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
|
|
63333
63946
|
const f = deps.sessionStore.read(sessionId);
|
|
63334
63947
|
if (!f) return;
|
|
63335
|
-
assertGuestAttachmentPath(ctx,
|
|
63948
|
+
assertGuestAttachmentPath(ctx, import_node_path59.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
|
|
63336
63949
|
}
|
|
63337
63950
|
const groupAdd = async (frame, _client, ctx) => {
|
|
63338
63951
|
if (!deps.groupFileStore || !deps.getSessionScope) {
|
|
@@ -63347,8 +63960,8 @@ function buildAttachmentHandlers(deps) {
|
|
|
63347
63960
|
if (!scope) {
|
|
63348
63961
|
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
|
|
63349
63962
|
}
|
|
63350
|
-
const cwdAbs =
|
|
63351
|
-
const candidateAbs =
|
|
63963
|
+
const cwdAbs = import_node_path59.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
|
|
63964
|
+
const candidateAbs = import_node_path59.default.isAbsolute(args.relPath) ? import_node_path59.default.resolve(args.relPath) : import_node_path59.default.resolve(cwdAbs, args.relPath);
|
|
63352
63965
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
|
|
63353
63966
|
const from = args.origin === "agent" ? "agent" : ctx?.principal.kind === "owner" ? "owner" : "agent";
|
|
63354
63967
|
const size = 0;
|
|
@@ -63406,21 +64019,21 @@ function buildAttachmentHandlers(deps) {
|
|
|
63406
64019
|
}
|
|
63407
64020
|
|
|
63408
64021
|
// src/handlers/extension.ts
|
|
63409
|
-
var
|
|
63410
|
-
var
|
|
64022
|
+
var import_promises14 = __toESM(require("fs/promises"), 1);
|
|
64023
|
+
var import_node_path64 = __toESM(require("path"), 1);
|
|
63411
64024
|
init_protocol();
|
|
63412
64025
|
|
|
63413
64026
|
// src/extension/bundle-zip.ts
|
|
63414
|
-
var
|
|
63415
|
-
var
|
|
64027
|
+
var import_promises11 = __toESM(require("fs/promises"), 1);
|
|
64028
|
+
var import_node_path60 = __toESM(require("path"), 1);
|
|
63416
64029
|
var import_node_crypto17 = __toESM(require("crypto"), 1);
|
|
63417
64030
|
var import_jszip2 = __toESM(require_lib3(), 1);
|
|
63418
64031
|
async function bundleExtensionDir(dir) {
|
|
63419
64032
|
const entries = await listFilesSorted(dir);
|
|
63420
64033
|
const zip = new import_jszip2.default();
|
|
63421
64034
|
for (const rel of entries) {
|
|
63422
|
-
const abs =
|
|
63423
|
-
const content = await
|
|
64035
|
+
const abs = import_node_path60.default.join(dir, rel);
|
|
64036
|
+
const content = await import_promises11.default.readFile(abs);
|
|
63424
64037
|
zip.file(rel, content, { date: FIXED_DATE });
|
|
63425
64038
|
}
|
|
63426
64039
|
const buffer = await zip.generateAsync({
|
|
@@ -63440,8 +64053,8 @@ async function listFilesSorted(rootDir) {
|
|
|
63440
64053
|
return out;
|
|
63441
64054
|
}
|
|
63442
64055
|
async function walk(absRoot, relPrefix, out) {
|
|
63443
|
-
const dirAbs =
|
|
63444
|
-
const entries = await
|
|
64056
|
+
const dirAbs = import_node_path60.default.join(absRoot, relPrefix);
|
|
64057
|
+
const entries = await import_promises11.default.readdir(dirAbs, { withFileTypes: true });
|
|
63445
64058
|
for (const e of entries) {
|
|
63446
64059
|
if (IGNORE_BASENAMES.has(e.name)) continue;
|
|
63447
64060
|
const rel = relPrefix ? `${relPrefix}/${e.name}` : e.name;
|
|
@@ -63493,26 +64106,26 @@ function computePublishCheck(args) {
|
|
|
63493
64106
|
}
|
|
63494
64107
|
|
|
63495
64108
|
// src/extension/install-flow.ts
|
|
63496
|
-
var
|
|
63497
|
-
var
|
|
64109
|
+
var import_promises12 = __toESM(require("fs/promises"), 1);
|
|
64110
|
+
var import_node_path62 = __toESM(require("path"), 1);
|
|
63498
64111
|
var import_node_os22 = __toESM(require("os"), 1);
|
|
63499
64112
|
var import_node_crypto18 = __toESM(require("crypto"), 1);
|
|
63500
64113
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
63501
64114
|
|
|
63502
64115
|
// src/extension/paths.ts
|
|
63503
64116
|
var import_node_os21 = __toESM(require("os"), 1);
|
|
63504
|
-
var
|
|
64117
|
+
var import_node_path61 = __toESM(require("path"), 1);
|
|
63505
64118
|
function clawdHomeRoot(override) {
|
|
63506
|
-
return override ?? process.env.CLAWD_HOME ??
|
|
64119
|
+
return override ?? process.env.CLAWD_HOME ?? import_node_path61.default.join(import_node_os21.default.homedir(), ".clawd");
|
|
63507
64120
|
}
|
|
63508
64121
|
function extensionsRoot(override) {
|
|
63509
|
-
return
|
|
64122
|
+
return import_node_path61.default.join(clawdHomeRoot(override), "extensions");
|
|
63510
64123
|
}
|
|
63511
64124
|
function publishedChannelsFile(override) {
|
|
63512
|
-
return
|
|
64125
|
+
return import_node_path61.default.join(clawdHomeRoot(override), "extensions-published.json");
|
|
63513
64126
|
}
|
|
63514
64127
|
function bundleCacheRoot(override) {
|
|
63515
|
-
return
|
|
64128
|
+
return import_node_path61.default.join(clawdHomeRoot(override), "extension-bundles");
|
|
63516
64129
|
}
|
|
63517
64130
|
|
|
63518
64131
|
// src/extension/install-flow.ts
|
|
@@ -63539,7 +64152,7 @@ async function installFromChannel(args, deps) {
|
|
|
63539
64152
|
throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
63540
64153
|
}
|
|
63541
64154
|
for (const name of Object.keys(zip.files)) {
|
|
63542
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
64155
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path62.default.isAbsolute(name)) {
|
|
63543
64156
|
throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
63544
64157
|
}
|
|
63545
64158
|
}
|
|
@@ -63571,10 +64184,10 @@ async function installFromChannel(args, deps) {
|
|
|
63571
64184
|
);
|
|
63572
64185
|
}
|
|
63573
64186
|
const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
|
|
63574
|
-
const destDir =
|
|
64187
|
+
const destDir = import_node_path62.default.join(deps.extensionsRoot, localExtId);
|
|
63575
64188
|
let destExists = false;
|
|
63576
64189
|
try {
|
|
63577
|
-
await
|
|
64190
|
+
await import_promises12.default.access(destDir);
|
|
63578
64191
|
destExists = true;
|
|
63579
64192
|
} catch {
|
|
63580
64193
|
}
|
|
@@ -63584,28 +64197,28 @@ async function installFromChannel(args, deps) {
|
|
|
63584
64197
|
`extension ${localExtId} already installed locally (from owner ${channelRef.ownerPrincipalId})`
|
|
63585
64198
|
);
|
|
63586
64199
|
}
|
|
63587
|
-
const stage = await
|
|
63588
|
-
|
|
64200
|
+
const stage = await import_promises12.default.mkdtemp(
|
|
64201
|
+
import_node_path62.default.join(import_node_os22.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
|
|
63589
64202
|
);
|
|
63590
64203
|
try {
|
|
63591
64204
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
63592
|
-
const dest =
|
|
64205
|
+
const dest = import_node_path62.default.join(stage, name);
|
|
63593
64206
|
if (entry.dir) {
|
|
63594
|
-
await
|
|
64207
|
+
await import_promises12.default.mkdir(dest, { recursive: true });
|
|
63595
64208
|
continue;
|
|
63596
64209
|
}
|
|
63597
|
-
await
|
|
64210
|
+
await import_promises12.default.mkdir(import_node_path62.default.dirname(dest), { recursive: true });
|
|
63598
64211
|
if (name === "manifest.json") {
|
|
63599
64212
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
63600
|
-
await
|
|
64213
|
+
await import_promises12.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
63601
64214
|
} else {
|
|
63602
|
-
await
|
|
64215
|
+
await import_promises12.default.writeFile(dest, await entry.async("nodebuffer"));
|
|
63603
64216
|
}
|
|
63604
64217
|
}
|
|
63605
|
-
await
|
|
63606
|
-
await
|
|
64218
|
+
await import_promises12.default.mkdir(deps.extensionsRoot, { recursive: true });
|
|
64219
|
+
await import_promises12.default.rename(stage, destDir);
|
|
63607
64220
|
} catch (e) {
|
|
63608
|
-
await
|
|
64221
|
+
await import_promises12.default.rm(stage, { recursive: true, force: true }).catch(() => {
|
|
63609
64222
|
});
|
|
63610
64223
|
throw e;
|
|
63611
64224
|
}
|
|
@@ -63614,8 +64227,8 @@ async function installFromChannel(args, deps) {
|
|
|
63614
64227
|
}
|
|
63615
64228
|
|
|
63616
64229
|
// src/extension/update-flow.ts
|
|
63617
|
-
var
|
|
63618
|
-
var
|
|
64230
|
+
var import_promises13 = __toESM(require("fs/promises"), 1);
|
|
64231
|
+
var import_node_path63 = __toESM(require("path"), 1);
|
|
63619
64232
|
var import_node_os23 = __toESM(require("os"), 1);
|
|
63620
64233
|
var import_node_crypto19 = __toESM(require("crypto"), 1);
|
|
63621
64234
|
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
@@ -63632,11 +64245,11 @@ async function updateFromChannel(args, deps) {
|
|
|
63632
64245
|
channelRef.extId,
|
|
63633
64246
|
channelRef.ownerPrincipalId
|
|
63634
64247
|
);
|
|
63635
|
-
const liveDir =
|
|
64248
|
+
const liveDir = import_node_path63.default.join(deps.extensionsRoot, localExtId);
|
|
63636
64249
|
const prevDir = `${liveDir}.prev`;
|
|
63637
64250
|
let existingVersion;
|
|
63638
64251
|
try {
|
|
63639
|
-
const raw = await
|
|
64252
|
+
const raw = await import_promises13.default.readFile(import_node_path63.default.join(liveDir, "manifest.json"), "utf8");
|
|
63640
64253
|
const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
|
|
63641
64254
|
if (!parsed2.success) {
|
|
63642
64255
|
throw new UpdateError(
|
|
@@ -63669,7 +64282,7 @@ async function updateFromChannel(args, deps) {
|
|
|
63669
64282
|
throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
63670
64283
|
}
|
|
63671
64284
|
for (const name of Object.keys(zip.files)) {
|
|
63672
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
64285
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path63.default.isAbsolute(name)) {
|
|
63673
64286
|
throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
63674
64287
|
}
|
|
63675
64288
|
}
|
|
@@ -63701,31 +64314,31 @@ async function updateFromChannel(args, deps) {
|
|
|
63701
64314
|
);
|
|
63702
64315
|
}
|
|
63703
64316
|
await deps.runtime.close(localExtId);
|
|
63704
|
-
await
|
|
63705
|
-
await
|
|
63706
|
-
const stage = await
|
|
63707
|
-
|
|
64317
|
+
await import_promises13.default.rm(prevDir, { recursive: true, force: true });
|
|
64318
|
+
await import_promises13.default.rename(liveDir, prevDir);
|
|
64319
|
+
const stage = await import_promises13.default.mkdtemp(
|
|
64320
|
+
import_node_path63.default.join(import_node_os23.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
|
|
63708
64321
|
);
|
|
63709
64322
|
try {
|
|
63710
64323
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
63711
|
-
const dest =
|
|
64324
|
+
const dest = import_node_path63.default.join(stage, name);
|
|
63712
64325
|
if (entry.dir) {
|
|
63713
|
-
await
|
|
64326
|
+
await import_promises13.default.mkdir(dest, { recursive: true });
|
|
63714
64327
|
continue;
|
|
63715
64328
|
}
|
|
63716
|
-
await
|
|
64329
|
+
await import_promises13.default.mkdir(import_node_path63.default.dirname(dest), { recursive: true });
|
|
63717
64330
|
if (name === "manifest.json") {
|
|
63718
64331
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
63719
|
-
await
|
|
64332
|
+
await import_promises13.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
63720
64333
|
} else {
|
|
63721
|
-
await
|
|
64334
|
+
await import_promises13.default.writeFile(dest, await entry.async("nodebuffer"));
|
|
63722
64335
|
}
|
|
63723
64336
|
}
|
|
63724
|
-
await
|
|
64337
|
+
await import_promises13.default.rename(stage, liveDir);
|
|
63725
64338
|
} catch (e) {
|
|
63726
|
-
await
|
|
64339
|
+
await import_promises13.default.rm(stage, { recursive: true, force: true }).catch(() => {
|
|
63727
64340
|
});
|
|
63728
|
-
await
|
|
64341
|
+
await import_promises13.default.rename(prevDir, liveDir).catch(() => {
|
|
63729
64342
|
});
|
|
63730
64343
|
await deps.runtime.open(localExtId).catch(() => {
|
|
63731
64344
|
});
|
|
@@ -63747,7 +64360,7 @@ async function updateFromChannel(args, deps) {
|
|
|
63747
64360
|
reason: e.message
|
|
63748
64361
|
};
|
|
63749
64362
|
}
|
|
63750
|
-
await
|
|
64363
|
+
await import_promises13.default.rm(prevDir, { recursive: true, force: true });
|
|
63751
64364
|
return {
|
|
63752
64365
|
kind: "updated",
|
|
63753
64366
|
extId: localExtId,
|
|
@@ -63755,9 +64368,9 @@ async function updateFromChannel(args, deps) {
|
|
|
63755
64368
|
};
|
|
63756
64369
|
}
|
|
63757
64370
|
async function rollback(deps, localExtId, liveDir, prevDir) {
|
|
63758
|
-
await
|
|
64371
|
+
await import_promises13.default.rm(liveDir, { recursive: true, force: true }).catch(() => {
|
|
63759
64372
|
});
|
|
63760
|
-
await
|
|
64373
|
+
await import_promises13.default.rename(prevDir, liveDir).catch(() => {
|
|
63761
64374
|
});
|
|
63762
64375
|
await deps.runtime.open(localExtId).catch(() => {
|
|
63763
64376
|
});
|
|
@@ -63780,18 +64393,18 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
63780
64393
|
);
|
|
63781
64394
|
}
|
|
63782
64395
|
}
|
|
63783
|
-
const manifestPath =
|
|
64396
|
+
const manifestPath = import_node_path64.default.join(root, extId, "manifest.json");
|
|
63784
64397
|
const manifest = await readManifest(root, extId);
|
|
63785
64398
|
const next = { ...manifest, version: newVersion };
|
|
63786
64399
|
const tmp = `${manifestPath}.tmp`;
|
|
63787
|
-
await
|
|
63788
|
-
await
|
|
64400
|
+
await import_promises14.default.writeFile(tmp, JSON.stringify(next, null, 2));
|
|
64401
|
+
await import_promises14.default.rename(tmp, manifestPath);
|
|
63789
64402
|
}
|
|
63790
64403
|
async function readManifest(root, extId) {
|
|
63791
|
-
const file =
|
|
64404
|
+
const file = import_node_path64.default.join(root, extId, "manifest.json");
|
|
63792
64405
|
let raw;
|
|
63793
64406
|
try {
|
|
63794
|
-
raw = await
|
|
64407
|
+
raw = await import_promises14.default.readFile(file, "utf8");
|
|
63795
64408
|
} catch (e) {
|
|
63796
64409
|
if (e.code === "ENOENT") {
|
|
63797
64410
|
throw new ClawdError(ERROR_CODES.INVALID_PARAM, `extension ${extId} not installed`);
|
|
@@ -63872,7 +64485,7 @@ function buildExtensionHandlers(deps) {
|
|
|
63872
64485
|
};
|
|
63873
64486
|
async function buildSnapshotMeta(extId) {
|
|
63874
64487
|
const manifest = await readManifest(deps.root, extId);
|
|
63875
|
-
const { sha256, buffer } = await bundleExtensionDir(
|
|
64488
|
+
const { sha256, buffer } = await bundleExtensionDir(import_node_path64.default.join(deps.root, extId));
|
|
63876
64489
|
return { manifest, contentHash: sha256, buffer };
|
|
63877
64490
|
}
|
|
63878
64491
|
const publish = async (frame, _client, ctx) => {
|
|
@@ -64049,7 +64662,7 @@ function buildExtensionHandlers(deps) {
|
|
|
64049
64662
|
// src/app-builder/project-store.ts
|
|
64050
64663
|
var import_node_fs50 = require("fs");
|
|
64051
64664
|
var import_node_child_process15 = require("child_process");
|
|
64052
|
-
var
|
|
64665
|
+
var import_node_path65 = require("path");
|
|
64053
64666
|
init_protocol();
|
|
64054
64667
|
var PROJECTS_DIR = "projects";
|
|
64055
64668
|
var META_FILE = ".clawd-project.json";
|
|
@@ -64063,14 +64676,14 @@ var ProjectStore = class {
|
|
|
64063
64676
|
root;
|
|
64064
64677
|
/** projects/<name>/.clawd-project.json 路径 */
|
|
64065
64678
|
metaPath(name) {
|
|
64066
|
-
return (0,
|
|
64679
|
+
return (0, import_node_path65.join)(this.projectsRoot(), name, META_FILE);
|
|
64067
64680
|
}
|
|
64068
64681
|
/** projects/<name>/ 目录路径(cwd 用) */
|
|
64069
64682
|
projectDir(name) {
|
|
64070
|
-
return (0,
|
|
64683
|
+
return (0, import_node_path65.join)(this.projectsRoot(), name);
|
|
64071
64684
|
}
|
|
64072
64685
|
projectsRoot() {
|
|
64073
|
-
return (0,
|
|
64686
|
+
return (0, import_node_path65.join)(this.root, PROJECTS_DIR);
|
|
64074
64687
|
}
|
|
64075
64688
|
async list() {
|
|
64076
64689
|
let entries;
|
|
@@ -64373,7 +64986,7 @@ var PublishJobRegistry = class {
|
|
|
64373
64986
|
// src/app-builder/publish-job-runner.ts
|
|
64374
64987
|
var import_node_child_process17 = require("child_process");
|
|
64375
64988
|
var import_node_fs51 = require("fs");
|
|
64376
|
-
var
|
|
64989
|
+
var import_node_path66 = require("path");
|
|
64377
64990
|
|
|
64378
64991
|
// src/app-builder/publish-stage-parser.ts
|
|
64379
64992
|
var STAGE_RE = /^\s*::stage::(build|deploy|verify)\s*$/;
|
|
@@ -64405,7 +65018,7 @@ async function startPublishJob(deps, args) {
|
|
|
64405
65018
|
return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
|
|
64406
65019
|
}
|
|
64407
65020
|
const projDir = projectDir(args.name);
|
|
64408
|
-
const logPath = (0,
|
|
65021
|
+
const logPath = (0, import_node_path66.join)(projDir, ".publish.log");
|
|
64409
65022
|
let logStream = null;
|
|
64410
65023
|
try {
|
|
64411
65024
|
logStream = (0, import_node_fs51.createWriteStream)(logPath, { flags: "w" });
|
|
@@ -64665,7 +65278,7 @@ async function recoverInterruptedJobs(deps) {
|
|
|
64665
65278
|
|
|
64666
65279
|
// src/handlers/app-builder.ts
|
|
64667
65280
|
init_protocol();
|
|
64668
|
-
var
|
|
65281
|
+
var import_node_path67 = require("path");
|
|
64669
65282
|
var import_node_fs52 = require("fs");
|
|
64670
65283
|
var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
|
|
64671
65284
|
var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
|
|
@@ -64816,8 +65429,8 @@ function buildAppBuilderHandlers(deps) {
|
|
|
64816
65429
|
const project = await userStore.create(f.name, reservedPorts);
|
|
64817
65430
|
try {
|
|
64818
65431
|
const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(session.ownerPersonaId ?? "") : deps.personaRoot;
|
|
64819
|
-
const templateSrcDir = (0,
|
|
64820
|
-
const scaffoldScript = (0,
|
|
65432
|
+
const templateSrcDir = (0, import_node_path67.join)(personaRoot, "extension-kit", "examples", DEFAULT_TEMPLATE);
|
|
65433
|
+
const scaffoldScript = (0, import_node_path67.join)(deps.deployKitRoot, "scripts", "new-extension.sh");
|
|
64821
65434
|
const scaffoldResult = await userStore.scaffold(project.name, templateSrcDir, scaffoldScript);
|
|
64822
65435
|
deps.logger?.info("app-builder.scaffold.done", {
|
|
64823
65436
|
name: project.name,
|
|
@@ -65021,7 +65634,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
65021
65634
|
await userStore.clearPublishJob(args.name);
|
|
65022
65635
|
}
|
|
65023
65636
|
const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(boundSession.ownerPersonaId ?? "") : deps.personaRoot;
|
|
65024
|
-
const scriptPath = (0,
|
|
65637
|
+
const scriptPath = (0, import_node_path67.join)(deps.deployKitRoot, "scripts", "publish.sh");
|
|
65025
65638
|
deps.logger?.info("app-builder.publish.start", {
|
|
65026
65639
|
name: args.name,
|
|
65027
65640
|
sessionId: boundSession.sessionId,
|
|
@@ -65250,7 +65863,7 @@ function joinLines(records, lineMeta) {
|
|
|
65250
65863
|
return out;
|
|
65251
65864
|
}
|
|
65252
65865
|
function buildTopicHandlers(deps) {
|
|
65253
|
-
const
|
|
65866
|
+
const mustGet2 = (topicId) => {
|
|
65254
65867
|
const t = deps.topicStore.get(topicId);
|
|
65255
65868
|
if (!t) throw new ClawdError(ERROR_CODES.INVALID_PARAM, `topic not found: ${topicId}`);
|
|
65256
65869
|
return t;
|
|
@@ -65283,7 +65896,7 @@ function buildTopicHandlers(deps) {
|
|
|
65283
65896
|
},
|
|
65284
65897
|
"topic:get": async (frame) => {
|
|
65285
65898
|
const args = TopicGetArgsSchema.parse(frame);
|
|
65286
|
-
const topic = args.topicId ?
|
|
65899
|
+
const topic = args.topicId ? mustGet2(args.topicId) : deps.topicStore.getByMasterSession(args.sessionId);
|
|
65287
65900
|
if (!topic) {
|
|
65288
65901
|
throw new ClawdError(
|
|
65289
65902
|
ERROR_CODES.INVALID_PARAM,
|
|
@@ -65314,7 +65927,7 @@ function buildTopicHandlers(deps) {
|
|
|
65314
65927
|
},
|
|
65315
65928
|
"topic:setPlan": async (frame) => {
|
|
65316
65929
|
const args = TopicSetPlanArgsSchema.parse(frame);
|
|
65317
|
-
|
|
65930
|
+
mustGet2(args.topicId);
|
|
65318
65931
|
const topic = deps.topicStore.setPlan(args.topicId, {
|
|
65319
65932
|
...args.title ? { title: args.title } : {},
|
|
65320
65933
|
goal: args.goal,
|
|
@@ -65326,7 +65939,7 @@ function buildTopicHandlers(deps) {
|
|
|
65326
65939
|
},
|
|
65327
65940
|
"topic:append": async (frame) => {
|
|
65328
65941
|
const args = TopicAppendArgsSchema.parse(frame);
|
|
65329
|
-
const topic =
|
|
65942
|
+
const topic = mustGet2(args.topicId);
|
|
65330
65943
|
deps.topicStore.appendActivity(args.topicId, {
|
|
65331
65944
|
actor: "master",
|
|
65332
65945
|
action: args.action,
|
|
@@ -65339,7 +65952,7 @@ function buildTopicHandlers(deps) {
|
|
|
65339
65952
|
},
|
|
65340
65953
|
"topic:reject": async (frame) => {
|
|
65341
65954
|
const args = TopicRejectArgsSchema.parse(frame);
|
|
65342
|
-
const topic =
|
|
65955
|
+
const topic = mustGet2(args.topicId);
|
|
65343
65956
|
const { rejectCount } = deps.topicStore.bumpReject(args.topicId, args.lineId);
|
|
65344
65957
|
if (topic.state === "done") deps.topicStore.setState(args.topicId, "running");
|
|
65345
65958
|
deps.topicStore.appendActivity(args.topicId, {
|
|
@@ -65358,7 +65971,7 @@ function buildTopicHandlers(deps) {
|
|
|
65358
65971
|
},
|
|
65359
65972
|
"topic:accept": async (frame) => {
|
|
65360
65973
|
const args = TopicAcceptArgsSchema.parse(frame);
|
|
65361
|
-
const topic =
|
|
65974
|
+
const topic = mustGet2(args.topicId);
|
|
65362
65975
|
if (!linesOf(topic).some((l) => l.lineId === args.lineId)) {
|
|
65363
65976
|
throw new ClawdError(
|
|
65364
65977
|
ERROR_CODES.INVALID_PARAM,
|
|
@@ -65382,11 +65995,11 @@ function buildTopicHandlers(deps) {
|
|
|
65382
65995
|
reason: args.reason,
|
|
65383
65996
|
...args.artifacts ? { artifacts: args.artifacts } : {}
|
|
65384
65997
|
});
|
|
65385
|
-
const lines = linesOf(
|
|
65998
|
+
const lines = linesOf(mustGet2(args.topicId));
|
|
65386
65999
|
const acceptedLines = lines.filter((l) => l.accepted).length;
|
|
65387
66000
|
const allAccepted = lines.length > 0 && acceptedLines === lines.length;
|
|
65388
66001
|
if (allAccepted) deps.topicStore.setState(args.topicId, "done");
|
|
65389
|
-
const overrides = Object.values(
|
|
66002
|
+
const overrides = Object.values(mustGet2(args.topicId).lineMeta).reduce(
|
|
65390
66003
|
(n, m2) => n + (m2.overrideCount ?? 0),
|
|
65391
66004
|
0
|
|
65392
66005
|
);
|
|
@@ -65403,21 +66016,21 @@ function buildTopicHandlers(deps) {
|
|
|
65403
66016
|
},
|
|
65404
66017
|
"topic:close": async (frame) => {
|
|
65405
66018
|
const args = TopicCloseArgsSchema.parse(frame);
|
|
65406
|
-
|
|
66019
|
+
mustGet2(args.topicId);
|
|
65407
66020
|
const topic = deps.topicStore.setState(args.topicId, args.state);
|
|
65408
66021
|
announceChanged(topic);
|
|
65409
66022
|
return { response: TopicResultSchema.parse({ topic }) };
|
|
65410
66023
|
},
|
|
65411
66024
|
"topic:rename": async (frame) => {
|
|
65412
66025
|
const args = TopicRenameArgsSchema.parse(frame);
|
|
65413
|
-
|
|
66026
|
+
mustGet2(args.topicId);
|
|
65414
66027
|
const topic = deps.topicStore.rename(args.topicId, args.title);
|
|
65415
66028
|
announceChanged(topic);
|
|
65416
66029
|
return { response: TopicResultSchema.parse({ topic }) };
|
|
65417
66030
|
},
|
|
65418
66031
|
"topic:delete": async (frame) => {
|
|
65419
66032
|
const { topicId } = TopicDeleteArgsSchema.parse(frame);
|
|
65420
|
-
const topic =
|
|
66033
|
+
const topic = mustGet2(topicId);
|
|
65421
66034
|
const { removed, broadcast } = deps.deleteSession(topic.masterSessionId);
|
|
65422
66035
|
const removedWorkerSessionIds = [];
|
|
65423
66036
|
const allBroadcast = [...broadcast];
|
|
@@ -65452,7 +66065,7 @@ function buildTopicHandlers(deps) {
|
|
|
65452
66065
|
init_protocol();
|
|
65453
66066
|
|
|
65454
66067
|
// src/channel/authority.ts
|
|
65455
|
-
var
|
|
66068
|
+
var import_promises15 = __toESM(require("fs/promises"), 1);
|
|
65456
66069
|
init_protocol();
|
|
65457
66070
|
var DEFAULT_AUTHORITY_RULES = [
|
|
65458
66071
|
{ id: "outbound-message", desc: "\u4EE5\u8001\u677F\u540D\u4E49\u7ED9\u5176\u4ED6\u4EBA\u53D1\u6D88\u606F\uFF08IM/\u90AE\u4EF6\uFF09", action: "ask" },
|
|
@@ -65470,7 +66083,7 @@ async function resolveAuthority(args) {
|
|
|
65470
66083
|
let source;
|
|
65471
66084
|
let raw = null;
|
|
65472
66085
|
try {
|
|
65473
|
-
raw = await
|
|
66086
|
+
raw = await import_promises15.default.readFile(args.tablePath, "utf8");
|
|
65474
66087
|
} catch (e) {
|
|
65475
66088
|
if (e.code !== "ENOENT") {
|
|
65476
66089
|
return askBecause(`\u6388\u6743\u8BBE\u5B9A\u8BFB\u4E0D\u51FA\u6765\uFF08${args.tablePath}\uFF09\uFF1A${e.message}`);
|
|
@@ -65755,7 +66368,7 @@ function buildGithubHandlers(deps) {
|
|
|
65755
66368
|
|
|
65756
66369
|
// src/handlers/visitor.ts
|
|
65757
66370
|
init_protocol();
|
|
65758
|
-
function
|
|
66371
|
+
function ensureOwner5(ctx) {
|
|
65759
66372
|
if (!ctx || ctx.principal.kind !== "owner") {
|
|
65760
66373
|
throw new ClawdError(
|
|
65761
66374
|
ERROR_CODES.UNAUTHORIZED,
|
|
@@ -65765,7 +66378,7 @@ function ensureOwner4(ctx) {
|
|
|
65765
66378
|
}
|
|
65766
66379
|
function buildVisitorHandlers(deps) {
|
|
65767
66380
|
const list = async (_frame, _client, ctx) => {
|
|
65768
|
-
|
|
66381
|
+
ensureOwner5(ctx);
|
|
65769
66382
|
return {
|
|
65770
66383
|
response: {
|
|
65771
66384
|
type: "visitor:list",
|
|
@@ -65779,12 +66392,12 @@ function buildVisitorHandlers(deps) {
|
|
|
65779
66392
|
}
|
|
65780
66393
|
|
|
65781
66394
|
// src/extension/registry.ts
|
|
65782
|
-
var
|
|
65783
|
-
var
|
|
66395
|
+
var import_promises16 = __toESM(require("fs/promises"), 1);
|
|
66396
|
+
var import_node_path68 = __toESM(require("path"), 1);
|
|
65784
66397
|
async function loadAll(root) {
|
|
65785
66398
|
let entries;
|
|
65786
66399
|
try {
|
|
65787
|
-
entries = await
|
|
66400
|
+
entries = await import_promises16.default.readdir(root, { withFileTypes: true });
|
|
65788
66401
|
} catch (e) {
|
|
65789
66402
|
if (e.code === "ENOENT") return [];
|
|
65790
66403
|
throw e;
|
|
@@ -65793,16 +66406,16 @@ async function loadAll(root) {
|
|
|
65793
66406
|
for (const ent of entries) {
|
|
65794
66407
|
if (!ent.isDirectory()) continue;
|
|
65795
66408
|
if (ent.name.startsWith(".")) continue;
|
|
65796
|
-
records.push(await loadOne(
|
|
66409
|
+
records.push(await loadOne(import_node_path68.default.join(root, ent.name), ent.name));
|
|
65797
66410
|
}
|
|
65798
66411
|
records.sort((a, b2) => a.extId < b2.extId ? -1 : a.extId > b2.extId ? 1 : 0);
|
|
65799
66412
|
return records;
|
|
65800
66413
|
}
|
|
65801
66414
|
async function loadOne(dir, dirName) {
|
|
65802
|
-
const manifestPath =
|
|
66415
|
+
const manifestPath = import_node_path68.default.join(dir, "manifest.json");
|
|
65803
66416
|
let raw;
|
|
65804
66417
|
try {
|
|
65805
|
-
raw = await
|
|
66418
|
+
raw = await import_promises16.default.readFile(manifestPath, "utf8");
|
|
65806
66419
|
} catch {
|
|
65807
66420
|
return {
|
|
65808
66421
|
extId: dirName,
|
|
@@ -65843,8 +66456,8 @@ async function loadOne(dir, dirName) {
|
|
|
65843
66456
|
}
|
|
65844
66457
|
|
|
65845
66458
|
// src/extension/uninstall.ts
|
|
65846
|
-
var
|
|
65847
|
-
var
|
|
66459
|
+
var import_promises17 = __toESM(require("fs/promises"), 1);
|
|
66460
|
+
var import_node_path69 = __toESM(require("path"), 1);
|
|
65848
66461
|
var UninstallError = class extends Error {
|
|
65849
66462
|
constructor(code, message) {
|
|
65850
66463
|
super(message);
|
|
@@ -65853,14 +66466,14 @@ var UninstallError = class extends Error {
|
|
|
65853
66466
|
code;
|
|
65854
66467
|
};
|
|
65855
66468
|
async function uninstall(deps) {
|
|
65856
|
-
const dir =
|
|
66469
|
+
const dir = import_node_path69.default.join(deps.root, deps.extId);
|
|
65857
66470
|
try {
|
|
65858
|
-
await
|
|
66471
|
+
await import_promises17.default.access(dir);
|
|
65859
66472
|
} catch {
|
|
65860
66473
|
throw new UninstallError("NOT_FOUND", `extension ${deps.extId} not installed`);
|
|
65861
66474
|
}
|
|
65862
66475
|
await deps.runtime.close(deps.extId);
|
|
65863
|
-
await
|
|
66476
|
+
await import_promises17.default.rm(dir, { recursive: true, force: true });
|
|
65864
66477
|
}
|
|
65865
66478
|
|
|
65866
66479
|
// src/handlers/index.ts
|
|
@@ -66086,7 +66699,7 @@ function buildMethodHandlers(deps) {
|
|
|
66086
66699
|
broadcast: deps.broadcastToOwners
|
|
66087
66700
|
}),
|
|
66088
66701
|
...buildMasterHandlers({
|
|
66089
|
-
authorityTablePath:
|
|
66702
|
+
authorityTablePath: import_node_path70.default.join(deps.masterDataDir, "master-authority.json")
|
|
66090
66703
|
}),
|
|
66091
66704
|
...buildTopicHandlers({
|
|
66092
66705
|
topicStore: deps.topicStore,
|
|
@@ -66132,8 +66745,8 @@ function refreshPathFromLoginShell() {
|
|
|
66132
66745
|
timeout: 3e3,
|
|
66133
66746
|
stdio: ["ignore", "pipe", "ignore"]
|
|
66134
66747
|
});
|
|
66135
|
-
const
|
|
66136
|
-
if (
|
|
66748
|
+
const path93 = out.trim();
|
|
66749
|
+
if (path93) process.env.PATH = path93;
|
|
66137
66750
|
} catch {
|
|
66138
66751
|
}
|
|
66139
66752
|
}
|
|
@@ -66547,8 +67160,8 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
|
|
|
66547
67160
|
|
|
66548
67161
|
// src/extension/runtime.ts
|
|
66549
67162
|
var import_node_child_process22 = require("child_process");
|
|
66550
|
-
var
|
|
66551
|
-
var
|
|
67163
|
+
var import_node_path71 = __toESM(require("path"), 1);
|
|
67164
|
+
var import_promises18 = require("timers/promises");
|
|
66552
67165
|
|
|
66553
67166
|
// src/extension/port-allocator.ts
|
|
66554
67167
|
var import_node_net2 = __toESM(require("net"), 1);
|
|
@@ -66648,7 +67261,7 @@ var Runtime = class {
|
|
|
66648
67261
|
/\$CLAWOS_EXT_PORT/g,
|
|
66649
67262
|
String(port)
|
|
66650
67263
|
);
|
|
66651
|
-
const dir =
|
|
67264
|
+
const dir = import_node_path71.default.join(this.root, extId);
|
|
66652
67265
|
const env = {
|
|
66653
67266
|
...process.env,
|
|
66654
67267
|
CLAWOS_EXT_PORT: String(port),
|
|
@@ -66724,7 +67337,7 @@ ${handle.stderrTail}`
|
|
|
66724
67337
|
if (res.ok) return;
|
|
66725
67338
|
} catch {
|
|
66726
67339
|
}
|
|
66727
|
-
await (0,
|
|
67340
|
+
await (0, import_promises18.setTimeout)(this.healthzIntervalMs);
|
|
66728
67341
|
}
|
|
66729
67342
|
throw new RuntimeError(
|
|
66730
67343
|
"HEALTHZ_FAILED",
|
|
@@ -66749,7 +67362,7 @@ ${handle.stderrTail}`
|
|
|
66749
67362
|
};
|
|
66750
67363
|
killGroup("SIGTERM");
|
|
66751
67364
|
const exited = new Promise((resolve9) => child.once("exit", () => resolve9()));
|
|
66752
|
-
const timed = (0,
|
|
67365
|
+
const timed = (0, import_promises18.setTimeout)(5e3).then(() => "timeout");
|
|
66753
67366
|
const winner = await Promise.race([exited.then(() => "exited"), timed]);
|
|
66754
67367
|
if (winner === "timeout" && child.exitCode === null) {
|
|
66755
67368
|
killGroup("SIGKILL");
|
|
@@ -66759,8 +67372,8 @@ ${handle.stderrTail}`
|
|
|
66759
67372
|
};
|
|
66760
67373
|
|
|
66761
67374
|
// src/extension/published-channels.ts
|
|
66762
|
-
var
|
|
66763
|
-
var
|
|
67375
|
+
var import_promises19 = __toESM(require("fs/promises"), 1);
|
|
67376
|
+
var import_node_path72 = __toESM(require("path"), 1);
|
|
66764
67377
|
init_zod();
|
|
66765
67378
|
var PublishedChannelsError = class extends Error {
|
|
66766
67379
|
constructor(code, message) {
|
|
@@ -66790,7 +67403,7 @@ var PublishedChannelStore = class {
|
|
|
66790
67403
|
this.channels.clear();
|
|
66791
67404
|
let raw;
|
|
66792
67405
|
try {
|
|
66793
|
-
raw = await
|
|
67406
|
+
raw = await import_promises19.default.readFile(this.filePath, "utf8");
|
|
66794
67407
|
} catch (e) {
|
|
66795
67408
|
if (e.code === "ENOENT") {
|
|
66796
67409
|
this.loaded = true;
|
|
@@ -66859,15 +67472,15 @@ var PublishedChannelStore = class {
|
|
|
66859
67472
|
)
|
|
66860
67473
|
};
|
|
66861
67474
|
const tmp = `${this.filePath}.tmp`;
|
|
66862
|
-
await
|
|
66863
|
-
await
|
|
66864
|
-
await
|
|
67475
|
+
await import_promises19.default.mkdir(import_node_path72.default.dirname(this.filePath), { recursive: true });
|
|
67476
|
+
await import_promises19.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
|
|
67477
|
+
await import_promises19.default.rename(tmp, this.filePath);
|
|
66865
67478
|
}
|
|
66866
67479
|
};
|
|
66867
67480
|
|
|
66868
67481
|
// src/extension/bundle-cache.ts
|
|
66869
|
-
var
|
|
66870
|
-
var
|
|
67482
|
+
var import_promises20 = __toESM(require("fs/promises"), 1);
|
|
67483
|
+
var import_node_path73 = __toESM(require("path"), 1);
|
|
66871
67484
|
var BundleCache = class {
|
|
66872
67485
|
constructor(rootDir) {
|
|
66873
67486
|
this.rootDir = rootDir;
|
|
@@ -66875,17 +67488,17 @@ var BundleCache = class {
|
|
|
66875
67488
|
rootDir;
|
|
66876
67489
|
/** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
|
|
66877
67490
|
async write(snapshotHash, buffer) {
|
|
66878
|
-
await
|
|
66879
|
-
const file =
|
|
67491
|
+
await import_promises20.default.mkdir(this.rootDir, { recursive: true });
|
|
67492
|
+
const file = import_node_path73.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
66880
67493
|
const tmp = `${file}.tmp`;
|
|
66881
|
-
await
|
|
66882
|
-
await
|
|
67494
|
+
await import_promises20.default.writeFile(tmp, buffer, { mode: 384 });
|
|
67495
|
+
await import_promises20.default.rename(tmp, file);
|
|
66883
67496
|
}
|
|
66884
67497
|
/** Returns the bundle bytes, or null when the file doesn't exist. */
|
|
66885
67498
|
async read(snapshotHash) {
|
|
66886
|
-
const file =
|
|
67499
|
+
const file = import_node_path73.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
66887
67500
|
try {
|
|
66888
|
-
return await
|
|
67501
|
+
return await import_promises20.default.readFile(file);
|
|
66889
67502
|
} catch (e) {
|
|
66890
67503
|
if (e.code === "ENOENT") return null;
|
|
66891
67504
|
throw e;
|
|
@@ -66893,8 +67506,8 @@ var BundleCache = class {
|
|
|
66893
67506
|
}
|
|
66894
67507
|
/** Idempotent — missing file is not an error. */
|
|
66895
67508
|
async delete(snapshotHash) {
|
|
66896
|
-
const file =
|
|
66897
|
-
await
|
|
67509
|
+
const file = import_node_path73.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
67510
|
+
await import_promises20.default.rm(file, { force: true });
|
|
66898
67511
|
}
|
|
66899
67512
|
};
|
|
66900
67513
|
|
|
@@ -66916,24 +67529,24 @@ async function startDaemon(config) {
|
|
|
66916
67529
|
sampling: logShippingCfg.sampling,
|
|
66917
67530
|
homeDir: import_node_os26.default.homedir()
|
|
66918
67531
|
});
|
|
66919
|
-
const logDir =
|
|
67532
|
+
const logDir = import_node_path74.default.join(config.dataDir, "log");
|
|
66920
67533
|
import_node_fs53.default.mkdirSync(logDir, { recursive: true });
|
|
66921
67534
|
const logger = createLogger({
|
|
66922
67535
|
level: config.logLevel,
|
|
66923
|
-
file:
|
|
67536
|
+
file: import_node_path74.default.join(logDir, "clawd.log"),
|
|
66924
67537
|
logClient
|
|
66925
67538
|
});
|
|
66926
67539
|
logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
|
|
66927
67540
|
const screenIdleProbeLogger = createFileOnlyLogger({
|
|
66928
|
-
file:
|
|
67541
|
+
file: import_node_path74.default.join(logDir, "screen-idle-probe.log"),
|
|
66929
67542
|
level: "debug"
|
|
66930
67543
|
});
|
|
66931
67544
|
logger.info("screen-idle probe logger enabled", {
|
|
66932
|
-
file:
|
|
67545
|
+
file: import_node_path74.default.join(logDir, "screen-idle-probe.log")
|
|
66933
67546
|
});
|
|
66934
67547
|
const CAP_TARGETS = [
|
|
66935
|
-
|
|
66936
|
-
|
|
67548
|
+
import_node_path74.default.join(logDir, "clawd.log"),
|
|
67549
|
+
import_node_path74.default.join(logDir, "screen-idle-probe.log")
|
|
66937
67550
|
];
|
|
66938
67551
|
const LOG_CAP_MAX_BYTES = 10 * 1024 * 1024;
|
|
66939
67552
|
const LOG_CAP_KEEP_BYTES = 5 * 1024 * 1024;
|
|
@@ -67055,8 +67668,8 @@ async function startDaemon(config) {
|
|
|
67055
67668
|
const agents = new AgentsScanner();
|
|
67056
67669
|
const history = new ClaudeHistoryReader();
|
|
67057
67670
|
let transport = null;
|
|
67058
|
-
const personaStore = new PersonaStore(
|
|
67059
|
-
const usersRoot =
|
|
67671
|
+
const personaStore = new PersonaStore(import_node_path74.default.join(config.dataDir, "personas"));
|
|
67672
|
+
const usersRoot = import_node_path74.default.join(config.dataDir, "users");
|
|
67060
67673
|
const defaultsRoot = findDefaultsRoot(logger);
|
|
67061
67674
|
if (defaultsRoot) {
|
|
67062
67675
|
seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
|
|
@@ -67080,7 +67693,7 @@ async function startDaemon(config) {
|
|
|
67080
67693
|
retirePersonaBuilder({ store: personaStore, logger });
|
|
67081
67694
|
const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
|
|
67082
67695
|
const dispatchStore = createDispatchStore({
|
|
67083
|
-
filePath:
|
|
67696
|
+
filePath: import_node_path74.default.join(config.dataDir, "dispatch.json"),
|
|
67084
67697
|
now: () => Date.now(),
|
|
67085
67698
|
onFlushError: (err) => logger.error("dispatch store flush failed", {
|
|
67086
67699
|
reason: err instanceof Error ? err.message : String(err)
|
|
@@ -67089,7 +67702,7 @@ async function startDaemon(config) {
|
|
|
67089
67702
|
await dispatchStore.load();
|
|
67090
67703
|
dispatchStore.markInterruptedAsFailed((/* @__PURE__ */ new Date()).toISOString());
|
|
67091
67704
|
const channelStore = createChannelStore({
|
|
67092
|
-
filePath:
|
|
67705
|
+
filePath: import_node_path74.default.join(config.dataDir, "channels.json"),
|
|
67093
67706
|
now: () => Date.now(),
|
|
67094
67707
|
genId: () => `ch-${(0, import_node_crypto22.randomUUID)().slice(0, 8)}`,
|
|
67095
67708
|
onFlushError: (err) => logger.error("channel store flush failed", {
|
|
@@ -67098,7 +67711,7 @@ async function startDaemon(config) {
|
|
|
67098
67711
|
});
|
|
67099
67712
|
await channelStore.load();
|
|
67100
67713
|
const topicStore = createTopicStore({
|
|
67101
|
-
filePath:
|
|
67714
|
+
filePath: import_node_path74.default.join(config.dataDir, "topics.json"),
|
|
67102
67715
|
now: () => Date.now(),
|
|
67103
67716
|
genId: () => `tp-${(0, import_node_crypto22.randomUUID)().slice(0, 8)}`,
|
|
67104
67717
|
onFlushError: (err) => logger.error("topic store flush failed", {
|
|
@@ -67125,18 +67738,18 @@ async function startDaemon(config) {
|
|
|
67125
67738
|
});
|
|
67126
67739
|
}
|
|
67127
67740
|
});
|
|
67128
|
-
const here = typeof __dirname === "string" ? __dirname :
|
|
67741
|
+
const here = typeof __dirname === "string" ? __dirname : import_node_path74.default.dirname((0, import_node_url4.fileURLToPath)(import_meta7.url));
|
|
67129
67742
|
const mcpConfigs = [];
|
|
67130
67743
|
const mcpDaemonUrl = `http://127.0.0.1:${config.port}`;
|
|
67131
67744
|
const dispatchServerCandidates = [
|
|
67132
|
-
|
|
67745
|
+
import_node_path74.default.join(here, "dispatch", "mcp-server.cjs"),
|
|
67133
67746
|
// 生产 dist/index → dist/dispatch/mcp-server.cjs
|
|
67134
|
-
|
|
67747
|
+
import_node_path74.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
|
|
67135
67748
|
// dev tsx src/index → ../dist/dispatch/mcp-server.cjs
|
|
67136
67749
|
];
|
|
67137
67750
|
const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs53.default.existsSync(p2));
|
|
67138
67751
|
if (dispatchServerScriptPath) {
|
|
67139
|
-
const dispatchLogPath =
|
|
67752
|
+
const dispatchLogPath = import_node_path74.default.join(logDir, "dispatch-mcp-server.log");
|
|
67140
67753
|
const dispatchCfgPath = writeDispatchMcpConfig({
|
|
67141
67754
|
dataDir: config.dataDir,
|
|
67142
67755
|
serverScriptPath: dispatchServerScriptPath,
|
|
@@ -67156,12 +67769,12 @@ async function startDaemon(config) {
|
|
|
67156
67769
|
});
|
|
67157
67770
|
}
|
|
67158
67771
|
const ticketServerCandidates = [
|
|
67159
|
-
|
|
67160
|
-
|
|
67772
|
+
import_node_path74.default.join(here, "ticket", "mcp-server.cjs"),
|
|
67773
|
+
import_node_path74.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
|
|
67161
67774
|
];
|
|
67162
67775
|
const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs53.default.existsSync(p2));
|
|
67163
67776
|
if (ticketServerScriptPath) {
|
|
67164
|
-
const ticketLogPath =
|
|
67777
|
+
const ticketLogPath = import_node_path74.default.join(logDir, "ticket-mcp-server.log");
|
|
67165
67778
|
const ticketCfgPath = writeTicketMcpConfig({
|
|
67166
67779
|
dataDir: config.dataDir,
|
|
67167
67780
|
serverScriptPath: ticketServerScriptPath,
|
|
@@ -67183,12 +67796,12 @@ async function startDaemon(config) {
|
|
|
67183
67796
|
});
|
|
67184
67797
|
}
|
|
67185
67798
|
const shiftServerCandidates = [
|
|
67186
|
-
|
|
67187
|
-
|
|
67799
|
+
import_node_path74.default.join(here, "shift", "mcp-server.cjs"),
|
|
67800
|
+
import_node_path74.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
|
|
67188
67801
|
];
|
|
67189
67802
|
const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs53.default.existsSync(p2));
|
|
67190
67803
|
if (shiftServerScriptPath) {
|
|
67191
|
-
const shiftLogPath =
|
|
67804
|
+
const shiftLogPath = import_node_path74.default.join(logDir, "shift-mcp-server.log");
|
|
67192
67805
|
const shiftCfgPath = await writeShiftMcpConfig({
|
|
67193
67806
|
dataDir: config.dataDir,
|
|
67194
67807
|
serverScriptPath: shiftServerScriptPath,
|
|
@@ -67209,12 +67822,12 @@ async function startDaemon(config) {
|
|
|
67209
67822
|
);
|
|
67210
67823
|
}
|
|
67211
67824
|
const inboxServerCandidates = [
|
|
67212
|
-
|
|
67213
|
-
|
|
67825
|
+
import_node_path74.default.join(here, "inbox", "mcp-server.cjs"),
|
|
67826
|
+
import_node_path74.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
|
|
67214
67827
|
];
|
|
67215
67828
|
const inboxServerScriptPath = inboxServerCandidates.find((p2) => import_node_fs53.default.existsSync(p2));
|
|
67216
67829
|
if (inboxServerScriptPath) {
|
|
67217
|
-
const inboxLogPath =
|
|
67830
|
+
const inboxLogPath = import_node_path74.default.join(logDir, "inbox-mcp-server.log");
|
|
67218
67831
|
const inboxCfgPath = await writeInboxMcpConfig({
|
|
67219
67832
|
dataDir: config.dataDir,
|
|
67220
67833
|
serverScriptPath: inboxServerScriptPath,
|
|
@@ -67235,8 +67848,8 @@ async function startDaemon(config) {
|
|
|
67235
67848
|
);
|
|
67236
67849
|
}
|
|
67237
67850
|
const peerOpsServerCandidates = [
|
|
67238
|
-
|
|
67239
|
-
|
|
67851
|
+
import_node_path74.default.join(here, "peer-ops", "mcp-server.cjs"),
|
|
67852
|
+
import_node_path74.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
|
|
67240
67853
|
];
|
|
67241
67854
|
const peerOpsServerScriptPath = peerOpsServerCandidates.find((p2) => import_node_fs53.default.existsSync(p2));
|
|
67242
67855
|
if (peerOpsServerScriptPath) {
|
|
@@ -67258,12 +67871,12 @@ async function startDaemon(config) {
|
|
|
67258
67871
|
);
|
|
67259
67872
|
}
|
|
67260
67873
|
const rpcToolServerCandidates = [
|
|
67261
|
-
|
|
67262
|
-
|
|
67874
|
+
import_node_path74.default.join(here, "rpc-tool", "mcp-server.cjs"),
|
|
67875
|
+
import_node_path74.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
|
|
67263
67876
|
];
|
|
67264
67877
|
const rpcToolServerScriptPath = rpcToolServerCandidates.find((p2) => import_node_fs53.default.existsSync(p2));
|
|
67265
67878
|
if (rpcToolServerScriptPath) {
|
|
67266
|
-
const rpcToolLogPath =
|
|
67879
|
+
const rpcToolLogPath = import_node_path74.default.join(logDir, "rpc-tool-mcp-server.log");
|
|
67267
67880
|
const rpcToolCfgPath = writeRpcToolMcpConfig({
|
|
67268
67881
|
dataDir: config.dataDir,
|
|
67269
67882
|
serverScriptPath: rpcToolServerScriptPath,
|
|
@@ -67284,7 +67897,7 @@ async function startDaemon(config) {
|
|
|
67284
67897
|
);
|
|
67285
67898
|
}
|
|
67286
67899
|
const shiftStore = createShiftStore({
|
|
67287
|
-
filePath:
|
|
67900
|
+
filePath: import_node_path74.default.join(config.dataDir, "shift.json"),
|
|
67288
67901
|
ownerIdProvider: () => ownerPrincipalId,
|
|
67289
67902
|
now: () => Date.now()
|
|
67290
67903
|
});
|
|
@@ -67306,7 +67919,7 @@ async function startDaemon(config) {
|
|
|
67306
67919
|
getAdapter,
|
|
67307
67920
|
historyReader: history,
|
|
67308
67921
|
dataDir: config.dataDir,
|
|
67309
|
-
personaRoot:
|
|
67922
|
+
personaRoot: import_node_path74.default.join(config.dataDir, "personas"),
|
|
67310
67923
|
// dispatch / shift 自动化 spawn 按 persona 绑定 tool 起 B session(codex persona 用 codex)。
|
|
67311
67924
|
// personaRegistry 声明在 manager 之后(同作用域 const,调用时机在启动完成后,无 TDZ 风险)。
|
|
67312
67925
|
getPersonaDefaults: (personaId2) => personaRegistry.get(personaId2),
|
|
@@ -67360,7 +67973,7 @@ async function startDaemon(config) {
|
|
|
67360
67973
|
// 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
|
|
67361
67974
|
attachmentGroup: {
|
|
67362
67975
|
onFileEdit: (input) => {
|
|
67363
|
-
const absPath =
|
|
67976
|
+
const absPath = import_node_path74.default.isAbsolute(input.relPath) ? input.relPath : import_node_path74.default.join(input.cwd, input.relPath);
|
|
67364
67977
|
let size = 0;
|
|
67365
67978
|
try {
|
|
67366
67979
|
size = import_node_fs53.default.statSync(absPath).size;
|
|
@@ -67393,9 +68006,9 @@ async function startDaemon(config) {
|
|
|
67393
68006
|
logger.info("projects.seed-dropped", { dropped: droppedSeed.dropped, backup: droppedSeed.backup });
|
|
67394
68007
|
}
|
|
67395
68008
|
const projectsStore = new ProjectsStore({
|
|
67396
|
-
file:
|
|
68009
|
+
file: import_node_path74.default.join(config.dataDir, "projects.json"),
|
|
67397
68010
|
clawdDir: config.dataDir,
|
|
67398
|
-
codexStateFile:
|
|
68011
|
+
codexStateFile: import_node_path74.default.join(import_node_os26.default.homedir(), ".codex", ".codex-global-state.json"),
|
|
67399
68012
|
logger
|
|
67400
68013
|
});
|
|
67401
68014
|
const observer = new SessionObserver({
|
|
@@ -67455,12 +68068,12 @@ async function startDaemon(config) {
|
|
|
67455
68068
|
screenIdleProbeLogger
|
|
67456
68069
|
}) : new ClaudeAdapter({ logger, historyReader: new ClaudeHistoryReader() });
|
|
67457
68070
|
registerAdapter("claude", claudeAdapter);
|
|
67458
|
-
const codexIsolatedHome =
|
|
68071
|
+
const codexIsolatedHome = import_node_path74.default.join(config.dataDir, "codex-home");
|
|
67459
68072
|
try {
|
|
67460
68073
|
import_node_fs53.default.mkdirSync(codexIsolatedHome, { recursive: true });
|
|
67461
68074
|
for (const f of ["auth.json", "config.toml"]) {
|
|
67462
|
-
const link =
|
|
67463
|
-
const target =
|
|
68075
|
+
const link = import_node_path74.default.join(codexIsolatedHome, f);
|
|
68076
|
+
const target = import_node_path74.default.join(import_node_os26.default.homedir(), ".codex", f);
|
|
67464
68077
|
if (!import_node_fs53.default.existsSync(link) && import_node_fs53.default.existsSync(target)) import_node_fs53.default.symlinkSync(target, link);
|
|
67465
68078
|
}
|
|
67466
68079
|
} catch (err) {
|
|
@@ -67474,11 +68087,11 @@ async function startDaemon(config) {
|
|
|
67474
68087
|
// projectPaths 每次调用现取 —— 用户新建 project 后立即生效,不用重启 daemon
|
|
67475
68088
|
codexHomeFor: (cwd) => resolveCodexHome({
|
|
67476
68089
|
cwd,
|
|
67477
|
-
personaRoot:
|
|
68090
|
+
personaRoot: import_node_path74.default.join(config.dataDir, "personas"),
|
|
67478
68091
|
// 必须用 listMerged(Codex registry ∪ 叠加层):只用本地 list() 的话,用户在
|
|
67479
68092
|
// Codex 里建的 project 不在表里,在它下面开的会话会被误判成隔离 → Codex 侧看不到
|
|
67480
68093
|
projectPaths: projectsStore.listMerged().map((x) => x.path),
|
|
67481
|
-
sharedHome:
|
|
68094
|
+
sharedHome: import_node_path74.default.join(import_node_os26.default.homedir(), ".codex"),
|
|
67482
68095
|
isolatedHome: codexIsolatedHome
|
|
67483
68096
|
})
|
|
67484
68097
|
})
|
|
@@ -67762,11 +68375,11 @@ async function startDaemon(config) {
|
|
|
67762
68375
|
// 'persona/<pid>/owner',default 走 'default'。
|
|
67763
68376
|
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
67764
68377
|
// guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
|
|
67765
|
-
personaRoot:
|
|
68378
|
+
personaRoot: import_node_path74.default.join(config.dataDir, "personas"),
|
|
67766
68379
|
usersRoot
|
|
67767
68380
|
},
|
|
67768
68381
|
// workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
|
|
67769
|
-
personaRoot:
|
|
68382
|
+
personaRoot: import_node_path74.default.join(config.dataDir, "personas"),
|
|
67770
68383
|
// v2 多人 persona 隔离:handler 派生 guest user-dir 放行
|
|
67771
68384
|
usersRoot,
|
|
67772
68385
|
// v2 Phase 6: whoami handler 装在 owner principal.displayName + persona 解析
|
|
@@ -67865,11 +68478,11 @@ async function startDaemon(config) {
|
|
|
67865
68478
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2):
|
|
67866
68479
|
// appBuilderPersonaRoot 用于拼 publish.sh 绝对路径(persona-app-builder 安装在
|
|
67867
68480
|
// dataDir/personas/persona-app-builder 之下,extension-kit/scripts/publish.sh 是相对路径)。
|
|
67868
|
-
appBuilderPersonaRoot:
|
|
68481
|
+
appBuilderPersonaRoot: import_node_path74.default.join(config.dataDir, "personas", "persona-app-builder"),
|
|
67869
68482
|
// 共享 deploy-kit 根:scaffold/publish 脚本骨架 + 阿里云凭证单一真源。
|
|
67870
|
-
deployKitRoot:
|
|
68483
|
+
deployKitRoot: import_node_path74.default.join(config.dataDir, "deploy-kit"),
|
|
67871
68484
|
// scaffold/publish 按当前 session 的 persona 解析其安装根,让每个 persona 用自己的模板/注入配置。
|
|
67872
|
-
resolvePersonaRoot: (personaId2) =>
|
|
68485
|
+
resolvePersonaRoot: (personaId2) => import_node_path74.default.join(config.dataDir, "personas", personaId2),
|
|
67873
68486
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2.2):
|
|
67874
68487
|
// 复用 SessionManagerDeps.broadcastFrame 同款 dispatch 逻辑 —— runner 调 manager.send
|
|
67875
68488
|
// 取回 broadcast 帧后逐帧 push 到 transport,跟 manager 自身的 deps 一致。
|
|
@@ -67981,6 +68594,58 @@ async function startDaemon(config) {
|
|
|
67981
68594
|
ownerIdProvider: () => ownerPrincipalId
|
|
67982
68595
|
});
|
|
67983
68596
|
Object.assign(handlers, shiftHandlers);
|
|
68597
|
+
const deployReceipts = createReceiptStore({
|
|
68598
|
+
filePath: import_node_path74.default.join(config.dataDir, "deploy.json"),
|
|
68599
|
+
now: () => Date.now(),
|
|
68600
|
+
onFlushError: (err) => logger.error("deploy receipts flush failed", { error: String(err) })
|
|
68601
|
+
});
|
|
68602
|
+
const deploySecrets = createSecretStore({
|
|
68603
|
+
filePath: import_node_path74.default.join(config.dataDir, "deploy-secrets.json"),
|
|
68604
|
+
now: () => Date.now(),
|
|
68605
|
+
onFlushError: (err) => logger.error("deploy secrets flush failed", { error: String(err) })
|
|
68606
|
+
});
|
|
68607
|
+
await deployReceipts.load();
|
|
68608
|
+
await deploySecrets.load();
|
|
68609
|
+
const interrupted = reconcileInterruptedScans(deployReceipts);
|
|
68610
|
+
if (interrupted.length > 0) logger.warn("deploy scans interrupted by restart", { deployIds: interrupted });
|
|
68611
|
+
const deployHandlers = buildDeployHandlers({
|
|
68612
|
+
receipts: deployReceipts,
|
|
68613
|
+
secrets: deploySecrets,
|
|
68614
|
+
hasPersona: (personaId2) => personaStore.has(personaId2),
|
|
68615
|
+
startScan: (deployId, personaId2) => {
|
|
68616
|
+
const assetLines = SCANNABLE_ASSETS.map(
|
|
68617
|
+
(name) => ` - ${name}\uFF1A${import_node_path74.default.join(config.dataDir, name)}`
|
|
68618
|
+
).join("\n");
|
|
68619
|
+
const prompt = [
|
|
68620
|
+
`\u626B\u63CF persona\u300C${personaId2}\u300D\u7684\u90E8\u7F72\u73AF\u5883\uFF0CdeployId=${deployId}\u3002`,
|
|
68621
|
+
"",
|
|
68622
|
+
`persona \u76EE\u5F55\uFF1A${personaStore.personaDirPath(personaId2)}`,
|
|
68623
|
+
"\u53EF\u4EE5\u8BFB\u5230\u7684 persona \u76EE\u5F55\u4E4B\u5916\u7684\u5171\u4EAB\u8D44\u4EA7\uFF1A",
|
|
68624
|
+
assetLines || " \uFF08\u65E0\uFF09",
|
|
68625
|
+
"",
|
|
68626
|
+
"\u6309 scan-persona-for-deploy skill \u5E72\u6D3B\uFF1A\u8FB9\u67E5\u8FB9\u7528 deploy:reportFinding \u4E0A\u62A5\uFF0C",
|
|
68627
|
+
"\u5168\u90E8\u67E5\u5B8C\u8C03 deploy:finishScan \u6536\u5C3E\u3002"
|
|
68628
|
+
].join("\n");
|
|
68629
|
+
let handle;
|
|
68630
|
+
try {
|
|
68631
|
+
handle = manager.createShiftSession({ targetPersona: BUTLER_PERSONA_ID, prompt });
|
|
68632
|
+
} catch (err) {
|
|
68633
|
+
deployReceipts.update(deployId, { status: "scanFailed", error: `\u8D77\u626B\u63CF\u4F1A\u8BDD\u5931\u8D25\uFF1A${String(err)}` });
|
|
68634
|
+
logger.error("deploy scan session failed to start", { deployId, personaId: personaId2, error: String(err) });
|
|
68635
|
+
return void 0;
|
|
68636
|
+
}
|
|
68637
|
+
void handle.ended.then((outcome) => {
|
|
68638
|
+
const patch = settleEndedScan(outcome, deployReceipts.get(deployId));
|
|
68639
|
+
if (!patch) return;
|
|
68640
|
+
deployReceipts.update(deployId, patch);
|
|
68641
|
+
logger.warn("deploy scan ended without finishScan", { deployId, personaId: personaId2, why: patch.error });
|
|
68642
|
+
});
|
|
68643
|
+
return handle.sessionId;
|
|
68644
|
+
},
|
|
68645
|
+
genId: () => `dp-${(0, import_node_crypto22.randomUUID)().slice(0, 8)}`,
|
|
68646
|
+
now: () => Date.now()
|
|
68647
|
+
});
|
|
68648
|
+
Object.assign(handlers, deployHandlers);
|
|
67984
68649
|
const shiftSpawnFn = createShiftSpawnFn({ sessionManager: manager });
|
|
67985
68650
|
const shiftScheduler = createShiftScheduler({
|
|
67986
68651
|
store: shiftStore,
|
|
@@ -67990,7 +68655,7 @@ async function startDaemon(config) {
|
|
|
67990
68655
|
});
|
|
67991
68656
|
shiftScheduler.start();
|
|
67992
68657
|
logger.info("shift scheduler started", { shiftCount: shiftStore.list().length });
|
|
67993
|
-
const larkBotStore = createLarkBotBindingStore(
|
|
68658
|
+
const larkBotStore = createLarkBotBindingStore(import_node_path74.default.join(config.dataDir, "personas"));
|
|
67994
68659
|
const larkBotCloud = createLarkBotCloudClient({
|
|
67995
68660
|
api: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
67996
68661
|
apiKey: resolveClawdTicketsApiKey(),
|
|
@@ -68004,7 +68669,7 @@ async function startDaemon(config) {
|
|
|
68004
68669
|
store: larkBotStore,
|
|
68005
68670
|
fetchResource: (appId, messageId, fileKey, maxBytes, type) => larkBotCloud.fetchResource(appId, messageId, fileKey, maxBytes, type),
|
|
68006
68671
|
// 图片落 guest userWorkDir 下(capId = lark-<chat_id>):CC 经 --add-dir + allowRead carve 可 Read
|
|
68007
|
-
mediaRootFor: (chatId) =>
|
|
68672
|
+
mediaRootFor: (chatId) => import_node_path74.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
|
|
68008
68673
|
isShuttingDown: () => larkDraining,
|
|
68009
68674
|
logger: {
|
|
68010
68675
|
warn: (msg) => logger.warn(msg),
|
|
@@ -68309,8 +68974,8 @@ async function startDaemon(config) {
|
|
|
68309
68974
|
const lines = [
|
|
68310
68975
|
`Tunnel: ${r.url}`,
|
|
68311
68976
|
...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
|
|
68312
|
-
`Frpc config: ${
|
|
68313
|
-
`Frpc log: ${
|
|
68977
|
+
`Frpc config: ${import_node_path74.default.join(config.dataDir, "frpc.toml")}`,
|
|
68978
|
+
`Frpc log: ${import_node_path74.default.join(logDir, "frpc.log")}`
|
|
68314
68979
|
];
|
|
68315
68980
|
const width2 = Math.max(...lines.map((l) => l.length));
|
|
68316
68981
|
const bar = "\u2550".repeat(width2 + 4);
|
|
@@ -68323,7 +68988,7 @@ ${bar}
|
|
|
68323
68988
|
|
|
68324
68989
|
`);
|
|
68325
68990
|
try {
|
|
68326
|
-
const connectPath =
|
|
68991
|
+
const connectPath = import_node_path74.default.join(config.dataDir, "connect.txt");
|
|
68327
68992
|
import_node_fs53.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
68328
68993
|
} catch {
|
|
68329
68994
|
}
|
|
@@ -68390,7 +69055,9 @@ ${bar}
|
|
|
68390
69055
|
await wss.stop();
|
|
68391
69056
|
for (const [name, store2] of [
|
|
68392
69057
|
["channels", channelStore],
|
|
68393
|
-
["topics", topicStore]
|
|
69058
|
+
["topics", topicStore],
|
|
69059
|
+
["deploy-receipts", deployReceipts],
|
|
69060
|
+
["deploy-secrets", deploySecrets]
|
|
68394
69061
|
]) {
|
|
68395
69062
|
await store2.flushNow().catch((err) => {
|
|
68396
69063
|
logger.warn("shutdown.store-flush-failed", {
|
|
@@ -68411,7 +69078,7 @@ ${bar}
|
|
|
68411
69078
|
};
|
|
68412
69079
|
}
|
|
68413
69080
|
function migrateDropPersonsDir(dataDir) {
|
|
68414
|
-
const dir =
|
|
69081
|
+
const dir = import_node_path74.default.join(dataDir, "persons");
|
|
68415
69082
|
try {
|
|
68416
69083
|
import_node_fs53.default.rmSync(dir, { recursive: true, force: true });
|
|
68417
69084
|
} catch {
|