@clawos-dev/clawd 0.2.261 → 0.2.263
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 +1611 -1365
- package/dist/dispatch/mcp-server.cjs +2001 -1491
- package/dist/rpc-tool/mcp-server.cjs +14 -4
- package/dist/share-ui/assets/{guest-DyvZnRwD.js → guest-7QpiTI6y.js} +126 -126
- package/dist/share-ui/guest.html +1 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -4149,346 +4149,6 @@ var init_zod = __esm({
|
|
|
4149
4149
|
}
|
|
4150
4150
|
});
|
|
4151
4151
|
|
|
4152
|
-
// ../protocol/src/methods.ts
|
|
4153
|
-
var METHOD_NAMES, RPC_METHOD_STATUSES, RpcMethodStatusSchema, RpcMethodInfoSchema, MetaMethodsResultSchema;
|
|
4154
|
-
var init_methods = __esm({
|
|
4155
|
-
"../protocol/src/methods.ts"() {
|
|
4156
|
-
"use strict";
|
|
4157
|
-
init_zod();
|
|
4158
|
-
METHOD_NAMES = [
|
|
4159
|
-
"session:create",
|
|
4160
|
-
"session:list",
|
|
4161
|
-
"session:get",
|
|
4162
|
-
"session:update",
|
|
4163
|
-
"session:delete",
|
|
4164
|
-
"session:send",
|
|
4165
|
-
// per-turn sender 2026-07-08 spec §4.6:MCP servers (ticket / inbox ...) 走 HTTP RPC
|
|
4166
|
-
// /rpc/session:currentTurnSender(Bearer)拉当前 turn caller;WS handler 同名
|
|
4167
|
-
"session:currentTurnSender",
|
|
4168
|
-
"session:stop",
|
|
4169
|
-
// 温柔中断当前轮次,不杀进程(走 CC IPC control_request.subtype=interrupt)
|
|
4170
|
-
"session:interrupt",
|
|
4171
|
-
// 回滚到指定 user message,并撤销其后 CC 的文件编辑(走 CC IPC control_request.subtype=rewind_files)
|
|
4172
|
-
"session:rewind",
|
|
4173
|
-
// Rewind 预览:daemon 读 ~/.claude/file-history 快照 + 磁盘现状算真实 diff,不依赖 CC 进程
|
|
4174
|
-
"session:rewind-diff",
|
|
4175
|
-
// 打开 session 时一次性拿到"有真实 diff"的 user message id 集合,UI heuristic 据此过滤按钮显示
|
|
4176
|
-
"session:rewindable-message-ids",
|
|
4177
|
-
// 从指定 message uuid 处 fork 出新 transcript(截断 + 重写 sessionId/parentUuid + forkedFrom)
|
|
4178
|
-
// daemon 只生成新 jsonl 文件并返回新 toolSessionId;UI 自行决定是否走 session:create 拉起 resume
|
|
4179
|
-
"session:fork",
|
|
4180
|
-
"session:new",
|
|
4181
|
-
"session:resume",
|
|
4182
|
-
"session:observe",
|
|
4183
|
-
"session:events",
|
|
4184
|
-
"session:subscribe",
|
|
4185
|
-
"session:unsubscribe",
|
|
4186
|
-
"session:pin",
|
|
4187
|
-
// 清共享未读标记(SessionFile.unreadAt → null)+ 广播 session:info;幂等
|
|
4188
|
-
"session:markRead",
|
|
4189
|
-
"session:reorderPins",
|
|
4190
|
-
// mirror peer sessions (2026-05-26): owner-only RPC,写/删本机 mirror SessionFile —
|
|
4191
|
-
// mirror 是「**我**在朋友 daemon 上自己创建的 session」的本机持久化副本(不是朋友的会话),
|
|
4192
|
-
// 方便 sidebar 跨设备聚合。daemon dumb 写删,**不广播任何 push 帧** (不发 session:info /
|
|
4193
|
-
// session:deleted);UI 是写入唯一源,双写完成后通过 cache.setData('sessions', ...) 同步
|
|
4194
|
-
// 本地 sidebar state。native session:* handler 完全不感知 mirror (UI 操作 mirror 不复用
|
|
4195
|
-
// native 路径)。
|
|
4196
|
-
"peerSession:upsert",
|
|
4197
|
-
"peerSession:remove",
|
|
4198
|
-
"permission:respond",
|
|
4199
|
-
// AskUserQuestion 表单回写:UI 答完所有 question 后调用,daemon 把答案合并进 updated_input
|
|
4200
|
-
// 写一条 control_response 到 CC stdin(详见 events.ts session:question JSDoc)
|
|
4201
|
-
"session:answerQuestion",
|
|
4202
|
-
// AskUserQuestion 用户跳过:daemon 向 CC 回 allow + answers={} 让 tool 走空答案路径,
|
|
4203
|
-
// 同时广播 cleared 帧(无 answers)让所有客户端 UI 卡片转 Ended
|
|
4204
|
-
"session:cancelQuestion",
|
|
4205
|
-
"history:projects",
|
|
4206
|
-
"history:list",
|
|
4207
|
-
"history:read",
|
|
4208
|
-
"history:subagents",
|
|
4209
|
-
"history:subagent-read",
|
|
4210
|
-
"history:recentDirs",
|
|
4211
|
-
"workspace:list",
|
|
4212
|
-
"workspace:read",
|
|
4213
|
-
"shift:list",
|
|
4214
|
-
// ---- shift-internal:* (cc 内 shift MCP server 管理 owner 排班,spec 2026-06-24-clawd-shift) ----
|
|
4215
|
-
// 统一 RPC 鉴权(spec 2026-07-28)后经 /rpc + Bearer owner token 调;personaId 归因
|
|
4216
|
-
// 从 body 来(env CLAWD_PERSONA_ID),handler 内 createdByPersona 自检防跨 persona 误操作。
|
|
4217
|
-
"shift-internal:add",
|
|
4218
|
-
"shift-internal:list",
|
|
4219
|
-
"shift-internal:cancel",
|
|
4220
|
-
"shift-internal:update",
|
|
4221
|
-
"shift-internal:history",
|
|
4222
|
-
"skills:list",
|
|
4223
|
-
"agents:list",
|
|
4224
|
-
"git:root",
|
|
4225
|
-
"git:branch",
|
|
4226
|
-
"git:branches",
|
|
4227
|
-
"capabilities:get",
|
|
4228
|
-
// ---- persona:* (persona 管理) ----
|
|
4229
|
-
// persona:list 响应 shape 不分流(统一返 PersonaFile[]),但 daemon handler 按
|
|
4230
|
-
// ConnectionContext 投影不同子集:
|
|
4231
|
-
// owner ctx → 返全量 personas(含 private)
|
|
4232
|
-
// guest ctx → persona.public === true ∧ assertGrant(ctx.grants, {persona,p.id}, 'read')
|
|
4233
|
-
// method-grants.ts: persona:list 是 CAPABILITY_SCOPED;其它 persona:* 仍 ADMIN_ANY。
|
|
4234
|
-
"persona:create",
|
|
4235
|
-
"persona:list",
|
|
4236
|
-
"persona:get",
|
|
4237
|
-
"persona:update",
|
|
4238
|
-
"persona:delete",
|
|
4239
|
-
// ---- personaDispatch:* (dispatch 全家,spec 2026-07-28-unify-rpc-auth 统一登记) ----
|
|
4240
|
-
// run:本地 MCP server 经 /rpc(Bearer owner token);跨设备 A 的 peer daemon 经 /rpc
|
|
4241
|
-
//(Bearer connect token)。capability-scoped(handler 自检 persona.public + assertGrant(send))。
|
|
4242
|
-
// complete / list:B / A 本机 MCP server 调(owner token → ADMIN_ANY)。
|
|
4243
|
-
// get:跨设备轮询——A 端 daemon 凭 connect token 查 B 台账终态;handler 校验行归属。
|
|
4244
|
-
"personaDispatch:run",
|
|
4245
|
-
"personaDispatch:complete",
|
|
4246
|
-
"personaDispatch:list",
|
|
4247
|
-
"personaDispatch:get",
|
|
4248
|
-
// ---- peerExec:run (跨设备 exec,spec 2026-07-16-cross-device-exec-mcp) ----
|
|
4249
|
-
// A 侧本机 MCP server 经 /rpc(Bearer owner token)带 peerDeviceId → daemon forward;
|
|
4250
|
-
// B 侧对端经 /rpc(Bearer connect token)无 peerDeviceId → 本地 spawn。METHOD_GRANT_MAP
|
|
4251
|
-
// 设 public,handler 内判 remoteAccessAllowed(跟 inbox:postMessage 同款)。
|
|
4252
|
-
"peerExec:run",
|
|
4253
|
-
// ---- session:pty 双向透传(仅 CLAWD_CC_MODE=tui 才生效,对应 session:pty push 帧的上行) ----
|
|
4254
|
-
// session:pty:input — UI 把用户键盘字节(base64 UTF-8)发给 daemon,daemon 直写 pty stdin。
|
|
4255
|
-
// 高频帧(每次按键 1 帧),不入 reducer / 不广播。response 是 fire-and-forget 风格 ack。
|
|
4256
|
-
// session:pty:resize — UI 端 xterm 尺寸(cols/rows)变化时同步给 daemon 调 pty resize;
|
|
4257
|
-
// 触发频率低(仅 window resize),response 也是 ack。
|
|
4258
|
-
"session:pty:input",
|
|
4259
|
-
"session:pty:resize",
|
|
4260
|
-
// session:pty:snapshot — UI XtermPanel 重新挂载(切 session 回来 / 刷新)时主动拉一次当前
|
|
4261
|
-
// 屏幕全量快照,再开始消费 incremental session:pty。daemon 调 manager.getPtyReplay(sessionId)
|
|
4262
|
-
// 先 drain detector parse queue 再 serialize,保证 atSeq 与 buffer 内容严格对齐。
|
|
4263
|
-
// response 字段:
|
|
4264
|
-
// - data:当前屏幕 + scrollback 的 ANSI 字节串(base64-utf8),与 session:pty push 帧同格式
|
|
4265
|
-
// - atSeq:此 snapshot 覆盖到的最后一帧 session:pty 的 seq(即 detector 已 parse 完成的最大 seq)
|
|
4266
|
-
// UI 端 flush 时丢弃 pending 中 seq ≤ atSeq 的帧
|
|
4267
|
-
// - popupKind:当前 detector 检测到的 popup 类型(null = 无 popup)
|
|
4268
|
-
// session 不存在 / 非 tui / pty 已 exit 时 data=null, atSeq=0。
|
|
4269
|
-
"session:pty:snapshot",
|
|
4270
|
-
// ---- attachment.* file-sharing(详见 attachment-schemas.ts) ----
|
|
4271
|
-
// 命名警告:这里的 `attachment.*` RPC 与 CC v2.x 上行 `type:"attachment"` 系统行
|
|
4272
|
-
// (attachment-skills / attachment-deferred-tools / attachment_memories)是不同概念。
|
|
4273
|
-
// 全部管理类 RPC dispatcher grant 限 owner(capability admin-only);
|
|
4274
|
-
// 实际文件传输走 HTTP 路由(GET /files?p=&e=&s=,HMAC 签名自包含,不在白名单内)。
|
|
4275
|
-
"attachment.signUrl",
|
|
4276
|
-
"attachment.groupAdd",
|
|
4277
|
-
"attachment.groupRemove",
|
|
4278
|
-
"attachment.groupList",
|
|
4279
|
-
// ---- inbox:* (capability platform Phase 3 跨用户通知 + Phase 4 DM) ----
|
|
4280
|
-
// owner 接 guest 的 cross-principal 消息事件 + DM 双向私聊.
|
|
4281
|
-
// inbox:list / markRead: admin-only (Phase 3); inbox:postMessage: DM 自带能力,
|
|
4282
|
-
// 任何 principal (owner/guest) 可调 (Phase 4).
|
|
4283
|
-
"inbox:list",
|
|
4284
|
-
"inbox:markRead",
|
|
4285
|
-
"inbox:postMessage",
|
|
4286
|
-
// inbox:sendDm——persona 代发 DM 编排(inbox MCP server 经 /rpc + Bearer owner token 调)。
|
|
4287
|
-
// sender/mode 由 handler 按 body.sessionId 反查 session scope 归因(业务逻辑非鉴权)。
|
|
4288
|
-
"inbox:sendDm",
|
|
4289
|
-
// ---- contact:* (联系人列表) ----
|
|
4290
|
-
// 飞书统一身份 Phase 3 (决策 #14): received-capability:* 正名为 contact:*——Phase 2 后
|
|
4291
|
-
// 联系人身份由中心 server introspect 背书,不再是"对方颁发的 capability"。
|
|
4292
|
-
// 写入路径:device:connect 落 store + 自动反向(决策 #11);list / remove 作联系人列表读删。
|
|
4293
|
-
"contact:list",
|
|
4294
|
-
"contact:pin",
|
|
4295
|
-
"contact:remove",
|
|
4296
|
-
// ---- contact:setRemoteAccess (远程访问授权,spec 2026-07-16) ----
|
|
4297
|
-
// owner UI 授权 contact 反向操作我的设备(跨设备 exec 开关 remoteAccessAllowed)。
|
|
4298
|
-
// 详见 protocol/src/contact-remote-access.ts.
|
|
4299
|
-
"contact:setRemoteAccess",
|
|
4300
|
-
// ---- contact:handshake (双向确认建联握手, spec 2026-07-22) ----
|
|
4301
|
-
// device:connect 临时连接调用;被调方同步落库+broadcast 后回 ok(携带身份载荷)。
|
|
4302
|
-
// 替代旧 whoami+auto-reverse 组合;whoami 对 connect-token guest 已封(旧客户端拦截)。
|
|
4303
|
-
"contact:handshake",
|
|
4304
|
-
// ---- visitor:* (web 访客 · persona web 分享,spec 2026-06-24-persona-web-share-design) ----
|
|
4305
|
-
// owner-only:列出登录访问过本机 public persona 的 web 访客(零安装、飞书登录、daemon 自签
|
|
4306
|
-
// visitor token)。存储 ~/.clawd/visitors.json(VisitorStore),登录(exchange)即 upsert;
|
|
4307
|
-
// 访客身份用 TTC unique_id,会话按 creatorPrincipalId='visitor-<id>' 进现有会话用户分组。
|
|
4308
|
-
// 访客换 token 走 HTTP-only 公开路由 POST /share/exchange(非 WS method)。
|
|
4309
|
-
"visitor:list",
|
|
4310
|
-
// ---- whoami (v2 capability platform) ----
|
|
4311
|
-
// 任何 authed connection 都能调;返回 owner 显示名 + 当前 capability wire 形态 +
|
|
4312
|
-
// grants 对应的 persona 元数据 (id + displayName)。UI 端 AddRemotePersonaDialog
|
|
4313
|
-
// 的 preview 一次性临时 client 用它判定身份和可用 persona。
|
|
4314
|
-
"whoami",
|
|
4315
|
-
"info",
|
|
4316
|
-
"ping",
|
|
4317
|
-
// ---- meta:methods (RPC 自省) ----
|
|
4318
|
-
// 任何 authed connection 都能调(同 whoami):返回 METHOD_NAMES 全集 + **对本连接**
|
|
4319
|
-
// 的可调用性三态。agent 侧 clawd-rpc 的 list tool 是唯一消费方——统一鉴权删掉白名单后
|
|
4320
|
-
// agent 面前是 104 个 method,没有自省就只能靠试错。
|
|
4321
|
-
"meta:methods",
|
|
4322
|
-
// ---- extension runtime (v1: local mode only, no host-bridge —
|
|
4323
|
-
// see clawd/superpowers/specs/2026-05-27-clawd-extensions-v1-design.md) ----
|
|
4324
|
-
"extension.list",
|
|
4325
|
-
"extension.open",
|
|
4326
|
-
"extension.close",
|
|
4327
|
-
"extension.uninstall",
|
|
4328
|
-
// ---- extension sharing v1 (spec 2026-05-28-clawd-extension-sharing-design) ----
|
|
4329
|
-
// owner-side: 公开 / 撤回 / 查 publish 状态(owner-only ADMIN_ANY)
|
|
4330
|
-
"extension.publish",
|
|
4331
|
-
"extension.unpublish",
|
|
4332
|
-
"extension.publish:status",
|
|
4333
|
-
// cross-tunnel: guest 从 owner 拉 published list + bundle(CAPABILITY_SCOPED)
|
|
4334
|
-
"extension.list-published",
|
|
4335
|
-
"extension.fetchBundle",
|
|
4336
|
-
// guest-self: guest 在自己 daemon 上做安装与更新(ADMIN_ANY,guest 是 owner of self daemon).
|
|
4337
|
-
// 无 subscription 持久化:guest 端身份完全来自文件系统 + reconciled publishedExtensions.
|
|
4338
|
-
"extension.install-from-channel",
|
|
4339
|
-
"extension.update-from-channel",
|
|
4340
|
-
// ---- auth:* 飞书统一身份 Phase 1 (spec 2026-06-01-feishu-identity-design) ----
|
|
4341
|
-
// owner-only:daemon loopback 登录流程(auth:login:start 起 state → HTTP /auth/callback
|
|
4342
|
-
// 回调落盘 → auth:login:done 事件)。中央字面量见 protocol/feishu-auth.ts FEISHU_AUTH_METHODS。
|
|
4343
|
-
"auth:login:start",
|
|
4344
|
-
"auth:getIdentity",
|
|
4345
|
-
"auth:logout",
|
|
4346
|
-
// ---- device:* 设备目录 + 连接(决策 #15:deviceId + 自包含 token) ----
|
|
4347
|
-
// owner-only:公共设备目录 + audience 绑定设备的签名 token 连接(daemon 代理中心 server)。
|
|
4348
|
-
// 中央字面量见 protocol/feishu-auth.ts DEVICE_METHODS。
|
|
4349
|
-
"device:list",
|
|
4350
|
-
"device:connect",
|
|
4351
|
-
// ---- app-builder Project (spec 2026-06-01 picker → 2026-06-02 单栏默认 refactor) ----
|
|
4352
|
-
// persona-app-builder Project 管理;schemas: ProjectMetadataSchema + 5 个 args/result 对。
|
|
4353
|
-
// listProjects: readdir projects/,按目录读 .clawd-project.json
|
|
4354
|
-
// createProject: 校验 personaId/未绑 + 校验名 + 从 6173-6182 段分配端口 + 写元数据 + 创建空目录
|
|
4355
|
-
// + daemon 内部 mutate session.appBuilderProject + 起 dev server(单栏 refactor 后唯一绑定入口)
|
|
4356
|
-
// deleteProject: 停 dev server + rm -rf 目录(绑定 session 由 session:delete 联动 / 不在这里删)
|
|
4357
|
-
// updateProjectPort: 校验新端口段内 + 未被别的 project 占 + 重启 dev server
|
|
4358
|
-
// setProdUrl: 发布上线后 assistant 调一次写入 .clawd-project.json.prodUrl(取代 prod marker)
|
|
4359
|
-
"appBuilder:listProjects",
|
|
4360
|
-
// getProject:按 sessionId 取单个绑定 project(含 status)。people/mirror 跨 daemon 场景:
|
|
4361
|
-
// 本机 owner 在远端是 guest,listProjects 被 per-user 隔离拿不到别人的 project;getProject
|
|
4362
|
-
// 按 session 可见性授权(ensureSessionAccess read)放行。本地也复用(省掉拉全量再 find)。
|
|
4363
|
-
"appBuilder:getProject",
|
|
4364
|
-
"appBuilder:createProject",
|
|
4365
|
-
"appBuilder:deleteProject",
|
|
4366
|
-
"appBuilder:updateProjectPort",
|
|
4367
|
-
"appBuilder:setProdUrl",
|
|
4368
|
-
// 单栏 refactor stage fix (spec 2026-06-02-app-builder-single-pane-default-design §5.6.2):
|
|
4369
|
-
// createProject 时不再立即起 dev server(fresh 目录必崩)。assistant scaffold + pnpm install
|
|
4370
|
-
// 完成后调 startDevServer 显式触发 supervisor spawn;中间用 reportStage 上报进度(scaffolding
|
|
4371
|
-
// / installing 等),daemon broadcast appBuilder:project-updated 帧让 UI PreviewPane 切阶段。
|
|
4372
|
-
"appBuilder:startDevServer",
|
|
4373
|
-
"appBuilder:reportStage",
|
|
4374
|
-
// 显式控制 fix (spec 2026-06-02-app-builder-explicit-dev-server-control):用户点"收起预览"按钮触发,
|
|
4375
|
-
// 对称 startDevServer。砍掉了 setActiveSession(dev server 不再跟用户 focus 走),切 session 不动 dev server。
|
|
4376
|
-
"appBuilder:stopDevServer",
|
|
4377
|
-
// 发布上线脚手架化 (spec 2026-06-03-app-builder-publish-scaffold-design):
|
|
4378
|
-
// publish:PreviewPane「发布上线」按钮 onClick 调本 RPC,daemon 内串行化 + spawn publish.sh +
|
|
4379
|
-
// 广播阶段进度帧 (appBuilder:publish-progress / publish-failed)。同 project 已有 in-flight job
|
|
4380
|
-
// 返回 already-publishing + 既有 jobId(UI 不报错继续订阅)。失败时 daemon 调 manager.send()
|
|
4381
|
-
// 注入 user_text 到 chat,由 assistant 接管完成部署。
|
|
4382
|
-
// dismissPublishJob:取消 in-flight publish(SIGTERM 子进程 + 清字段)或清掉 daemon 崩溃留下的
|
|
4383
|
-
// 中断残骸 publishJob 字段。UI 端 [取消] / [interrupted 取消] 都走这个 RPC。
|
|
4384
|
-
"appBuilder:publish",
|
|
4385
|
-
"appBuilder:dismissPublishJob"
|
|
4386
|
-
];
|
|
4387
|
-
RPC_METHOD_STATUSES = ["allowed", "conditional", "denied"];
|
|
4388
|
-
RpcMethodStatusSchema = external_exports.enum(RPC_METHOD_STATUSES);
|
|
4389
|
-
RpcMethodInfoSchema = external_exports.object({
|
|
4390
|
-
/** canonical method 名,直接可作为 clawd-rpc call 的 method 参数 */
|
|
4391
|
-
name: external_exports.string().min(1),
|
|
4392
|
-
status: RpcMethodStatusSchema,
|
|
4393
|
-
/**
|
|
4394
|
-
* `denied` 必带:daemon error code(`UNAUTHORIZED` / `FEISHU_LOGIN_REQUIRED` /
|
|
4395
|
-
* `METHOD_NOT_IMPLEMENTED`)。`conditional` 必带:谁来做二次校验。
|
|
4396
|
-
* `allowed` 恒无。
|
|
4397
|
-
*/
|
|
4398
|
-
reason: external_exports.string().optional()
|
|
4399
|
-
});
|
|
4400
|
-
MetaMethodsResultSchema = external_exports.object({
|
|
4401
|
-
type: external_exports.literal("meta:methods"),
|
|
4402
|
-
/** METHOD_NAMES 全集,顺序与之一致 */
|
|
4403
|
-
methods: external_exports.array(RpcMethodInfoSchema)
|
|
4404
|
-
});
|
|
4405
|
-
}
|
|
4406
|
-
});
|
|
4407
|
-
|
|
4408
|
-
// ../protocol/src/events.ts
|
|
4409
|
-
var DAEMON_MODE_VALUES, SESSION_STATUS_VALUES, HISTORY_USER_META_VALUES, SKILL_SOURCE_VALUES, AGENT_SOURCE_VALUES, ASK_USER_QUESTION_TOOL_NAME;
|
|
4410
|
-
var init_events = __esm({
|
|
4411
|
-
"../protocol/src/events.ts"() {
|
|
4412
|
-
"use strict";
|
|
4413
|
-
DAEMON_MODE_VALUES = ["sdk", "tui"];
|
|
4414
|
-
SESSION_STATUS_VALUES = [
|
|
4415
|
-
"idle",
|
|
4416
|
-
"running",
|
|
4417
|
-
"running-idle",
|
|
4418
|
-
"stopped",
|
|
4419
|
-
"error",
|
|
4420
|
-
"observing"
|
|
4421
|
-
];
|
|
4422
|
-
HISTORY_USER_META_VALUES = [
|
|
4423
|
-
"task-notification",
|
|
4424
|
-
"slash-command",
|
|
4425
|
-
"local-command",
|
|
4426
|
-
"system-reminder",
|
|
4427
|
-
"skill-hint",
|
|
4428
|
-
"meta-text",
|
|
4429
|
-
"attachment-skills",
|
|
4430
|
-
"attachment-deferred-tools"
|
|
4431
|
-
];
|
|
4432
|
-
SKILL_SOURCE_VALUES = ["builtin", "global", "project", "plugin"];
|
|
4433
|
-
AGENT_SOURCE_VALUES = [
|
|
4434
|
-
"builtin",
|
|
4435
|
-
"global",
|
|
4436
|
-
"project",
|
|
4437
|
-
"policy",
|
|
4438
|
-
"plugin"
|
|
4439
|
-
];
|
|
4440
|
-
ASK_USER_QUESTION_TOOL_NAME = "AskUserQuestion";
|
|
4441
|
-
}
|
|
4442
|
-
});
|
|
4443
|
-
|
|
4444
|
-
// ../protocol/src/errors.ts
|
|
4445
|
-
var ERROR_CODES, ClawdError;
|
|
4446
|
-
var init_errors2 = __esm({
|
|
4447
|
-
"../protocol/src/errors.ts"() {
|
|
4448
|
-
"use strict";
|
|
4449
|
-
ERROR_CODES = {
|
|
4450
|
-
SESSION_NOT_FOUND: "SESSION_NOT_FOUND",
|
|
4451
|
-
SESSION_BUSY: "SESSION_BUSY",
|
|
4452
|
-
INVALID_CWD: "INVALID_CWD",
|
|
4453
|
-
INVALID_PATH: "INVALID_PATH",
|
|
4454
|
-
TOOL_NOT_SUPPORTED: "TOOL_NOT_SUPPORTED",
|
|
4455
|
-
CLAUDE_NOT_FOUND: "CLAUDE_NOT_FOUND",
|
|
4456
|
-
SPAWN_FAILED: "SPAWN_FAILED",
|
|
4457
|
-
INVALID_PERMISSION_MODE: "INVALID_PERMISSION_MODE",
|
|
4458
|
-
METHOD_NOT_IMPLEMENTED: "METHOD_NOT_IMPLEMENTED",
|
|
4459
|
-
METHOD_NOT_ALLOWED: "METHOD_NOT_ALLOWED",
|
|
4460
|
-
VALIDATION_ERROR: "VALIDATION_ERROR",
|
|
4461
|
-
PERMISSION_REQUEST_STALE: "PERMISSION_REQUEST_STALE",
|
|
4462
|
-
FILE_TOO_LARGE: "FILE_TOO_LARGE",
|
|
4463
|
-
INTERNAL: "INTERNAL",
|
|
4464
|
-
UNAUTHORIZED: "UNAUTHORIZED",
|
|
4465
|
-
FORBIDDEN: "FORBIDDEN",
|
|
4466
|
-
INVALID_PARAM: "INVALID_PARAM",
|
|
4467
|
-
// 飞书统一身份(spec 2026-06-01 决策 #9):People/远程体系强制飞书登录。
|
|
4468
|
-
// daemon 进程身份未激活为飞书 unionId 时,FEISHU_GATED_METHODS 内的 RPC 一律返回此错误;
|
|
4469
|
-
// UI 据此显示登录引导(区别于 UNAUTHORIZED 的越权语义)。
|
|
4470
|
-
FEISHU_LOGIN_REQUIRED: "FEISHU_LOGIN_REQUIRED",
|
|
4471
|
-
// app-builder 单栏默认 refactor (spec 2026-06-02-app-builder-single-pane-default-design):
|
|
4472
|
-
// appBuilder:createProject 加 personaId + session 未绑校验后抛的两个错码。
|
|
4473
|
-
WRONG_PERSONA: "WRONG_PERSONA",
|
|
4474
|
-
SESSION_ALREADY_BOUND: "SESSION_ALREADY_BOUND",
|
|
4475
|
-
// 2026-07-02 unified people sidebar: contact:pin 时 deviceId 不在 store(可能被别处删了)
|
|
4476
|
-
CONTACT_NOT_FOUND: "CONTACT_NOT_FOUND",
|
|
4477
|
-
// 统一 RPC 鉴权(spec 2026-07-28):personaDispatch:get 查不到台账行,或 guest ctx
|
|
4478
|
-
// 查非自己发起的行(越权与未知 id 同码,不泄露存在性)。A 端轮询遇此码立即判失败。
|
|
4479
|
-
DISPATCH_NOT_FOUND: "DISPATCH_NOT_FOUND"
|
|
4480
|
-
};
|
|
4481
|
-
ClawdError = class extends Error {
|
|
4482
|
-
constructor(code, message) {
|
|
4483
|
-
super(message);
|
|
4484
|
-
this.code = code;
|
|
4485
|
-
this.name = "ClawdError";
|
|
4486
|
-
}
|
|
4487
|
-
code;
|
|
4488
|
-
};
|
|
4489
|
-
}
|
|
4490
|
-
});
|
|
4491
|
-
|
|
4492
4152
|
// ../protocol/src/attachment-schemas.ts
|
|
4493
4153
|
var TOKEN_ROLES, GROUP_FILE_SOURCES, GroupFileEntrySchema, AttachmentSignUrlArgs, AttachmentSignUrlResponseSchema, AttachmentGroupAddArgs, AttachmentGroupAddResponseSchema, AttachmentGroupRemoveArgs, AttachmentGroupRemoveResponseSchema, AttachmentGroupListArgs, AttachmentGroupListResponseSchema, AttachmentUploadResponseSchema;
|
|
4494
4154
|
var init_attachment_schemas = __esm({
|
|
@@ -4573,59 +4233,736 @@ var init_attachment_schemas = __esm({
|
|
|
4573
4233
|
}
|
|
4574
4234
|
});
|
|
4575
4235
|
|
|
4576
|
-
// ../protocol/src/
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
kind: "owner",
|
|
4581
|
-
displayName,
|
|
4582
|
-
...feishuUnionId ? { feishuUnionId } : {}
|
|
4583
|
-
});
|
|
4584
|
-
}
|
|
4585
|
-
function principalToSender(p2) {
|
|
4586
|
-
return {
|
|
4587
|
-
did: p2.id,
|
|
4588
|
-
displayName: p2.displayName,
|
|
4589
|
-
principal: p2.kind,
|
|
4590
|
-
...p2.feishuUnionId ? { feishuUnionId: p2.feishuUnionId } : {}
|
|
4591
|
-
};
|
|
4592
|
-
}
|
|
4593
|
-
function makeGuestSender(did, displayName, feishuUnionId) {
|
|
4594
|
-
return SenderInfoSchema.parse({
|
|
4595
|
-
did,
|
|
4596
|
-
displayName,
|
|
4597
|
-
principal: "guest",
|
|
4598
|
-
...feishuUnionId ? { feishuUnionId } : {}
|
|
4599
|
-
});
|
|
4600
|
-
}
|
|
4601
|
-
var PrincipalKindSchema, PrincipalSchema, SenderInfoSchema;
|
|
4602
|
-
var init_principal = __esm({
|
|
4603
|
-
"../protocol/src/principal.ts"() {
|
|
4236
|
+
// ../protocol/src/capability.ts
|
|
4237
|
+
var ResourceSchema, ActionSchema, GrantSchema, CapabilitySchema, CapabilityWireSchema, WhoamiResponseSchema, PERSONAL_CAP_GRANTS;
|
|
4238
|
+
var init_capability = __esm({
|
|
4239
|
+
"../protocol/src/capability.ts"() {
|
|
4604
4240
|
"use strict";
|
|
4605
4241
|
init_zod();
|
|
4606
|
-
|
|
4607
|
-
|
|
4242
|
+
ResourceSchema = external_exports.discriminatedUnion("type", [
|
|
4243
|
+
external_exports.object({ type: external_exports.literal("persona"), id: external_exports.string().min(1) }).strict(),
|
|
4244
|
+
external_exports.object({ type: external_exports.literal("chat"), id: external_exports.string().min(1) }).strict(),
|
|
4245
|
+
external_exports.object({ type: external_exports.literal("*") }).strict()
|
|
4246
|
+
]);
|
|
4247
|
+
ActionSchema = external_exports.enum(["read", "send", "admin"]);
|
|
4248
|
+
GrantSchema = external_exports.object({
|
|
4249
|
+
resource: ResourceSchema,
|
|
4250
|
+
actions: external_exports.array(ActionSchema).min(1)
|
|
4251
|
+
}).strict();
|
|
4252
|
+
CapabilitySchema = external_exports.object({
|
|
4608
4253
|
id: external_exports.string().min(1),
|
|
4609
|
-
|
|
4254
|
+
// sha256(token) hex 64
|
|
4255
|
+
secretHash: external_exports.string().regex(/^[a-f0-9]{64}$/),
|
|
4610
4256
|
displayName: external_exports.string(),
|
|
4257
|
+
// 空数组合法 = 纯访客(只能 DM)
|
|
4258
|
+
grants: external_exports.array(GrantSchema),
|
|
4259
|
+
issuedAt: external_exports.number().int().nonnegative(),
|
|
4260
|
+
expiresAt: external_exports.number().int().positive().optional(),
|
|
4261
|
+
maxUses: external_exports.number().int().positive().optional(),
|
|
4262
|
+
usedCount: external_exports.number().int().nonnegative(),
|
|
4611
4263
|
/**
|
|
4612
|
-
*
|
|
4613
|
-
*
|
|
4614
|
-
* 消费方(如 ticket MCP / 未来别的飞书身份挂钩场景)按 undefined 决定是否降级;本层不做 fallback。
|
|
4264
|
+
* guest 在 auth 帧捎带 selfPrincipalId 时由 AuthGate.authenticate 回写;
|
|
4265
|
+
* 未被消费的 cap 此字段缺失。
|
|
4615
4266
|
*/
|
|
4616
|
-
|
|
4267
|
+
peerOwnerId: external_exports.string().min(1).optional(),
|
|
4268
|
+
/** 首次 client hello 时间戳(与 peerOwnerId 同步写入) */
|
|
4269
|
+
firstUsedByPeerAt: external_exports.number().int().positive().optional(),
|
|
4270
|
+
/**
|
|
4271
|
+
* 对方 daemon owner 的 displayName,guest auth 帧 selfDisplayName 触发
|
|
4272
|
+
* recordPeerHello 时同步回写。视角 B (2026-05-23) UI 派生联系人列表用此字段
|
|
4273
|
+
* 显示对方名字(避免 fallback 到我颁 cap 时填的 displayName)。
|
|
4274
|
+
*/
|
|
4275
|
+
peerDisplayName: external_exports.string().optional()
|
|
4617
4276
|
}).strict();
|
|
4618
|
-
|
|
4619
|
-
|
|
4620
|
-
|
|
4277
|
+
CapabilityWireSchema = CapabilitySchema.omit({ secretHash: true });
|
|
4278
|
+
WhoamiResponseSchema = external_exports.object({
|
|
4279
|
+
type: external_exports.literal("whoami:ok"),
|
|
4280
|
+
owner: external_exports.object({
|
|
4281
|
+
id: external_exports.string(),
|
|
4282
|
+
kind: external_exports.enum(["owner", "guest"]),
|
|
4283
|
+
displayName: external_exports.string(),
|
|
4284
|
+
/** 归属人 id(决策 #16:TTC unique_id 等,落 contact.ownerId) */
|
|
4285
|
+
ownerId: external_exports.string(),
|
|
4286
|
+
/** 身份来源(决策 #16:'ttc'/'google',落 contact.provider) */
|
|
4287
|
+
provider: external_exports.string()
|
|
4288
|
+
}).strict(),
|
|
4289
|
+
capability: CapabilityWireSchema,
|
|
4290
|
+
grantedPersonas: external_exports.array(
|
|
4291
|
+
external_exports.object({
|
|
4292
|
+
id: external_exports.string().min(1),
|
|
4293
|
+
displayName: external_exports.string()
|
|
4294
|
+
}).strict()
|
|
4295
|
+
)
|
|
4296
|
+
}).strict();
|
|
4297
|
+
PERSONAL_CAP_GRANTS = Object.freeze([
|
|
4298
|
+
Object.freeze({
|
|
4299
|
+
resource: Object.freeze({ type: "persona", id: "*" }),
|
|
4300
|
+
actions: Object.freeze(["read", "send"])
|
|
4301
|
+
})
|
|
4302
|
+
]);
|
|
4303
|
+
}
|
|
4304
|
+
});
|
|
4305
|
+
|
|
4306
|
+
// ../protocol/src/contact-handshake.ts
|
|
4307
|
+
var ContactHandshakeArgsSchema, ContactHandshakeOkSchema;
|
|
4308
|
+
var init_contact_handshake = __esm({
|
|
4309
|
+
"../protocol/src/contact-handshake.ts"() {
|
|
4310
|
+
"use strict";
|
|
4311
|
+
init_zod();
|
|
4312
|
+
init_capability();
|
|
4313
|
+
ContactHandshakeArgsSchema = external_exports.object({
|
|
4314
|
+
selfUrl: external_exports.string().min(1)
|
|
4315
|
+
});
|
|
4316
|
+
ContactHandshakeOkSchema = external_exports.object({
|
|
4317
|
+
type: external_exports.literal("contact:handshake:ok"),
|
|
4318
|
+
owner: external_exports.object({
|
|
4319
|
+
/** 被调方 deviceId(路由主键;调用方落 Contact 的主键用自己请求的 args.deviceId,此值供校验/展示) */
|
|
4320
|
+
id: external_exports.string(),
|
|
4321
|
+
/** 归属人(落 Contact.ownerId / provider,显示分组用) */
|
|
4322
|
+
ownerId: external_exports.string(),
|
|
4323
|
+
provider: external_exports.string(),
|
|
4324
|
+
displayName: external_exports.string()
|
|
4325
|
+
}),
|
|
4326
|
+
/** 被调方授调用方的 grants(落 Contact.grants) */
|
|
4327
|
+
grants: external_exports.array(GrantSchema)
|
|
4328
|
+
});
|
|
4329
|
+
}
|
|
4330
|
+
});
|
|
4331
|
+
|
|
4332
|
+
// ../protocol/src/contact-remote-access.ts
|
|
4333
|
+
var ContactSetRemoteAccessArgsSchema, ContactSetRemoteAccessOkSchema, ContactRemoteAccessUpdatedFrameSchema;
|
|
4334
|
+
var init_contact_remote_access = __esm({
|
|
4335
|
+
"../protocol/src/contact-remote-access.ts"() {
|
|
4336
|
+
"use strict";
|
|
4337
|
+
init_zod();
|
|
4338
|
+
ContactSetRemoteAccessArgsSchema = external_exports.object({
|
|
4339
|
+
deviceId: external_exports.string().min(1),
|
|
4340
|
+
remoteAccessAllowed: external_exports.boolean()
|
|
4341
|
+
}).strict();
|
|
4342
|
+
ContactSetRemoteAccessOkSchema = external_exports.object({
|
|
4343
|
+
type: external_exports.literal("contact:setRemoteAccess:ok"),
|
|
4344
|
+
deviceId: external_exports.string().min(1),
|
|
4345
|
+
remoteAccessAllowed: external_exports.boolean()
|
|
4346
|
+
}).strict();
|
|
4347
|
+
ContactRemoteAccessUpdatedFrameSchema = external_exports.object({
|
|
4348
|
+
type: external_exports.literal("contact:remote-access-updated"),
|
|
4349
|
+
deviceId: external_exports.string().min(1),
|
|
4350
|
+
remoteAccessAllowed: external_exports.boolean()
|
|
4351
|
+
}).strict();
|
|
4352
|
+
}
|
|
4353
|
+
});
|
|
4354
|
+
|
|
4355
|
+
// ../protocol/src/contact.ts
|
|
4356
|
+
var ContactSchema, ContactWireSchema, ContactRemoveArgsSchema, ContactRemoveOkSchema, ContactListOkSchema, ContactAddedFrameSchema, ContactRemovedFrameSchema, ContactPinArgsSchema, ContactPinOkSchema, ContactPinnedFrameSchema;
|
|
4357
|
+
var init_contact = __esm({
|
|
4358
|
+
"../protocol/src/contact.ts"() {
|
|
4359
|
+
"use strict";
|
|
4360
|
+
init_zod();
|
|
4361
|
+
init_capability();
|
|
4362
|
+
ContactSchema = external_exports.object({
|
|
4363
|
+
/**
|
|
4364
|
+
* 对方设备标识(主键):对方 daemon 自己生成并持久化的标识(auth.json deviceId,
|
|
4365
|
+
* 如 dev-<uuid>),provider 无关。同 deviceId 重复 upsert 覆盖。
|
|
4366
|
+
*/
|
|
4367
|
+
deviceId: external_exports.string().min(1),
|
|
4368
|
+
/**
|
|
4369
|
+
* 归属人 id(决策 #16):TTC unique_id 等,由 connect token subOwner 签名背书。
|
|
4370
|
+
* 与 provider 一起唯一标识一个人。DM 不再按它路由(路由用 deviceId),仅显示/分组用。
|
|
4371
|
+
*/
|
|
4372
|
+
ownerId: external_exports.string().min(1),
|
|
4373
|
+
/** 身份来源(决策 #16):'ttc'(飞书/手机/邮箱登入 TTC)| 'google' | ...,token 背书 */
|
|
4374
|
+
provider: external_exports.string().min(1),
|
|
4375
|
+
/** 联系人显示名 */
|
|
4621
4376
|
displayName: external_exports.string(),
|
|
4622
|
-
/**
|
|
4623
|
-
|
|
4624
|
-
|
|
4377
|
+
/** 该设备可达的 ws/tunnel 地址 */
|
|
4378
|
+
remoteUrl: external_exports.string().min(1),
|
|
4379
|
+
// 自动反向建立联系人(spec 决策 #11):被连接方本地验票成功后自动落 A 为
|
|
4380
|
+
// 联系人,但它不持有 A 颁发的 token(A 从未给它换票)→ connectToken 为空串。
|
|
4381
|
+
// device:connect 出站路径仍存中心 server 签发的真实 connect token(断线重连复用)。
|
|
4382
|
+
// 不用 .min(1):自动反向路径合法地存空串,禁止填假 token 占位(不造假数据)。
|
|
4383
|
+
connectToken: external_exports.string(),
|
|
4384
|
+
grants: external_exports.array(GrantSchema),
|
|
4385
|
+
addedAt: external_exports.number().int().nonnegative(),
|
|
4386
|
+
/**
|
|
4387
|
+
* pin 时间戳(ms,Date.now() 语义);null = 未 pin。sidebar 顶部固定区渲染由此驱动。
|
|
4388
|
+
* 老 contacts.json 缺此字段 → zod default 补 null(无破坏性升级;不 orphan)。
|
|
4389
|
+
* 对齐 SessionFile.pinnedAt 语义(daemon 侧持久化,contact:pin RPC 更新 → contact:pinned push)。
|
|
4390
|
+
*/
|
|
4391
|
+
pinnedAt: external_exports.number().int().nullable().default(null),
|
|
4392
|
+
/**
|
|
4393
|
+
* 远程访问授权(spec 2026-07-16)。owner 视角:允许该 contact 反向操作我的设备——
|
|
4394
|
+
* 跨设备 exec 的总开关(peerExec:run handler 运行时判它)。default=false,owner 显式开。
|
|
4395
|
+
* 授权粒度 per-people (per-contact):借用别人 persona 本来就带信任对方本人的前提。
|
|
4396
|
+
*/
|
|
4397
|
+
remoteAccessAllowed: external_exports.boolean().default(false)
|
|
4398
|
+
}).strict();
|
|
4399
|
+
ContactWireSchema = ContactSchema;
|
|
4400
|
+
ContactRemoveArgsSchema = external_exports.object({
|
|
4401
|
+
deviceId: external_exports.string().min(1)
|
|
4402
|
+
}).strict();
|
|
4403
|
+
ContactRemoveOkSchema = external_exports.object({
|
|
4404
|
+
type: external_exports.literal("contact:remove:ok"),
|
|
4405
|
+
deviceId: external_exports.string().min(1)
|
|
4406
|
+
}).strict();
|
|
4407
|
+
ContactListOkSchema = external_exports.object({
|
|
4408
|
+
type: external_exports.literal("contact:list:ok"),
|
|
4409
|
+
contacts: external_exports.array(ContactWireSchema)
|
|
4410
|
+
}).strict();
|
|
4411
|
+
ContactAddedFrameSchema = external_exports.object({
|
|
4412
|
+
type: external_exports.literal("contact:added"),
|
|
4413
|
+
contact: ContactWireSchema
|
|
4414
|
+
}).strict();
|
|
4415
|
+
ContactRemovedFrameSchema = external_exports.object({
|
|
4416
|
+
type: external_exports.literal("contact:removed"),
|
|
4417
|
+
deviceId: external_exports.string().min(1)
|
|
4418
|
+
}).strict();
|
|
4419
|
+
ContactPinArgsSchema = external_exports.object({
|
|
4420
|
+
deviceId: external_exports.string().min(1),
|
|
4421
|
+
pinned: external_exports.boolean()
|
|
4422
|
+
}).strict();
|
|
4423
|
+
ContactPinOkSchema = external_exports.object({
|
|
4424
|
+
type: external_exports.literal("contact:pin:ok"),
|
|
4425
|
+
deviceId: external_exports.string().min(1),
|
|
4426
|
+
pinnedAt: external_exports.number().int().nullable()
|
|
4427
|
+
}).strict();
|
|
4428
|
+
ContactPinnedFrameSchema = external_exports.object({
|
|
4429
|
+
type: external_exports.literal("contact:pinned"),
|
|
4430
|
+
deviceId: external_exports.string().min(1),
|
|
4431
|
+
pinnedAt: external_exports.number().int().nullable()
|
|
4625
4432
|
}).strict();
|
|
4626
4433
|
}
|
|
4627
4434
|
});
|
|
4628
4435
|
|
|
4436
|
+
// ../protocol/src/feishu-auth.ts
|
|
4437
|
+
var FEISHU_GATED_METHODS, DeviceEntrySchema, DeviceListResponseSchema, DeviceConnectArgsSchema, DeviceConnectResponseSchema, FeishuIdentitySchema, AuthLoginStartResponseSchema, AuthGetIdentityResponseSchema, AuthLogoutResponseSchema, AuthLoginDoneEventSchema, AuthLoginFailedEventSchema;
|
|
4438
|
+
var init_feishu_auth = __esm({
|
|
4439
|
+
"../protocol/src/feishu-auth.ts"() {
|
|
4440
|
+
"use strict";
|
|
4441
|
+
init_zod();
|
|
4442
|
+
FEISHU_GATED_METHODS = [
|
|
4443
|
+
// 联系人列表(device:connect 落同一 store;list 读 / remove 删)
|
|
4444
|
+
"contact:list",
|
|
4445
|
+
"contact:remove",
|
|
4446
|
+
// DM / 跨用户通知
|
|
4447
|
+
"inbox:list",
|
|
4448
|
+
"inbox:markRead",
|
|
4449
|
+
"inbox:postMessage",
|
|
4450
|
+
// mirror peer sessions(远端会话镜像)
|
|
4451
|
+
"peerSession:upsert",
|
|
4452
|
+
"peerSession:remove",
|
|
4453
|
+
// 设备目录 + 连接(决策 #15:daemon 代理中心 server,需要 owner 的 ttcJwt)
|
|
4454
|
+
"device:list",
|
|
4455
|
+
"device:connect"
|
|
4456
|
+
];
|
|
4457
|
+
DeviceEntrySchema = external_exports.object({
|
|
4458
|
+
/**
|
|
4459
|
+
* 设备标识(决策 #15:daemon 本地生成的 dev-<uuid>,与人的身份 unionId 无关)。
|
|
4460
|
+
* 中心 server clawd_devices 注册表仅作服务发现(url 下发 + 目录),不在安全路径上。
|
|
4461
|
+
*/
|
|
4462
|
+
deviceId: external_exports.string().min(1),
|
|
4463
|
+
/** 显示名 */
|
|
4464
|
+
name: external_exports.string().min(1),
|
|
4465
|
+
/** ws/tunnel 地址 */
|
|
4466
|
+
url: external_exports.string().min(1)
|
|
4467
|
+
});
|
|
4468
|
+
DeviceListResponseSchema = external_exports.object({
|
|
4469
|
+
type: external_exports.literal("device:list:ok"),
|
|
4470
|
+
devices: external_exports.array(DeviceEntrySchema)
|
|
4471
|
+
});
|
|
4472
|
+
DeviceConnectArgsSchema = external_exports.object({
|
|
4473
|
+
/** 目标设备的 deviceId(对方 daemon 生成的 dev-<uuid>) */
|
|
4474
|
+
deviceId: external_exports.string().min(1),
|
|
4475
|
+
/**
|
|
4476
|
+
* 目标设备的 ws/tunnel 地址(可选):
|
|
4477
|
+
* - 公开目录点击:带 url(device:list 已下发,省一次 server 查询)
|
|
4478
|
+
* - 凭 deviceId 连接:缺省 url → daemon exchange 时由中心 server 下发该设备上报的 url
|
|
4479
|
+
* - 注册表不在安全路径上:知道对方 url 时显式传入即可连接(不依赖中心 server 服务发现)
|
|
4480
|
+
*/
|
|
4481
|
+
url: external_exports.string().min(1).optional(),
|
|
4482
|
+
/** 显示名(公共设备来自目录;缺省时连上后用 whoami 回填) */
|
|
4483
|
+
name: external_exports.string().optional()
|
|
4484
|
+
});
|
|
4485
|
+
DeviceConnectResponseSchema = external_exports.object({
|
|
4486
|
+
type: external_exports.literal("device:connect:ok"),
|
|
4487
|
+
/** 连接的目标设备标识(= 请求 args.deviceId) */
|
|
4488
|
+
deviceId: external_exports.string(),
|
|
4489
|
+
name: external_exports.string(),
|
|
4490
|
+
url: external_exports.string()
|
|
4491
|
+
});
|
|
4492
|
+
FeishuIdentitySchema = external_exports.object({
|
|
4493
|
+
/** 归属人 id(决策 #16:TTC unique_id,取代飞书 union_id;跨登录方式稳定) */
|
|
4494
|
+
ownerId: external_exports.string().min(1),
|
|
4495
|
+
/** 身份来源:'ttc'(飞书/手机/邮箱登入 TTC)| 'google' | ...(决策 #16,拓展用) */
|
|
4496
|
+
provider: external_exports.string().min(1),
|
|
4497
|
+
/** 显示名。TTC user_info 接口 data.name */
|
|
4498
|
+
displayName: external_exports.string().min(1),
|
|
4499
|
+
/** TTC user_info 接口 data.avatar_url,可缺省 */
|
|
4500
|
+
avatarUrl: external_exports.string().optional(),
|
|
4501
|
+
/** TTC user_info 接口 data.union_id(飞书 union_id;dataclaw 可信入口 X-User-UnionId 用),可缺省 */
|
|
4502
|
+
unionId: external_exports.string().optional()
|
|
4503
|
+
});
|
|
4504
|
+
AuthLoginStartResponseSchema = external_exports.object({
|
|
4505
|
+
type: external_exports.literal("auth:login:start:ok"),
|
|
4506
|
+
/** 完整 TTC 授权页 URL(含 callback_url + state + auto=1),UI 直接 window.open */
|
|
4507
|
+
authUrl: external_exports.string().min(1),
|
|
4508
|
+
/** 防 CSRF 的一次性 nonce;回调时 daemon 校验 */
|
|
4509
|
+
state: external_exports.string().min(1)
|
|
4510
|
+
});
|
|
4511
|
+
AuthGetIdentityResponseSchema = external_exports.object({
|
|
4512
|
+
type: external_exports.literal("auth:getIdentity:ok"),
|
|
4513
|
+
/** null = 未登录 */
|
|
4514
|
+
identity: FeishuIdentitySchema.nullable(),
|
|
4515
|
+
/**
|
|
4516
|
+
* 本机设备标识(决策 #15:daemon 生成并持久化在 auth.json,如 dev-<uuid>)。
|
|
4517
|
+
* 设备属性,与登录态无关、登录登出不变。UI"我的设备标识"用它拼
|
|
4518
|
+
* clawos://device/<deviceId>(替代旧的 unionId——不再向外暴露人的身份标识)。
|
|
4519
|
+
*/
|
|
4520
|
+
deviceId: external_exports.string().min(1)
|
|
4521
|
+
});
|
|
4522
|
+
AuthLogoutResponseSchema = external_exports.object({
|
|
4523
|
+
type: external_exports.literal("auth:logout:ok")
|
|
4524
|
+
});
|
|
4525
|
+
AuthLoginDoneEventSchema = external_exports.object({
|
|
4526
|
+
type: external_exports.literal("auth:login:done"),
|
|
4527
|
+
identity: FeishuIdentitySchema
|
|
4528
|
+
});
|
|
4529
|
+
AuthLoginFailedEventSchema = external_exports.object({
|
|
4530
|
+
type: external_exports.literal("auth:login:failed"),
|
|
4531
|
+
reason: external_exports.string()
|
|
4532
|
+
});
|
|
4533
|
+
}
|
|
4534
|
+
});
|
|
4535
|
+
|
|
4536
|
+
// ../protocol/src/dispatch.ts
|
|
4537
|
+
var DispatchOutcomeSchema, DispatchRunArgsSchema, DispatchCompleteArgsSchema, DISPATCH_STATUSES, DispatchStatusSchema, DispatchRecordSchema, DispatchListArgsSchema, DispatchListResultSchema, DispatchGetArgsSchema, DispatchGetOkSchema;
|
|
4538
|
+
var init_dispatch = __esm({
|
|
4539
|
+
"../protocol/src/dispatch.ts"() {
|
|
4540
|
+
"use strict";
|
|
4541
|
+
init_zod();
|
|
4542
|
+
DispatchOutcomeSchema = external_exports.discriminatedUnion("kind", [
|
|
4543
|
+
external_exports.object({
|
|
4544
|
+
kind: external_exports.literal("success"),
|
|
4545
|
+
text: external_exports.string(),
|
|
4546
|
+
filePaths: external_exports.array(external_exports.string()).optional()
|
|
4547
|
+
}),
|
|
4548
|
+
external_exports.object({
|
|
4549
|
+
kind: external_exports.literal("failure"),
|
|
4550
|
+
reason: external_exports.string()
|
|
4551
|
+
})
|
|
4552
|
+
]);
|
|
4553
|
+
DispatchRunArgsSchema = external_exports.object({
|
|
4554
|
+
// 新开必填;续派(dispatchId 非空)时可省略——targetPersonaId 从台账行取。
|
|
4555
|
+
targetPersona: external_exports.string().min(1).optional(),
|
|
4556
|
+
// 续派(spec 2026-07-21,单 dispatchId 语义:一件事一行一 id):非空 = 把 prompt
|
|
4557
|
+
// 作为新 turn 打进该 dispatch 的原 worker session 接着干(台账行复位 running)。
|
|
4558
|
+
// 省略 = 新开一件事,daemon 铸新 id。
|
|
4559
|
+
dispatchId: external_exports.string().min(1).optional(),
|
|
4560
|
+
prompt: external_exports.string(),
|
|
4561
|
+
// 跨设备 dispatch:非空 = A 角色,转发到该 contact deviceId 的 peer daemon;
|
|
4562
|
+
// 省略 = 本地 dispatch / B 角色本地执行。A 转发给 B 时 body 不带此字段。
|
|
4563
|
+
targetDeviceId: external_exports.string().min(1).optional(),
|
|
4564
|
+
// 可选:override B session 使用的 claude 模型。缺省 = 用 persona 默认。
|
|
4565
|
+
// 合法值集与 claude adapter capabilities.models[].id 一致(见 daemon
|
|
4566
|
+
// tools/claude.ts CLAUDE_MODEL_IDS);handler 层做二次校验,非法值 fail-fast。
|
|
4567
|
+
// protocol 层保持 string 便于未来跨 tool 扩展(届时 union 收合法字面量)。
|
|
4568
|
+
model: external_exports.string().min(1).optional(),
|
|
4569
|
+
// 可选:给新 worker session 起 label(写入 SessionFile.label,sidebar 显示)。
|
|
4570
|
+
// 仅在**新开 dispatch**(dispatchId 缺席)时生效;续派(dispatchId 非空)
|
|
4571
|
+
// 时 daemon 层静默丢弃(避免半途改 label 造成 sidebar 抖动)。
|
|
4572
|
+
// 上限 60 字符——sidebar 显示 tolerance,卡在 dispatch 入口即可。
|
|
4573
|
+
// 协议层不硬拒 sessionLabel + dispatchId 同传,保留 forward-compat。
|
|
4574
|
+
sessionLabel: external_exports.string().min(1).max(60).optional()
|
|
4575
|
+
}).refine((v2) => v2.targetPersona !== void 0 || v2.dispatchId !== void 0, {
|
|
4576
|
+
message: "either targetPersona (new dispatch) or dispatchId (follow-up) is required"
|
|
4577
|
+
}).refine((v2) => !(v2.dispatchId !== void 0 && v2.targetDeviceId !== void 0), {
|
|
4578
|
+
message: "cross-device dispatch cannot be continued (dispatchId + targetDeviceId are mutually exclusive)"
|
|
4579
|
+
});
|
|
4580
|
+
DispatchCompleteArgsSchema = external_exports.object({
|
|
4581
|
+
dispatchId: external_exports.string().min(1),
|
|
4582
|
+
outcome: DispatchOutcomeSchema
|
|
4583
|
+
});
|
|
4584
|
+
DISPATCH_STATUSES = ["running", "completed", "failed"];
|
|
4585
|
+
DispatchStatusSchema = external_exports.enum(DISPATCH_STATUSES);
|
|
4586
|
+
DispatchRecordSchema = external_exports.object({
|
|
4587
|
+
dispatchId: external_exports.string().min(1),
|
|
4588
|
+
sourceSessionId: external_exports.string().min(1),
|
|
4589
|
+
sourcePersonaId: external_exports.string().min(1).optional(),
|
|
4590
|
+
targetPersonaId: external_exports.string().min(1),
|
|
4591
|
+
/** B 的 sessionId;registerBSession 后回填 */
|
|
4592
|
+
workerSessionId: external_exports.string().min(1).optional(),
|
|
4593
|
+
/** 任务摘要;截断(≤500 字符)在 daemon store.add 处保证 */
|
|
4594
|
+
taskText: external_exports.string(),
|
|
4595
|
+
status: DispatchStatusSchema,
|
|
4596
|
+
outcome: DispatchOutcomeSchema.optional(),
|
|
4597
|
+
/** 上层消费者语义(如司礼监的口谕/验收状态),daemon 不解释 */
|
|
4598
|
+
meta: external_exports.record(external_exports.unknown()).optional(),
|
|
4599
|
+
createdAt: external_exports.string().min(1),
|
|
4600
|
+
completedAt: external_exports.string().min(1).optional(),
|
|
4601
|
+
/** 结果注入 source session 成功时戳,兼当投递 dedup 标记 */
|
|
4602
|
+
deliveredAt: external_exports.string().min(1).optional()
|
|
4603
|
+
});
|
|
4604
|
+
DispatchListArgsSchema = external_exports.object({
|
|
4605
|
+
sourceSessionId: external_exports.string().min(1).optional()
|
|
4606
|
+
});
|
|
4607
|
+
DispatchListResultSchema = external_exports.object({
|
|
4608
|
+
records: external_exports.array(DispatchRecordSchema)
|
|
4609
|
+
});
|
|
4610
|
+
DispatchGetArgsSchema = external_exports.object({
|
|
4611
|
+
dispatchId: external_exports.string().min(1)
|
|
4612
|
+
});
|
|
4613
|
+
DispatchGetOkSchema = external_exports.object({
|
|
4614
|
+
type: external_exports.literal("personaDispatch:get:ok"),
|
|
4615
|
+
status: DispatchStatusSchema,
|
|
4616
|
+
outcome: DispatchOutcomeSchema.optional()
|
|
4617
|
+
});
|
|
4618
|
+
}
|
|
4619
|
+
});
|
|
4620
|
+
|
|
4621
|
+
// ../protocol/src/extension.ts
|
|
4622
|
+
function isAllowedHostedUrl(raw) {
|
|
4623
|
+
let u;
|
|
4624
|
+
try {
|
|
4625
|
+
u = new URL(raw);
|
|
4626
|
+
} catch {
|
|
4627
|
+
return false;
|
|
4628
|
+
}
|
|
4629
|
+
if (u.protocol === "https:") return true;
|
|
4630
|
+
if (u.protocol === "http:" && LOCALHOST_HOSTS.has(u.hostname)) return true;
|
|
4631
|
+
return false;
|
|
4632
|
+
}
|
|
4633
|
+
function manifestMode(m2) {
|
|
4634
|
+
return m2.entry?.url ? "hosted" : "local";
|
|
4635
|
+
}
|
|
4636
|
+
function ownerNamespace(ownerPrincipalId) {
|
|
4637
|
+
let h = 2166136261;
|
|
4638
|
+
for (let i = 0; i < ownerPrincipalId.length; i++) {
|
|
4639
|
+
h ^= ownerPrincipalId.charCodeAt(i);
|
|
4640
|
+
h = Math.imul(h, 16777619) >>> 0;
|
|
4641
|
+
}
|
|
4642
|
+
return (h >>> 0).toString(16).padStart(8, "0");
|
|
4643
|
+
}
|
|
4644
|
+
function namespacedExtId(slug, ownerPrincipalId) {
|
|
4645
|
+
return `${slug}-${ownerNamespace(ownerPrincipalId)}`;
|
|
4646
|
+
}
|
|
4647
|
+
function validateSimpleSemver(v2) {
|
|
4648
|
+
if (typeof v2 !== "string") {
|
|
4649
|
+
return { ok: false, reason: "version must be a string" };
|
|
4650
|
+
}
|
|
4651
|
+
const parts = v2.split(".");
|
|
4652
|
+
if (parts.length !== 3) {
|
|
4653
|
+
return { ok: false, reason: `"${v2}" \u2014 only MAJOR.MINOR.PATCH allowed` };
|
|
4654
|
+
}
|
|
4655
|
+
for (const p2 of parts) {
|
|
4656
|
+
if (!/^\d+$/.test(p2)) {
|
|
4657
|
+
return { ok: false, reason: `"${v2}" \u2014 only numeric segments allowed` };
|
|
4658
|
+
}
|
|
4659
|
+
}
|
|
4660
|
+
return { ok: true };
|
|
4661
|
+
}
|
|
4662
|
+
function compareSimpleSemver(a, b2) {
|
|
4663
|
+
const pa = parseOrThrow(a);
|
|
4664
|
+
const pb = parseOrThrow(b2);
|
|
4665
|
+
for (let i = 0; i < 3; i++) {
|
|
4666
|
+
if (pa[i] < pb[i]) return -1;
|
|
4667
|
+
if (pa[i] > pb[i]) return 1;
|
|
4668
|
+
}
|
|
4669
|
+
return 0;
|
|
4670
|
+
}
|
|
4671
|
+
function parseOrThrow(v2) {
|
|
4672
|
+
const r = validateSimpleSemver(v2);
|
|
4673
|
+
if (!r.ok) throw new Error(r.reason);
|
|
4674
|
+
const [a, b2, c] = v2.split(".").map((p2) => parseInt(p2, 10));
|
|
4675
|
+
return [a, b2, c];
|
|
4676
|
+
}
|
|
4677
|
+
var EXT_ID_REGEX, ExtensionStateSchema, LOCALHOST_HOSTS, ExtensionManifestSchema, ExtensionTargetSchema, ExtensionRecordSchema, PublishedSnapshotSchema, ChannelRefSchema, SourceRefSchema, PublishedExtensionRecordSchema, PublishCheckSchema, PublishStatusResultSchema, ExtensionPublishArgs, ExtensionIdArgs, ExtensionFetchBundleArgs, ExtensionFromChannelArgs;
|
|
4678
|
+
var init_extension = __esm({
|
|
4679
|
+
"../protocol/src/extension.ts"() {
|
|
4680
|
+
"use strict";
|
|
4681
|
+
init_zod();
|
|
4682
|
+
EXT_ID_REGEX = /^[a-z0-9][a-z0-9-]*$/;
|
|
4683
|
+
ExtensionStateSchema = external_exports.enum([
|
|
4684
|
+
"stopped",
|
|
4685
|
+
"starting",
|
|
4686
|
+
"running",
|
|
4687
|
+
"crashed",
|
|
4688
|
+
"invalid"
|
|
4689
|
+
]);
|
|
4690
|
+
LOCALHOST_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1"]);
|
|
4691
|
+
ExtensionManifestSchema = external_exports.object({
|
|
4692
|
+
id: external_exports.string().regex(EXT_ID_REGEX),
|
|
4693
|
+
name: external_exports.string().min(1),
|
|
4694
|
+
version: external_exports.string().min(1),
|
|
4695
|
+
apiVersion: external_exports.literal("1"),
|
|
4696
|
+
runtime: external_exports.object({ startCommand: external_exports.string().min(1) }).passthrough().optional(),
|
|
4697
|
+
entry: external_exports.object({
|
|
4698
|
+
url: external_exports.string().url().refine(isAllowedHostedUrl, {
|
|
4699
|
+
message: "INVALID_URL_SCHEME: only https or http://localhost is allowed"
|
|
4700
|
+
})
|
|
4701
|
+
}).strict().optional()
|
|
4702
|
+
}).passthrough().superRefine((m2, ctx) => {
|
|
4703
|
+
const hasRuntime = !!m2.runtime;
|
|
4704
|
+
const hasUrl = !!m2.entry?.url;
|
|
4705
|
+
if (hasRuntime && hasUrl) {
|
|
4706
|
+
ctx.addIssue({
|
|
4707
|
+
code: external_exports.ZodIssueCode.custom,
|
|
4708
|
+
message: "INVALID_MANIFEST: entry.url and runtime cannot coexist"
|
|
4709
|
+
});
|
|
4710
|
+
}
|
|
4711
|
+
if (!hasRuntime && !hasUrl) {
|
|
4712
|
+
ctx.addIssue({
|
|
4713
|
+
code: external_exports.ZodIssueCode.custom,
|
|
4714
|
+
message: "INVALID_MANIFEST: must have either entry.url or runtime"
|
|
4715
|
+
});
|
|
4716
|
+
}
|
|
4717
|
+
});
|
|
4718
|
+
ExtensionTargetSchema = external_exports.discriminatedUnion("kind", [
|
|
4719
|
+
external_exports.object({ kind: external_exports.literal("local"), port: external_exports.number().int().min(1).max(65535) }),
|
|
4720
|
+
external_exports.object({ kind: external_exports.literal("hosted"), url: external_exports.string().url() })
|
|
4721
|
+
]);
|
|
4722
|
+
ExtensionRecordSchema = external_exports.discriminatedUnion("state", [
|
|
4723
|
+
external_exports.object({
|
|
4724
|
+
extId: external_exports.string(),
|
|
4725
|
+
manifest: ExtensionManifestSchema,
|
|
4726
|
+
state: external_exports.literal("stopped")
|
|
4727
|
+
}),
|
|
4728
|
+
external_exports.object({
|
|
4729
|
+
extId: external_exports.string(),
|
|
4730
|
+
manifest: ExtensionManifestSchema,
|
|
4731
|
+
state: external_exports.literal("starting")
|
|
4732
|
+
}),
|
|
4733
|
+
external_exports.object({
|
|
4734
|
+
extId: external_exports.string(),
|
|
4735
|
+
manifest: ExtensionManifestSchema,
|
|
4736
|
+
state: external_exports.literal("running"),
|
|
4737
|
+
target: ExtensionTargetSchema
|
|
4738
|
+
}),
|
|
4739
|
+
external_exports.object({
|
|
4740
|
+
extId: external_exports.string(),
|
|
4741
|
+
manifest: ExtensionManifestSchema,
|
|
4742
|
+
state: external_exports.literal("crashed")
|
|
4743
|
+
}),
|
|
4744
|
+
external_exports.object({
|
|
4745
|
+
extId: external_exports.string(),
|
|
4746
|
+
manifest: external_exports.unknown().nullable(),
|
|
4747
|
+
state: external_exports.literal("invalid"),
|
|
4748
|
+
invalidReason: external_exports.string().min(1)
|
|
4749
|
+
})
|
|
4750
|
+
]);
|
|
4751
|
+
PublishedSnapshotSchema = external_exports.object({
|
|
4752
|
+
snapshotHash: external_exports.string().min(1),
|
|
4753
|
+
version: external_exports.string().min(1),
|
|
4754
|
+
publishedAt: external_exports.number()
|
|
4755
|
+
});
|
|
4756
|
+
ChannelRefSchema = external_exports.discriminatedUnion("kind", [
|
|
4757
|
+
external_exports.object({
|
|
4758
|
+
kind: external_exports.literal("p2p-tunnel"),
|
|
4759
|
+
ownerPrincipalId: external_exports.string().min(1),
|
|
4760
|
+
extId: external_exports.string().min(1)
|
|
4761
|
+
})
|
|
4762
|
+
]);
|
|
4763
|
+
SourceRefSchema = external_exports.discriminatedUnion("kind", [
|
|
4764
|
+
external_exports.object({
|
|
4765
|
+
kind: external_exports.literal("p2p-tunnel"),
|
|
4766
|
+
ownerPrincipalId: external_exports.string().min(1),
|
|
4767
|
+
extId: external_exports.string().min(1),
|
|
4768
|
+
snapshotHash: external_exports.string().min(1)
|
|
4769
|
+
})
|
|
4770
|
+
]);
|
|
4771
|
+
PublishedExtensionRecordSchema = external_exports.object({
|
|
4772
|
+
extId: external_exports.string().min(1),
|
|
4773
|
+
name: external_exports.string().min(1),
|
|
4774
|
+
version: external_exports.string().min(1),
|
|
4775
|
+
contentHash: external_exports.string().min(1),
|
|
4776
|
+
publishedAt: external_exports.number()
|
|
4777
|
+
});
|
|
4778
|
+
PublishCheckSchema = external_exports.discriminatedUnion("kind", [
|
|
4779
|
+
external_exports.object({ kind: external_exports.literal("clean") }),
|
|
4780
|
+
external_exports.object({
|
|
4781
|
+
kind: external_exports.literal("ready-new-version"),
|
|
4782
|
+
fromVersion: external_exports.string().min(1),
|
|
4783
|
+
toVersion: external_exports.string().min(1)
|
|
4784
|
+
}),
|
|
4785
|
+
external_exports.object({
|
|
4786
|
+
kind: external_exports.literal("error-same-hash"),
|
|
4787
|
+
version: external_exports.string().min(1)
|
|
4788
|
+
}),
|
|
4789
|
+
external_exports.object({
|
|
4790
|
+
kind: external_exports.literal("error-version-not-bumped"),
|
|
4791
|
+
localVersion: external_exports.string().min(1),
|
|
4792
|
+
publishedVersion: external_exports.string().min(1)
|
|
4793
|
+
}),
|
|
4794
|
+
external_exports.object({
|
|
4795
|
+
kind: external_exports.literal("error-version-regression"),
|
|
4796
|
+
localVersion: external_exports.string().min(1),
|
|
4797
|
+
publishedVersion: external_exports.string().min(1)
|
|
4798
|
+
})
|
|
4799
|
+
]);
|
|
4800
|
+
PublishStatusResultSchema = external_exports.object({
|
|
4801
|
+
localManifest: external_exports.object({
|
|
4802
|
+
name: external_exports.string().min(1),
|
|
4803
|
+
version: external_exports.string().min(1),
|
|
4804
|
+
contentHash: external_exports.string().min(1)
|
|
4805
|
+
}),
|
|
4806
|
+
publishState: external_exports.discriminatedUnion("kind", [
|
|
4807
|
+
external_exports.object({ kind: external_exports.literal("unpublished") }),
|
|
4808
|
+
external_exports.object({
|
|
4809
|
+
kind: external_exports.literal("published"),
|
|
4810
|
+
version: external_exports.string().min(1),
|
|
4811
|
+
contentHash: external_exports.string().min(1),
|
|
4812
|
+
publishedAt: external_exports.number()
|
|
4813
|
+
})
|
|
4814
|
+
]),
|
|
4815
|
+
check: PublishCheckSchema
|
|
4816
|
+
});
|
|
4817
|
+
ExtensionPublishArgs = external_exports.object({
|
|
4818
|
+
extId: external_exports.string().min(1),
|
|
4819
|
+
/**
|
|
4820
|
+
* 可选版本号:给了就在 publish-check 之前重写 manifest.json 的 version。
|
|
4821
|
+
* nullish 而非 optional —— 改造前的 pickOptionalString 显式把 null 当「没给」处理,
|
|
4822
|
+
* 换成纯 optional 会让 `newVersion: null` 从「不 bump」变成 INVALID_PARAM。
|
|
4823
|
+
*/
|
|
4824
|
+
newVersion: external_exports.string().min(1).nullish()
|
|
4825
|
+
});
|
|
4826
|
+
ExtensionIdArgs = external_exports.object({
|
|
4827
|
+
extId: external_exports.string().min(1)
|
|
4828
|
+
});
|
|
4829
|
+
ExtensionFetchBundleArgs = external_exports.object({
|
|
4830
|
+
extId: external_exports.string().min(1),
|
|
4831
|
+
snapshotHash: external_exports.string().min(1)
|
|
4832
|
+
});
|
|
4833
|
+
ExtensionFromChannelArgs = external_exports.object({
|
|
4834
|
+
channelRef: ChannelRefSchema,
|
|
4835
|
+
snapshotHash: external_exports.string().min(1),
|
|
4836
|
+
zipBase64: external_exports.string().min(1)
|
|
4837
|
+
});
|
|
4838
|
+
}
|
|
4839
|
+
});
|
|
4840
|
+
|
|
4841
|
+
// ../protocol/src/inbox.ts
|
|
4842
|
+
var InboxMessageSchema, InboxPostMessageArgsSchema, InboxListArgsSchema, InboxMarkReadArgsSchema, InboxSendDmArgsSchema;
|
|
4843
|
+
var init_inbox = __esm({
|
|
4844
|
+
"../protocol/src/inbox.ts"() {
|
|
4845
|
+
"use strict";
|
|
4846
|
+
init_zod();
|
|
4847
|
+
InboxMessageSchema = external_exports.object({
|
|
4848
|
+
id: external_exports.string().min(1),
|
|
4849
|
+
peerDeviceId: external_exports.string().min(1),
|
|
4850
|
+
senderDeviceId: external_exports.string().min(1),
|
|
4851
|
+
text: external_exports.string().min(1),
|
|
4852
|
+
createdAt: external_exports.number().int().nonnegative(),
|
|
4853
|
+
readBy: external_exports.record(external_exports.string().min(1), external_exports.number().int().positive()).default({}),
|
|
4854
|
+
// persona 代发署名(B 版设计):非空 = 该消息由某 persona 代发,非真人手打。
|
|
4855
|
+
// 缺省 = 真人。routing 身份仍看 senderDeviceId;origin 只用于末端 UI 渲染来源。
|
|
4856
|
+
origin: external_exports.object({ kind: external_exports.literal("persona"), personaId: external_exports.string().min(1) }).optional()
|
|
4857
|
+
}).strict();
|
|
4858
|
+
InboxPostMessageArgsSchema = external_exports.object({
|
|
4859
|
+
peerDeviceId: external_exports.string().min(1).optional(),
|
|
4860
|
+
id: external_exports.string().min(1),
|
|
4861
|
+
text: external_exports.string().min(1),
|
|
4862
|
+
createdAt: external_exports.number().int().nonnegative(),
|
|
4863
|
+
// persona 代发署名(跨 daemon forward 时随远程腿透传;真人发缺省)。
|
|
4864
|
+
origin: external_exports.object({ kind: external_exports.literal("persona"), personaId: external_exports.string().min(1) }).optional()
|
|
4865
|
+
}).strict();
|
|
4866
|
+
InboxListArgsSchema = external_exports.object({
|
|
4867
|
+
peerDeviceId: external_exports.string().min(1),
|
|
4868
|
+
sinceCreatedAt: external_exports.number().int().nonnegative().optional()
|
|
4869
|
+
}).strict();
|
|
4870
|
+
InboxMarkReadArgsSchema = external_exports.object({
|
|
4871
|
+
peerDeviceId: external_exports.string().min(1),
|
|
4872
|
+
upToCreatedAt: external_exports.number().int().nonnegative()
|
|
4873
|
+
}).strict();
|
|
4874
|
+
InboxSendDmArgsSchema = external_exports.object({
|
|
4875
|
+
peerDeviceId: external_exports.string().min(1).optional(),
|
|
4876
|
+
text: external_exports.string().min(1)
|
|
4877
|
+
});
|
|
4878
|
+
}
|
|
4879
|
+
});
|
|
4880
|
+
|
|
4881
|
+
// ../protocol/src/peer-exec.ts
|
|
4882
|
+
var PeerExecRunArgsSchema, PeerExecRunOkSchema;
|
|
4883
|
+
var init_peer_exec = __esm({
|
|
4884
|
+
"../protocol/src/peer-exec.ts"() {
|
|
4885
|
+
"use strict";
|
|
4886
|
+
init_zod();
|
|
4887
|
+
PeerExecRunArgsSchema = external_exports.object({
|
|
4888
|
+
/** A 侧发起时带:目标设备 deviceId。peer-forward 转发前 strip 掉,B 侧本地执行时无此字段。 */
|
|
4889
|
+
peerDeviceId: external_exports.string().min(1).optional(),
|
|
4890
|
+
/** 交给对端 `bash -c` 的命令;cc 自拼完整路径(一发一收,无跨命令会话状态)。 */
|
|
4891
|
+
command: external_exports.string().min(1),
|
|
4892
|
+
/** 超时上限(ms);缺省用 handler 默认 30_000,clamp 300_000。 */
|
|
4893
|
+
timeoutMs: external_exports.number().int().positive().optional()
|
|
4894
|
+
}).strict();
|
|
4895
|
+
PeerExecRunOkSchema = external_exports.object({
|
|
4896
|
+
type: external_exports.literal("peerExec:run:ok"),
|
|
4897
|
+
stdout: external_exports.string(),
|
|
4898
|
+
stderr: external_exports.string(),
|
|
4899
|
+
/** 进程退出码;被超时 kill 时 null。 */
|
|
4900
|
+
exitCode: external_exports.number().int().nullable(),
|
|
4901
|
+
timedOut: external_exports.boolean(),
|
|
4902
|
+
stdoutTruncated: external_exports.boolean(),
|
|
4903
|
+
stderrTruncated: external_exports.boolean()
|
|
4904
|
+
}).strict();
|
|
4905
|
+
}
|
|
4906
|
+
});
|
|
4907
|
+
|
|
4908
|
+
// ../protocol/src/shift-internal.ts
|
|
4909
|
+
var ShiftScheduleSchema, personaId, ShiftInternalAddArgs, ShiftInternalListArgs, ShiftInternalCancelArgs, ShiftPatchSchema, ShiftInternalUpdateArgs, ShiftInternalHistoryArgs;
|
|
4910
|
+
var init_shift_internal = __esm({
|
|
4911
|
+
"../protocol/src/shift-internal.ts"() {
|
|
4912
|
+
"use strict";
|
|
4913
|
+
init_zod();
|
|
4914
|
+
ShiftScheduleSchema = external_exports.discriminatedUnion("kind", [
|
|
4915
|
+
/** ISO-8601 时间点;时区随字符串自带 */
|
|
4916
|
+
external_exports.object({ kind: external_exports.literal("at"), at: external_exports.string().min(1) }),
|
|
4917
|
+
/** 固定间隔;anchorMs 缺省 = 从登记时刻起算 */
|
|
4918
|
+
external_exports.object({
|
|
4919
|
+
kind: external_exports.literal("every"),
|
|
4920
|
+
everyMs: external_exports.number().int().positive(),
|
|
4921
|
+
anchorMs: external_exports.number().int().nonnegative().optional()
|
|
4922
|
+
}),
|
|
4923
|
+
/** 5 字段 cron 表达式;tz 缺省 = 系统本地时区 */
|
|
4924
|
+
external_exports.object({ kind: external_exports.literal("cron"), expr: external_exports.string().min(1), tz: external_exports.string().min(1).optional() })
|
|
4925
|
+
]);
|
|
4926
|
+
personaId = external_exports.string().trim().min(1);
|
|
4927
|
+
ShiftInternalAddArgs = external_exports.object({
|
|
4928
|
+
personaId,
|
|
4929
|
+
name: external_exports.string().min(1),
|
|
4930
|
+
schedule: ShiftScheduleSchema,
|
|
4931
|
+
prompt: external_exports.string().min(1),
|
|
4932
|
+
/** 缺省 = 派给调用方自己 */
|
|
4933
|
+
targetPersona: external_exports.string().min(1).optional(),
|
|
4934
|
+
timeoutMs: external_exports.number().int().positive().optional()
|
|
4935
|
+
});
|
|
4936
|
+
ShiftInternalListArgs = external_exports.object({
|
|
4937
|
+
personaId,
|
|
4938
|
+
/** 缺省 true —— 只列本 persona 建的 */
|
|
4939
|
+
onlyMine: external_exports.boolean().optional()
|
|
4940
|
+
});
|
|
4941
|
+
ShiftInternalCancelArgs = external_exports.object({
|
|
4942
|
+
personaId,
|
|
4943
|
+
shiftId: external_exports.string().min(1)
|
|
4944
|
+
});
|
|
4945
|
+
ShiftPatchSchema = external_exports.object({
|
|
4946
|
+
name: external_exports.string().min(1).optional(),
|
|
4947
|
+
schedule: ShiftScheduleSchema.optional(),
|
|
4948
|
+
prompt: external_exports.string().min(1).optional(),
|
|
4949
|
+
targetPersona: external_exports.string().min(1).optional(),
|
|
4950
|
+
timeoutMs: external_exports.number().int().positive().optional(),
|
|
4951
|
+
enabled: external_exports.boolean().optional()
|
|
4952
|
+
});
|
|
4953
|
+
ShiftInternalUpdateArgs = external_exports.object({
|
|
4954
|
+
personaId,
|
|
4955
|
+
shiftId: external_exports.string().min(1),
|
|
4956
|
+
patch: ShiftPatchSchema
|
|
4957
|
+
});
|
|
4958
|
+
ShiftInternalHistoryArgs = external_exports.object({
|
|
4959
|
+
personaId,
|
|
4960
|
+
shiftId: external_exports.string().min(1),
|
|
4961
|
+
limit: external_exports.number().int().positive().optional()
|
|
4962
|
+
});
|
|
4963
|
+
}
|
|
4964
|
+
});
|
|
4965
|
+
|
|
4629
4966
|
// ../protocol/src/persona-schemas.ts
|
|
4630
4967
|
var PersonaFileSchema, PersonaSkillSummarySchema, PersonaPluginSummarySchema, PersonaSandboxSettingsSchema, PersonaInfoResponseSchema, PersonaCreateArgsSchema, PersonaIdArgsSchema, PersonaUpdateArgsSchema, CodexSandboxSettingsSchema;
|
|
4631
4968
|
var init_persona_schemas = __esm({
|
|
@@ -4726,8 +5063,97 @@ var init_persona_schemas = __esm({
|
|
|
4726
5063
|
}
|
|
4727
5064
|
});
|
|
4728
5065
|
|
|
5066
|
+
// ../protocol/src/events.ts
|
|
5067
|
+
var DAEMON_MODE_VALUES, SESSION_STATUS_VALUES, HISTORY_USER_META_VALUES, SKILL_SOURCE_VALUES, AGENT_SOURCE_VALUES, ASK_USER_QUESTION_TOOL_NAME;
|
|
5068
|
+
var init_events = __esm({
|
|
5069
|
+
"../protocol/src/events.ts"() {
|
|
5070
|
+
"use strict";
|
|
5071
|
+
DAEMON_MODE_VALUES = ["sdk", "tui"];
|
|
5072
|
+
SESSION_STATUS_VALUES = [
|
|
5073
|
+
"idle",
|
|
5074
|
+
"running",
|
|
5075
|
+
"running-idle",
|
|
5076
|
+
"stopped",
|
|
5077
|
+
"error",
|
|
5078
|
+
"observing"
|
|
5079
|
+
];
|
|
5080
|
+
HISTORY_USER_META_VALUES = [
|
|
5081
|
+
"task-notification",
|
|
5082
|
+
"slash-command",
|
|
5083
|
+
"local-command",
|
|
5084
|
+
"system-reminder",
|
|
5085
|
+
"skill-hint",
|
|
5086
|
+
"meta-text",
|
|
5087
|
+
"attachment-skills",
|
|
5088
|
+
"attachment-deferred-tools"
|
|
5089
|
+
];
|
|
5090
|
+
SKILL_SOURCE_VALUES = ["builtin", "global", "project", "plugin"];
|
|
5091
|
+
AGENT_SOURCE_VALUES = [
|
|
5092
|
+
"builtin",
|
|
5093
|
+
"global",
|
|
5094
|
+
"project",
|
|
5095
|
+
"policy",
|
|
5096
|
+
"plugin"
|
|
5097
|
+
];
|
|
5098
|
+
ASK_USER_QUESTION_TOOL_NAME = "AskUserQuestion";
|
|
5099
|
+
}
|
|
5100
|
+
});
|
|
5101
|
+
|
|
5102
|
+
// ../protocol/src/principal.ts
|
|
5103
|
+
function makeOwnerPrincipal(id, displayName, feishuUnionId) {
|
|
5104
|
+
return PrincipalSchema.parse({
|
|
5105
|
+
id,
|
|
5106
|
+
kind: "owner",
|
|
5107
|
+
displayName,
|
|
5108
|
+
...feishuUnionId ? { feishuUnionId } : {}
|
|
5109
|
+
});
|
|
5110
|
+
}
|
|
5111
|
+
function principalToSender(p2) {
|
|
5112
|
+
return {
|
|
5113
|
+
did: p2.id,
|
|
5114
|
+
displayName: p2.displayName,
|
|
5115
|
+
principal: p2.kind,
|
|
5116
|
+
...p2.feishuUnionId ? { feishuUnionId: p2.feishuUnionId } : {}
|
|
5117
|
+
};
|
|
5118
|
+
}
|
|
5119
|
+
function makeGuestSender(did, displayName, feishuUnionId) {
|
|
5120
|
+
return SenderInfoSchema.parse({
|
|
5121
|
+
did,
|
|
5122
|
+
displayName,
|
|
5123
|
+
principal: "guest",
|
|
5124
|
+
...feishuUnionId ? { feishuUnionId } : {}
|
|
5125
|
+
});
|
|
5126
|
+
}
|
|
5127
|
+
var PrincipalKindSchema, PrincipalSchema, SenderInfoSchema;
|
|
5128
|
+
var init_principal = __esm({
|
|
5129
|
+
"../protocol/src/principal.ts"() {
|
|
5130
|
+
"use strict";
|
|
5131
|
+
init_zod();
|
|
5132
|
+
PrincipalKindSchema = external_exports.enum(["owner", "guest"]);
|
|
5133
|
+
PrincipalSchema = external_exports.object({
|
|
5134
|
+
id: external_exports.string().min(1),
|
|
5135
|
+
kind: PrincipalKindSchema,
|
|
5136
|
+
displayName: external_exports.string(),
|
|
5137
|
+
/**
|
|
5138
|
+
* 飞书 union_id。owner: 本机 daemon 已飞书登录时透传自 owner-identity.json;未登录 undefined。
|
|
5139
|
+
* guest: v1 保持 undefined(connect token 当前不携带 unionId;未来若签名 payload 加字段可透传)。
|
|
5140
|
+
* 消费方(如 ticket MCP / 未来别的飞书身份挂钩场景)按 undefined 决定是否降级;本层不做 fallback。
|
|
5141
|
+
*/
|
|
5142
|
+
feishuUnionId: external_exports.string().optional()
|
|
5143
|
+
}).strict();
|
|
5144
|
+
SenderInfoSchema = external_exports.object({
|
|
5145
|
+
/** = principal.id = deviceId(决策 #16)。稳定路由 id */
|
|
5146
|
+
did: external_exports.string().min(1),
|
|
5147
|
+
displayName: external_exports.string(),
|
|
5148
|
+
/** owner 未登录 / guest 无飞书身份时缺省。消费方各自决定是否降级 */
|
|
5149
|
+
feishuUnionId: external_exports.string().optional(),
|
|
5150
|
+
principal: PrincipalKindSchema
|
|
5151
|
+
}).strict();
|
|
5152
|
+
}
|
|
5153
|
+
});
|
|
5154
|
+
|
|
4729
5155
|
// ../protocol/src/schemas.ts
|
|
4730
|
-
var SessionStatusSchema, UsageSchema, ContextUsageSchema, sessionMetaShape, SessionMetaSchema, ModelInfoSchema, ModeInfoSchema, ConfigFieldSchemaSchema, CapabilitiesGetArgs, ToolFeaturesSchema, CapabilitiesResponseSchema, AllowRuleSchema, SessionFileSchema, ParsedEventBase, HistoryUserMetaSchema, SubagentToolStatsSchema, StructuredPatchHunkSchema, ToolResultExtraSchema, MemoryEntrySchema, AskQuestionOptionSchema, AskQuestionItemSchema, ParsedEventSchema, SessionCreateArgs, SessionListArgs, SessionIdArgs, SessionUpdateArgs, SessionSendArgs, SessionRewindArgs, SessionRewindResponseSchema, SessionRewindDiffArgs, RewindDiffHunkSchema, RewindDiffFileSchema, SessionRewindDiffResponseSchema, SessionRewindableMessageIdsArgs, SessionRewindableMessageIdsResponseSchema, SessionResumeArgs, SessionForkArgs, SessionForkResponseSchema, SessionObserveArgs, SessionEventsArgs, PermissionRespondArgs, HistoryListArgs, HistoryReadArgs, HistorySubagentsArgs, HistorySubagentReadArgs, WorkspaceListArgs, WorkspaceReadArgs, SkillsListArgs, SkillEntrySchema, AgentEntrySchema, AgentsListArgs, AgentsListResponseSchema, SessionSubscribeArgs, SessionPinArgs, PeerSessionUpsertArgs, PeerSessionUpsertResponseSchema, PeerSessionRemoveArgs, PeerSessionRemoveResponseSchema, SessionReorderPinsArgs, GitRootArgs, GitRootResponseSchema, GitBranchArgs, GitBranchResponseSchema, GitBranchesArgs, GitBranchesResponseSchema, HistoryRecentDirsArgs, RecentDirEntrySchema, HistoryRecentDirsResponseSchema, SessionQuestionFrameSchema, SessionQuestionClearedFrameSchema, AnswerQuestionArgs, AnswerQuestionResponseSchema, CancelQuestionArgs, CancelQuestionResponseSchema, AuthRequestFrameSchema, AuthOkFrameSchema, TunnelReadyEventSchema, TunnelExitedEventSchema, TunnelUnavailableEventSchema, InfoRunningSessionSchema, InfoResponseSchema, PROJECT_PORT_MIN, PROJECT_PORT_MAX, projectNameRegex, DEFAULT_DEV_COMMAND, ProjectMetadataSchema, PROJECT_STAGE_VALUES, ProjectStageSchema, ProjectWithStatusSchema, ListProjectsArgsSchema, ListProjectsResultSchema, GetProjectArgsSchema, GetProjectResultSchema, CreateProjectArgsSchema, CreateProjectResultSchema, DeleteProjectArgsSchema, DeleteProjectResultSchema, UpdateProjectPortArgsSchema, UpdateProjectPortResultSchema, SetProdUrlArgsSchema, SetProdUrlResultSchema, StartDevServerArgsSchema, StartDevServerResultSchema, ASSISTANT_REPORTABLE_STAGES, ReportStageArgsSchema, ReportStageResultSchema, StopDevServerArgsSchema, StopDevServerResultSchema, AppBuilderProjectUpdatedEventSchema, PublishArgsSchema, PublishResultSchema, DismissPublishJobArgsSchema, DismissPublishJobResultSchema, AppBuilderPublishProgressEventSchema, AppBuilderPublishFailedEventSchema;
|
|
5156
|
+
var SessionStatusSchema, UsageSchema, ContextUsageSchema, sessionMetaShape, SessionMetaSchema, ModelInfoSchema, ModeInfoSchema, ConfigFieldSchemaSchema, CapabilitiesGetArgs, ToolFeaturesSchema, CapabilitiesResponseSchema, AllowRuleSchema, SessionFileSchema, ParsedEventBase, HistoryUserMetaSchema, SubagentToolStatsSchema, StructuredPatchHunkSchema, ToolResultExtraSchema, MemoryEntrySchema, AskQuestionOptionSchema, AskQuestionItemSchema, ParsedEventSchema, SessionCreateArgs, SessionListArgs, SessionIdArgs, SessionUpdateArgs, SessionSendArgs, SessionInterruptArgs, SessionRewindArgs, SessionRewindResponseSchema, SessionRewindDiffArgs, RewindDiffHunkSchema, RewindDiffFileSchema, SessionRewindDiffResponseSchema, SessionRewindableMessageIdsArgs, SessionRewindableMessageIdsResponseSchema, SessionResumeArgs, SessionForkArgs, SessionForkResponseSchema, SessionObserveArgs, SessionEventsArgs, PermissionRespondArgs, HistoryListArgs, HistoryReadArgs, HistorySubagentsArgs, HistorySubagentReadArgs, WorkspaceListArgs, WorkspaceReadArgs, SkillsListArgs, SkillEntrySchema, AgentEntrySchema, AgentsListArgs, AgentsListResponseSchema, SessionCurrentTurnSenderArgs, SessionSubscribeArgs, SessionPinArgs, PeerSessionUpsertArgs, PeerSessionUpsertResponseSchema, PeerSessionRemoveArgs, PeerSessionRemoveResponseSchema, SessionReorderPinsArgs, GitRootArgs, GitRootResponseSchema, GitBranchArgs, GitBranchResponseSchema, GitBranchesArgs, GitBranchesResponseSchema, HistoryRecentDirsArgs, RecentDirEntrySchema, HistoryRecentDirsResponseSchema, SessionQuestionFrameSchema, SessionQuestionClearedFrameSchema, AnswerQuestionArgs, AnswerQuestionResponseSchema, CancelQuestionArgs, CancelQuestionResponseSchema, AuthRequestFrameSchema, AuthOkFrameSchema, TunnelReadyEventSchema, TunnelExitedEventSchema, TunnelUnavailableEventSchema, InfoRunningSessionSchema, InfoResponseSchema, PROJECT_PORT_MIN, PROJECT_PORT_MAX, projectNameRegex, DEFAULT_DEV_COMMAND, ProjectMetadataSchema, PROJECT_STAGE_VALUES, ProjectStageSchema, ProjectWithStatusSchema, ListProjectsArgsSchema, ListProjectsResultSchema, GetProjectArgsSchema, GetProjectResultSchema, CreateProjectArgsSchema, CreateProjectResultSchema, DeleteProjectArgsSchema, DeleteProjectResultSchema, UpdateProjectPortArgsSchema, UpdateProjectPortResultSchema, SetProdUrlArgsSchema, SetProdUrlResultSchema, StartDevServerArgsSchema, StartDevServerResultSchema, ASSISTANT_REPORTABLE_STAGES, ReportStageArgsSchema, ReportStageResultSchema, StopDevServerArgsSchema, StopDevServerResultSchema, AppBuilderProjectUpdatedEventSchema, PublishArgsSchema, PublishResultSchema, DismissPublishJobArgsSchema, DismissPublishJobResultSchema, AppBuilderPublishProgressEventSchema, AppBuilderPublishFailedEventSchema;
|
|
4731
5157
|
var init_schemas = __esm({
|
|
4732
5158
|
"../protocol/src/schemas.ts"() {
|
|
4733
5159
|
"use strict";
|
|
@@ -5214,6 +5640,7 @@ var init_schemas = __esm({
|
|
|
5214
5640
|
sessionId: external_exports.string().min(1),
|
|
5215
5641
|
text: external_exports.string()
|
|
5216
5642
|
});
|
|
5643
|
+
SessionInterruptArgs = SessionIdArgs;
|
|
5217
5644
|
SessionRewindArgs = external_exports.object({
|
|
5218
5645
|
sessionId: external_exports.string().min(1),
|
|
5219
5646
|
userMessageId: external_exports.string().min(1),
|
|
@@ -5344,7 +5771,12 @@ var init_schemas = __esm({
|
|
|
5344
5771
|
AgentsListResponseSchema = external_exports.object({
|
|
5345
5772
|
agents: external_exports.array(AgentEntrySchema)
|
|
5346
5773
|
});
|
|
5347
|
-
|
|
5774
|
+
SessionCurrentTurnSenderArgs = external_exports.object({
|
|
5775
|
+
// 刻意不加 .min(1):空串是被依赖的软路径(handler 见空即返 sender:null,
|
|
5776
|
+
// session-current-turn-sender.spec 有用例守着)。加了 min 会把它变成硬报错。
|
|
5777
|
+
sessionId: external_exports.string().optional()
|
|
5778
|
+
});
|
|
5779
|
+
SessionSubscribeArgs = external_exports.object({ sessionId: external_exports.string().min(1).optional() });
|
|
5348
5780
|
SessionPinArgs = external_exports.object({
|
|
5349
5781
|
sessionId: external_exports.string().min(1),
|
|
5350
5782
|
pinned: external_exports.boolean()
|
|
@@ -5583,7 +6015,9 @@ var init_schemas = __esm({
|
|
|
5583
6015
|
CreateProjectArgsSchema = external_exports.object({
|
|
5584
6016
|
/** 必填:caller session,daemon 自动绑过去(spec 2026-06-02 §3 invariant 1 Session ↔ 1 Project) */
|
|
5585
6017
|
sessionId: external_exports.string().min(1),
|
|
5586
|
-
|
|
6018
|
+
// .min(1):改造前手写校验是 `!f.name` 明确拒空串;空 name 会让 projectDir('')
|
|
6019
|
+
// 落到 projects 根目录,scaffold 往根上铺模板。
|
|
6020
|
+
name: external_exports.string().min(1)
|
|
5587
6021
|
}).strict();
|
|
5588
6022
|
CreateProjectResultSchema = external_exports.object({
|
|
5589
6023
|
project: ProjectMetadataSchema
|
|
@@ -5607,733 +6041,607 @@ var init_schemas = __esm({
|
|
|
5607
6041
|
project: ProjectMetadataSchema
|
|
5608
6042
|
}).strict();
|
|
5609
6043
|
StartDevServerArgsSchema = external_exports.object({
|
|
5610
|
-
sessionId: external_exports.string().min(1),
|
|
5611
|
-
force: external_exports.boolean().optional()
|
|
5612
|
-
}).strict();
|
|
5613
|
-
StartDevServerResultSchema = external_exports.object({
|
|
5614
|
-
project: ProjectMetadataSchema
|
|
5615
|
-
}).strict();
|
|
5616
|
-
ASSISTANT_REPORTABLE_STAGES = [
|
|
5617
|
-
"installing",
|
|
5618
|
-
"failed"
|
|
5619
|
-
];
|
|
5620
|
-
ReportStageArgsSchema = external_exports.object({
|
|
5621
|
-
sessionId: external_exports.string().min(1),
|
|
5622
|
-
stage: external_exports.enum(ASSISTANT_REPORTABLE_STAGES),
|
|
5623
|
-
/** stage='failed' 时必填的原因(一句话),其它 stage optional */
|
|
5624
|
-
reason: external_exports.string().optional()
|
|
5625
|
-
}).strict();
|
|
5626
|
-
ReportStageResultSchema = external_exports.object({
|
|
5627
|
-
ok: external_exports.literal(true)
|
|
5628
|
-
}).strict();
|
|
5629
|
-
StopDevServerArgsSchema = external_exports.object({
|
|
5630
|
-
sessionId: external_exports.string().min(1)
|
|
5631
|
-
}).strict();
|
|
5632
|
-
StopDevServerResultSchema = external_exports.object({
|
|
5633
|
-
ok: external_exports.literal(true)
|
|
5634
|
-
}).strict();
|
|
5635
|
-
AppBuilderProjectUpdatedEventSchema = external_exports.object({
|
|
5636
|
-
type: external_exports.literal("appBuilder:project-updated"),
|
|
5637
|
-
project: ProjectWithStatusSchema,
|
|
5638
|
-
stage: ProjectStageSchema,
|
|
5639
|
-
/** stage='failed' 时的失败原因 */
|
|
5640
|
-
stageReason: external_exports.string().optional()
|
|
5641
|
-
}).strict();
|
|
5642
|
-
PublishArgsSchema = external_exports.object({
|
|
5643
|
-
name: external_exports.string().regex(projectNameRegex)
|
|
5644
|
-
});
|
|
5645
|
-
PublishResultSchema = external_exports.object({
|
|
5646
|
-
jobId: external_exports.string().min(1),
|
|
5647
|
-
status: external_exports.enum(["started", "already-publishing"])
|
|
5648
|
-
}).strict();
|
|
5649
|
-
DismissPublishJobArgsSchema = external_exports.object({
|
|
5650
|
-
name: external_exports.string().regex(projectNameRegex)
|
|
5651
|
-
});
|
|
5652
|
-
DismissPublishJobResultSchema = external_exports.object({
|
|
5653
|
-
ok: external_exports.literal(true)
|
|
5654
|
-
}).strict();
|
|
5655
|
-
AppBuilderPublishProgressEventSchema = external_exports.object({
|
|
5656
|
-
type: external_exports.literal("appBuilder:publish-progress"),
|
|
5657
|
-
name: external_exports.string().regex(projectNameRegex),
|
|
5658
|
-
jobId: external_exports.string().min(1),
|
|
5659
|
-
stage: external_exports.enum(["build", "deploy", "verify"]),
|
|
5660
|
-
status: external_exports.enum(["started", "completed"])
|
|
5661
|
-
}).strict();
|
|
5662
|
-
AppBuilderPublishFailedEventSchema = external_exports.object({
|
|
5663
|
-
type: external_exports.literal("appBuilder:publish-failed"),
|
|
5664
|
-
name: external_exports.string().regex(projectNameRegex),
|
|
5665
|
-
jobId: external_exports.string().min(1),
|
|
5666
|
-
stage: external_exports.enum(["build", "deploy", "verify", "unknown"]),
|
|
5667
|
-
errorSummary: external_exports.string()
|
|
5668
|
-
}).strict();
|
|
5669
|
-
}
|
|
5670
|
-
});
|
|
5671
|
-
|
|
5672
|
-
// ../protocol/src/frames.ts
|
|
5673
|
-
var PROTOCOL_VERSION, DISPATCH_MCP_ID;
|
|
5674
|
-
var init_frames = __esm({
|
|
5675
|
-
"../protocol/src/frames.ts"() {
|
|
5676
|
-
"use strict";
|
|
5677
|
-
PROTOCOL_VERSION = 1;
|
|
5678
|
-
DISPATCH_MCP_ID = "dispatch";
|
|
5679
|
-
}
|
|
5680
|
-
});
|
|
5681
|
-
|
|
5682
|
-
// ../protocol/src/persona-mode.ts
|
|
5683
|
-
var init_persona_mode = __esm({
|
|
5684
|
-
"../protocol/src/persona-mode.ts"() {
|
|
5685
|
-
"use strict";
|
|
5686
|
-
}
|
|
5687
|
-
});
|
|
5688
|
-
|
|
5689
|
-
// ../protocol/src/capability.ts
|
|
5690
|
-
var ResourceSchema, ActionSchema, GrantSchema, CapabilitySchema, CapabilityWireSchema, WhoamiResponseSchema, PERSONAL_CAP_GRANTS;
|
|
5691
|
-
var init_capability = __esm({
|
|
5692
|
-
"../protocol/src/capability.ts"() {
|
|
5693
|
-
"use strict";
|
|
5694
|
-
init_zod();
|
|
5695
|
-
ResourceSchema = external_exports.discriminatedUnion("type", [
|
|
5696
|
-
external_exports.object({ type: external_exports.literal("persona"), id: external_exports.string().min(1) }).strict(),
|
|
5697
|
-
external_exports.object({ type: external_exports.literal("chat"), id: external_exports.string().min(1) }).strict(),
|
|
5698
|
-
external_exports.object({ type: external_exports.literal("*") }).strict()
|
|
5699
|
-
]);
|
|
5700
|
-
ActionSchema = external_exports.enum(["read", "send", "admin"]);
|
|
5701
|
-
GrantSchema = external_exports.object({
|
|
5702
|
-
resource: ResourceSchema,
|
|
5703
|
-
actions: external_exports.array(ActionSchema).min(1)
|
|
5704
|
-
}).strict();
|
|
5705
|
-
CapabilitySchema = external_exports.object({
|
|
5706
|
-
id: external_exports.string().min(1),
|
|
5707
|
-
// sha256(token) hex 64
|
|
5708
|
-
secretHash: external_exports.string().regex(/^[a-f0-9]{64}$/),
|
|
5709
|
-
displayName: external_exports.string(),
|
|
5710
|
-
// 空数组合法 = 纯访客(只能 DM)
|
|
5711
|
-
grants: external_exports.array(GrantSchema),
|
|
5712
|
-
issuedAt: external_exports.number().int().nonnegative(),
|
|
5713
|
-
expiresAt: external_exports.number().int().positive().optional(),
|
|
5714
|
-
maxUses: external_exports.number().int().positive().optional(),
|
|
5715
|
-
usedCount: external_exports.number().int().nonnegative(),
|
|
5716
|
-
/**
|
|
5717
|
-
* guest 在 auth 帧捎带 selfPrincipalId 时由 AuthGate.authenticate 回写;
|
|
5718
|
-
* 未被消费的 cap 此字段缺失。
|
|
5719
|
-
*/
|
|
5720
|
-
peerOwnerId: external_exports.string().min(1).optional(),
|
|
5721
|
-
/** 首次 client hello 时间戳(与 peerOwnerId 同步写入) */
|
|
5722
|
-
firstUsedByPeerAt: external_exports.number().int().positive().optional(),
|
|
5723
|
-
/**
|
|
5724
|
-
* 对方 daemon owner 的 displayName,guest auth 帧 selfDisplayName 触发
|
|
5725
|
-
* recordPeerHello 时同步回写。视角 B (2026-05-23) UI 派生联系人列表用此字段
|
|
5726
|
-
* 显示对方名字(避免 fallback 到我颁 cap 时填的 displayName)。
|
|
5727
|
-
*/
|
|
5728
|
-
peerDisplayName: external_exports.string().optional()
|
|
5729
|
-
}).strict();
|
|
5730
|
-
CapabilityWireSchema = CapabilitySchema.omit({ secretHash: true });
|
|
5731
|
-
WhoamiResponseSchema = external_exports.object({
|
|
5732
|
-
type: external_exports.literal("whoami:ok"),
|
|
5733
|
-
owner: external_exports.object({
|
|
5734
|
-
id: external_exports.string(),
|
|
5735
|
-
kind: external_exports.enum(["owner", "guest"]),
|
|
5736
|
-
displayName: external_exports.string(),
|
|
5737
|
-
/** 归属人 id(决策 #16:TTC unique_id 等,落 contact.ownerId) */
|
|
5738
|
-
ownerId: external_exports.string(),
|
|
5739
|
-
/** 身份来源(决策 #16:'ttc'/'google',落 contact.provider) */
|
|
5740
|
-
provider: external_exports.string()
|
|
5741
|
-
}).strict(),
|
|
5742
|
-
capability: CapabilityWireSchema,
|
|
5743
|
-
grantedPersonas: external_exports.array(
|
|
5744
|
-
external_exports.object({
|
|
5745
|
-
id: external_exports.string().min(1),
|
|
5746
|
-
displayName: external_exports.string()
|
|
5747
|
-
}).strict()
|
|
5748
|
-
)
|
|
5749
|
-
}).strict();
|
|
5750
|
-
PERSONAL_CAP_GRANTS = Object.freeze([
|
|
5751
|
-
Object.freeze({
|
|
5752
|
-
resource: Object.freeze({ type: "persona", id: "*" }),
|
|
5753
|
-
actions: Object.freeze(["read", "send"])
|
|
5754
|
-
})
|
|
5755
|
-
]);
|
|
5756
|
-
}
|
|
5757
|
-
});
|
|
5758
|
-
|
|
5759
|
-
// ../protocol/src/inbox.ts
|
|
5760
|
-
var InboxMessageSchema, InboxPostMessageArgsSchema, InboxListArgsSchema, InboxMarkReadArgsSchema, InboxSendDmArgsSchema;
|
|
5761
|
-
var init_inbox = __esm({
|
|
5762
|
-
"../protocol/src/inbox.ts"() {
|
|
5763
|
-
"use strict";
|
|
5764
|
-
init_zod();
|
|
5765
|
-
InboxMessageSchema = external_exports.object({
|
|
5766
|
-
id: external_exports.string().min(1),
|
|
5767
|
-
peerDeviceId: external_exports.string().min(1),
|
|
5768
|
-
senderDeviceId: external_exports.string().min(1),
|
|
5769
|
-
text: external_exports.string().min(1),
|
|
5770
|
-
createdAt: external_exports.number().int().nonnegative(),
|
|
5771
|
-
readBy: external_exports.record(external_exports.string().min(1), external_exports.number().int().positive()).default({}),
|
|
5772
|
-
// persona 代发署名(B 版设计):非空 = 该消息由某 persona 代发,非真人手打。
|
|
5773
|
-
// 缺省 = 真人。routing 身份仍看 senderDeviceId;origin 只用于末端 UI 渲染来源。
|
|
5774
|
-
origin: external_exports.object({ kind: external_exports.literal("persona"), personaId: external_exports.string().min(1) }).optional()
|
|
5775
|
-
}).strict();
|
|
5776
|
-
InboxPostMessageArgsSchema = external_exports.object({
|
|
5777
|
-
peerDeviceId: external_exports.string().min(1).optional(),
|
|
5778
|
-
id: external_exports.string().min(1),
|
|
5779
|
-
text: external_exports.string().min(1),
|
|
5780
|
-
createdAt: external_exports.number().int().nonnegative(),
|
|
5781
|
-
// persona 代发署名(跨 daemon forward 时随远程腿透传;真人发缺省)。
|
|
5782
|
-
origin: external_exports.object({ kind: external_exports.literal("persona"), personaId: external_exports.string().min(1) }).optional()
|
|
5783
|
-
}).strict();
|
|
5784
|
-
InboxListArgsSchema = external_exports.object({
|
|
5785
|
-
peerDeviceId: external_exports.string().min(1),
|
|
5786
|
-
sinceCreatedAt: external_exports.number().int().nonnegative().optional()
|
|
5787
|
-
}).strict();
|
|
5788
|
-
InboxMarkReadArgsSchema = external_exports.object({
|
|
5789
|
-
peerDeviceId: external_exports.string().min(1),
|
|
5790
|
-
upToCreatedAt: external_exports.number().int().nonnegative()
|
|
5791
|
-
}).strict();
|
|
5792
|
-
InboxSendDmArgsSchema = external_exports.object({
|
|
5793
|
-
peerDeviceId: external_exports.string().min(1).optional(),
|
|
5794
|
-
text: external_exports.string().min(1)
|
|
5795
|
-
});
|
|
5796
|
-
}
|
|
5797
|
-
});
|
|
5798
|
-
|
|
5799
|
-
// ../protocol/src/contact.ts
|
|
5800
|
-
var ContactSchema, ContactWireSchema, ContactRemoveArgsSchema, ContactRemoveOkSchema, ContactListOkSchema, ContactAddedFrameSchema, ContactRemovedFrameSchema, ContactPinArgsSchema, ContactPinOkSchema, ContactPinnedFrameSchema;
|
|
5801
|
-
var init_contact = __esm({
|
|
5802
|
-
"../protocol/src/contact.ts"() {
|
|
5803
|
-
"use strict";
|
|
5804
|
-
init_zod();
|
|
5805
|
-
init_capability();
|
|
5806
|
-
ContactSchema = external_exports.object({
|
|
5807
|
-
/**
|
|
5808
|
-
* 对方设备标识(主键):对方 daemon 自己生成并持久化的标识(auth.json deviceId,
|
|
5809
|
-
* 如 dev-<uuid>),provider 无关。同 deviceId 重复 upsert 覆盖。
|
|
5810
|
-
*/
|
|
5811
|
-
deviceId: external_exports.string().min(1),
|
|
5812
|
-
/**
|
|
5813
|
-
* 归属人 id(决策 #16):TTC unique_id 等,由 connect token subOwner 签名背书。
|
|
5814
|
-
* 与 provider 一起唯一标识一个人。DM 不再按它路由(路由用 deviceId),仅显示/分组用。
|
|
5815
|
-
*/
|
|
5816
|
-
ownerId: external_exports.string().min(1),
|
|
5817
|
-
/** 身份来源(决策 #16):'ttc'(飞书/手机/邮箱登入 TTC)| 'google' | ...,token 背书 */
|
|
5818
|
-
provider: external_exports.string().min(1),
|
|
5819
|
-
/** 联系人显示名 */
|
|
5820
|
-
displayName: external_exports.string(),
|
|
5821
|
-
/** 该设备可达的 ws/tunnel 地址 */
|
|
5822
|
-
remoteUrl: external_exports.string().min(1),
|
|
5823
|
-
// 自动反向建立联系人(spec 决策 #11):被连接方本地验票成功后自动落 A 为
|
|
5824
|
-
// 联系人,但它不持有 A 颁发的 token(A 从未给它换票)→ connectToken 为空串。
|
|
5825
|
-
// device:connect 出站路径仍存中心 server 签发的真实 connect token(断线重连复用)。
|
|
5826
|
-
// 不用 .min(1):自动反向路径合法地存空串,禁止填假 token 占位(不造假数据)。
|
|
5827
|
-
connectToken: external_exports.string(),
|
|
5828
|
-
grants: external_exports.array(GrantSchema),
|
|
5829
|
-
addedAt: external_exports.number().int().nonnegative(),
|
|
5830
|
-
/**
|
|
5831
|
-
* pin 时间戳(ms,Date.now() 语义);null = 未 pin。sidebar 顶部固定区渲染由此驱动。
|
|
5832
|
-
* 老 contacts.json 缺此字段 → zod default 补 null(无破坏性升级;不 orphan)。
|
|
5833
|
-
* 对齐 SessionFile.pinnedAt 语义(daemon 侧持久化,contact:pin RPC 更新 → contact:pinned push)。
|
|
5834
|
-
*/
|
|
5835
|
-
pinnedAt: external_exports.number().int().nullable().default(null),
|
|
5836
|
-
/**
|
|
5837
|
-
* 远程访问授权(spec 2026-07-16)。owner 视角:允许该 contact 反向操作我的设备——
|
|
5838
|
-
* 跨设备 exec 的总开关(peerExec:run handler 运行时判它)。default=false,owner 显式开。
|
|
5839
|
-
* 授权粒度 per-people (per-contact):借用别人 persona 本来就带信任对方本人的前提。
|
|
5840
|
-
*/
|
|
5841
|
-
remoteAccessAllowed: external_exports.boolean().default(false)
|
|
5842
|
-
}).strict();
|
|
5843
|
-
ContactWireSchema = ContactSchema;
|
|
5844
|
-
ContactRemoveArgsSchema = external_exports.object({
|
|
5845
|
-
deviceId: external_exports.string().min(1)
|
|
5846
|
-
}).strict();
|
|
5847
|
-
ContactRemoveOkSchema = external_exports.object({
|
|
5848
|
-
type: external_exports.literal("contact:remove:ok"),
|
|
5849
|
-
deviceId: external_exports.string().min(1)
|
|
5850
|
-
}).strict();
|
|
5851
|
-
ContactListOkSchema = external_exports.object({
|
|
5852
|
-
type: external_exports.literal("contact:list:ok"),
|
|
5853
|
-
contacts: external_exports.array(ContactWireSchema)
|
|
5854
|
-
}).strict();
|
|
5855
|
-
ContactAddedFrameSchema = external_exports.object({
|
|
5856
|
-
type: external_exports.literal("contact:added"),
|
|
5857
|
-
contact: ContactWireSchema
|
|
5858
|
-
}).strict();
|
|
5859
|
-
ContactRemovedFrameSchema = external_exports.object({
|
|
5860
|
-
type: external_exports.literal("contact:removed"),
|
|
5861
|
-
deviceId: external_exports.string().min(1)
|
|
5862
|
-
}).strict();
|
|
5863
|
-
ContactPinArgsSchema = external_exports.object({
|
|
5864
|
-
deviceId: external_exports.string().min(1),
|
|
5865
|
-
pinned: external_exports.boolean()
|
|
5866
|
-
}).strict();
|
|
5867
|
-
ContactPinOkSchema = external_exports.object({
|
|
5868
|
-
type: external_exports.literal("contact:pin:ok"),
|
|
5869
|
-
deviceId: external_exports.string().min(1),
|
|
5870
|
-
pinnedAt: external_exports.number().int().nullable()
|
|
5871
|
-
}).strict();
|
|
5872
|
-
ContactPinnedFrameSchema = external_exports.object({
|
|
5873
|
-
type: external_exports.literal("contact:pinned"),
|
|
5874
|
-
deviceId: external_exports.string().min(1),
|
|
5875
|
-
pinnedAt: external_exports.number().int().nullable()
|
|
5876
|
-
}).strict();
|
|
5877
|
-
}
|
|
5878
|
-
});
|
|
5879
|
-
|
|
5880
|
-
// ../protocol/src/contact-handshake.ts
|
|
5881
|
-
var ContactHandshakeArgsSchema, ContactHandshakeOkSchema;
|
|
5882
|
-
var init_contact_handshake = __esm({
|
|
5883
|
-
"../protocol/src/contact-handshake.ts"() {
|
|
5884
|
-
"use strict";
|
|
5885
|
-
init_zod();
|
|
5886
|
-
init_capability();
|
|
5887
|
-
ContactHandshakeArgsSchema = external_exports.object({
|
|
5888
|
-
selfUrl: external_exports.string().min(1)
|
|
5889
|
-
});
|
|
5890
|
-
ContactHandshakeOkSchema = external_exports.object({
|
|
5891
|
-
type: external_exports.literal("contact:handshake:ok"),
|
|
5892
|
-
owner: external_exports.object({
|
|
5893
|
-
/** 被调方 deviceId(路由主键;调用方落 Contact 的主键用自己请求的 args.deviceId,此值供校验/展示) */
|
|
5894
|
-
id: external_exports.string(),
|
|
5895
|
-
/** 归属人(落 Contact.ownerId / provider,显示分组用) */
|
|
5896
|
-
ownerId: external_exports.string(),
|
|
5897
|
-
provider: external_exports.string(),
|
|
5898
|
-
displayName: external_exports.string()
|
|
5899
|
-
}),
|
|
5900
|
-
/** 被调方授调用方的 grants(落 Contact.grants) */
|
|
5901
|
-
grants: external_exports.array(GrantSchema)
|
|
5902
|
-
});
|
|
5903
|
-
}
|
|
5904
|
-
});
|
|
5905
|
-
|
|
5906
|
-
// ../protocol/src/contact-remote-access.ts
|
|
5907
|
-
var ContactSetRemoteAccessArgsSchema, ContactSetRemoteAccessOkSchema, ContactRemoteAccessUpdatedFrameSchema;
|
|
5908
|
-
var init_contact_remote_access = __esm({
|
|
5909
|
-
"../protocol/src/contact-remote-access.ts"() {
|
|
5910
|
-
"use strict";
|
|
5911
|
-
init_zod();
|
|
5912
|
-
ContactSetRemoteAccessArgsSchema = external_exports.object({
|
|
5913
|
-
deviceId: external_exports.string().min(1),
|
|
5914
|
-
remoteAccessAllowed: external_exports.boolean()
|
|
5915
|
-
}).strict();
|
|
5916
|
-
ContactSetRemoteAccessOkSchema = external_exports.object({
|
|
5917
|
-
type: external_exports.literal("contact:setRemoteAccess:ok"),
|
|
5918
|
-
deviceId: external_exports.string().min(1),
|
|
5919
|
-
remoteAccessAllowed: external_exports.boolean()
|
|
5920
|
-
}).strict();
|
|
5921
|
-
ContactRemoteAccessUpdatedFrameSchema = external_exports.object({
|
|
5922
|
-
type: external_exports.literal("contact:remote-access-updated"),
|
|
5923
|
-
deviceId: external_exports.string().min(1),
|
|
5924
|
-
remoteAccessAllowed: external_exports.boolean()
|
|
5925
|
-
}).strict();
|
|
5926
|
-
}
|
|
5927
|
-
});
|
|
5928
|
-
|
|
5929
|
-
// ../protocol/src/peer-exec.ts
|
|
5930
|
-
var PeerExecRunArgsSchema, PeerExecRunOkSchema;
|
|
5931
|
-
var init_peer_exec = __esm({
|
|
5932
|
-
"../protocol/src/peer-exec.ts"() {
|
|
5933
|
-
"use strict";
|
|
5934
|
-
init_zod();
|
|
5935
|
-
PeerExecRunArgsSchema = external_exports.object({
|
|
5936
|
-
/** A 侧发起时带:目标设备 deviceId。peer-forward 转发前 strip 掉,B 侧本地执行时无此字段。 */
|
|
5937
|
-
peerDeviceId: external_exports.string().min(1).optional(),
|
|
5938
|
-
/** 交给对端 `bash -c` 的命令;cc 自拼完整路径(一发一收,无跨命令会话状态)。 */
|
|
5939
|
-
command: external_exports.string().min(1),
|
|
5940
|
-
/** 超时上限(ms);缺省用 handler 默认 30_000,clamp 300_000。 */
|
|
5941
|
-
timeoutMs: external_exports.number().int().positive().optional()
|
|
5942
|
-
}).strict();
|
|
5943
|
-
PeerExecRunOkSchema = external_exports.object({
|
|
5944
|
-
type: external_exports.literal("peerExec:run:ok"),
|
|
5945
|
-
stdout: external_exports.string(),
|
|
5946
|
-
stderr: external_exports.string(),
|
|
5947
|
-
/** 进程退出码;被超时 kill 时 null。 */
|
|
5948
|
-
exitCode: external_exports.number().int().nullable(),
|
|
5949
|
-
timedOut: external_exports.boolean(),
|
|
5950
|
-
stdoutTruncated: external_exports.boolean(),
|
|
5951
|
-
stderrTruncated: external_exports.boolean()
|
|
5952
|
-
}).strict();
|
|
5953
|
-
}
|
|
5954
|
-
});
|
|
5955
|
-
|
|
5956
|
-
// ../protocol/src/extension.ts
|
|
5957
|
-
function isAllowedHostedUrl(raw) {
|
|
5958
|
-
let u;
|
|
5959
|
-
try {
|
|
5960
|
-
u = new URL(raw);
|
|
5961
|
-
} catch {
|
|
5962
|
-
return false;
|
|
5963
|
-
}
|
|
5964
|
-
if (u.protocol === "https:") return true;
|
|
5965
|
-
if (u.protocol === "http:" && LOCALHOST_HOSTS.has(u.hostname)) return true;
|
|
5966
|
-
return false;
|
|
5967
|
-
}
|
|
5968
|
-
function manifestMode(m2) {
|
|
5969
|
-
return m2.entry?.url ? "hosted" : "local";
|
|
5970
|
-
}
|
|
5971
|
-
function ownerNamespace(ownerPrincipalId) {
|
|
5972
|
-
let h = 2166136261;
|
|
5973
|
-
for (let i = 0; i < ownerPrincipalId.length; i++) {
|
|
5974
|
-
h ^= ownerPrincipalId.charCodeAt(i);
|
|
5975
|
-
h = Math.imul(h, 16777619) >>> 0;
|
|
5976
|
-
}
|
|
5977
|
-
return (h >>> 0).toString(16).padStart(8, "0");
|
|
5978
|
-
}
|
|
5979
|
-
function namespacedExtId(slug, ownerPrincipalId) {
|
|
5980
|
-
return `${slug}-${ownerNamespace(ownerPrincipalId)}`;
|
|
5981
|
-
}
|
|
5982
|
-
function validateSimpleSemver(v2) {
|
|
5983
|
-
if (typeof v2 !== "string") {
|
|
5984
|
-
return { ok: false, reason: "version must be a string" };
|
|
5985
|
-
}
|
|
5986
|
-
const parts = v2.split(".");
|
|
5987
|
-
if (parts.length !== 3) {
|
|
5988
|
-
return { ok: false, reason: `"${v2}" \u2014 only MAJOR.MINOR.PATCH allowed` };
|
|
5989
|
-
}
|
|
5990
|
-
for (const p2 of parts) {
|
|
5991
|
-
if (!/^\d+$/.test(p2)) {
|
|
5992
|
-
return { ok: false, reason: `"${v2}" \u2014 only numeric segments allowed` };
|
|
5993
|
-
}
|
|
5994
|
-
}
|
|
5995
|
-
return { ok: true };
|
|
5996
|
-
}
|
|
5997
|
-
function compareSimpleSemver(a, b2) {
|
|
5998
|
-
const pa = parseOrThrow(a);
|
|
5999
|
-
const pb = parseOrThrow(b2);
|
|
6000
|
-
for (let i = 0; i < 3; i++) {
|
|
6001
|
-
if (pa[i] < pb[i]) return -1;
|
|
6002
|
-
if (pa[i] > pb[i]) return 1;
|
|
6003
|
-
}
|
|
6004
|
-
return 0;
|
|
6005
|
-
}
|
|
6006
|
-
function parseOrThrow(v2) {
|
|
6007
|
-
const r = validateSimpleSemver(v2);
|
|
6008
|
-
if (!r.ok) throw new Error(r.reason);
|
|
6009
|
-
const [a, b2, c] = v2.split(".").map((p2) => parseInt(p2, 10));
|
|
6010
|
-
return [a, b2, c];
|
|
6011
|
-
}
|
|
6012
|
-
var EXT_ID_REGEX, ExtensionStateSchema, LOCALHOST_HOSTS, ExtensionManifestSchema, ExtensionTargetSchema, ExtensionRecordSchema, PublishedSnapshotSchema, ChannelRefSchema, SourceRefSchema, PublishedExtensionRecordSchema, PublishCheckSchema, PublishStatusResultSchema;
|
|
6013
|
-
var init_extension = __esm({
|
|
6014
|
-
"../protocol/src/extension.ts"() {
|
|
6015
|
-
"use strict";
|
|
6016
|
-
init_zod();
|
|
6017
|
-
EXT_ID_REGEX = /^[a-z0-9][a-z0-9-]*$/;
|
|
6018
|
-
ExtensionStateSchema = external_exports.enum([
|
|
6019
|
-
"stopped",
|
|
6020
|
-
"starting",
|
|
6021
|
-
"running",
|
|
6022
|
-
"crashed",
|
|
6023
|
-
"invalid"
|
|
6024
|
-
]);
|
|
6025
|
-
LOCALHOST_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1"]);
|
|
6026
|
-
ExtensionManifestSchema = external_exports.object({
|
|
6027
|
-
id: external_exports.string().regex(EXT_ID_REGEX),
|
|
6028
|
-
name: external_exports.string().min(1),
|
|
6029
|
-
version: external_exports.string().min(1),
|
|
6030
|
-
apiVersion: external_exports.literal("1"),
|
|
6031
|
-
runtime: external_exports.object({ startCommand: external_exports.string().min(1) }).passthrough().optional(),
|
|
6032
|
-
entry: external_exports.object({
|
|
6033
|
-
url: external_exports.string().url().refine(isAllowedHostedUrl, {
|
|
6034
|
-
message: "INVALID_URL_SCHEME: only https or http://localhost is allowed"
|
|
6035
|
-
})
|
|
6036
|
-
}).strict().optional()
|
|
6037
|
-
}).passthrough().superRefine((m2, ctx) => {
|
|
6038
|
-
const hasRuntime = !!m2.runtime;
|
|
6039
|
-
const hasUrl = !!m2.entry?.url;
|
|
6040
|
-
if (hasRuntime && hasUrl) {
|
|
6041
|
-
ctx.addIssue({
|
|
6042
|
-
code: external_exports.ZodIssueCode.custom,
|
|
6043
|
-
message: "INVALID_MANIFEST: entry.url and runtime cannot coexist"
|
|
6044
|
-
});
|
|
6045
|
-
}
|
|
6046
|
-
if (!hasRuntime && !hasUrl) {
|
|
6047
|
-
ctx.addIssue({
|
|
6048
|
-
code: external_exports.ZodIssueCode.custom,
|
|
6049
|
-
message: "INVALID_MANIFEST: must have either entry.url or runtime"
|
|
6050
|
-
});
|
|
6051
|
-
}
|
|
6052
|
-
});
|
|
6053
|
-
ExtensionTargetSchema = external_exports.discriminatedUnion("kind", [
|
|
6054
|
-
external_exports.object({ kind: external_exports.literal("local"), port: external_exports.number().int().min(1).max(65535) }),
|
|
6055
|
-
external_exports.object({ kind: external_exports.literal("hosted"), url: external_exports.string().url() })
|
|
6056
|
-
]);
|
|
6057
|
-
ExtensionRecordSchema = external_exports.discriminatedUnion("state", [
|
|
6058
|
-
external_exports.object({
|
|
6059
|
-
extId: external_exports.string(),
|
|
6060
|
-
manifest: ExtensionManifestSchema,
|
|
6061
|
-
state: external_exports.literal("stopped")
|
|
6062
|
-
}),
|
|
6063
|
-
external_exports.object({
|
|
6064
|
-
extId: external_exports.string(),
|
|
6065
|
-
manifest: ExtensionManifestSchema,
|
|
6066
|
-
state: external_exports.literal("starting")
|
|
6067
|
-
}),
|
|
6068
|
-
external_exports.object({
|
|
6069
|
-
extId: external_exports.string(),
|
|
6070
|
-
manifest: ExtensionManifestSchema,
|
|
6071
|
-
state: external_exports.literal("running"),
|
|
6072
|
-
target: ExtensionTargetSchema
|
|
6073
|
-
}),
|
|
6074
|
-
external_exports.object({
|
|
6075
|
-
extId: external_exports.string(),
|
|
6076
|
-
manifest: ExtensionManifestSchema,
|
|
6077
|
-
state: external_exports.literal("crashed")
|
|
6078
|
-
}),
|
|
6079
|
-
external_exports.object({
|
|
6080
|
-
extId: external_exports.string(),
|
|
6081
|
-
manifest: external_exports.unknown().nullable(),
|
|
6082
|
-
state: external_exports.literal("invalid"),
|
|
6083
|
-
invalidReason: external_exports.string().min(1)
|
|
6084
|
-
})
|
|
6085
|
-
]);
|
|
6086
|
-
PublishedSnapshotSchema = external_exports.object({
|
|
6087
|
-
snapshotHash: external_exports.string().min(1),
|
|
6088
|
-
version: external_exports.string().min(1),
|
|
6089
|
-
publishedAt: external_exports.number()
|
|
6090
|
-
});
|
|
6091
|
-
ChannelRefSchema = external_exports.discriminatedUnion("kind", [
|
|
6092
|
-
external_exports.object({
|
|
6093
|
-
kind: external_exports.literal("p2p-tunnel"),
|
|
6094
|
-
ownerPrincipalId: external_exports.string().min(1),
|
|
6095
|
-
extId: external_exports.string().min(1)
|
|
6096
|
-
})
|
|
6097
|
-
]);
|
|
6098
|
-
SourceRefSchema = external_exports.discriminatedUnion("kind", [
|
|
6099
|
-
external_exports.object({
|
|
6100
|
-
kind: external_exports.literal("p2p-tunnel"),
|
|
6101
|
-
ownerPrincipalId: external_exports.string().min(1),
|
|
6102
|
-
extId: external_exports.string().min(1),
|
|
6103
|
-
snapshotHash: external_exports.string().min(1)
|
|
6104
|
-
})
|
|
6105
|
-
]);
|
|
6106
|
-
PublishedExtensionRecordSchema = external_exports.object({
|
|
6107
|
-
extId: external_exports.string().min(1),
|
|
6108
|
-
name: external_exports.string().min(1),
|
|
6109
|
-
version: external_exports.string().min(1),
|
|
6110
|
-
contentHash: external_exports.string().min(1),
|
|
6111
|
-
publishedAt: external_exports.number()
|
|
6044
|
+
sessionId: external_exports.string().min(1),
|
|
6045
|
+
force: external_exports.boolean().optional()
|
|
6046
|
+
}).strict();
|
|
6047
|
+
StartDevServerResultSchema = external_exports.object({
|
|
6048
|
+
project: ProjectMetadataSchema
|
|
6049
|
+
}).strict();
|
|
6050
|
+
ASSISTANT_REPORTABLE_STAGES = [
|
|
6051
|
+
"installing",
|
|
6052
|
+
"failed"
|
|
6053
|
+
];
|
|
6054
|
+
ReportStageArgsSchema = external_exports.object({
|
|
6055
|
+
sessionId: external_exports.string().min(1),
|
|
6056
|
+
stage: external_exports.enum(ASSISTANT_REPORTABLE_STAGES),
|
|
6057
|
+
/** stage='failed' 时必填的原因(一句话),其它 stage optional */
|
|
6058
|
+
reason: external_exports.string().optional()
|
|
6059
|
+
}).strict();
|
|
6060
|
+
ReportStageResultSchema = external_exports.object({
|
|
6061
|
+
ok: external_exports.literal(true)
|
|
6062
|
+
}).strict();
|
|
6063
|
+
StopDevServerArgsSchema = external_exports.object({
|
|
6064
|
+
sessionId: external_exports.string().min(1)
|
|
6065
|
+
}).strict();
|
|
6066
|
+
StopDevServerResultSchema = external_exports.object({
|
|
6067
|
+
ok: external_exports.literal(true)
|
|
6068
|
+
}).strict();
|
|
6069
|
+
AppBuilderProjectUpdatedEventSchema = external_exports.object({
|
|
6070
|
+
type: external_exports.literal("appBuilder:project-updated"),
|
|
6071
|
+
project: ProjectWithStatusSchema,
|
|
6072
|
+
stage: ProjectStageSchema,
|
|
6073
|
+
/** stage='failed' 时的失败原因 */
|
|
6074
|
+
stageReason: external_exports.string().optional()
|
|
6075
|
+
}).strict();
|
|
6076
|
+
PublishArgsSchema = external_exports.object({
|
|
6077
|
+
name: external_exports.string().regex(projectNameRegex)
|
|
6112
6078
|
});
|
|
6113
|
-
|
|
6114
|
-
|
|
6115
|
-
external_exports.
|
|
6116
|
-
|
|
6117
|
-
|
|
6118
|
-
|
|
6119
|
-
}),
|
|
6120
|
-
external_exports.object({
|
|
6121
|
-
kind: external_exports.literal("error-same-hash"),
|
|
6122
|
-
version: external_exports.string().min(1)
|
|
6123
|
-
}),
|
|
6124
|
-
external_exports.object({
|
|
6125
|
-
kind: external_exports.literal("error-version-not-bumped"),
|
|
6126
|
-
localVersion: external_exports.string().min(1),
|
|
6127
|
-
publishedVersion: external_exports.string().min(1)
|
|
6128
|
-
}),
|
|
6129
|
-
external_exports.object({
|
|
6130
|
-
kind: external_exports.literal("error-version-regression"),
|
|
6131
|
-
localVersion: external_exports.string().min(1),
|
|
6132
|
-
publishedVersion: external_exports.string().min(1)
|
|
6133
|
-
})
|
|
6134
|
-
]);
|
|
6135
|
-
PublishStatusResultSchema = external_exports.object({
|
|
6136
|
-
localManifest: external_exports.object({
|
|
6137
|
-
name: external_exports.string().min(1),
|
|
6138
|
-
version: external_exports.string().min(1),
|
|
6139
|
-
contentHash: external_exports.string().min(1)
|
|
6140
|
-
}),
|
|
6141
|
-
publishState: external_exports.discriminatedUnion("kind", [
|
|
6142
|
-
external_exports.object({ kind: external_exports.literal("unpublished") }),
|
|
6143
|
-
external_exports.object({
|
|
6144
|
-
kind: external_exports.literal("published"),
|
|
6145
|
-
version: external_exports.string().min(1),
|
|
6146
|
-
contentHash: external_exports.string().min(1),
|
|
6147
|
-
publishedAt: external_exports.number()
|
|
6148
|
-
})
|
|
6149
|
-
]),
|
|
6150
|
-
check: PublishCheckSchema
|
|
6079
|
+
PublishResultSchema = external_exports.object({
|
|
6080
|
+
jobId: external_exports.string().min(1),
|
|
6081
|
+
status: external_exports.enum(["started", "already-publishing"])
|
|
6082
|
+
}).strict();
|
|
6083
|
+
DismissPublishJobArgsSchema = external_exports.object({
|
|
6084
|
+
name: external_exports.string().regex(projectNameRegex)
|
|
6151
6085
|
});
|
|
6086
|
+
DismissPublishJobResultSchema = external_exports.object({
|
|
6087
|
+
ok: external_exports.literal(true)
|
|
6088
|
+
}).strict();
|
|
6089
|
+
AppBuilderPublishProgressEventSchema = external_exports.object({
|
|
6090
|
+
type: external_exports.literal("appBuilder:publish-progress"),
|
|
6091
|
+
name: external_exports.string().regex(projectNameRegex),
|
|
6092
|
+
jobId: external_exports.string().min(1),
|
|
6093
|
+
stage: external_exports.enum(["build", "deploy", "verify"]),
|
|
6094
|
+
status: external_exports.enum(["started", "completed"])
|
|
6095
|
+
}).strict();
|
|
6096
|
+
AppBuilderPublishFailedEventSchema = external_exports.object({
|
|
6097
|
+
type: external_exports.literal("appBuilder:publish-failed"),
|
|
6098
|
+
name: external_exports.string().regex(projectNameRegex),
|
|
6099
|
+
jobId: external_exports.string().min(1),
|
|
6100
|
+
stage: external_exports.enum(["build", "deploy", "verify", "unknown"]),
|
|
6101
|
+
errorSummary: external_exports.string()
|
|
6102
|
+
}).strict();
|
|
6152
6103
|
}
|
|
6153
6104
|
});
|
|
6154
6105
|
|
|
6155
|
-
// ../protocol/src/
|
|
6156
|
-
|
|
6157
|
-
|
|
6158
|
-
|
|
6106
|
+
// ../protocol/src/methods.ts
|
|
6107
|
+
function methodArgFields(method) {
|
|
6108
|
+
let schema = METHOD_DOCS[method].args;
|
|
6109
|
+
if (!schema) return null;
|
|
6110
|
+
for (let i = 0; i < 5 && schema && !schema.shape; i += 1) {
|
|
6111
|
+
schema = schema._def?.schema;
|
|
6112
|
+
}
|
|
6113
|
+
const shape = schema?.shape;
|
|
6114
|
+
if (!shape) return null;
|
|
6115
|
+
return Object.entries(shape).map(([name, def]) => ({ name, required: !def.isOptional() }));
|
|
6116
|
+
}
|
|
6117
|
+
var NO_ARGS, METHOD_DOCS, METHOD_NAMES, RPC_METHOD_STATUSES, RpcMethodStatusSchema, RpcMethodInfoSchema, MetaMethodsResultSchema;
|
|
6118
|
+
var init_methods = __esm({
|
|
6119
|
+
"../protocol/src/methods.ts"() {
|
|
6159
6120
|
"use strict";
|
|
6160
6121
|
init_zod();
|
|
6161
|
-
|
|
6162
|
-
|
|
6163
|
-
|
|
6164
|
-
|
|
6165
|
-
|
|
6166
|
-
|
|
6167
|
-
|
|
6168
|
-
|
|
6169
|
-
|
|
6170
|
-
|
|
6171
|
-
|
|
6172
|
-
|
|
6173
|
-
|
|
6174
|
-
|
|
6175
|
-
|
|
6176
|
-
|
|
6177
|
-
|
|
6178
|
-
|
|
6179
|
-
|
|
6180
|
-
|
|
6181
|
-
|
|
6182
|
-
|
|
6122
|
+
init_attachment_schemas();
|
|
6123
|
+
init_contact_handshake();
|
|
6124
|
+
init_contact_remote_access();
|
|
6125
|
+
init_contact();
|
|
6126
|
+
init_feishu_auth();
|
|
6127
|
+
init_dispatch();
|
|
6128
|
+
init_extension();
|
|
6129
|
+
init_inbox();
|
|
6130
|
+
init_peer_exec();
|
|
6131
|
+
init_shift_internal();
|
|
6132
|
+
init_persona_schemas();
|
|
6133
|
+
init_schemas();
|
|
6134
|
+
NO_ARGS = external_exports.object({});
|
|
6135
|
+
METHOD_DOCS = {
|
|
6136
|
+
"session:create": {
|
|
6137
|
+
summary: "\u65B0\u5EFA\u4F1A\u8BDD\u5E76\u62C9\u8D77 tool \u8FDB\u7A0B\uFF08claude / codex\uFF09\u3002**cwd \u4E0E ownerPersonaId \u81F3\u5C11\u4F20\u4E00\u4E2A**\uFF08\u5E26 ownerPersonaId \u65F6 cwd \u7531 daemon \u6D3E\u751F\uFF09\u2014\u2014\u8FD9\u6761\u4E92\u65A5\u7EA6\u675F\u662F schema \u7684 refine\uFF0C\u53CD\u5C04\u4E0D\u51FA\u6765",
|
|
6138
|
+
args: SessionCreateArgs
|
|
6139
|
+
},
|
|
6140
|
+
"session:list": {
|
|
6141
|
+
summary: "\u5217\u51FA\u5F53\u524D\u8EAB\u4EFD\u53EF\u89C1\u7684\u4F1A\u8BDD\uFF08owner \u5168\u91CF\uFF1Bguest \u9650\u88AB\u6388\u6743 persona\uFF09",
|
|
6142
|
+
args: SessionListArgs
|
|
6143
|
+
},
|
|
6144
|
+
"session:get": {
|
|
6145
|
+
summary: "\u53D6\u5355\u4E2A\u4F1A\u8BDD\u7684\u5B8C\u6574 SessionFile\uFF08\u5143\u6570\u636E + \u72B6\u6001\uFF09",
|
|
6146
|
+
args: SessionIdArgs
|
|
6147
|
+
},
|
|
6148
|
+
"session:update": {
|
|
6149
|
+
summary: "\u6539\u4F1A\u8BDD\u5143\u6570\u636E\uFF0C\u4E0D\u5F71\u54CD\u8FDB\u7A0B\u3002patch \u5141\u8BB8\u7684\u952E\uFF1Alabel / model / permissionMode / effort / cwd / iconKey\u2014\u2014**\u4F20\u522B\u7684\u952E\u4F1A\u88AB\u9759\u9ED8\u4E22\u5F03**\uFF08zod strip\uFF09\uFF0Chandler \u7167\u6837\u8FD4 ok",
|
|
6150
|
+
args: SessionUpdateArgs
|
|
6151
|
+
},
|
|
6152
|
+
"session:delete": {
|
|
6153
|
+
summary: "\u5220\u4F1A\u8BDD\uFF1A\u505C\u8FDB\u7A0B + \u5220 SessionFile\uFF0C\u5E76\u8054\u52A8\u6E05\u7406\u7ED1\u5B9A\u7684 app-builder project",
|
|
6154
|
+
args: SessionIdArgs
|
|
6155
|
+
},
|
|
6156
|
+
"session:send": {
|
|
6157
|
+
summary: "\u5411\u4F1A\u8BDD\u53D1\u4E00\u6761\u7528\u6237\u6D88\u606F\uFF08\u89E6\u53D1\u65B0\u4E00\u8F6E turn\uFF09",
|
|
6158
|
+
args: SessionSendArgs
|
|
6159
|
+
},
|
|
6160
|
+
"session:currentTurnSender": {
|
|
6161
|
+
summary: "\u67E5\u5F53\u524D turn \u7684\u9A71\u52A8\u8005\uFF08owner / guest \u7684 SenderInfo\uFF09\u3002\u7701\u7565 sessionId \u6216\u4F20\u7A7A\u4E32 \u2192 \u76F4\u63A5\u8FD4 sender:null\uFF0C\u4E0D\u62A5\u9519",
|
|
6162
|
+
args: SessionCurrentTurnSenderArgs
|
|
6163
|
+
},
|
|
6164
|
+
"session:stop": {
|
|
6165
|
+
summary: "\u505C\u6389\u4F1A\u8BDD\u7684 tool \u8FDB\u7A0B\uFF08\u6740\u8FDB\u7A0B\uFF0C\u4F1A\u8BDD\u672C\u8EAB\u4FDD\u7559\uFF09",
|
|
6166
|
+
args: SessionIdArgs
|
|
6167
|
+
},
|
|
6168
|
+
"session:interrupt": {
|
|
6169
|
+
summary: "\u6E29\u67D4\u4E2D\u65AD\u5F53\u524D\u8F6E\u6B21\uFF0C\u4E0D\u6740\u8FDB\u7A0B\uFF08\u8D70 CC IPC control_request.subtype=interrupt\uFF09",
|
|
6170
|
+
args: SessionInterruptArgs
|
|
6171
|
+
},
|
|
6172
|
+
"session:rewind": {
|
|
6173
|
+
summary: "\u56DE\u6EDA\u5230\u6307\u5B9A user message\uFF0C\u5E76\u64A4\u9500\u5176\u540E CC \u505A\u7684\u6587\u4EF6\u7F16\u8F91",
|
|
6174
|
+
args: SessionRewindArgs
|
|
6175
|
+
},
|
|
6176
|
+
"session:rewind-diff": {
|
|
6177
|
+
summary: "\u56DE\u6EDA\u9884\u89C8\uFF1A\u8BFB ~/.claude/file-history \u5FEB\u7167 + \u78C1\u76D8\u73B0\u72B6\u7B97\u771F\u5B9E diff\uFF0C\u4E0D\u4F9D\u8D56 CC \u8FDB\u7A0B",
|
|
6178
|
+
args: SessionRewindDiffArgs
|
|
6179
|
+
},
|
|
6180
|
+
"session:rewindable-message-ids": {
|
|
6181
|
+
summary: "\u4E00\u6B21\u6027\u62FF\u5230\u300C\u6709\u771F\u5B9E diff\u300D\u7684 user message id \u96C6\u5408\uFF0CUI \u636E\u6B64\u51B3\u5B9A\u54EA\u4E9B\u6D88\u606F\u663E\u793A\u56DE\u6EDA\u6309\u94AE",
|
|
6182
|
+
args: SessionRewindableMessageIdsArgs
|
|
6183
|
+
},
|
|
6184
|
+
"session:fork": {
|
|
6185
|
+
summary: "\u4ECE\u6307\u5B9A message \u5904 fork \u51FA\u65B0 transcript\uFF08\u622A\u65AD + \u91CD\u5199 sessionId/parentUuid\uFF09\uFF0C\u8FD4\u56DE\u65B0 toolSessionId\uFF1B\u4E0D\u81EA\u52A8\u62C9\u8D77\u8FDB\u7A0B",
|
|
6186
|
+
args: SessionForkArgs
|
|
6187
|
+
},
|
|
6188
|
+
"session:new": {
|
|
6189
|
+
summary: "\u5728**\u5DF2\u6709**\u4F1A\u8BDD\u4E0A\u6E05\u7A7A\u4E0A\u4E0B\u6587\u5F00\u65B0\u4E00\u8F6E\uFF0C\u76F8\u5F53\u4E8E CC \u7684 /clear\uFF08\u4E0D\u662F\u5EFA\u65B0\u4F1A\u8BDD\u2014\u2014\u5EFA\u65B0\u4F1A\u8BDD\u7528 session:create\uFF09",
|
|
6190
|
+
args: SessionIdArgs
|
|
6191
|
+
},
|
|
6192
|
+
"session:resume": {
|
|
6193
|
+
summary: "\u628A\u4F1A\u8BDD\u6062\u590D\u5230\u6307\u5B9A\u7684 tool \u4F1A\u8BDD\uFF08CC transcript\uFF09\u4E0A\u7EE7\u7EED",
|
|
6194
|
+
args: SessionResumeArgs
|
|
6195
|
+
},
|
|
6196
|
+
"session:observe": {
|
|
6197
|
+
summary: "\u6302 observer \u76D1\u542C\u8BE5\u4F1A\u8BDD\u7684 CC jsonl\uFF0C\u628A daemon \u4E4B\u5916\u542F\u52A8\u7684 CC \u6D3B\u52A8\u56DE\u704C\u8FDB\u6765\uFF08\u591A\u7AEF\u5171\u4EAB / \u63A5\u7BA1\u5916\u90E8\u4F1A\u8BDD\uFF09\u3002\u4EC5 claude \u652F\u6301",
|
|
6198
|
+
args: SessionObserveArgs
|
|
6199
|
+
},
|
|
6200
|
+
"session:events": {
|
|
6201
|
+
summary: "\u62C9\u53D6\u4F1A\u8BDD\u7684\u5386\u53F2\u4E8B\u4EF6\uFF08\u6309 seq \u589E\u91CF\uFF09\uFF0C\u7528\u4E8E\u65AD\u7EBF\u91CD\u8FDE\u8865\u5E27",
|
|
6202
|
+
args: SessionEventsArgs
|
|
6203
|
+
},
|
|
6204
|
+
"session:subscribe": {
|
|
6205
|
+
summary: "\u8BA2\u9605\u8BE5\u4F1A\u8BDD\u7684 push \u5E27\uFF08\u672C\u8FDE\u63A5\u751F\u6548\uFF0CrefCount \u8BA1\u6570\uFF09\u3002**\u7701\u7565 sessionId = \u4E0D\u5EFA\u7ACB\u4EFB\u4F55\u8BA2\u9605**\uFF0C\u4F46\u7167\u6837\u8FD4 subscribed \u2014\u2014 \u4E0D\u662F\u300C\u8BA2\u9605\u5168\u90E8\u300D",
|
|
6206
|
+
args: SessionSubscribeArgs
|
|
6207
|
+
},
|
|
6208
|
+
"session:unsubscribe": {
|
|
6209
|
+
summary: "\u53D6\u6D88\u8BA2\u9605\u8BE5\u4F1A\u8BDD\u7684 push \u5E27\u3002\u7701\u7565 sessionId \u65F6\u4E0D\u53D6\u6D88\u4EFB\u4F55\u8BA2\u9605\uFF0C\u7167\u6837\u8FD4 ok",
|
|
6210
|
+
args: SessionSubscribeArgs
|
|
6211
|
+
},
|
|
6212
|
+
"session:pin": {
|
|
6213
|
+
summary: "\u7F6E\u9876 / \u53D6\u6D88\u7F6E\u9876\u4F1A\u8BDD",
|
|
6214
|
+
args: SessionPinArgs
|
|
6215
|
+
},
|
|
6216
|
+
"session:markRead": {
|
|
6217
|
+
summary: "\u6E05\u6389\u4F1A\u8BDD\u7684\u5171\u4EAB\u672A\u8BFB\u6807\u8BB0\u5E76\u5E7F\u64AD session:info\uFF1B\u5E42\u7B49",
|
|
6218
|
+
args: SessionIdArgs
|
|
6219
|
+
},
|
|
6220
|
+
"session:reorderPins": {
|
|
6221
|
+
summary: "\u6574\u4F53\u91CD\u5199\u6240\u6709\u7F6E\u9876\u4F1A\u8BDD\u7684\u6392\u5E8F\uFF08sidebar \u62D6\u62FD\u5B8C\u6210\u65F6\u8C03\uFF09",
|
|
6222
|
+
args: SessionReorderPinsArgs
|
|
6223
|
+
},
|
|
6224
|
+
"peerSession:upsert": {
|
|
6225
|
+
summary: "\u5199\u5165 / \u66F4\u65B0\u4E00\u6761 mirror SessionFile \u2014\u2014 \u300C\u6211\u5728\u670B\u53CB daemon \u4E0A\u521B\u5EFA\u7684\u4F1A\u8BDD\u300D\u5728\u672C\u673A\u7684\u526F\u672C\uFF0C\u4EC5\u4F9B sidebar \u8DE8\u8BBE\u5907\u805A\u5408\uFF1Bdaemon \u53EA dumb \u5199\uFF0C\u4E0D\u5E7F\u64AD\u4EFB\u4F55 push \u5E27",
|
|
6226
|
+
args: PeerSessionUpsertArgs
|
|
6227
|
+
},
|
|
6228
|
+
"peerSession:remove": {
|
|
6229
|
+
summary: "\u5220\u9664\u4E00\u6761 mirror SessionFile\uFF08\u540C\u6837\u4E0D\u5E7F\u64AD\uFF09",
|
|
6230
|
+
args: PeerSessionRemoveArgs
|
|
6231
|
+
},
|
|
6232
|
+
"permission:respond": {
|
|
6233
|
+
summary: "\u56DE\u5E94 CC \u7684\u6743\u9650\u8BF7\u6C42\uFF08\u5141\u8BB8 / \u62D2\u7EDD / \u8BB0\u4F4F\u89C4\u5219\uFF09",
|
|
6234
|
+
args: PermissionRespondArgs
|
|
6235
|
+
},
|
|
6236
|
+
"session:answerQuestion": {
|
|
6237
|
+
summary: "\u56DE\u586B AskUserQuestion \u8868\u5355\u7B54\u6848\uFF0Cdaemon \u5408\u5E76\u8FDB updated_input \u5199 control_response \u7ED9 CC",
|
|
6238
|
+
args: AnswerQuestionArgs
|
|
6239
|
+
},
|
|
6240
|
+
"session:cancelQuestion": {
|
|
6241
|
+
summary: "\u7528\u6237\u8DF3\u8FC7 AskUserQuestion\uFF1Adaemon \u56DE allow + \u7A7A\u7B54\u6848\u8BA9 tool \u8D70\u7A7A\u8DEF\u5F84\uFF0C\u5E76\u5E7F\u64AD cleared \u5E27",
|
|
6242
|
+
args: CancelQuestionArgs
|
|
6243
|
+
},
|
|
6244
|
+
"history:projects": {
|
|
6245
|
+
summary: "\u5217\u51FA CC \u5386\u53F2\u91CC\u7684\u5168\u90E8\u9879\u76EE\uFF08\u6309 projectPath \u805A\u5408\uFF09\uFF1Bguest \u53EA\u770B\u5230\u81EA\u5DF1\u88AB\u6388\u6743 persona \u5B50\u6811\u4E0B\u7684",
|
|
6246
|
+
args: NO_ARGS
|
|
6247
|
+
},
|
|
6248
|
+
"history:list": {
|
|
6249
|
+
summary: "\u5217\u51FA\u67D0\u4E2A\u9879\u76EE\u4E0B\u7684\u5386\u53F2\u4F1A\u8BDD",
|
|
6250
|
+
args: HistoryListArgs
|
|
6251
|
+
},
|
|
6252
|
+
"history:read": {
|
|
6253
|
+
summary: "\u8BFB\u4E00\u6761\u5386\u53F2\u4F1A\u8BDD\u7684\u5B8C\u6574\u6D88\u606F\uFF08\u89E3\u6790 CC jsonl\uFF09",
|
|
6254
|
+
args: HistoryReadArgs
|
|
6255
|
+
},
|
|
6256
|
+
"history:subagents": {
|
|
6257
|
+
summary: "\u5217\u51FA\u67D0\u6B21\u4F1A\u8BDD\u91CC\u7684 subagent \u8FD0\u884C\u8BB0\u5F55",
|
|
6258
|
+
args: HistorySubagentsArgs
|
|
6259
|
+
},
|
|
6260
|
+
"history:subagent-read": {
|
|
6261
|
+
summary: "\u8BFB\u4E00\u6761 subagent \u7684\u5B8C\u6574\u8BB0\u5F55",
|
|
6262
|
+
args: HistorySubagentReadArgs
|
|
6263
|
+
},
|
|
6264
|
+
"history:recentDirs": {
|
|
6265
|
+
summary: "\u6700\u8FD1\u7528\u8FC7\u7684\u5DE5\u4F5C\u76EE\u5F55\u5217\u8868\uFF08\u6309 cwd \u53BB\u91CD\u3001\u53D6\u6700\u65B0 updatedAt\uFF09\u3002\u65E0\u53C2\u6570",
|
|
6266
|
+
args: NO_ARGS
|
|
6267
|
+
},
|
|
6268
|
+
"workspace:list": {
|
|
6269
|
+
summary: "\u5217\u76EE\u5F55\u5185\u5BB9\uFF08\u6587\u4EF6\u6D4F\u89C8\uFF09\uFF1Bguest \u88AB\u9650\u5236\u5728\u88AB\u6388\u6743 persona \u5B50\u6811\u5185",
|
|
6270
|
+
args: WorkspaceListArgs
|
|
6271
|
+
},
|
|
6272
|
+
"workspace:read": {
|
|
6273
|
+
summary: "\u8BFB\u6587\u4EF6\u5185\u5BB9\uFF1Bguest \u8DEF\u5F84\u8FB9\u754C\u4E0E workspace:list \u540C",
|
|
6274
|
+
args: WorkspaceReadArgs
|
|
6275
|
+
},
|
|
6276
|
+
"shift:list": {
|
|
6277
|
+
summary: "\u5217\u51FA owner \u7684\u5168\u90E8 shift\uFF08\u6392\u73ED\uFF09\uFF0C\u7ED9 UI \u65E5\u5386\u6E32\u67D3\u7528\uFF1Bowner-only",
|
|
6278
|
+
args: NO_ARGS
|
|
6279
|
+
},
|
|
6280
|
+
"shift-internal:add": {
|
|
6281
|
+
summary: "\u6392\u4E00\u4E2A shift\uFF08\u5230\u70B9\u81EA\u52A8\u62C9\u8D77 persona \u5E72\u6D3B\uFF09\u3002\u7701\u7565 targetPersona = \u6D3E\u7ED9\u8C03\u7528\u65B9\u81EA\u5DF1",
|
|
6282
|
+
args: ShiftInternalAddArgs
|
|
6283
|
+
},
|
|
6284
|
+
"shift-internal:list": {
|
|
6285
|
+
summary: "\u5217 shift\u3002\u7701\u7565 onlyMine \u9ED8\u8BA4 true \u2014\u2014 \u53EA\u5217\u672C persona \u5EFA\u7684",
|
|
6286
|
+
args: ShiftInternalListArgs
|
|
6287
|
+
},
|
|
6288
|
+
"shift-internal:cancel": {
|
|
6289
|
+
summary: "\u53D6\u6D88 shift\uFF08\u4EC5\u521B\u5EFA\u5B83\u7684 persona \u53EF\u64CD\u4F5C\uFF09",
|
|
6290
|
+
args: ShiftInternalCancelArgs
|
|
6291
|
+
},
|
|
6292
|
+
"shift-internal:update": {
|
|
6293
|
+
summary: "\u4FEE\u6539 shift \u5B57\u6BB5\uFF08\u4EC5\u521B\u5EFA\u8005\uFF09\u3002patch \u5141\u8BB8\u7684\u952E\uFF1Aname / schedule / prompt / targetPersona / timeoutMs / enabled\uFF1Bschedule \u53D8\u4E86 store \u81EA\u52A8\u91CD\u7B97 nextRunAtMs",
|
|
6294
|
+
args: ShiftInternalUpdateArgs
|
|
6295
|
+
},
|
|
6296
|
+
"shift-internal:history": {
|
|
6297
|
+
summary: "\u67E5 shift \u7684\u6267\u884C\u5386\u53F2\uFF08\u4EC5\u521B\u5EFA\u8005\uFF09",
|
|
6298
|
+
args: ShiftInternalHistoryArgs
|
|
6299
|
+
},
|
|
6300
|
+
"skills:list": {
|
|
6301
|
+
summary: "\u626B\u63CF\u5E76\u5217\u51FA\u8BE5\u76EE\u5F55\u53EF\u7528\u7684 skill",
|
|
6302
|
+
args: SkillsListArgs
|
|
6303
|
+
},
|
|
6304
|
+
"agents:list": {
|
|
6305
|
+
summary: "\u626B\u63CF\u5E76\u5217\u51FA\u8BE5\u76EE\u5F55\u53EF\u7528\u7684 subagent \u5B9A\u4E49",
|
|
6306
|
+
args: AgentsListArgs
|
|
6307
|
+
},
|
|
6308
|
+
"git:root": {
|
|
6309
|
+
summary: "\u53D6\u8BE5\u8DEF\u5F84\u6240\u5C5E git \u4ED3\u5E93\u7684\u6839\u76EE\u5F55\uFF08\u4E0D\u5728\u4ED3\u5E93\u91CC\u8FD4 null\uFF09",
|
|
6310
|
+
args: GitRootArgs
|
|
6311
|
+
},
|
|
6312
|
+
"git:branch": {
|
|
6313
|
+
summary: "\u53D6\u5F53\u524D\u5206\u652F\u540D",
|
|
6314
|
+
args: GitBranchArgs
|
|
6315
|
+
},
|
|
6316
|
+
"git:branches": {
|
|
6317
|
+
summary: "\u5217\u51FA\u672C\u5730\u5206\u652F",
|
|
6318
|
+
args: GitBranchesArgs
|
|
6319
|
+
},
|
|
6320
|
+
"capabilities:get": {
|
|
6321
|
+
summary: "\u53D6\u67D0\u4E2A tool \u7684\u80FD\u529B\u96C6\uFF1A\u53EF\u7528\u6A21\u578B\u5217\u8868 / permissionModes / configSchema",
|
|
6322
|
+
args: CapabilitiesGetArgs
|
|
6323
|
+
},
|
|
6324
|
+
"persona:create": {
|
|
6325
|
+
summary: "\u65B0\u5EFA persona\uFF08\u5199 PersonaFile + CLAUDE.md \u9AA8\u67B6\uFF09\u3002owner-only",
|
|
6326
|
+
args: PersonaCreateArgsSchema
|
|
6327
|
+
},
|
|
6328
|
+
"persona:list": {
|
|
6329
|
+
summary: "\u5217\u51FA persona \u5143\u6570\u636E\uFF08\u4E0D\u542B CLAUDE.md \u6B63\u6587\uFF09\u3002owner \u8FD4\u5168\u91CF\u542B private\uFF1Bguest \u53EA\u8FD4 public \u4E14\u88AB\u6388\u6743\u7684",
|
|
6330
|
+
args: NO_ARGS
|
|
6331
|
+
},
|
|
6332
|
+
"persona:get": {
|
|
6333
|
+
summary: "\u53D6\u5355\u4E2A persona \u8BE6\u60C5\uFF0C**\u542B personality\uFF08CLAUDE.md \u6B63\u6587\uFF09**\u2014\u2014\u552F\u4E00\u643A\u5E26\u6B63\u6587\u7684 method",
|
|
6334
|
+
args: PersonaIdArgsSchema
|
|
6335
|
+
},
|
|
6336
|
+
"persona:update": {
|
|
6337
|
+
summary: "\u6539 persona\uFF08label / model / public / CLAUDE.md \u7B49\uFF09\u3002owner-only",
|
|
6338
|
+
args: PersonaUpdateArgsSchema
|
|
6339
|
+
},
|
|
6340
|
+
"persona:delete": {
|
|
6341
|
+
summary: "\u5220 persona\u3002owner-only",
|
|
6342
|
+
args: PersonaIdArgsSchema
|
|
6343
|
+
},
|
|
6344
|
+
"personaDispatch:run": {
|
|
6345
|
+
summary: "\u628A\u4EFB\u52A1\u59D4\u6D3E\u7ED9\u53E6\u4E00\u4E2A persona\uFF08\u53EF\u8DE8\u8BBE\u5907\uFF09\uFF0C\u5F02\u6B65\u79D2\u56DE { dispatchId }\u3002targetPersona \u4E0E dispatchId **\u81F3\u5C11\u7ED9\u4E00\u4E2A**\uFF08\u524D\u8005\u65B0\u5F00\u3001\u540E\u8005\u7EED\u6D3E\uFF09\uFF1BdispatchId \u4E0E targetDeviceId **\u4E92\u65A5**",
|
|
6346
|
+
args: DispatchRunArgsSchema
|
|
6347
|
+
},
|
|
6348
|
+
"personaDispatch:complete": {
|
|
6349
|
+
summary: '\u88AB\u59D4\u6D3E\u65B9\u56DE\u62A5\u7ED3\u679C\uFF1A\u5199\u53F0\u8D26\u5E76\u628A\u7ED3\u679C\u6295\u9012\u56DE\u53D1\u8D77\u65B9\u4F1A\u8BDD\u3002outcome \u662F { kind:"success", text, filePaths? } \u6216 { kind:"failure", reason } \u4E8C\u9009\u4E00',
|
|
6350
|
+
args: DispatchCompleteArgsSchema
|
|
6351
|
+
},
|
|
6352
|
+
"personaDispatch:list": {
|
|
6353
|
+
summary: "\u67E5 dispatch \u53F0\u8D26\uFF08\u72B6\u6001 / \u7ED3\u679C / \u65F6\u95F4\u6233\uFF09\u3002\u7701\u7565 sourceSessionId = \u8FD4\u5168\u91CF",
|
|
6354
|
+
args: DispatchListArgsSchema
|
|
6355
|
+
},
|
|
6356
|
+
"personaDispatch:get": {
|
|
6357
|
+
summary: "\u67E5\u5355\u6761 dispatch \u53F0\u8D26\u7EC8\u6001\uFF1B\u8DE8\u8BBE\u5907\u65F6 A \u7AEF\u51ED connect token \u8F6E\u8BE2 B \u7AEF\u7528",
|
|
6358
|
+
args: DispatchGetArgsSchema
|
|
6359
|
+
},
|
|
6360
|
+
"peerExec:run": {
|
|
6361
|
+
summary: "\u5728\u8054\u7CFB\u4EBA\u8BBE\u5907\u4E0A\u8DD1\u4E00\u6761 bash \u547D\u4EE4\uFF08\u4E00\u53D1\u4E00\u6536\uFF0C\u65E0\u8DE8\u547D\u4EE4\u4F1A\u8BDD\u72B6\u6001\uFF09\u3002**\u672C\u673A\u53D1\u8D77\u5FC5\u586B peerDeviceId**\u2014\u2014\u7701\u7565\u4EC5\u7528\u4E8E\u5BF9\u7AEF guest \u53CD\u5411\u5165\u53E3\uFF0Cowner ctx \u7701\u7565\u4F1A\u88AB\u62D2\uFF1B\u9700\u5BF9\u65B9\u5F00\u4E86 remoteAccess",
|
|
6362
|
+
args: PeerExecRunArgsSchema
|
|
6363
|
+
},
|
|
6364
|
+
"session:pty:input": {
|
|
6365
|
+
summary: "\u628A\u7528\u6237\u952E\u76D8\u5B57\u8282\u5199\u8FDB pty stdin\uFF08\u4EC5 CLAWD_CC_MODE=tui\uFF09\u3002\u9AD8\u9891\u5E27\uFF0C\u4E0D\u5165 reducer\u3002body: { sessionId, data\uFF08base64-utf8\uFF09 }"
|
|
6366
|
+
},
|
|
6367
|
+
"session:pty:resize": {
|
|
6368
|
+
summary: "\u540C\u6B65\u7EC8\u7AEF\u5C3A\u5BF8\u7ED9 pty\uFF08\u4EC5 tui \u6A21\u5F0F\uFF09\u3002body: { sessionId, cols, rows }"
|
|
6369
|
+
},
|
|
6370
|
+
"session:pty:snapshot": {
|
|
6371
|
+
summary: "\u62C9\u5F53\u524D pty \u5C4F\u5E55\u5168\u91CF\u5FEB\u7167\uFF08\u5207\u56DE\u4F1A\u8BDD / \u5237\u65B0\u65F6\u7528\uFF09\uFF0C\u8FD4\u56DE { data, atSeq, popupKind }\uFF1B\u975E tui \u6216\u5DF2\u9000\u51FA\u65F6 data=null\u3002body: { sessionId }"
|
|
6372
|
+
},
|
|
6373
|
+
"attachment.signUrl": {
|
|
6374
|
+
summary: "\u7ED9\u5DF2\u5165\u7FA4\u7684\u6587\u4EF6\u7B7E\u53D1 HMAC \u4E0B\u8F7D URL\uFF08\u8DE8\u8BBE\u5907\u53EF\u76F4\u63A5\u6253\u5F00\uFF09",
|
|
6375
|
+
args: AttachmentSignUrlArgs
|
|
6376
|
+
},
|
|
6377
|
+
"attachment.groupAdd": {
|
|
6378
|
+
summary: "\u628A\u6587\u4EF6\u767B\u8BB0\u8FDB\u672C\u4F1A\u8BDD\u7684\u5171\u4EAB\u6E05\u5355\uFF08\u7B7E URL \u524D\u5FC5\u987B\u5148\u5165\u7FA4\uFF09",
|
|
6379
|
+
args: AttachmentGroupAddArgs
|
|
6380
|
+
},
|
|
6381
|
+
"attachment.groupRemove": {
|
|
6382
|
+
summary: "\u628A\u6587\u4EF6\u79FB\u51FA\u5171\u4EAB\u6E05\u5355",
|
|
6383
|
+
args: AttachmentGroupRemoveArgs
|
|
6384
|
+
},
|
|
6385
|
+
"attachment.groupList": {
|
|
6386
|
+
summary: "\u5217\u51FA\u672C\u4F1A\u8BDD\u5171\u4EAB\u6E05\u5355\u91CC\u7684\u6587\u4EF6",
|
|
6387
|
+
args: AttachmentGroupListArgs
|
|
6388
|
+
},
|
|
6389
|
+
"inbox:list": {
|
|
6390
|
+
summary: "\u62C9\u67D0\u4E2A peer \u7684 DM / \u901A\u77E5\u961F\u5217",
|
|
6391
|
+
args: InboxListArgsSchema
|
|
6392
|
+
},
|
|
6393
|
+
"inbox:markRead": {
|
|
6394
|
+
summary: "\u628A\u67D0 peer \u961F\u5217\u6807\u8BB0\u4E3A\u5DF2\u8BFB\u5230\u67D0\u65F6\u95F4\u70B9",
|
|
6395
|
+
args: InboxMarkReadArgsSchema
|
|
6396
|
+
},
|
|
6397
|
+
"inbox:postMessage": {
|
|
6398
|
+
summary: "\u6295\u9012\u4E00\u6761 P2P IM \u6D88\u606F\uFF08\u53CC\u6295\uFF1A\u672C\u673A\u843D\u5E93 + \u8F6C\u53D1\u5BF9\u7AEF\uFF09\u3002**owner \u8C03\u7528\u5FC5\u586B peerDeviceId**\uFF0C\u4EC5 guest \u53EF\u7701\uFF08\u4ECE ctx \u63A8\uFF09",
|
|
6399
|
+
args: InboxPostMessageArgsSchema
|
|
6400
|
+
},
|
|
6401
|
+
"inbox:sendDm": {
|
|
6402
|
+
summary: "\u4EE5\u5F53\u524D\u4F1A\u8BDD\u7684\u8EAB\u4EFD\u53D1\u4E00\u6761 DM\uFF08\u53D1\u4FE1\u4EBA\u7531 session scope \u5F52\u56E0\uFF0C\u4E0D\u53EF\u4F2A\u9020\uFF09\u3002**owner \u9A71\u52A8\u7684\u4F1A\u8BDD\u5FC5\u586B peerDeviceId**\uFF0Cguest \u9A71\u52A8\u7684\u53EF\u7701",
|
|
6403
|
+
args: InboxSendDmArgsSchema
|
|
6404
|
+
},
|
|
6405
|
+
"contact:list": {
|
|
6406
|
+
summary: "\u5217\u51FA\u8054\u7CFB\u4EBA\uFF08\u5DF2\u5EFA\u8054\u7684\u8BBE\u5907\uFF09\u3002owner-only",
|
|
6407
|
+
args: NO_ARGS
|
|
6408
|
+
},
|
|
6409
|
+
"contact:pin": {
|
|
6410
|
+
summary: "\u7F6E\u9876 / \u53D6\u6D88\u7F6E\u9876\u8054\u7CFB\u4EBA",
|
|
6411
|
+
args: ContactPinArgsSchema
|
|
6412
|
+
},
|
|
6413
|
+
"contact:remove": {
|
|
6414
|
+
summary: "\u5220\u9664\u8054\u7CFB\u4EBA\u5E76\u6E05\u6389\u5BF9\u5E94\u7684 inbox \u961F\u5217",
|
|
6415
|
+
args: ContactRemoveArgsSchema
|
|
6416
|
+
},
|
|
6417
|
+
"contact:setRemoteAccess": {
|
|
6418
|
+
summary: "\u5F00\u5173\u67D0\u8054\u7CFB\u4EBA\u7684\u8FDC\u7A0B\u8BBF\u95EE\u6388\u6743\uFF08\u63A7\u5236\u5B83\u80FD\u5426\u53CD\u5411 peerExec \u6211\u7684\u8BBE\u5907\uFF09",
|
|
6419
|
+
args: ContactSetRemoteAccessArgsSchema
|
|
6420
|
+
},
|
|
6421
|
+
"contact:handshake": {
|
|
6422
|
+
summary: "\u53CC\u5411\u786E\u8BA4\u5EFA\u8054\u63E1\u624B\uFF1A\u8FDE\u63A5\u65B9\u81EA\u62A5 selfUrl\uFF0C\u88AB\u8FDE\u65B9\u843D\u5E93 + \u5E7F\u64AD\u540E\u56DE\u8EAB\u4EFD\u8F7D\u8377\u3002\u7531 device:connect \u7684\u4E34\u65F6\u8FDE\u63A5\u8C03\u7528",
|
|
6423
|
+
args: ContactHandshakeArgsSchema
|
|
6424
|
+
},
|
|
6425
|
+
"visitor:list": {
|
|
6426
|
+
summary: "\u5217\u51FA\u767B\u5F55\u8BBF\u95EE\u8FC7\u672C\u673A public persona \u7684 web \u8BBF\u5BA2\u3002owner-only",
|
|
6427
|
+
args: NO_ARGS
|
|
6428
|
+
},
|
|
6429
|
+
"whoami": {
|
|
6430
|
+
summary: "\u8FD4\u56DE\u672C\u8FDE\u63A5\u7684\u8EAB\u4EFD\uFF1Aowner \u663E\u793A\u540D + capability wire \u5F62\u6001 + \u88AB\u6388\u6743\u7684 persona \u5217\u8868\u3002\u4EFB\u4F55 authed \u8FDE\u63A5\u53EF\u8C03",
|
|
6431
|
+
args: NO_ARGS
|
|
6432
|
+
},
|
|
6433
|
+
"info": {
|
|
6434
|
+
summary: "daemon \u8FD0\u884C\u65F6\u4FE1\u606F\uFF1A\u7248\u672C / \u534F\u8BAE\u7248\u672C / \u4E3B\u673A / \u53EF\u7528 tool / \u5728\u8DD1\u7684\u4F1A\u8BDD / tunnel URL \u7B49",
|
|
6435
|
+
args: NO_ARGS
|
|
6436
|
+
},
|
|
6437
|
+
"ping": {
|
|
6438
|
+
summary: "\u5B58\u6D3B\u63A2\u6D4B\uFF0C\u56DE pong",
|
|
6439
|
+
args: NO_ARGS
|
|
6440
|
+
},
|
|
6441
|
+
"meta:methods": {
|
|
6442
|
+
summary: "RPC \u81EA\u7701\uFF1A\u8FD4\u56DE METHOD_NAMES \u5168\u96C6 + **\u5BF9\u672C\u8FDE\u63A5**\u7684\u53EF\u8C03\u7528\u6027\u4E09\u6001\uFF08allowed / conditional / denied\uFF09+ \u6BCF\u6761\u7684\u8BF4\u660E\u3002agent \u4FA7 clawd-rpc \u7684 list tool \u662F\u552F\u4E00\u6D88\u8D39\u65B9",
|
|
6443
|
+
args: NO_ARGS
|
|
6444
|
+
},
|
|
6445
|
+
"extension.list": {
|
|
6446
|
+
summary: "\u5217\u51FA\u5DF2\u5B89\u88C5\u7684 extension",
|
|
6447
|
+
args: NO_ARGS
|
|
6448
|
+
},
|
|
6449
|
+
"extension.open": {
|
|
6450
|
+
summary: "\u62C9\u8D77\u67D0\u4E2A extension\uFF08local-spawn \u8D77\u8FDB\u7A0B\u5E76\u7B49 healthz\uFF09",
|
|
6451
|
+
args: ExtensionIdArgs
|
|
6452
|
+
},
|
|
6453
|
+
"extension.close": {
|
|
6454
|
+
summary: "\u5173\u6389\u67D0\u4E2A\u6B63\u5728\u8DD1\u7684 extension",
|
|
6455
|
+
args: ExtensionIdArgs
|
|
6456
|
+
},
|
|
6457
|
+
"extension.uninstall": {
|
|
6458
|
+
summary: "\u5378\u8F7D extension\uFF08\u5220\u5B89\u88C5\u76EE\u5F55\uFF09",
|
|
6459
|
+
args: ExtensionIdArgs
|
|
6460
|
+
},
|
|
6461
|
+
"extension.publish": {
|
|
6462
|
+
summary: "\u628A\u672C\u673A extension \u516C\u5F00\u5230\u5206\u4EAB\u9891\u9053\uFF0C\u4F9B\u8054\u7CFB\u4EBA\u62C9\u53D6\u3002owner-only",
|
|
6463
|
+
args: ExtensionPublishArgs
|
|
6464
|
+
},
|
|
6465
|
+
"extension.unpublish": {
|
|
6466
|
+
summary: "\u64A4\u56DE\u5DF2\u516C\u5F00\u7684 extension\u3002owner-only",
|
|
6467
|
+
args: ExtensionIdArgs
|
|
6468
|
+
},
|
|
6469
|
+
"extension.publish:status": {
|
|
6470
|
+
summary: "\u67E5\u67D0\u4E2A extension \u7684\u516C\u5F00\u72B6\u6001\u3002owner-only",
|
|
6471
|
+
args: ExtensionIdArgs
|
|
6472
|
+
},
|
|
6473
|
+
"extension.list-published": {
|
|
6474
|
+
summary: "\uFF08\u8DE8\u8BBE\u5907\uFF09\u4ECE\u5BF9\u7AEF owner \u62C9\u5B83\u516C\u5F00\u7684 extension \u6E05\u5355",
|
|
6475
|
+
args: NO_ARGS
|
|
6476
|
+
},
|
|
6477
|
+
"extension.fetchBundle": {
|
|
6478
|
+
summary: "\uFF08\u8DE8\u8BBE\u5907\uFF09\u4ECE\u5BF9\u7AEF owner \u4E0B\u8F7D extension bundle \u5B57\u8282\u3002extId \u5FC5\u4F20\u4F46\u4E0D\u53C2\u4E0E\u7D22\u5F15\u2014\u2014\u771F\u6B63\u7684\u952E\u662F snapshotHash\uFF08publish \u90A3\u523B\u51BB\u7ED3\u7684\u90A3\u4EFD\uFF0C\u4E0E owner \u5DE5\u4F5C\u76EE\u5F55\u540E\u7EED\u53D8\u5316\u89E3\u8026\uFF09",
|
|
6479
|
+
args: ExtensionFetchBundleArgs
|
|
6480
|
+
},
|
|
6481
|
+
"extension.install-from-channel": {
|
|
6482
|
+
summary: "\u5728\u81EA\u5DF1 daemon \u4E0A\u4ECE\u5206\u4EAB\u9891\u9053\u5B89\u88C5 extension",
|
|
6483
|
+
args: ExtensionFromChannelArgs
|
|
6484
|
+
},
|
|
6485
|
+
"extension.update-from-channel": {
|
|
6486
|
+
summary: "\u5728\u81EA\u5DF1 daemon \u4E0A\u628A\u5DF2\u88C5 extension \u66F4\u65B0\u5230\u9891\u9053\u6700\u65B0\u7248",
|
|
6487
|
+
args: ExtensionFromChannelArgs
|
|
6488
|
+
},
|
|
6489
|
+
"auth:login:start": {
|
|
6490
|
+
summary: "\u8D77\u98DE\u4E66\u767B\u5F55\u6D41\u7A0B\uFF1A\u751F\u6210 state \u5E76\u8FD4\u56DE\u6388\u6743 URL\uFF0C\u56DE\u8C03\u8D70 HTTP /auth/callback \u843D\u76D8\u3002owner-only",
|
|
6491
|
+
args: NO_ARGS
|
|
6492
|
+
},
|
|
6493
|
+
"auth:getIdentity": {
|
|
6494
|
+
summary: "\u53D6\u672C\u673A owner \u7684\u98DE\u4E66\u8EAB\u4EFD\uFF08ownerId / provider / displayName / unionId\uFF09+ **\u672C\u673A deviceId**\uFF08\u8BBE\u5907\u5C5E\u6027\uFF0C\u4E0E\u767B\u5F55\u6001\u65E0\u5173\uFF1Bdevice:connect / contact:* / inbox:* \u7684\u4E3B\u952E\u90FD\u662F\u5B83\uFF09\uFF1B\u7EDD\u4E0D\u8FD4\u56DE ttcToken",
|
|
6495
|
+
args: NO_ARGS
|
|
6496
|
+
},
|
|
6497
|
+
"auth:logout": {
|
|
6498
|
+
summary: "\u767B\u51FA\u98DE\u4E66\u8EAB\u4EFD\uFF08\u6E05 owner-identity \u843D\u76D8\uFF09\u3002owner-only",
|
|
6499
|
+
args: NO_ARGS
|
|
6500
|
+
},
|
|
6501
|
+
"device:list": {
|
|
6502
|
+
summary: "\u5217\u51FA\u516C\u5171\u8BBE\u5907\u76EE\u5F55\u91CC\u53EF\u8FDE\u63A5\u7684\u8BBE\u5907\uFF08daemon \u4EE3\u7406\u4E2D\u5FC3 server\uFF09\u3002owner-only",
|
|
6503
|
+
args: NO_ARGS
|
|
6504
|
+
},
|
|
6505
|
+
"device:connect": {
|
|
6506
|
+
summary: "\u8FDE\u63A5\u76EE\u6807\u8BBE\u5907\uFF1A\u6362 aud \u7ED1\u5B9A\u7684\u7B7E\u540D token \u5E76\u8D70 contact:handshake \u5EFA\u8054\u3002owner-only",
|
|
6507
|
+
args: DeviceConnectArgsSchema
|
|
6508
|
+
},
|
|
6509
|
+
"appBuilder:listProjects": {
|
|
6510
|
+
summary: "\u5217\u51FA app-builder project\uFF08\u542B dev server \u72B6\u6001\uFF09",
|
|
6511
|
+
args: ListProjectsArgsSchema
|
|
6512
|
+
},
|
|
6513
|
+
"appBuilder:getProject": {
|
|
6514
|
+
summary: "\u6309 sessionId \u53D6\u5355\u4E2A\u7ED1\u5B9A\u7684 project\uFF08\u542B status\uFF09",
|
|
6515
|
+
args: GetProjectArgsSchema
|
|
6516
|
+
},
|
|
6517
|
+
"appBuilder:createProject": {
|
|
6518
|
+
summary: "\u7ED9\u4F1A\u8BDD\u7ED1\u5B9A\u65B0 project\uFF1A\u6821\u9A8C\u540D + \u4ECE 6173-6182 \u6BB5\u5206\u914D\u7AEF\u53E3 + \u5EFA\u76EE\u5F55\u5199\u5143\u6570\u636E",
|
|
6519
|
+
args: CreateProjectArgsSchema
|
|
6520
|
+
},
|
|
6521
|
+
"appBuilder:deleteProject": {
|
|
6522
|
+
summary: "\u505C dev server + \u5220 project \u76EE\u5F55\uFF08\u7ED1\u5B9A\u7684\u4F1A\u8BDD\u4E0D\u5728\u8FD9\u91CC\u5220\uFF09",
|
|
6523
|
+
args: DeleteProjectArgsSchema
|
|
6524
|
+
},
|
|
6525
|
+
"appBuilder:updateProjectPort": {
|
|
6526
|
+
summary: "\u6539 dev server \u7AEF\u53E3\uFF08\u6821\u9A8C\u6BB5\u5185 + \u4E0D\u649E\u8F66\uFF09\u5E76\u91CD\u542F",
|
|
6527
|
+
args: UpdateProjectPortArgsSchema
|
|
6528
|
+
},
|
|
6529
|
+
"appBuilder:setProdUrl": {
|
|
6530
|
+
summary: "\u53D1\u5E03\u4E0A\u7EBF\u540E\u56DE\u586B\u7EBF\u4E0A\u5730\u5740\u5230 .clawd-project.json",
|
|
6531
|
+
args: SetProdUrlArgsSchema
|
|
6532
|
+
},
|
|
6533
|
+
"appBuilder:startDevServer": {
|
|
6534
|
+
summary: "scaffold + \u4F9D\u8D56\u5B89\u88C5\u5B8C\u6210\u540E\u663E\u5F0F\u62C9\u8D77 dev server\uFF08createProject \u4E0D\u518D\u81EA\u52A8\u8D77\uFF09",
|
|
6535
|
+
args: StartDevServerArgsSchema
|
|
6536
|
+
},
|
|
6537
|
+
"appBuilder:reportStage": {
|
|
6538
|
+
summary: "\u4E0A\u62A5\u811A\u624B\u67B6\u9636\u6BB5\uFF08scaffolding / installing / failed \u7B49\uFF09\uFF0Cdaemon \u5E7F\u64AD\u5E27\u8BA9 UI \u5207 PreviewPane",
|
|
6539
|
+
args: ReportStageArgsSchema
|
|
6540
|
+
},
|
|
6541
|
+
"appBuilder:stopDevServer": {
|
|
6542
|
+
summary: "\u6536\u8D77\u9884\u89C8\uFF1A\u505C\u6389 dev server\uFF08\u5BF9\u79F0 startDevServer\uFF09",
|
|
6543
|
+
args: StopDevServerArgsSchema
|
|
6544
|
+
},
|
|
6545
|
+
"appBuilder:publish": {
|
|
6546
|
+
summary: "\u53D1\u5E03\u4E0A\u7EBF\uFF1A\u4E32\u884C\u5316 spawn publish.sh \u5E76\u5E7F\u64AD\u9636\u6BB5\u8FDB\u5EA6\u5E27\uFF1B\u540C project \u5DF2\u6709 in-flight job \u65F6\u8FD4\u56DE already-publishing",
|
|
6547
|
+
args: PublishArgsSchema
|
|
6548
|
+
},
|
|
6549
|
+
"appBuilder:dismissPublishJob": {
|
|
6550
|
+
summary: "\u53D6\u6D88 in-flight publish\uFF08SIGTERM \u5B50\u8FDB\u7A0B\uFF09\u6216\u6E05\u6389 daemon \u5D29\u6E83\u7559\u4E0B\u7684\u6B8B\u9AB8 publishJob \u5B57\u6BB5",
|
|
6551
|
+
args: DismissPublishJobArgsSchema
|
|
6552
|
+
}
|
|
6553
|
+
};
|
|
6554
|
+
METHOD_NAMES = Object.keys(METHOD_DOCS);
|
|
6555
|
+
RPC_METHOD_STATUSES = ["allowed", "conditional", "denied"];
|
|
6556
|
+
RpcMethodStatusSchema = external_exports.enum(RPC_METHOD_STATUSES);
|
|
6557
|
+
RpcMethodInfoSchema = external_exports.object({
|
|
6558
|
+
/** canonical method 名,直接可作为 clawd-rpc call 的 method 参数 */
|
|
6183
6559
|
name: external_exports.string().min(1),
|
|
6184
|
-
|
|
6185
|
-
|
|
6186
|
-
|
|
6187
|
-
DeviceListResponseSchema = external_exports.object({
|
|
6188
|
-
type: external_exports.literal("device:list:ok"),
|
|
6189
|
-
devices: external_exports.array(DeviceEntrySchema)
|
|
6190
|
-
});
|
|
6191
|
-
DeviceConnectArgsSchema = external_exports.object({
|
|
6192
|
-
/** 目标设备的 deviceId(对方 daemon 生成的 dev-<uuid>) */
|
|
6193
|
-
deviceId: external_exports.string().min(1),
|
|
6560
|
+
status: RpcMethodStatusSchema,
|
|
6561
|
+
/** 该 method 干什么,取自 {@link METHOD_DOCS} 的 summary */
|
|
6562
|
+
description: external_exports.string().min(1),
|
|
6194
6563
|
/**
|
|
6195
|
-
*
|
|
6196
|
-
*
|
|
6197
|
-
* - 凭 deviceId 连接:缺省 url → daemon exchange 时由中心 server 下发该设备上报的 url
|
|
6198
|
-
* - 注册表不在安全路径上:知道对方 url 时显式传入即可连接(不依赖中心 server 服务发现)
|
|
6564
|
+
* 参数字段,从 {@link METHOD_DOCS} 的 args schema **反射**得来(不手写)。
|
|
6565
|
+
* `null` = 该 method 还没有中央 zod schema(欠账,见 RpcMethodDoc),调用方需自行试探。
|
|
6199
6566
|
*/
|
|
6200
|
-
|
|
6201
|
-
/** 显示名(公共设备来自目录;缺省时连上后用 whoami 回填) */
|
|
6202
|
-
name: external_exports.string().optional()
|
|
6203
|
-
});
|
|
6204
|
-
DeviceConnectResponseSchema = external_exports.object({
|
|
6205
|
-
type: external_exports.literal("device:connect:ok"),
|
|
6206
|
-
/** 连接的目标设备标识(= 请求 args.deviceId) */
|
|
6207
|
-
deviceId: external_exports.string(),
|
|
6208
|
-
name: external_exports.string(),
|
|
6209
|
-
url: external_exports.string()
|
|
6210
|
-
});
|
|
6211
|
-
FeishuIdentitySchema = external_exports.object({
|
|
6212
|
-
/** 归属人 id(决策 #16:TTC unique_id,取代飞书 union_id;跨登录方式稳定) */
|
|
6213
|
-
ownerId: external_exports.string().min(1),
|
|
6214
|
-
/** 身份来源:'ttc'(飞书/手机/邮箱登入 TTC)| 'google' | ...(决策 #16,拓展用) */
|
|
6215
|
-
provider: external_exports.string().min(1),
|
|
6216
|
-
/** 显示名。TTC user_info 接口 data.name */
|
|
6217
|
-
displayName: external_exports.string().min(1),
|
|
6218
|
-
/** TTC user_info 接口 data.avatar_url,可缺省 */
|
|
6219
|
-
avatarUrl: external_exports.string().optional(),
|
|
6220
|
-
/** TTC user_info 接口 data.union_id(飞书 union_id;dataclaw 可信入口 X-User-UnionId 用),可缺省 */
|
|
6221
|
-
unionId: external_exports.string().optional()
|
|
6222
|
-
});
|
|
6223
|
-
AuthLoginStartResponseSchema = external_exports.object({
|
|
6224
|
-
type: external_exports.literal("auth:login:start:ok"),
|
|
6225
|
-
/** 完整 TTC 授权页 URL(含 callback_url + state + auto=1),UI 直接 window.open */
|
|
6226
|
-
authUrl: external_exports.string().min(1),
|
|
6227
|
-
/** 防 CSRF 的一次性 nonce;回调时 daemon 校验 */
|
|
6228
|
-
state: external_exports.string().min(1)
|
|
6229
|
-
});
|
|
6230
|
-
AuthGetIdentityResponseSchema = external_exports.object({
|
|
6231
|
-
type: external_exports.literal("auth:getIdentity:ok"),
|
|
6232
|
-
/** null = 未登录 */
|
|
6233
|
-
identity: FeishuIdentitySchema.nullable(),
|
|
6567
|
+
args: external_exports.array(external_exports.object({ name: external_exports.string(), required: external_exports.boolean() })).nullable(),
|
|
6234
6568
|
/**
|
|
6235
|
-
*
|
|
6236
|
-
*
|
|
6237
|
-
*
|
|
6569
|
+
* `denied` 必带:daemon error code(`UNAUTHORIZED` / `FEISHU_LOGIN_REQUIRED` /
|
|
6570
|
+
* `METHOD_NOT_IMPLEMENTED`)。`conditional` 必带:谁来做二次校验。
|
|
6571
|
+
* `allowed` 恒无。
|
|
6238
6572
|
*/
|
|
6239
|
-
|
|
6240
|
-
});
|
|
6241
|
-
AuthLogoutResponseSchema = external_exports.object({
|
|
6242
|
-
type: external_exports.literal("auth:logout:ok")
|
|
6243
|
-
});
|
|
6244
|
-
AuthLoginDoneEventSchema = external_exports.object({
|
|
6245
|
-
type: external_exports.literal("auth:login:done"),
|
|
6246
|
-
identity: FeishuIdentitySchema
|
|
6573
|
+
reason: external_exports.string().optional()
|
|
6247
6574
|
});
|
|
6248
|
-
|
|
6249
|
-
type: external_exports.literal("
|
|
6250
|
-
|
|
6575
|
+
MetaMethodsResultSchema = external_exports.object({
|
|
6576
|
+
type: external_exports.literal("meta:methods"),
|
|
6577
|
+
/** METHOD_NAMES 全集,顺序与之一致 */
|
|
6578
|
+
methods: external_exports.array(RpcMethodInfoSchema)
|
|
6251
6579
|
});
|
|
6252
6580
|
}
|
|
6253
6581
|
});
|
|
6254
6582
|
|
|
6255
|
-
// ../protocol/src/
|
|
6256
|
-
var
|
|
6257
|
-
var
|
|
6258
|
-
"../protocol/src/
|
|
6583
|
+
// ../protocol/src/errors.ts
|
|
6584
|
+
var ERROR_CODES, ClawdError;
|
|
6585
|
+
var init_errors2 = __esm({
|
|
6586
|
+
"../protocol/src/errors.ts"() {
|
|
6587
|
+
"use strict";
|
|
6588
|
+
ERROR_CODES = {
|
|
6589
|
+
SESSION_NOT_FOUND: "SESSION_NOT_FOUND",
|
|
6590
|
+
SESSION_BUSY: "SESSION_BUSY",
|
|
6591
|
+
INVALID_CWD: "INVALID_CWD",
|
|
6592
|
+
INVALID_PATH: "INVALID_PATH",
|
|
6593
|
+
TOOL_NOT_SUPPORTED: "TOOL_NOT_SUPPORTED",
|
|
6594
|
+
CLAUDE_NOT_FOUND: "CLAUDE_NOT_FOUND",
|
|
6595
|
+
SPAWN_FAILED: "SPAWN_FAILED",
|
|
6596
|
+
INVALID_PERMISSION_MODE: "INVALID_PERMISSION_MODE",
|
|
6597
|
+
METHOD_NOT_IMPLEMENTED: "METHOD_NOT_IMPLEMENTED",
|
|
6598
|
+
METHOD_NOT_ALLOWED: "METHOD_NOT_ALLOWED",
|
|
6599
|
+
VALIDATION_ERROR: "VALIDATION_ERROR",
|
|
6600
|
+
PERMISSION_REQUEST_STALE: "PERMISSION_REQUEST_STALE",
|
|
6601
|
+
FILE_TOO_LARGE: "FILE_TOO_LARGE",
|
|
6602
|
+
INTERNAL: "INTERNAL",
|
|
6603
|
+
UNAUTHORIZED: "UNAUTHORIZED",
|
|
6604
|
+
FORBIDDEN: "FORBIDDEN",
|
|
6605
|
+
INVALID_PARAM: "INVALID_PARAM",
|
|
6606
|
+
// 飞书统一身份(spec 2026-06-01 决策 #9):People/远程体系强制飞书登录。
|
|
6607
|
+
// daemon 进程身份未激活为飞书 unionId 时,FEISHU_GATED_METHODS 内的 RPC 一律返回此错误;
|
|
6608
|
+
// UI 据此显示登录引导(区别于 UNAUTHORIZED 的越权语义)。
|
|
6609
|
+
FEISHU_LOGIN_REQUIRED: "FEISHU_LOGIN_REQUIRED",
|
|
6610
|
+
// app-builder 单栏默认 refactor (spec 2026-06-02-app-builder-single-pane-default-design):
|
|
6611
|
+
// appBuilder:createProject 加 personaId + session 未绑校验后抛的两个错码。
|
|
6612
|
+
WRONG_PERSONA: "WRONG_PERSONA",
|
|
6613
|
+
SESSION_ALREADY_BOUND: "SESSION_ALREADY_BOUND",
|
|
6614
|
+
// 2026-07-02 unified people sidebar: contact:pin 时 deviceId 不在 store(可能被别处删了)
|
|
6615
|
+
CONTACT_NOT_FOUND: "CONTACT_NOT_FOUND",
|
|
6616
|
+
// 统一 RPC 鉴权(spec 2026-07-28):personaDispatch:get 查不到台账行,或 guest ctx
|
|
6617
|
+
// 查非自己发起的行(越权与未知 id 同码,不泄露存在性)。A 端轮询遇此码立即判失败。
|
|
6618
|
+
DISPATCH_NOT_FOUND: "DISPATCH_NOT_FOUND"
|
|
6619
|
+
};
|
|
6620
|
+
ClawdError = class extends Error {
|
|
6621
|
+
constructor(code, message) {
|
|
6622
|
+
super(message);
|
|
6623
|
+
this.code = code;
|
|
6624
|
+
this.name = "ClawdError";
|
|
6625
|
+
}
|
|
6626
|
+
code;
|
|
6627
|
+
};
|
|
6628
|
+
}
|
|
6629
|
+
});
|
|
6630
|
+
|
|
6631
|
+
// ../protocol/src/frames.ts
|
|
6632
|
+
var PROTOCOL_VERSION, DISPATCH_MCP_ID;
|
|
6633
|
+
var init_frames = __esm({
|
|
6634
|
+
"../protocol/src/frames.ts"() {
|
|
6635
|
+
"use strict";
|
|
6636
|
+
PROTOCOL_VERSION = 1;
|
|
6637
|
+
DISPATCH_MCP_ID = "dispatch";
|
|
6638
|
+
}
|
|
6639
|
+
});
|
|
6640
|
+
|
|
6641
|
+
// ../protocol/src/persona-mode.ts
|
|
6642
|
+
var init_persona_mode = __esm({
|
|
6643
|
+
"../protocol/src/persona-mode.ts"() {
|
|
6259
6644
|
"use strict";
|
|
6260
|
-
init_zod();
|
|
6261
|
-
DispatchOutcomeSchema = external_exports.discriminatedUnion("kind", [
|
|
6262
|
-
external_exports.object({
|
|
6263
|
-
kind: external_exports.literal("success"),
|
|
6264
|
-
text: external_exports.string(),
|
|
6265
|
-
filePaths: external_exports.array(external_exports.string()).optional()
|
|
6266
|
-
}),
|
|
6267
|
-
external_exports.object({
|
|
6268
|
-
kind: external_exports.literal("failure"),
|
|
6269
|
-
reason: external_exports.string()
|
|
6270
|
-
})
|
|
6271
|
-
]);
|
|
6272
|
-
DispatchRunArgsSchema = external_exports.object({
|
|
6273
|
-
// 新开必填;续派(dispatchId 非空)时可省略——targetPersonaId 从台账行取。
|
|
6274
|
-
targetPersona: external_exports.string().min(1).optional(),
|
|
6275
|
-
// 续派(spec 2026-07-21,单 dispatchId 语义:一件事一行一 id):非空 = 把 prompt
|
|
6276
|
-
// 作为新 turn 打进该 dispatch 的原 worker session 接着干(台账行复位 running)。
|
|
6277
|
-
// 省略 = 新开一件事,daemon 铸新 id。
|
|
6278
|
-
dispatchId: external_exports.string().min(1).optional(),
|
|
6279
|
-
prompt: external_exports.string(),
|
|
6280
|
-
// 跨设备 dispatch:非空 = A 角色,转发到该 contact deviceId 的 peer daemon;
|
|
6281
|
-
// 省略 = 本地 dispatch / B 角色本地执行。A 转发给 B 时 body 不带此字段。
|
|
6282
|
-
targetDeviceId: external_exports.string().min(1).optional(),
|
|
6283
|
-
// 可选:override B session 使用的 claude 模型。缺省 = 用 persona 默认。
|
|
6284
|
-
// 合法值集与 claude adapter capabilities.models[].id 一致(见 daemon
|
|
6285
|
-
// tools/claude.ts CLAUDE_MODEL_IDS);handler 层做二次校验,非法值 fail-fast。
|
|
6286
|
-
// protocol 层保持 string 便于未来跨 tool 扩展(届时 union 收合法字面量)。
|
|
6287
|
-
model: external_exports.string().min(1).optional(),
|
|
6288
|
-
// 可选:给新 worker session 起 label(写入 SessionFile.label,sidebar 显示)。
|
|
6289
|
-
// 仅在**新开 dispatch**(dispatchId 缺席)时生效;续派(dispatchId 非空)
|
|
6290
|
-
// 时 daemon 层静默丢弃(避免半途改 label 造成 sidebar 抖动)。
|
|
6291
|
-
// 上限 60 字符——sidebar 显示 tolerance,卡在 dispatch 入口即可。
|
|
6292
|
-
// 协议层不硬拒 sessionLabel + dispatchId 同传,保留 forward-compat。
|
|
6293
|
-
sessionLabel: external_exports.string().min(1).max(60).optional()
|
|
6294
|
-
}).refine((v2) => v2.targetPersona !== void 0 || v2.dispatchId !== void 0, {
|
|
6295
|
-
message: "either targetPersona (new dispatch) or dispatchId (follow-up) is required"
|
|
6296
|
-
}).refine((v2) => !(v2.dispatchId !== void 0 && v2.targetDeviceId !== void 0), {
|
|
6297
|
-
message: "cross-device dispatch cannot be continued (dispatchId + targetDeviceId are mutually exclusive)"
|
|
6298
|
-
});
|
|
6299
|
-
DispatchCompleteArgsSchema = external_exports.object({
|
|
6300
|
-
dispatchId: external_exports.string().min(1),
|
|
6301
|
-
outcome: DispatchOutcomeSchema
|
|
6302
|
-
});
|
|
6303
|
-
DISPATCH_STATUSES = ["running", "completed", "failed"];
|
|
6304
|
-
DispatchStatusSchema = external_exports.enum(DISPATCH_STATUSES);
|
|
6305
|
-
DispatchRecordSchema = external_exports.object({
|
|
6306
|
-
dispatchId: external_exports.string().min(1),
|
|
6307
|
-
sourceSessionId: external_exports.string().min(1),
|
|
6308
|
-
sourcePersonaId: external_exports.string().min(1).optional(),
|
|
6309
|
-
targetPersonaId: external_exports.string().min(1),
|
|
6310
|
-
/** B 的 sessionId;registerBSession 后回填 */
|
|
6311
|
-
workerSessionId: external_exports.string().min(1).optional(),
|
|
6312
|
-
/** 任务摘要;截断(≤500 字符)在 daemon store.add 处保证 */
|
|
6313
|
-
taskText: external_exports.string(),
|
|
6314
|
-
status: DispatchStatusSchema,
|
|
6315
|
-
outcome: DispatchOutcomeSchema.optional(),
|
|
6316
|
-
/** 上层消费者语义(如司礼监的口谕/验收状态),daemon 不解释 */
|
|
6317
|
-
meta: external_exports.record(external_exports.unknown()).optional(),
|
|
6318
|
-
createdAt: external_exports.string().min(1),
|
|
6319
|
-
completedAt: external_exports.string().min(1).optional(),
|
|
6320
|
-
/** 结果注入 source session 成功时戳,兼当投递 dedup 标记 */
|
|
6321
|
-
deliveredAt: external_exports.string().min(1).optional()
|
|
6322
|
-
});
|
|
6323
|
-
DispatchListArgsSchema = external_exports.object({
|
|
6324
|
-
sourceSessionId: external_exports.string().min(1).optional()
|
|
6325
|
-
});
|
|
6326
|
-
DispatchListResultSchema = external_exports.object({
|
|
6327
|
-
records: external_exports.array(DispatchRecordSchema)
|
|
6328
|
-
});
|
|
6329
|
-
DispatchGetArgsSchema = external_exports.object({
|
|
6330
|
-
dispatchId: external_exports.string().min(1)
|
|
6331
|
-
});
|
|
6332
|
-
DispatchGetOkSchema = external_exports.object({
|
|
6333
|
-
type: external_exports.literal("personaDispatch:get:ok"),
|
|
6334
|
-
status: DispatchStatusSchema,
|
|
6335
|
-
outcome: DispatchOutcomeSchema.optional()
|
|
6336
|
-
});
|
|
6337
6645
|
}
|
|
6338
6646
|
});
|
|
6339
6647
|
|
|
@@ -6413,6 +6721,7 @@ var init_runtime = __esm({
|
|
|
6413
6721
|
init_dispatch();
|
|
6414
6722
|
init_log();
|
|
6415
6723
|
init_visitor_schemas();
|
|
6724
|
+
init_shift_internal();
|
|
6416
6725
|
}
|
|
6417
6726
|
});
|
|
6418
6727
|
|
|
@@ -41624,21 +41933,21 @@ var SessionStoreFactory = class {
|
|
|
41624
41933
|
bareRoot() {
|
|
41625
41934
|
return path5.join(this.dataDir, "sessions");
|
|
41626
41935
|
}
|
|
41627
|
-
vmOwnerRoot(
|
|
41936
|
+
vmOwnerRoot(personaId2) {
|
|
41628
41937
|
return path5.join(
|
|
41629
41938
|
this.dataDir,
|
|
41630
41939
|
"personas",
|
|
41631
|
-
safeFileName(
|
|
41940
|
+
safeFileName(personaId2),
|
|
41632
41941
|
".clawd",
|
|
41633
41942
|
"sessions",
|
|
41634
41943
|
"owner"
|
|
41635
41944
|
);
|
|
41636
41945
|
}
|
|
41637
|
-
vmGuestRoot(
|
|
41946
|
+
vmGuestRoot(personaId2, capId) {
|
|
41638
41947
|
return path5.join(
|
|
41639
41948
|
this.dataDir,
|
|
41640
41949
|
"personas",
|
|
41641
|
-
safeFileName(
|
|
41950
|
+
safeFileName(personaId2),
|
|
41642
41951
|
".clawd",
|
|
41643
41952
|
"sessions",
|
|
41644
41953
|
"guests",
|
|
@@ -41652,19 +41961,19 @@ var SessionStoreFactory = class {
|
|
|
41652
41961
|
}
|
|
41653
41962
|
return this.bareStore;
|
|
41654
41963
|
}
|
|
41655
|
-
forVmOwner(
|
|
41656
|
-
const key =
|
|
41964
|
+
forVmOwner(personaId2) {
|
|
41965
|
+
const key = personaId2;
|
|
41657
41966
|
const cached = this.vmOwnerStores.get(key);
|
|
41658
41967
|
if (cached) return cached;
|
|
41659
|
-
const st = new SessionStore({ root: this.vmOwnerRoot(
|
|
41968
|
+
const st = new SessionStore({ root: this.vmOwnerRoot(personaId2) });
|
|
41660
41969
|
this.vmOwnerStores.set(key, st);
|
|
41661
41970
|
return st;
|
|
41662
41971
|
}
|
|
41663
|
-
forVmGuest(
|
|
41664
|
-
const key = `${
|
|
41972
|
+
forVmGuest(personaId2, capId) {
|
|
41973
|
+
const key = `${personaId2}::${capId}`;
|
|
41665
41974
|
const cached = this.vmGuestStores.get(key);
|
|
41666
41975
|
if (cached) return cached;
|
|
41667
|
-
const st = new SessionStore({ root: this.vmGuestRoot(
|
|
41976
|
+
const st = new SessionStore({ root: this.vmGuestRoot(personaId2, capId) });
|
|
41668
41977
|
this.vmGuestStores.set(key, st);
|
|
41669
41978
|
return st;
|
|
41670
41979
|
}
|
|
@@ -41712,7 +42021,7 @@ function buildGuestSettingsV1() {
|
|
|
41712
42021
|
denyWrite: [],
|
|
41713
42022
|
// **不放 '~/'**(写是白名单制,home 自动不可写);persona(cwd) 由 compose 强制 deny
|
|
41714
42023
|
allowRead: [],
|
|
41715
|
-
//
|
|
42024
|
+
// userWorkDir + persona cwd 由 compose 强制注入,profile 加工具链精确路径
|
|
41716
42025
|
allowWrite: []
|
|
41717
42026
|
}
|
|
41718
42027
|
}
|
|
@@ -41750,7 +42059,7 @@ function composeGuestSandbox(base, userWorkDir, spawnCwd) {
|
|
|
41750
42059
|
s.sandbox.allowUnsandboxedCommands = false;
|
|
41751
42060
|
fsv.denyRead = unionArr(fsv.denyRead, FORCED_DENY_READ);
|
|
41752
42061
|
fsv.denyWrite = unionArr((fsv.denyWrite ?? []).filter((p2) => p2 !== "~/"), [spawnCwd]);
|
|
41753
|
-
fsv.allowRead = unionArr(fsv.allowRead, [userWorkDir]);
|
|
42062
|
+
fsv.allowRead = unionArr(fsv.allowRead, [userWorkDir, spawnCwd]);
|
|
41754
42063
|
fsv.allowWrite = unionArr(fsv.allowWrite, [userWorkDir]);
|
|
41755
42064
|
return s;
|
|
41756
42065
|
}
|
|
@@ -42146,8 +42455,8 @@ function buildSpawnContext(state, deps) {
|
|
|
42146
42455
|
if (clawosApi) env.CLAWOS_API = clawosApi;
|
|
42147
42456
|
const dispatchId = deps.lookupDispatchByBSessionId?.(file.sessionId);
|
|
42148
42457
|
if (dispatchId) env.CLAWD_DISPATCH_ID = dispatchId;
|
|
42149
|
-
const
|
|
42150
|
-
if (
|
|
42458
|
+
const personaId2 = file.ownerPersonaId;
|
|
42459
|
+
if (personaId2) env.CLAWD_PERSONA_ID = personaId2;
|
|
42151
42460
|
const mcpConfigs = deps.getMcpConfigs?.() ?? [];
|
|
42152
42461
|
const ctx = {
|
|
42153
42462
|
cwd: file.cwd,
|
|
@@ -42162,7 +42471,7 @@ function buildSpawnContext(state, deps) {
|
|
|
42162
42471
|
...mcpConfigs.length > 0 ? { mcpConfigs } : {},
|
|
42163
42472
|
// shift v1:把 SessionFile.ownerPersonaId 透传到 SpawnContext;buildSpawnArgs 等下游
|
|
42164
42473
|
// 不直接读这个字段(只读 env),但保留显式字段方便 daemon 内部诊断/日志。
|
|
42165
|
-
personaId
|
|
42474
|
+
personaId: personaId2
|
|
42166
42475
|
};
|
|
42167
42476
|
const meta = state.subSessionMeta;
|
|
42168
42477
|
if (meta?.personaMode) {
|
|
@@ -43456,14 +43765,14 @@ When done, call the \`personaDispatchComplete\` tool from the \`clawd-dispatch\`
|
|
|
43456
43765
|
dispatchId for this task: ${args.dispatchId}`;
|
|
43457
43766
|
}
|
|
43458
43767
|
function derivePersonaSpawnCwd(file, personaRoot) {
|
|
43459
|
-
const
|
|
43460
|
-
if (!
|
|
43768
|
+
const personaId2 = file.ownerPersonaId;
|
|
43769
|
+
if (!personaId2) return file.cwd;
|
|
43461
43770
|
if (!personaRoot) {
|
|
43462
43771
|
throw new Error(
|
|
43463
|
-
`derivePersonaSpawnCwd: personaRoot missing for owner session ${file.sessionId} (ownerPersonaId=${
|
|
43772
|
+
`derivePersonaSpawnCwd: personaRoot missing for owner session ${file.sessionId} (ownerPersonaId=${personaId2})`
|
|
43464
43773
|
);
|
|
43465
43774
|
}
|
|
43466
|
-
return import_node_path9.default.join(personaRoot, safeFileName(
|
|
43775
|
+
return import_node_path9.default.join(personaRoot, safeFileName(personaId2));
|
|
43467
43776
|
}
|
|
43468
43777
|
function makeInitialState(file, subSessionMeta) {
|
|
43469
43778
|
return {
|
|
@@ -43613,12 +43922,12 @@ var SessionManager = class {
|
|
|
43613
43922
|
// 扫某 persona 下 guests/ 子目录, 拿所有 capId.
|
|
43614
43923
|
// 路径: <dataDir>/personas/<pid>/.clawd/sessions/guests/<capId>/
|
|
43615
43924
|
// 只在 storeFactory 注入 (新布局) 下生效, 老布局无 guest 目录.
|
|
43616
|
-
listGuestCapIdsForPersona(
|
|
43925
|
+
listGuestCapIdsForPersona(personaId2) {
|
|
43617
43926
|
if (!this.deps.dataDir || !this.deps.storeFactory) return [];
|
|
43618
43927
|
const root = import_node_path9.default.join(
|
|
43619
43928
|
this.deps.dataDir,
|
|
43620
43929
|
"personas",
|
|
43621
|
-
|
|
43930
|
+
personaId2,
|
|
43622
43931
|
".clawd",
|
|
43623
43932
|
"sessions",
|
|
43624
43933
|
"guests"
|
|
@@ -43650,12 +43959,12 @@ var SessionManager = class {
|
|
|
43650
43959
|
if (runner) return runner.getState().file;
|
|
43651
43960
|
const dflt = this.deps.store.read(sessionId);
|
|
43652
43961
|
if (dflt) return dflt;
|
|
43653
|
-
for (const
|
|
43654
|
-
const ownerStore = this.storeFor({ kind: "persona", personaId, mode: "owner" });
|
|
43962
|
+
for (const personaId2 of this.listPersonaIdsOnDisk()) {
|
|
43963
|
+
const ownerStore = this.storeFor({ kind: "persona", personaId: personaId2, mode: "owner" });
|
|
43655
43964
|
const found = ownerStore.read(sessionId);
|
|
43656
43965
|
if (found) return found;
|
|
43657
|
-
for (const capId of this.listGuestCapIdsForPersona(
|
|
43658
|
-
const guestStore = this.storeFor({ kind: "persona", personaId, mode: "guest", capId });
|
|
43966
|
+
for (const capId of this.listGuestCapIdsForPersona(personaId2)) {
|
|
43967
|
+
const guestStore = this.storeFor({ kind: "persona", personaId: personaId2, mode: "guest", capId });
|
|
43659
43968
|
const g2 = guestStore.read(sessionId);
|
|
43660
43969
|
if (g2) return g2;
|
|
43661
43970
|
}
|
|
@@ -43684,11 +43993,11 @@ var SessionManager = class {
|
|
|
43684
43993
|
listAllOwned() {
|
|
43685
43994
|
const out = [];
|
|
43686
43995
|
out.push(...this.deps.store.list());
|
|
43687
|
-
for (const
|
|
43688
|
-
const ownerStore = this.storeFor({ kind: "persona", personaId, mode: "owner" });
|
|
43996
|
+
for (const personaId2 of this.listPersonaIdsOnDisk()) {
|
|
43997
|
+
const ownerStore = this.storeFor({ kind: "persona", personaId: personaId2, mode: "owner" });
|
|
43689
43998
|
out.push(...ownerStore.list());
|
|
43690
|
-
for (const capId of this.listGuestCapIdsForPersona(
|
|
43691
|
-
const guestStore = this.storeFor({ kind: "persona", personaId, mode: "guest", capId });
|
|
43999
|
+
for (const capId of this.listGuestCapIdsForPersona(personaId2)) {
|
|
44000
|
+
const guestStore = this.storeFor({ kind: "persona", personaId: personaId2, mode: "guest", capId });
|
|
43692
44001
|
out.push(...guestStore.list());
|
|
43693
44002
|
}
|
|
43694
44003
|
}
|
|
@@ -43716,11 +44025,11 @@ var SessionManager = class {
|
|
|
43716
44025
|
// 删除 owned SessionFile(default / persona owner / persona guest),与 findOwnedSession 对称扫盘.
|
|
43717
44026
|
deleteOwned(sessionId) {
|
|
43718
44027
|
if (this.deps.store.delete(sessionId)) return true;
|
|
43719
|
-
for (const
|
|
43720
|
-
const ownerStore = this.storeFor({ kind: "persona", personaId, mode: "owner" });
|
|
44028
|
+
for (const personaId2 of this.listPersonaIdsOnDisk()) {
|
|
44029
|
+
const ownerStore = this.storeFor({ kind: "persona", personaId: personaId2, mode: "owner" });
|
|
43721
44030
|
if (ownerStore.delete(sessionId)) return true;
|
|
43722
|
-
for (const capId of this.listGuestCapIdsForPersona(
|
|
43723
|
-
const guestStore = this.storeFor({ kind: "persona", personaId, mode: "guest", capId });
|
|
44031
|
+
for (const capId of this.listGuestCapIdsForPersona(personaId2)) {
|
|
44032
|
+
const guestStore = this.storeFor({ kind: "persona", personaId: personaId2, mode: "guest", capId });
|
|
43724
44033
|
if (guestStore.delete(sessionId)) return true;
|
|
43725
44034
|
}
|
|
43726
44035
|
}
|
|
@@ -45418,19 +45727,19 @@ var PersonaStore = class {
|
|
|
45418
45727
|
fs10.mkdirSync(root, { recursive: true });
|
|
45419
45728
|
}
|
|
45420
45729
|
root;
|
|
45421
|
-
personaDir(
|
|
45422
|
-
return path12.join(this.root, safeFileName(
|
|
45730
|
+
personaDir(personaId2) {
|
|
45731
|
+
return path12.join(this.root, safeFileName(personaId2));
|
|
45423
45732
|
}
|
|
45424
|
-
metaPath(
|
|
45425
|
-
return path12.join(this.personaDir(
|
|
45733
|
+
metaPath(personaId2) {
|
|
45734
|
+
return path12.join(this.personaDir(personaId2), ".clawd", "persona.json");
|
|
45426
45735
|
}
|
|
45427
|
-
claudeMdPath(
|
|
45428
|
-
return path12.join(this.personaDir(
|
|
45736
|
+
claudeMdPath(personaId2) {
|
|
45737
|
+
return path12.join(this.personaDir(personaId2), "CLAUDE.md");
|
|
45429
45738
|
}
|
|
45430
45739
|
// codex 原生读 cwd 的 AGENTS.md。人格双写镜像:claude 读 CLAUDE.md、codex 读 AGENTS.md,
|
|
45431
45740
|
// 两份内容恒一致,persona 切 tool 零迁移。
|
|
45432
|
-
agentsMdPath(
|
|
45433
|
-
return path12.join(this.personaDir(
|
|
45741
|
+
agentsMdPath(personaId2) {
|
|
45742
|
+
return path12.join(this.personaDir(personaId2), "AGENTS.md");
|
|
45434
45743
|
}
|
|
45435
45744
|
/**
|
|
45436
45745
|
* persona 级 sandbox base 落盘路径 —— 故意放 `.clawd/` 而非 `.claude/`,让 CC 的 project
|
|
@@ -45438,8 +45747,8 @@ var PersonaStore = class {
|
|
|
45438
45747
|
* 这份是 guest 沙箱的 **base 真源**(manager compose 读它当 base);guest 实际加载的是 manager
|
|
45439
45748
|
* spawn 前 per-guest 动态拼到各自 session 目录的那份(base + 强制底座 + 本 guest userWorkDir carve)。
|
|
45440
45749
|
*/
|
|
45441
|
-
sandboxSettingsPath(
|
|
45442
|
-
return path12.join(this.personaDir(
|
|
45750
|
+
sandboxSettingsPath(personaId2) {
|
|
45751
|
+
return path12.join(this.personaDir(personaId2), ".clawd", "sandbox-settings.json");
|
|
45443
45752
|
}
|
|
45444
45753
|
write(persona, personality) {
|
|
45445
45754
|
const dir = this.personaDir(persona.personaId);
|
|
@@ -45449,9 +45758,9 @@ var PersonaStore = class {
|
|
|
45449
45758
|
this.writeSandboxSettings(persona.personaId, buildGuestSettingsV1());
|
|
45450
45759
|
this.atomicWrite(this.metaPath(persona.personaId), JSON.stringify(persona, null, 2));
|
|
45451
45760
|
}
|
|
45452
|
-
writePersonality(
|
|
45453
|
-
this.atomicWrite(this.claudeMdPath(
|
|
45454
|
-
this.atomicWrite(this.agentsMdPath(
|
|
45761
|
+
writePersonality(personaId2, personality) {
|
|
45762
|
+
this.atomicWrite(this.claudeMdPath(personaId2), personality);
|
|
45763
|
+
this.atomicWrite(this.agentsMdPath(personaId2), personality);
|
|
45455
45764
|
}
|
|
45456
45765
|
/**
|
|
45457
45766
|
* 历史 persona 补 AGENTS.md:人格双写镜像是 codex 适配后才加的,更早落盘的 persona 只有
|
|
@@ -45459,9 +45768,9 @@ var PersonaStore = class {
|
|
|
45459
45768
|
* migrate(见 seed.migrateAgentsMirror)。幂等:已有 AGENTS.md(含用户手改的)不覆盖;
|
|
45460
45769
|
* 无 CLAUDE.md 不凭空造。返回是否实际补写。
|
|
45461
45770
|
*/
|
|
45462
|
-
ensureAgentsMirror(
|
|
45463
|
-
const claudeMd = this.claudeMdPath(
|
|
45464
|
-
const agentsMd = this.agentsMdPath(
|
|
45771
|
+
ensureAgentsMirror(personaId2) {
|
|
45772
|
+
const claudeMd = this.claudeMdPath(personaId2);
|
|
45773
|
+
const agentsMd = this.agentsMdPath(personaId2);
|
|
45465
45774
|
if (!fs10.existsSync(claudeMd)) return false;
|
|
45466
45775
|
if (fs10.existsSync(agentsMd)) return false;
|
|
45467
45776
|
this.atomicWrite(agentsMd, fs10.readFileSync(claudeMd, "utf8"));
|
|
@@ -45474,25 +45783,25 @@ var PersonaStore = class {
|
|
|
45474
45783
|
* 写入时强制注入本 persona 的 Edit-deny('~/<persona>/**' 按实际 persona dir 算)+ 剥掉历史相对 'Edit(./**)',
|
|
45475
45784
|
* 让落盘 base 就是 source of truth(compose 不再运行时替换 permission deny)。
|
|
45476
45785
|
*/
|
|
45477
|
-
writeSandboxSettings(
|
|
45786
|
+
writeSandboxSettings(personaId2, settings) {
|
|
45478
45787
|
this.atomicWrite(
|
|
45479
|
-
this.sandboxSettingsPath(
|
|
45480
|
-
JSON.stringify(this.injectPersonaEditDeny(
|
|
45788
|
+
this.sandboxSettingsPath(personaId2),
|
|
45789
|
+
JSON.stringify(this.injectPersonaEditDeny(personaId2, settings), null, 2)
|
|
45481
45790
|
);
|
|
45482
45791
|
}
|
|
45483
45792
|
/** 把 persona Edit-deny(绝对 '~/<persona>/**')并进 settings.permissions.deny,剥掉历史相对 'Edit(./**)'。 */
|
|
45484
|
-
injectPersonaEditDeny(
|
|
45793
|
+
injectPersonaEditDeny(personaId2, settings) {
|
|
45485
45794
|
const s = settings;
|
|
45486
|
-
const rule = personaEditDeny(this.personaDir(
|
|
45795
|
+
const rule = personaEditDeny(this.personaDir(personaId2));
|
|
45487
45796
|
const prev = (s.permissions?.deny ?? []).filter((r) => r !== "Edit(./**)" && r !== rule);
|
|
45488
45797
|
return { ...s, permissions: { ...s.permissions ?? {}, deny: [...prev, rule] } };
|
|
45489
45798
|
}
|
|
45490
|
-
codexSandboxSettingsPath(
|
|
45491
|
-
return path12.join(this.personaDir(
|
|
45799
|
+
codexSandboxSettingsPath(personaId2) {
|
|
45800
|
+
return path12.join(this.personaDir(personaId2), ".clawd", "codex-sandbox.json");
|
|
45492
45801
|
}
|
|
45493
45802
|
/** 读 codex-sandbox.json;不存在/损坏 → null。 */
|
|
45494
|
-
readCodexSandboxSettings(
|
|
45495
|
-
const p2 = this.codexSandboxSettingsPath(
|
|
45803
|
+
readCodexSandboxSettings(personaId2) {
|
|
45804
|
+
const p2 = this.codexSandboxSettingsPath(personaId2);
|
|
45496
45805
|
if (!fs10.existsSync(p2)) return null;
|
|
45497
45806
|
try {
|
|
45498
45807
|
return CodexSandboxSettingsSchema.parse(JSON.parse(fs10.readFileSync(p2, "utf8")));
|
|
@@ -45501,16 +45810,16 @@ var PersonaStore = class {
|
|
|
45501
45810
|
}
|
|
45502
45811
|
}
|
|
45503
45812
|
/** 覆盖写 codex-sandbox.json(seed/migrate 用)。 */
|
|
45504
|
-
writeCodexSandboxSettings(
|
|
45505
|
-
const dir = path12.join(this.personaDir(
|
|
45813
|
+
writeCodexSandboxSettings(personaId2, settings) {
|
|
45814
|
+
const dir = path12.join(this.personaDir(personaId2), ".clawd");
|
|
45506
45815
|
fs10.mkdirSync(dir, { recursive: true });
|
|
45507
|
-
this.atomicWrite(this.codexSandboxSettingsPath(
|
|
45816
|
+
this.atomicWrite(this.codexSandboxSettingsPath(personaId2), JSON.stringify(settings, null, 2));
|
|
45508
45817
|
}
|
|
45509
45818
|
writeMeta(persona) {
|
|
45510
45819
|
this.atomicWrite(this.metaPath(persona.personaId), JSON.stringify(persona, null, 2));
|
|
45511
45820
|
}
|
|
45512
|
-
read(
|
|
45513
|
-
const p2 = this.metaPath(
|
|
45821
|
+
read(personaId2) {
|
|
45822
|
+
const p2 = this.metaPath(personaId2);
|
|
45514
45823
|
if (!fs10.existsSync(p2)) return null;
|
|
45515
45824
|
const raw = JSON.parse(fs10.readFileSync(p2, "utf8"));
|
|
45516
45825
|
if (raw && typeof raw === "object" && "tokenMap" in raw) {
|
|
@@ -45519,13 +45828,13 @@ var PersonaStore = class {
|
|
|
45519
45828
|
}
|
|
45520
45829
|
return PersonaFileSchema.parse(raw);
|
|
45521
45830
|
}
|
|
45522
|
-
has(
|
|
45523
|
-
return fs10.existsSync(this.metaPath(
|
|
45831
|
+
has(personaId2) {
|
|
45832
|
+
return fs10.existsSync(this.metaPath(personaId2));
|
|
45524
45833
|
}
|
|
45525
|
-
readPersonality(
|
|
45526
|
-
const claudeMd = this.claudeMdPath(
|
|
45834
|
+
readPersonality(personaId2) {
|
|
45835
|
+
const claudeMd = this.claudeMdPath(personaId2);
|
|
45527
45836
|
if (fs10.existsSync(claudeMd)) return fs10.readFileSync(claudeMd, "utf8");
|
|
45528
|
-
const agentsMd = this.agentsMdPath(
|
|
45837
|
+
const agentsMd = this.agentsMdPath(personaId2);
|
|
45529
45838
|
if (fs10.existsSync(agentsMd)) return fs10.readFileSync(agentsMd, "utf8");
|
|
45530
45839
|
return null;
|
|
45531
45840
|
}
|
|
@@ -45533,8 +45842,8 @@ var PersonaStore = class {
|
|
|
45533
45842
|
* 读 sandbox-settings.json 当前内容;文件不存在 / JSON 解析失败均返回 null。
|
|
45534
45843
|
* owner 手改文件可能写出非法形状,daemon 不强校验,UI 拿到 null → 显示空状态。
|
|
45535
45844
|
*/
|
|
45536
|
-
readSandboxSettings(
|
|
45537
|
-
const p2 = this.sandboxSettingsPath(
|
|
45845
|
+
readSandboxSettings(personaId2) {
|
|
45846
|
+
const p2 = this.sandboxSettingsPath(personaId2);
|
|
45538
45847
|
if (!fs10.existsSync(p2)) return null;
|
|
45539
45848
|
try {
|
|
45540
45849
|
return JSON.parse(fs10.readFileSync(p2, "utf8"));
|
|
@@ -45543,15 +45852,15 @@ var PersonaStore = class {
|
|
|
45543
45852
|
}
|
|
45544
45853
|
}
|
|
45545
45854
|
/** Persona 私有 skills 目录路径:<personaDir>/.claude/skills */
|
|
45546
|
-
skillsDir(
|
|
45547
|
-
return path12.join(this.personaDir(
|
|
45855
|
+
skillsDir(personaId2) {
|
|
45856
|
+
return path12.join(this.personaDir(personaId2), ".claude", "skills");
|
|
45548
45857
|
}
|
|
45549
45858
|
/**
|
|
45550
45859
|
* Claude Code 项目级 settings 路径:`<personaDir>/.claude/settings.json`。
|
|
45551
45860
|
* 这里只读 `enabledPlugins` 字段,由 owner 通过 CC `/plugin` 之类命令维护,daemon 不写。
|
|
45552
45861
|
*/
|
|
45553
|
-
claudeSettingsPath(
|
|
45554
|
-
return path12.join(this.personaDir(
|
|
45862
|
+
claudeSettingsPath(personaId2) {
|
|
45863
|
+
return path12.join(this.personaDir(personaId2), ".claude", "settings.json");
|
|
45555
45864
|
}
|
|
45556
45865
|
/**
|
|
45557
45866
|
* 读取 persona 的 `.claude/settings.json` 中 `enabledPlugins` map,把 value === true
|
|
@@ -45564,8 +45873,8 @@ var PersonaStore = class {
|
|
|
45564
45873
|
* - 单 value 非 boolean → 跳过该 entry
|
|
45565
45874
|
* 其他错误(fs 权限等)原样抛出,由上层 handler 转 ws error 帧。
|
|
45566
45875
|
*/
|
|
45567
|
-
readEnabledPlugins(
|
|
45568
|
-
const p2 = this.claudeSettingsPath(
|
|
45876
|
+
readEnabledPlugins(personaId2) {
|
|
45877
|
+
const p2 = this.claudeSettingsPath(personaId2);
|
|
45569
45878
|
if (!fs10.existsSync(p2)) return [];
|
|
45570
45879
|
let raw;
|
|
45571
45880
|
try {
|
|
@@ -45588,12 +45897,12 @@ var PersonaStore = class {
|
|
|
45588
45897
|
return fs10.existsSync(path12.join(this.root, name, ".clawd", "persona.json"));
|
|
45589
45898
|
});
|
|
45590
45899
|
}
|
|
45591
|
-
remove(
|
|
45592
|
-
const dir = this.personaDir(
|
|
45900
|
+
remove(personaId2) {
|
|
45901
|
+
const dir = this.personaDir(personaId2);
|
|
45593
45902
|
if (fs10.existsSync(dir)) fs10.rmSync(dir, { recursive: true, force: true });
|
|
45594
45903
|
}
|
|
45595
|
-
personaDirPath(
|
|
45596
|
-
return this.personaDir(
|
|
45904
|
+
personaDirPath(personaId2) {
|
|
45905
|
+
return this.personaDir(personaId2);
|
|
45597
45906
|
}
|
|
45598
45907
|
atomicWrite(file, content) {
|
|
45599
45908
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
@@ -45625,15 +45934,15 @@ var PersonaRegistry = class {
|
|
|
45625
45934
|
}
|
|
45626
45935
|
}
|
|
45627
45936
|
}
|
|
45628
|
-
get(
|
|
45629
|
-
return this.cache.get(
|
|
45937
|
+
get(personaId2) {
|
|
45938
|
+
return this.cache.get(personaId2);
|
|
45630
45939
|
}
|
|
45631
45940
|
/** PersonaManager 写盘后同步 cache;不主动写盘 */
|
|
45632
45941
|
set(file) {
|
|
45633
45942
|
this.cache.set(file.personaId, file);
|
|
45634
45943
|
}
|
|
45635
|
-
remove(
|
|
45636
|
-
this.cache.delete(
|
|
45944
|
+
remove(personaId2) {
|
|
45945
|
+
this.cache.delete(personaId2);
|
|
45637
45946
|
}
|
|
45638
45947
|
list() {
|
|
45639
45948
|
return Array.from(this.cache.values());
|
|
@@ -45923,10 +46232,10 @@ var PersonaManager = class {
|
|
|
45923
46232
|
}
|
|
45924
46233
|
deps;
|
|
45925
46234
|
create(args) {
|
|
45926
|
-
const
|
|
46235
|
+
const personaId2 = this.generatePersonaId(args.label);
|
|
45927
46236
|
const now = Date.now();
|
|
45928
46237
|
const persona = {
|
|
45929
|
-
personaId,
|
|
46238
|
+
personaId: personaId2,
|
|
45930
46239
|
label: args.label,
|
|
45931
46240
|
model: args.model,
|
|
45932
46241
|
tool: args.tool,
|
|
@@ -45939,9 +46248,9 @@ var PersonaManager = class {
|
|
|
45939
46248
|
this.deps.registry.set(persona);
|
|
45940
46249
|
return persona;
|
|
45941
46250
|
}
|
|
45942
|
-
update(
|
|
45943
|
-
const existing = this.deps.registry.get(
|
|
45944
|
-
if (!existing) throw new Error(`persona not found: ${
|
|
46251
|
+
update(personaId2, patch, personality) {
|
|
46252
|
+
const existing = this.deps.registry.get(personaId2);
|
|
46253
|
+
if (!existing) throw new Error(`persona not found: ${personaId2}`);
|
|
45945
46254
|
const { iconKey: iconKeyPatch, ...restPatch } = patch;
|
|
45946
46255
|
const updated = {
|
|
45947
46256
|
...existing,
|
|
@@ -45954,30 +46263,30 @@ var PersonaManager = class {
|
|
|
45954
46263
|
updated.iconKey = iconKeyPatch;
|
|
45955
46264
|
}
|
|
45956
46265
|
if (personality !== void 0) {
|
|
45957
|
-
this.deps.store.writePersonality(
|
|
46266
|
+
this.deps.store.writePersonality(personaId2, personality);
|
|
45958
46267
|
}
|
|
45959
46268
|
this.deps.store.writeMeta(updated);
|
|
45960
46269
|
this.deps.registry.set(updated);
|
|
45961
46270
|
return updated;
|
|
45962
46271
|
}
|
|
45963
46272
|
/** 读取 CLAUDE.md 内容;persona 目录或文件不存在时返回 null。透传给 handler 拼响应。 */
|
|
45964
|
-
readPersonality(
|
|
45965
|
-
return this.deps.store.readPersonality(
|
|
46273
|
+
readPersonality(personaId2) {
|
|
46274
|
+
return this.deps.store.readPersonality(personaId2);
|
|
45966
46275
|
}
|
|
45967
46276
|
/** 扫 persona 私有 skills 目录;目录不存在返回空数组。供 persona:get handler 拼响应。 */
|
|
45968
|
-
listSkills(
|
|
45969
|
-
return listSkillsForDir(this.deps.store.skillsDir(
|
|
46277
|
+
listSkills(personaId2) {
|
|
46278
|
+
return listSkillsForDir(this.deps.store.skillsDir(personaId2), "project");
|
|
45970
46279
|
}
|
|
45971
46280
|
/**
|
|
45972
46281
|
* 读取 persona `.claude/settings.json` 中已启用的插件列表(value === true 的 key)。
|
|
45973
46282
|
* 文件不存在 / 解析失败 / 字段缺失 → 空数组。供 persona:get handler 拼响应。
|
|
45974
46283
|
*/
|
|
45975
|
-
listEnabledPlugins(
|
|
45976
|
-
return this.deps.store.readEnabledPlugins(
|
|
46284
|
+
listEnabledPlugins(personaId2) {
|
|
46285
|
+
return this.deps.store.readEnabledPlugins(personaId2);
|
|
45977
46286
|
}
|
|
45978
46287
|
/** 读 sandbox-settings.json;不存在 / 损坏返回 null。供 persona:get handler 拼响应。 */
|
|
45979
|
-
readSandboxSettings(
|
|
45980
|
-
return this.deps.store.readSandboxSettings(
|
|
46288
|
+
readSandboxSettings(personaId2) {
|
|
46289
|
+
return this.deps.store.readSandboxSettings(personaId2);
|
|
45981
46290
|
}
|
|
45982
46291
|
/**
|
|
45983
46292
|
* 删除 persona。
|
|
@@ -45985,9 +46294,9 @@ var PersonaManager = class {
|
|
|
45985
46294
|
* (含 .clawd/sessions/owner/ 和 .clawd/sessions/guests/<capId>/),rmSync
|
|
45986
46295
|
* recursive force 一锅清。
|
|
45987
46296
|
*/
|
|
45988
|
-
delete(
|
|
45989
|
-
this.deps.store.remove(
|
|
45990
|
-
this.deps.registry.remove(
|
|
46297
|
+
delete(personaId2) {
|
|
46298
|
+
this.deps.store.remove(personaId2);
|
|
46299
|
+
this.deps.registry.remove(personaId2);
|
|
45991
46300
|
}
|
|
45992
46301
|
/**
|
|
45993
46302
|
* label 转 4-16 char slug。优先用 `persona-<slug>`;若 slug 已被占用,追加 4 char
|
|
@@ -46317,15 +46626,15 @@ function refreshSandboxSettings(args) {
|
|
|
46317
46626
|
}
|
|
46318
46627
|
function migrateAgentsMirror(args) {
|
|
46319
46628
|
let mirrored = 0;
|
|
46320
|
-
for (const
|
|
46629
|
+
for (const personaId2 of args.store.list()) {
|
|
46321
46630
|
try {
|
|
46322
|
-
if (args.store.ensureAgentsMirror(
|
|
46631
|
+
if (args.store.ensureAgentsMirror(personaId2)) {
|
|
46323
46632
|
mirrored++;
|
|
46324
|
-
args.logger.info("persona.agents-mirror.synced", { personaId });
|
|
46633
|
+
args.logger.info("persona.agents-mirror.synced", { personaId: personaId2 });
|
|
46325
46634
|
}
|
|
46326
46635
|
} catch (err) {
|
|
46327
46636
|
args.logger.warn("persona.agents-mirror.failed", {
|
|
46328
|
-
personaId,
|
|
46637
|
+
personaId: personaId2,
|
|
46329
46638
|
error: err instanceof Error ? err.message : String(err)
|
|
46330
46639
|
});
|
|
46331
46640
|
}
|
|
@@ -46335,15 +46644,15 @@ function migrateAgentsMirror(args) {
|
|
|
46335
46644
|
function migrateCodexSandbox(args) {
|
|
46336
46645
|
const entries = args.entries ?? DEFAULT_PERSONAS;
|
|
46337
46646
|
let n = 0;
|
|
46338
|
-
for (const
|
|
46339
|
-
if (args.store.readCodexSandboxSettings(
|
|
46647
|
+
for (const personaId2 of args.store.list()) {
|
|
46648
|
+
if (args.store.readCodexSandboxSettings(personaId2)) continue;
|
|
46340
46649
|
try {
|
|
46341
|
-
const def = entries.find((e) => e.personaId ===
|
|
46342
|
-
args.store.writeCodexSandboxSettings(
|
|
46650
|
+
const def = entries.find((e) => e.personaId === personaId2)?.codexSandbox ?? { writableRoots: [], denyRead: [], network: false };
|
|
46651
|
+
args.store.writeCodexSandboxSettings(personaId2, def);
|
|
46343
46652
|
n++;
|
|
46344
|
-
args.logger.info("persona.codex-sandbox.synced", { personaId });
|
|
46653
|
+
args.logger.info("persona.codex-sandbox.synced", { personaId: personaId2 });
|
|
46345
46654
|
} catch (err) {
|
|
46346
|
-
args.logger.warn("persona.codex-sandbox.failed", { personaId, error: err instanceof Error ? err.message : String(err) });
|
|
46655
|
+
args.logger.warn("persona.codex-sandbox.failed", { personaId: personaId2, error: err instanceof Error ? err.message : String(err) });
|
|
46347
46656
|
}
|
|
46348
46657
|
}
|
|
46349
46658
|
if (n > 0) args.logger.info("persona.codex-sandbox.done", { migrated: n });
|
|
@@ -49193,16 +49502,17 @@ function createShiftSpawnFn(deps) {
|
|
|
49193
49502
|
};
|
|
49194
49503
|
}
|
|
49195
49504
|
|
|
49196
|
-
// src/handlers/
|
|
49197
|
-
|
|
49198
|
-
|
|
49199
|
-
|
|
49200
|
-
|
|
49201
|
-
|
|
49202
|
-
|
|
49203
|
-
}
|
|
49204
|
-
return raw;
|
|
49505
|
+
// src/handlers/types.ts
|
|
49506
|
+
init_protocol();
|
|
49507
|
+
function parseArgs2(schema, frame, what, code = ERROR_CODES.VALIDATION_ERROR) {
|
|
49508
|
+
const effective = typeof schema.strip === "function" ? schema.strip() : schema;
|
|
49509
|
+
const r = effective.safeParse(frame);
|
|
49510
|
+
if (!r.success) throw new ClawdError(code, `${what}: ${r.error.message}`);
|
|
49511
|
+
return r.data;
|
|
49205
49512
|
}
|
|
49513
|
+
|
|
49514
|
+
// src/handlers/shift-internal.ts
|
|
49515
|
+
init_protocol();
|
|
49206
49516
|
function validateSchedule(schedule) {
|
|
49207
49517
|
const next = computeNextRunAtMs(schedule, Date.now());
|
|
49208
49518
|
if (next === null) {
|
|
@@ -49213,10 +49523,9 @@ function validateSchedule(schedule) {
|
|
|
49213
49523
|
}
|
|
49214
49524
|
function buildShiftInternalHandlers(deps) {
|
|
49215
49525
|
const add = async (frame) => {
|
|
49216
|
-
const persona = readPersonaId(frame);
|
|
49217
49526
|
const callerSessionId = typeof frame.sessionId === "string" ? frame.sessionId : void 0;
|
|
49218
|
-
const
|
|
49219
|
-
const
|
|
49527
|
+
const args = parseArgs2(ShiftInternalAddArgs, frame, "shift-internal:add");
|
|
49528
|
+
const persona = args.personaId;
|
|
49220
49529
|
validateSchedule(args.schedule);
|
|
49221
49530
|
const shift = deps.store.add({
|
|
49222
49531
|
ownerId: deps.ownerIdProvider(),
|
|
@@ -49234,17 +49543,15 @@ function buildShiftInternalHandlers(deps) {
|
|
|
49234
49543
|
};
|
|
49235
49544
|
};
|
|
49236
49545
|
const list = async (frame) => {
|
|
49237
|
-
const
|
|
49238
|
-
const
|
|
49239
|
-
const args = rest;
|
|
49546
|
+
const args = parseArgs2(ShiftInternalListArgs, frame, "shift-internal:list");
|
|
49547
|
+
const persona = args.personaId;
|
|
49240
49548
|
const onlyMine = args.onlyMine !== false;
|
|
49241
49549
|
const filter = onlyMine ? { ownerId: deps.ownerIdProvider(), createdByPersona: persona } : { ownerId: deps.ownerIdProvider() };
|
|
49242
49550
|
return { response: { shifts: deps.store.list(filter) } };
|
|
49243
49551
|
};
|
|
49244
49552
|
const cancel = async (frame) => {
|
|
49245
|
-
const
|
|
49246
|
-
const
|
|
49247
|
-
const args = rest;
|
|
49553
|
+
const args = parseArgs2(ShiftInternalCancelArgs, frame, "shift-internal:cancel");
|
|
49554
|
+
const persona = args.personaId;
|
|
49248
49555
|
const shift = deps.store.get(args.shiftId);
|
|
49249
49556
|
if (!shift) {
|
|
49250
49557
|
throw new Error(`shift-internal:cancel: shift not found: ${args.shiftId}`);
|
|
@@ -49258,9 +49565,8 @@ function buildShiftInternalHandlers(deps) {
|
|
|
49258
49565
|
return { response: { ok: true } };
|
|
49259
49566
|
};
|
|
49260
49567
|
const update = async (frame) => {
|
|
49261
|
-
const
|
|
49262
|
-
const
|
|
49263
|
-
const args = rest;
|
|
49568
|
+
const args = parseArgs2(ShiftInternalUpdateArgs, frame, "shift-internal:update");
|
|
49569
|
+
const persona = args.personaId;
|
|
49264
49570
|
const shift = deps.store.get(args.shiftId);
|
|
49265
49571
|
if (!shift) {
|
|
49266
49572
|
throw new Error(`shift-internal:update: shift not found: ${args.shiftId}`);
|
|
@@ -49280,9 +49586,8 @@ function buildShiftInternalHandlers(deps) {
|
|
|
49280
49586
|
};
|
|
49281
49587
|
};
|
|
49282
49588
|
const history = async (frame) => {
|
|
49283
|
-
const
|
|
49284
|
-
const
|
|
49285
|
-
const args = rest;
|
|
49589
|
+
const args = parseArgs2(ShiftInternalHistoryArgs, frame, "shift-internal:history");
|
|
49590
|
+
const persona = args.personaId;
|
|
49286
49591
|
const shift = deps.store.get(args.shiftId);
|
|
49287
49592
|
if (!shift) {
|
|
49288
49593
|
throw new Error(`shift-internal:history: shift not found: ${args.shiftId}`);
|
|
@@ -49338,9 +49643,9 @@ function canAccessSession(ctx, sessionId, action, deps) {
|
|
|
49338
49643
|
if (!file) return true;
|
|
49339
49644
|
return canAccessPersona(ctx.grants, file.ownerPersonaId, action);
|
|
49340
49645
|
}
|
|
49341
|
-
function canAccessPersona(grants,
|
|
49342
|
-
if (!
|
|
49343
|
-
const resource = { type: "persona", id:
|
|
49646
|
+
function canAccessPersona(grants, personaId2, action) {
|
|
49647
|
+
if (!personaId2) return false;
|
|
49648
|
+
const resource = { type: "persona", id: personaId2 };
|
|
49344
49649
|
return assertGrant(grants, resource, action);
|
|
49345
49650
|
}
|
|
49346
49651
|
|
|
@@ -50685,7 +50990,7 @@ function listRegistered() {
|
|
|
50685
50990
|
|
|
50686
50991
|
// ../node_modules/.pnpm/ws@8.20.0/node_modules/ws/wrapper.mjs
|
|
50687
50992
|
var import_stream = __toESM(require_stream(), 1);
|
|
50688
|
-
var
|
|
50993
|
+
var import_extension2 = __toESM(require_extension(), 1);
|
|
50689
50994
|
var import_permessage_deflate = __toESM(require_permessage_deflate(), 1);
|
|
50690
50995
|
var import_receiver = __toESM(require_receiver(), 1);
|
|
50691
50996
|
var import_sender = __toESM(require_sender(), 1);
|
|
@@ -54287,14 +54592,14 @@ function buildSessionHandlers(deps) {
|
|
|
54287
54592
|
);
|
|
54288
54593
|
}
|
|
54289
54594
|
};
|
|
54290
|
-
const ensurePersonaAccess = (ctx,
|
|
54595
|
+
const ensurePersonaAccess = (ctx, personaId2, action) => {
|
|
54291
54596
|
if (!ctx) return;
|
|
54292
54597
|
if (ctx.principal.kind === "owner") return;
|
|
54293
|
-
const ok = canAccessPersona(ctx.grants,
|
|
54598
|
+
const ok = canAccessPersona(ctx.grants, personaId2, action);
|
|
54294
54599
|
if (!ok) {
|
|
54295
54600
|
throw new ClawdError(
|
|
54296
54601
|
ERROR_CODES.UNAUTHORIZED,
|
|
54297
|
-
`principal ${ctx.principal.kind}:${ctx.principal.id} cannot ${action} on persona:${
|
|
54602
|
+
`principal ${ctx.principal.kind}:${ctx.principal.id} cannot ${action} on persona:${personaId2 ?? "<none>"}`
|
|
54298
54603
|
);
|
|
54299
54604
|
}
|
|
54300
54605
|
};
|
|
@@ -54405,7 +54710,7 @@ function buildSessionHandlers(deps) {
|
|
|
54405
54710
|
return { response: { type: "session:send", ok: true }, broadcast };
|
|
54406
54711
|
};
|
|
54407
54712
|
const currentTurnSender = async (frame, _client, ctx) => {
|
|
54408
|
-
const sid =
|
|
54713
|
+
const sid = SessionCurrentTurnSenderArgs.parse(frame).sessionId ?? "";
|
|
54409
54714
|
if (!sid) {
|
|
54410
54715
|
return { response: { type: "session:currentTurnSender", sender: null } };
|
|
54411
54716
|
}
|
|
@@ -54510,19 +54815,20 @@ function buildSessionHandlers(deps) {
|
|
|
54510
54815
|
return { response: { type: "session:events", ...response } };
|
|
54511
54816
|
};
|
|
54512
54817
|
const subscribe = async (frame, client, ctx) => {
|
|
54513
|
-
|
|
54514
|
-
|
|
54515
|
-
|
|
54818
|
+
const args = SessionSubscribeArgs.parse(frame);
|
|
54819
|
+
if (args.sessionId !== void 0) {
|
|
54820
|
+
ensureSessionAccess(ctx, args.sessionId, "read");
|
|
54821
|
+
addSubscription(client, args.sessionId);
|
|
54516
54822
|
}
|
|
54517
54823
|
return {
|
|
54518
|
-
response: { type: "subscribed", sessionId:
|
|
54824
|
+
response: { type: "subscribed", sessionId: args.sessionId }
|
|
54519
54825
|
};
|
|
54520
54826
|
};
|
|
54521
54827
|
const unsubscribe = async (frame, client) => {
|
|
54522
|
-
|
|
54523
|
-
|
|
54828
|
+
const args = SessionSubscribeArgs.parse(frame);
|
|
54829
|
+
if (args.sessionId !== void 0) removeSubscription(client, args.sessionId);
|
|
54524
54830
|
return {
|
|
54525
|
-
response: { type: "unsubscribed", sessionId:
|
|
54831
|
+
response: { type: "unsubscribed", sessionId: args.sessionId }
|
|
54526
54832
|
};
|
|
54527
54833
|
};
|
|
54528
54834
|
const pin = async (frame, _client, ctx) => {
|
|
@@ -54721,11 +55027,11 @@ function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userW
|
|
|
54721
55027
|
if (!target.startsWith(root + sep3)) return false;
|
|
54722
55028
|
const rel = path56.relative(root, target);
|
|
54723
55029
|
if (!rel || rel.startsWith("..")) return false;
|
|
54724
|
-
const
|
|
54725
|
-
if (!
|
|
55030
|
+
const personaId2 = rel.split(path56.sep)[0];
|
|
55031
|
+
if (!personaId2) return false;
|
|
54726
55032
|
const allowed = getAllowedPersonaIds(grants, action);
|
|
54727
55033
|
if (allowed === "*") return true;
|
|
54728
|
-
return allowed.has(
|
|
55034
|
+
return allowed.has(personaId2);
|
|
54729
55035
|
}
|
|
54730
55036
|
function personaIdFromPath(absPath, personaRoot) {
|
|
54731
55037
|
const root = path56.resolve(personaRoot);
|
|
@@ -54743,9 +55049,9 @@ function isPathWithin(dir, absPath) {
|
|
|
54743
55049
|
const sep3 = d.endsWith(path56.sep) ? "" : path56.sep;
|
|
54744
55050
|
return t === d || t.startsWith(d + sep3);
|
|
54745
55051
|
}
|
|
54746
|
-
function isPathInGuestBoundary(personaRoot,
|
|
55052
|
+
function isPathInGuestBoundary(personaRoot, personaId2, userWorkDir, absPath) {
|
|
54747
55053
|
if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
|
|
54748
|
-
return personaIdFromPath(path56.resolve(absPath), personaRoot) ===
|
|
55054
|
+
return personaIdFromPath(path56.resolve(absPath), personaRoot) === personaId2;
|
|
54749
55055
|
}
|
|
54750
55056
|
|
|
54751
55057
|
// src/handlers/history.ts
|
|
@@ -54878,9 +55184,9 @@ var path58 = __toESM(require("path"), 1);
|
|
|
54878
55184
|
var os16 = __toESM(require("os"), 1);
|
|
54879
55185
|
init_protocol();
|
|
54880
55186
|
init_protocol();
|
|
54881
|
-
function buildEnabledPluginNames(personaManager,
|
|
55187
|
+
function buildEnabledPluginNames(personaManager, personaId2) {
|
|
54882
55188
|
const out = /* @__PURE__ */ new Set();
|
|
54883
|
-
for (const p2 of personaManager.listEnabledPlugins(
|
|
55189
|
+
for (const p2 of personaManager.listEnabledPlugins(personaId2)) {
|
|
54884
55190
|
const name = p2.id.includes("@") ? p2.id.slice(0, p2.id.indexOf("@")) : p2.id;
|
|
54885
55191
|
if (name) out.add(name);
|
|
54886
55192
|
}
|
|
@@ -54935,8 +55241,8 @@ function buildWorkspaceHandlers(deps) {
|
|
|
54935
55241
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
|
|
54936
55242
|
const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
|
|
54937
55243
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
54938
|
-
const
|
|
54939
|
-
const enabled =
|
|
55244
|
+
const personaId2 = personaIdFromPath(cwdAbs, personaRoot);
|
|
55245
|
+
const enabled = personaId2 ? buildEnabledPluginNames(personaManager, personaId2) : /* @__PURE__ */ new Set();
|
|
54940
55246
|
return { response: { type: "skills:list", skills: filterGuestSkills(list2, enabled) } };
|
|
54941
55247
|
}
|
|
54942
55248
|
return { response: { type: "skills:list", skills: list2 } };
|
|
@@ -54950,8 +55256,8 @@ function buildWorkspaceHandlers(deps) {
|
|
|
54950
55256
|
}
|
|
54951
55257
|
const list2 = agents.list(args);
|
|
54952
55258
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
54953
|
-
const
|
|
54954
|
-
const enabled =
|
|
55259
|
+
const personaId2 = personaIdFromPath(cwdAbs, personaRoot);
|
|
55260
|
+
const enabled = personaId2 ? buildEnabledPluginNames(personaManager, personaId2) : /* @__PURE__ */ new Set();
|
|
54955
55261
|
return { response: { type: "agents:list", agents: filterGuestAgents(list2, enabled) } };
|
|
54956
55262
|
}
|
|
54957
55263
|
return { response: { type: "agents:list", agents: list2 } };
|
|
@@ -55124,8 +55430,7 @@ function resolvePeerDeviceId(ctx, argsPeerDeviceId) {
|
|
|
55124
55430
|
function buildInboxHandlers(deps) {
|
|
55125
55431
|
const { manager } = deps;
|
|
55126
55432
|
const postMessage = async (frame, _client, ctx) => {
|
|
55127
|
-
const
|
|
55128
|
-
const args = InboxPostMessageArgsSchema.parse(rest);
|
|
55433
|
+
const args = parseArgs2(InboxPostMessageArgsSchema, frame, "inbox:postMessage");
|
|
55129
55434
|
if (!ctx) {
|
|
55130
55435
|
throw new ClawdError(ERROR_CODES.INTERNAL, "inbox:postMessage: missing ConnectionContext");
|
|
55131
55436
|
}
|
|
@@ -55143,8 +55448,7 @@ function buildInboxHandlers(deps) {
|
|
|
55143
55448
|
};
|
|
55144
55449
|
};
|
|
55145
55450
|
const list = async (frame, _client, ctx) => {
|
|
55146
|
-
const
|
|
55147
|
-
const args = InboxListArgsSchema.parse(rest);
|
|
55451
|
+
const args = parseArgs2(InboxListArgsSchema, frame, "inbox:list");
|
|
55148
55452
|
if (!ctx) {
|
|
55149
55453
|
throw new ClawdError(ERROR_CODES.INTERNAL, "inbox:list: missing ConnectionContext");
|
|
55150
55454
|
}
|
|
@@ -55155,8 +55459,7 @@ function buildInboxHandlers(deps) {
|
|
|
55155
55459
|
};
|
|
55156
55460
|
};
|
|
55157
55461
|
const markRead = async (frame, _client, ctx) => {
|
|
55158
|
-
const
|
|
55159
|
-
const args = InboxMarkReadArgsSchema.parse(rest);
|
|
55462
|
+
const args = parseArgs2(InboxMarkReadArgsSchema, frame, "inbox:markRead");
|
|
55160
55463
|
if (!ctx) {
|
|
55161
55464
|
throw new ClawdError(ERROR_CODES.INTERNAL, "inbox:markRead: missing ConnectionContext");
|
|
55162
55465
|
}
|
|
@@ -55178,7 +55481,7 @@ function buildInboxHandlers(deps) {
|
|
|
55178
55481
|
const sendDm = async (frame) => {
|
|
55179
55482
|
const { type: _t, requestId: _r, ...rest } = frame;
|
|
55180
55483
|
const sessionId = typeof rest.sessionId === "string" ? rest.sessionId : void 0;
|
|
55181
|
-
const args = InboxSendDmArgsSchema
|
|
55484
|
+
const args = parseArgs2(InboxSendDmArgsSchema, frame, "inbox:sendDm");
|
|
55182
55485
|
const d = deps.sendDmDeps;
|
|
55183
55486
|
if (!d) throw new ClawdError(ERROR_CODES.INTERNAL, "inbox:sendDm not wired");
|
|
55184
55487
|
if (!sessionId) {
|
|
@@ -55339,8 +55642,7 @@ function buildContactHandlers(deps) {
|
|
|
55339
55642
|
};
|
|
55340
55643
|
const pin = async (frame, _client, ctx) => {
|
|
55341
55644
|
ensureOwner(ctx);
|
|
55342
|
-
const
|
|
55343
|
-
const args = ContactPinArgsSchema.parse(rest);
|
|
55645
|
+
const args = parseArgs2(ContactPinArgsSchema, frame, "contact:pin");
|
|
55344
55646
|
const pinnedAt = args.pinned ? deps.now() : null;
|
|
55345
55647
|
const hit = deps.store.setPin(args.deviceId, pinnedAt);
|
|
55346
55648
|
if (!hit) {
|
|
@@ -55364,8 +55666,7 @@ function buildContactHandlers(deps) {
|
|
|
55364
55666
|
};
|
|
55365
55667
|
const remove = async (frame, _client, ctx) => {
|
|
55366
55668
|
ensureOwner(ctx);
|
|
55367
|
-
const
|
|
55368
|
-
const args = ContactRemoveArgsSchema.parse(rest);
|
|
55669
|
+
const args = parseArgs2(ContactRemoveArgsSchema, frame, "contact:remove");
|
|
55369
55670
|
deps.store.removeByDeviceId(args.deviceId);
|
|
55370
55671
|
deps.broadcast({
|
|
55371
55672
|
type: "contact:removed",
|
|
@@ -55385,8 +55686,7 @@ function buildContactHandlers(deps) {
|
|
|
55385
55686
|
"contact:handshake \u4EC5\u63A5\u53D7 connect-token \u8FDE\u63A5\uFF08\u8BBE\u5907\u4E92\u8FDE\u63E1\u624B\u4E13\u7528\uFF09"
|
|
55386
55687
|
);
|
|
55387
55688
|
}
|
|
55388
|
-
const
|
|
55389
|
-
const args = ContactHandshakeArgsSchema.parse(rest);
|
|
55689
|
+
const args = parseArgs2(ContactHandshakeArgsSchema, frame, "contact:handshake");
|
|
55390
55690
|
const contact = upsertPeerContact({
|
|
55391
55691
|
store: deps.store,
|
|
55392
55692
|
broadcast: deps.broadcast,
|
|
@@ -55437,8 +55737,7 @@ function ensureOwner2(ctx) {
|
|
|
55437
55737
|
function buildContactRemoteAccessHandlers(deps) {
|
|
55438
55738
|
const setRemoteAccess = async (frame, _client, ctx) => {
|
|
55439
55739
|
ensureOwner2(ctx);
|
|
55440
|
-
const
|
|
55441
|
-
const args = ContactSetRemoteAccessArgsSchema.parse(rest);
|
|
55740
|
+
const args = parseArgs2(ContactSetRemoteAccessArgsSchema, frame, "contact:setRemoteAccess");
|
|
55442
55741
|
const hit = deps.store.setRemoteAccess(args.deviceId, {
|
|
55443
55742
|
remoteAccessAllowed: args.remoteAccessAllowed
|
|
55444
55743
|
});
|
|
@@ -55880,24 +56179,28 @@ function computeGrant(method) {
|
|
|
55880
56179
|
}
|
|
55881
56180
|
function computeMethodAccess(args) {
|
|
55882
56181
|
const { method, grants, feishuActive, isImplemented } = args;
|
|
56182
|
+
const description = METHOD_DOCS[method].summary;
|
|
56183
|
+
const argFields = methodArgFields(method);
|
|
55883
56184
|
if (!isImplemented(method)) {
|
|
55884
|
-
return { name: method, status: "denied", reason: "METHOD_NOT_IMPLEMENTED" };
|
|
56185
|
+
return { name: method, description, args: argFields, status: "denied", reason: "METHOD_NOT_IMPLEMENTED" };
|
|
55885
56186
|
}
|
|
55886
56187
|
if (!feishuActive && FEISHU_GATED_METHODS.includes(method)) {
|
|
55887
|
-
return { name: method, status: "denied", reason: "FEISHU_LOGIN_REQUIRED" };
|
|
56188
|
+
return { name: method, description, args: argFields, status: "denied", reason: "FEISHU_LOGIN_REQUIRED" };
|
|
55888
56189
|
}
|
|
55889
56190
|
if (METHOD_GRANT_MAP[method]?.kind === "capability-scoped") {
|
|
55890
56191
|
return {
|
|
55891
56192
|
name: method,
|
|
56193
|
+
description,
|
|
56194
|
+
args: argFields,
|
|
55892
56195
|
status: "conditional",
|
|
55893
56196
|
reason: "handler checks your grants for the target resource"
|
|
55894
56197
|
};
|
|
55895
56198
|
}
|
|
55896
56199
|
const verdict = computeGrant(method);
|
|
55897
56200
|
if (verdict.kind === "check" && !assertGrant(grants, verdict.resource, verdict.action)) {
|
|
55898
|
-
return { name: method, status: "denied", reason: "UNAUTHORIZED" };
|
|
56201
|
+
return { name: method, description, args: argFields, status: "denied", reason: "UNAUTHORIZED" };
|
|
55899
56202
|
}
|
|
55900
|
-
return { name: method, status: "allowed" };
|
|
56203
|
+
return { name: method, description, args: argFields, status: "allowed" };
|
|
55901
56204
|
}
|
|
55902
56205
|
|
|
55903
56206
|
// src/version.ts
|
|
@@ -55973,7 +56276,7 @@ function buildPersonaHandlers(deps) {
|
|
|
55973
56276
|
const { personaManager, personaRegistry } = deps;
|
|
55974
56277
|
const create = async (frame) => {
|
|
55975
56278
|
const { type: _type, requestId: _requestId, ...rest } = frame;
|
|
55976
|
-
const args = PersonaCreateArgsSchema
|
|
56279
|
+
const args = parseArgs2(PersonaCreateArgsSchema, frame, "persona:create");
|
|
55977
56280
|
const persona = personaManager.create(args);
|
|
55978
56281
|
return { response: { type: "persona:info", ...persona } };
|
|
55979
56282
|
};
|
|
@@ -55989,7 +56292,7 @@ function buildPersonaHandlers(deps) {
|
|
|
55989
56292
|
};
|
|
55990
56293
|
};
|
|
55991
56294
|
const get = async (frame, _client, ctx) => {
|
|
55992
|
-
const args = PersonaIdArgsSchema
|
|
56295
|
+
const args = parseArgs2(PersonaIdArgsSchema, frame, "persona:get");
|
|
55993
56296
|
const persona = personaRegistry.get(args.personaId) ?? null;
|
|
55994
56297
|
if (!persona) {
|
|
55995
56298
|
return { response: { type: "persona:info", persona: null } };
|
|
@@ -56018,13 +56321,13 @@ function buildPersonaHandlers(deps) {
|
|
|
56018
56321
|
};
|
|
56019
56322
|
const update = async (frame) => {
|
|
56020
56323
|
const { type: _type, requestId: _requestId, ...rest } = frame;
|
|
56021
|
-
const args = PersonaUpdateArgsSchema
|
|
56324
|
+
const args = parseArgs2(PersonaUpdateArgsSchema, frame, "persona:update");
|
|
56022
56325
|
const { personality, ...metaPatch } = args.patch;
|
|
56023
56326
|
const persona = personaManager.update(args.personaId, metaPatch, personality);
|
|
56024
56327
|
return { response: { type: "persona:info", ...persona } };
|
|
56025
56328
|
};
|
|
56026
56329
|
const del = async (frame) => {
|
|
56027
|
-
const args = PersonaIdArgsSchema
|
|
56330
|
+
const args = parseArgs2(PersonaIdArgsSchema, frame, "persona:get");
|
|
56028
56331
|
personaManager.delete(args.personaId);
|
|
56029
56332
|
return {
|
|
56030
56333
|
response: { type: "persona:deleted", personaId: args.personaId }
|
|
@@ -56582,32 +56885,6 @@ async function rollback(deps, localExtId, liveDir, prevDir) {
|
|
|
56582
56885
|
}
|
|
56583
56886
|
|
|
56584
56887
|
// src/handlers/extension.ts
|
|
56585
|
-
function pickChannelRef(frame) {
|
|
56586
|
-
const ref = frame.channelRef;
|
|
56587
|
-
const parsed = ChannelRefSchema.safeParse(ref);
|
|
56588
|
-
if (!parsed.success) {
|
|
56589
|
-
throw new ClawdError(
|
|
56590
|
-
ERROR_CODES.INVALID_PARAM,
|
|
56591
|
-
`channelRef invalid: ${parsed.error.issues.map((i) => i.message).join("; ")}`
|
|
56592
|
-
);
|
|
56593
|
-
}
|
|
56594
|
-
return parsed.data;
|
|
56595
|
-
}
|
|
56596
|
-
function pickStringField(frame, name) {
|
|
56597
|
-
const v2 = frame[name];
|
|
56598
|
-
if (typeof v2 !== "string" || v2.length === 0) {
|
|
56599
|
-
throw new ClawdError(ERROR_CODES.INVALID_PARAM, `${name} required`);
|
|
56600
|
-
}
|
|
56601
|
-
return v2;
|
|
56602
|
-
}
|
|
56603
|
-
function pickOptionalString(frame, name) {
|
|
56604
|
-
const v2 = frame[name];
|
|
56605
|
-
if (v2 === void 0 || v2 === null) return null;
|
|
56606
|
-
if (typeof v2 !== "string") {
|
|
56607
|
-
throw new ClawdError(ERROR_CODES.INVALID_PARAM, `${name} must be string`);
|
|
56608
|
-
}
|
|
56609
|
-
return v2;
|
|
56610
|
-
}
|
|
56611
56888
|
async function rewriteManifestVersion(root, extId, newVersion, previousPublishedVersion) {
|
|
56612
56889
|
const v2 = validateSimpleSemver(newVersion);
|
|
56613
56890
|
if (!v2.ok) {
|
|
@@ -56665,13 +56942,6 @@ function assertOwner(ctx) {
|
|
|
56665
56942
|
throw new ClawdError(ERROR_CODES.FORBIDDEN, "owner only");
|
|
56666
56943
|
}
|
|
56667
56944
|
}
|
|
56668
|
-
function pickExtId(frame) {
|
|
56669
|
-
const extId = frame.extId;
|
|
56670
|
-
if (typeof extId !== "string") {
|
|
56671
|
-
throw new ClawdError(ERROR_CODES.INVALID_PARAM, "extId required");
|
|
56672
|
-
}
|
|
56673
|
-
return extId;
|
|
56674
|
-
}
|
|
56675
56945
|
function composeState(rec3, running, crashed, getPort) {
|
|
56676
56946
|
if (rec3.state === "invalid") return rec3;
|
|
56677
56947
|
if (manifestMode(rec3.manifest) === "hosted") {
|
|
@@ -56705,19 +56975,19 @@ function buildExtensionHandlers(deps) {
|
|
|
56705
56975
|
};
|
|
56706
56976
|
const open = async (frame, _client, ctx) => {
|
|
56707
56977
|
assertOwner(ctx);
|
|
56708
|
-
const extId =
|
|
56978
|
+
const { extId } = parseArgs2(ExtensionIdArgs, frame, "extension", ERROR_CODES.INVALID_PARAM);
|
|
56709
56979
|
const target = await deps.runtime.open(extId);
|
|
56710
56980
|
return { response: target };
|
|
56711
56981
|
};
|
|
56712
56982
|
const close = async (frame, _client, ctx) => {
|
|
56713
56983
|
assertOwner(ctx);
|
|
56714
|
-
const extId =
|
|
56984
|
+
const { extId } = parseArgs2(ExtensionIdArgs, frame, "extension", ERROR_CODES.INVALID_PARAM);
|
|
56715
56985
|
await deps.runtime.close(extId);
|
|
56716
56986
|
return { response: { ok: true } };
|
|
56717
56987
|
};
|
|
56718
56988
|
const uninstall2 = async (frame, _client, ctx) => {
|
|
56719
56989
|
assertOwner(ctx);
|
|
56720
|
-
const extId =
|
|
56990
|
+
const { extId } = parseArgs2(ExtensionIdArgs, frame, "extension", ERROR_CODES.INVALID_PARAM);
|
|
56721
56991
|
await deps.uninstall({ root: deps.root, extId, runtime: deps.runtime });
|
|
56722
56992
|
return { response: { ok: true } };
|
|
56723
56993
|
};
|
|
@@ -56728,9 +56998,8 @@ function buildExtensionHandlers(deps) {
|
|
|
56728
56998
|
}
|
|
56729
56999
|
const publish = async (frame, _client, ctx) => {
|
|
56730
57000
|
assertOwner(ctx);
|
|
56731
|
-
const extId =
|
|
56732
|
-
|
|
56733
|
-
if (newVersion !== null) {
|
|
57001
|
+
const { extId, newVersion } = parseArgs2(ExtensionPublishArgs, frame, "publish", ERROR_CODES.INVALID_PARAM);
|
|
57002
|
+
if (newVersion != null) {
|
|
56734
57003
|
await rewriteManifestVersion(deps.root, extId, newVersion, deps.publishedChannelStore.get(extId)?.version);
|
|
56735
57004
|
}
|
|
56736
57005
|
const { manifest, contentHash, buffer } = await buildSnapshotMeta(extId);
|
|
@@ -56774,7 +57043,7 @@ function buildExtensionHandlers(deps) {
|
|
|
56774
57043
|
};
|
|
56775
57044
|
const unpublish = async (frame, _client, ctx) => {
|
|
56776
57045
|
assertOwner(ctx);
|
|
56777
|
-
const extId =
|
|
57046
|
+
const { extId } = parseArgs2(ExtensionIdArgs, frame, "extension", ERROR_CODES.INVALID_PARAM);
|
|
56778
57047
|
const head = deps.publishedChannelStore.get(extId);
|
|
56779
57048
|
await deps.publishedChannelStore.delete(extId);
|
|
56780
57049
|
if (head) {
|
|
@@ -56784,7 +57053,7 @@ function buildExtensionHandlers(deps) {
|
|
|
56784
57053
|
};
|
|
56785
57054
|
const publishStatus = async (frame, _client, ctx) => {
|
|
56786
57055
|
assertOwner(ctx);
|
|
56787
|
-
const extId =
|
|
57056
|
+
const { extId } = parseArgs2(ExtensionIdArgs, frame, "extension", ERROR_CODES.INVALID_PARAM);
|
|
56788
57057
|
const { manifest, contentHash } = await buildSnapshotMeta(extId);
|
|
56789
57058
|
const head = deps.publishedChannelStore.get(extId);
|
|
56790
57059
|
const check = computePublishCheck({
|
|
@@ -56833,8 +57102,7 @@ function buildExtensionHandlers(deps) {
|
|
|
56833
57102
|
if (!ctx || ctx.principal.kind !== "guest") {
|
|
56834
57103
|
throw new ClawdError(ERROR_CODES.FORBIDDEN, "guest only");
|
|
56835
57104
|
}
|
|
56836
|
-
|
|
56837
|
-
const expectedHash = pickStringField(frame, "snapshotHash");
|
|
57105
|
+
const { snapshotHash: expectedHash } = parseArgs2(ExtensionFetchBundleArgs, frame, "fetchBundle", ERROR_CODES.INVALID_PARAM);
|
|
56838
57106
|
const cached = await deps.bundleCache.read(expectedHash);
|
|
56839
57107
|
if (cached === null) {
|
|
56840
57108
|
throw new ClawdError(
|
|
@@ -56846,9 +57114,7 @@ function buildExtensionHandlers(deps) {
|
|
|
56846
57114
|
};
|
|
56847
57115
|
const installFromChannelHandler = async (frame, _client, ctx) => {
|
|
56848
57116
|
assertOwner(ctx);
|
|
56849
|
-
const channelRef =
|
|
56850
|
-
const snapshotHash = pickStringField(frame, "snapshotHash");
|
|
56851
|
-
const zipBase64 = pickStringField(frame, "zipBase64");
|
|
57117
|
+
const { channelRef, snapshotHash, zipBase64 } = parseArgs2(ExtensionFromChannelArgs, frame, "fromChannel", ERROR_CODES.INVALID_PARAM);
|
|
56852
57118
|
const bundleZip = Buffer.from(zipBase64, "base64");
|
|
56853
57119
|
try {
|
|
56854
57120
|
const { extId, installedVersion } = await installFromChannel(
|
|
@@ -56868,9 +57134,7 @@ function buildExtensionHandlers(deps) {
|
|
|
56868
57134
|
};
|
|
56869
57135
|
const updateFromChannelHandler = async (frame, _client, ctx) => {
|
|
56870
57136
|
assertOwner(ctx);
|
|
56871
|
-
const channelRef =
|
|
56872
|
-
const snapshotHash = pickStringField(frame, "snapshotHash");
|
|
56873
|
-
const zipBase64 = pickStringField(frame, "zipBase64");
|
|
57137
|
+
const { channelRef, snapshotHash, zipBase64 } = parseArgs2(ExtensionFromChannelArgs, frame, "fromChannel", ERROR_CODES.INVALID_PARAM);
|
|
56874
57138
|
const bundleZip = Buffer.from(zipBase64, "base64");
|
|
56875
57139
|
try {
|
|
56876
57140
|
const result = await updateFromChannel(
|
|
@@ -57635,10 +57899,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
57635
57899
|
return { response: { projects: metas.map(toProjectWithStatus) } };
|
|
57636
57900
|
};
|
|
57637
57901
|
const getProject = async (frame, _client, ctx) => {
|
|
57638
|
-
const f = frame;
|
|
57639
|
-
if (typeof f.sessionId !== "string" || !f.sessionId) {
|
|
57640
|
-
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, "getProject: sessionId required");
|
|
57641
|
-
}
|
|
57902
|
+
const f = parseArgs2(GetProjectArgsSchema, frame, "getProject");
|
|
57642
57903
|
if (ctx && !canAccessSession(ctx, f.sessionId, "read", {
|
|
57643
57904
|
readSession: (sid) => sessionManager.findOwnedSession(sid) ?? null
|
|
57644
57905
|
})) {
|
|
@@ -57653,13 +57914,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
57653
57914
|
return { response: { project: meta ? toProjectWithStatus(meta) : null } };
|
|
57654
57915
|
};
|
|
57655
57916
|
const createProject = async (frame, _client, ctx) => {
|
|
57656
|
-
const f = frame;
|
|
57657
|
-
if (typeof f.sessionId !== "string" || !f.sessionId) {
|
|
57658
|
-
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, "createProject: sessionId required");
|
|
57659
|
-
}
|
|
57660
|
-
if (typeof f.name !== "string" || !f.name) {
|
|
57661
|
-
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, "createProject: name required");
|
|
57662
|
-
}
|
|
57917
|
+
const f = parseArgs2(CreateProjectArgsSchema, frame, "createProject");
|
|
57663
57918
|
const session = sessionManager.findOwnedSession(f.sessionId);
|
|
57664
57919
|
if (!session) {
|
|
57665
57920
|
throw new ClawdError(ERROR_CODES.SESSION_NOT_FOUND, `session ${f.sessionId} not found`);
|
|
@@ -57713,8 +57968,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
57713
57968
|
return { response: { project, projectDir: userStore.projectDir(project.name) }, broadcast };
|
|
57714
57969
|
};
|
|
57715
57970
|
const deleteProject = async (frame, _client, ctx) => {
|
|
57716
|
-
const name = frame
|
|
57717
|
-
if (typeof name !== "string") throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, "deleteProject: name required");
|
|
57971
|
+
const { name } = parseArgs2(DeleteProjectArgsSchema, frame, "deleteProject");
|
|
57718
57972
|
const userStore = resolveStore({ ctx, projectName: name });
|
|
57719
57973
|
await devServerLifecycle.stopForProject(name);
|
|
57720
57974
|
await userStore.delete(name);
|
|
@@ -57722,9 +57976,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
57722
57976
|
return { response: {} };
|
|
57723
57977
|
};
|
|
57724
57978
|
const updateProjectPort = async (frame, _client, ctx) => {
|
|
57725
|
-
const f = frame;
|
|
57726
|
-
if (typeof f.name !== "string") throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, "updateProjectPort: name required");
|
|
57727
|
-
if (typeof f.newPort !== "number") throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, "updateProjectPort: newPort required");
|
|
57979
|
+
const f = parseArgs2(UpdateProjectPortArgsSchema, frame, "updateProjectPort");
|
|
57728
57980
|
const userStore = resolveStore({ ctx, projectName: f.name });
|
|
57729
57981
|
await devServerLifecycle.stopForProject(f.name);
|
|
57730
57982
|
const project = await userStore.updatePort(f.name, f.newPort);
|
|
@@ -57732,9 +57984,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
57732
57984
|
return { response: { project } };
|
|
57733
57985
|
};
|
|
57734
57986
|
const setProdUrl = async (frame, _client, ctx) => {
|
|
57735
|
-
const f = frame;
|
|
57736
|
-
if (typeof f.name !== "string") throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, "setProdUrl: name required");
|
|
57737
|
-
if (typeof f.url !== "string") throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, "setProdUrl: url required");
|
|
57987
|
+
const f = parseArgs2(SetProdUrlArgsSchema, frame, "setProdUrl");
|
|
57738
57988
|
ensureProjectWriteAccess(ctx, { projectName: f.name });
|
|
57739
57989
|
const userStore = resolveStore({ ctx, projectName: f.name });
|
|
57740
57990
|
const project = await userStore.setProdUrl(f.name, f.url);
|
|
@@ -57743,10 +57993,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
57743
57993
|
return { response: { project } };
|
|
57744
57994
|
};
|
|
57745
57995
|
const startDevServer = async (frame, _client, ctx) => {
|
|
57746
|
-
const f = frame;
|
|
57747
|
-
if (typeof f.sessionId !== "string" || !f.sessionId) {
|
|
57748
|
-
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, "startDevServer: sessionId required");
|
|
57749
|
-
}
|
|
57996
|
+
const f = parseArgs2(StartDevServerArgsSchema, frame, "startDevServer");
|
|
57750
57997
|
const force = f.force === true;
|
|
57751
57998
|
ensureProjectWriteAccess(ctx, { sessionId: f.sessionId });
|
|
57752
57999
|
const session = sessionManager.findOwnedSession(f.sessionId);
|
|
@@ -57805,13 +58052,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
57805
58052
|
return { response: { project: meta } };
|
|
57806
58053
|
};
|
|
57807
58054
|
const reportStage = async (frame, _client, ctx) => {
|
|
57808
|
-
const f = frame;
|
|
57809
|
-
if (typeof f.sessionId !== "string" || !f.sessionId) {
|
|
57810
|
-
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, "reportStage: sessionId required");
|
|
57811
|
-
}
|
|
57812
|
-
if (typeof f.stage !== "string") {
|
|
57813
|
-
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, "reportStage: stage required");
|
|
57814
|
-
}
|
|
58055
|
+
const f = parseArgs2(ReportStageArgsSchema, frame, "reportStage");
|
|
57815
58056
|
if (!ASSISTANT_REPORTABLE_STAGES.includes(f.stage)) {
|
|
57816
58057
|
throw new ClawdError(
|
|
57817
58058
|
ERROR_CODES.VALIDATION_ERROR,
|
|
@@ -57839,10 +58080,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
57839
58080
|
return { response: { ok: true } };
|
|
57840
58081
|
};
|
|
57841
58082
|
const stopDevServer = async (frame, _client, ctx) => {
|
|
57842
|
-
const f = frame;
|
|
57843
|
-
if (typeof f.sessionId !== "string" || !f.sessionId) {
|
|
57844
|
-
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, "stopDevServer: sessionId required");
|
|
57845
|
-
}
|
|
58083
|
+
const f = parseArgs2(StopDevServerArgsSchema, frame, "stopDevServer");
|
|
57846
58084
|
ensureProjectWriteAccess(ctx, { sessionId: f.sessionId });
|
|
57847
58085
|
const session = sessionManager.findOwnedSession(f.sessionId);
|
|
57848
58086
|
if (!session) {
|
|
@@ -58652,6 +58890,7 @@ var DevServerSupervisor = class extends import_node_events2.EventEmitter {
|
|
|
58652
58890
|
};
|
|
58653
58891
|
|
|
58654
58892
|
// src/handlers/dispatch-rpc.ts
|
|
58893
|
+
init_zod();
|
|
58655
58894
|
init_protocol();
|
|
58656
58895
|
async function dispatchRpc(method, frame, client, ctx, deps) {
|
|
58657
58896
|
if (!METHOD_NAMES.includes(method)) {
|
|
@@ -58675,7 +58914,14 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
|
|
|
58675
58914
|
);
|
|
58676
58915
|
}
|
|
58677
58916
|
}
|
|
58678
|
-
|
|
58917
|
+
try {
|
|
58918
|
+
return await handler(frame, client, ctx);
|
|
58919
|
+
} catch (err) {
|
|
58920
|
+
if (err instanceof ZodError) {
|
|
58921
|
+
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, err.message);
|
|
58922
|
+
}
|
|
58923
|
+
throw err;
|
|
58924
|
+
}
|
|
58679
58925
|
}
|
|
58680
58926
|
|
|
58681
58927
|
// src/extension/runtime.ts
|
|
@@ -59383,7 +59629,7 @@ async function startDaemon(config) {
|
|
|
59383
59629
|
personaRoot: import_node_path62.default.join(config.dataDir, "personas"),
|
|
59384
59630
|
// dispatch / shift 自动化 spawn 按 persona 绑定 tool 起 B session(codex persona 用 codex)。
|
|
59385
59631
|
// personaRegistry 声明在 manager 之后(同作用域 const,调用时机在启动完成后,无 TDZ 风险)。
|
|
59386
|
-
getPersonaTool: (
|
|
59632
|
+
getPersonaTool: (personaId2) => personaRegistry.get(personaId2)?.tool,
|
|
59387
59633
|
usersRoot,
|
|
59388
59634
|
personaStore,
|
|
59389
59635
|
ownerDisplayName,
|
|
@@ -59805,7 +60051,7 @@ async function startDaemon(config) {
|
|
|
59805
60051
|
// 共享 deploy-kit 根:scaffold/publish 脚本骨架 + 阿里云凭证单一真源。
|
|
59806
60052
|
deployKitRoot: import_node_path62.default.join(config.dataDir, "deploy-kit"),
|
|
59807
60053
|
// scaffold/publish 按当前 session 的 persona 解析其安装根,让每个 persona 用自己的模板/注入配置。
|
|
59808
|
-
resolvePersonaRoot: (
|
|
60054
|
+
resolvePersonaRoot: (personaId2) => import_node_path62.default.join(config.dataDir, "personas", personaId2),
|
|
59809
60055
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2.2):
|
|
59810
60056
|
// 复用 SessionManagerDeps.broadcastFrame 同款 dispatch 逻辑 —— runner 调 manager.send
|
|
59811
60057
|
// 取回 broadcast 帧后逐帧 push 到 transport,跟 manager 自身的 deps 一致。
|
|
@@ -59899,9 +60145,9 @@ async function startDaemon(config) {
|
|
|
59899
60145
|
});
|
|
59900
60146
|
},
|
|
59901
60147
|
// B 角色:判断 targetPersona 是否 public(跨设备授权边界,private 拒)。
|
|
59902
|
-
getPersonaPublic: (
|
|
60148
|
+
getPersonaPublic: (personaId2) => personaRegistry.get(personaId2)?.public ?? false,
|
|
59903
60149
|
// model 校验按 target persona 绑定 tool 选表(claude / codex 模型集不同)
|
|
59904
|
-
getPersonaTool: (
|
|
60150
|
+
getPersonaTool: (personaId2) => personaRegistry.get(personaId2)?.tool
|
|
59905
60151
|
});
|
|
59906
60152
|
handlers = { ...handlers, ...dispatchHandlers };
|
|
59907
60153
|
const shiftHandlers = buildShiftInternalHandlers({
|