@clawos-dev/clawd 0.2.90-beta.169.a6af395 → 0.2.90
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 +100 -2
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -65,6 +65,14 @@ var init_methods = __esm({
|
|
|
65
65
|
"session:unsubscribe",
|
|
66
66
|
"session:pin",
|
|
67
67
|
"session:reorderPins",
|
|
68
|
+
// mirror peer sessions (2026-05-26): owner-only RPC,写/删本机 mirror SessionFile —
|
|
69
|
+
// mirror 是「**我**在朋友 daemon 上自己创建的 session」的本机持久化副本(不是朋友的会话),
|
|
70
|
+
// 方便 sidebar 跨设备聚合。daemon dumb 写删,**不广播任何 push 帧** (不发 session:info /
|
|
71
|
+
// session:deleted);UI 是写入唯一源,双写完成后通过 cache.setData('sessions', ...) 同步
|
|
72
|
+
// 本地 sidebar state。native session:* handler 完全不感知 mirror (UI 操作 mirror 不复用
|
|
73
|
+
// native 路径)。
|
|
74
|
+
"peerSession:upsert",
|
|
75
|
+
"peerSession:remove",
|
|
68
76
|
"permission:respond",
|
|
69
77
|
// AskUserQuestion 表单回写:UI 答完所有 question 后调用,daemon 把答案合并进 updated_input
|
|
70
78
|
// 写一条 control_response 到 CC stdin(详见 events.ts session:question JSDoc)
|
|
@@ -4493,7 +4501,7 @@ var init_persona_schemas = __esm({
|
|
|
4493
4501
|
});
|
|
4494
4502
|
|
|
4495
4503
|
// ../protocol/src/schemas.ts
|
|
4496
|
-
var SessionStatusSchema, UsageSchema, ContextUsageSchema, sessionMetaShape, SessionMetaSchema, ModelInfoSchema, ModeInfoSchema, ConfigFieldSchemaSchema, CapabilitiesGetArgs, CapabilitiesResponseSchema, AllowRuleSchema, SessionFileSchema, ParsedEventBase, HistoryUserMetaSchema, SubagentToolStatsSchema, StructuredPatchHunkSchema, ToolResultExtraSchema, MemoryEntrySchema, AskQuestionOptionSchema, AskQuestionItemSchema, ParsedEventSchema, SessionCreateArgs, 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, SessionReorderPinsArgs, GitRootArgs, GitRootResponseSchema, GitBranchArgs, GitBranchResponseSchema, GitBranchesArgs, GitBranchesResponseSchema, HistoryRecentDirsArgs, RecentDirEntrySchema, HistoryRecentDirsResponseSchema, SessionQuestionFrameSchema, SessionQuestionClearedFrameSchema, AnswerQuestionArgs, AnswerQuestionResponseSchema, CancelQuestionArgs, CancelQuestionResponseSchema, AuthRequestFrameSchema, AuthOkFrameSchema, TunnelExitedEventSchema, TunnelUnavailableEventSchema, InfoRunningSessionSchema, InfoResponseSchema;
|
|
4504
|
+
var SessionStatusSchema, UsageSchema, ContextUsageSchema, sessionMetaShape, SessionMetaSchema, ModelInfoSchema, ModeInfoSchema, ConfigFieldSchemaSchema, CapabilitiesGetArgs, CapabilitiesResponseSchema, AllowRuleSchema, SessionFileSchema, ParsedEventBase, HistoryUserMetaSchema, SubagentToolStatsSchema, StructuredPatchHunkSchema, ToolResultExtraSchema, MemoryEntrySchema, AskQuestionOptionSchema, AskQuestionItemSchema, ParsedEventSchema, SessionCreateArgs, 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, TunnelExitedEventSchema, TunnelUnavailableEventSchema, InfoRunningSessionSchema, InfoResponseSchema;
|
|
4497
4505
|
var init_schemas = __esm({
|
|
4498
4506
|
"../protocol/src/schemas.ts"() {
|
|
4499
4507
|
"use strict";
|
|
@@ -4621,6 +4629,35 @@ var init_schemas = __esm({
|
|
|
4621
4629
|
* 当前为 caller 自报,daemon 不密码学验证真伪;强身份验签是独立工作(B 方案)。
|
|
4622
4630
|
*/
|
|
4623
4631
|
creatorOwnerPrincipalId: external_exports.string().min(1).optional(),
|
|
4632
|
+
/**
|
|
4633
|
+
* Mirror peer sessions (2026-05-26): mirror 标识。**我在朋友 daemon 上以 guest ctx
|
|
4634
|
+
* 创建的 session**,远端是 source of truth,本机是该 session 的持久化副本,方便
|
|
4635
|
+
* sidebar 跨设备聚合。字段值是远端 daemon 的 ownerPrincipalId(即我接入的那位朋友)。
|
|
4636
|
+
*
|
|
4637
|
+
* 语义关键澄清:mirror **不是朋友创建给我的会话**——它是我自己的会话,只是在朋友
|
|
4638
|
+
* 的机器上跑。sidebar chip 显示 `@<朋友>` 暗示「位置」,不是「来源」。
|
|
4639
|
+
*
|
|
4640
|
+
* - undefined / 缺省 → 本机 native session(在我自己机器上跑)
|
|
4641
|
+
* - 非空 → 我的会话在该 ownerPrincipalId 朋友的 daemon 上跑,本机为持久化副本
|
|
4642
|
+
*
|
|
4643
|
+
* 与 `creatorPrincipalId` / `creatorOwnerPrincipalId` 在四类 session 下取值矩阵:
|
|
4644
|
+
* | 形态 | creatorPrincipalId | creatorOwnerPrincipalId | originOwnerPrincipalId |
|
|
4645
|
+
* |-------------------------------------|--------------------------|-------------------------|------------------------|
|
|
4646
|
+
* | 本机 owner 自创 | 本机 ownerPrincipalId | 本机 ownerPrincipalId | undefined |
|
|
4647
|
+
* | 本机被别人通过 personal token 接入创建 | 远端接入者 cap.id | 远端接入者 ownerPrincipalId | undefined |
|
|
4648
|
+
* | 我在朋友 daemon 上以 guest ctx 创建(mirror 回本机) | 朋友 daemon personal cap.id | 我自己 ownerPrincipalId | 朋友 ownerPrincipalId |
|
|
4649
|
+
*
|
|
4650
|
+
* UI 用法:
|
|
4651
|
+
* - sidebar Active/Pinned/Recents 过滤:`origin 非空 → 一律视作 self`(绕过 #739 隔离)
|
|
4652
|
+
* - 行内显示 `@<朋友>` chip 暗示位置
|
|
4653
|
+
* - 进 ChatPanel 时按 origin 路由到 `pool.ensureRemoteForOwner(origin)` 走远端
|
|
4654
|
+
*
|
|
4655
|
+
* daemon 用法:
|
|
4656
|
+
* - `peerSession:upsert` / `peerSession:remove` 一族 RPC 专管 mirror 写删;
|
|
4657
|
+
* daemon dumb write/delete,**不广播任何 push 帧**,UI 是写入唯一源
|
|
4658
|
+
* - native `session:*` handler 完全不感知 mirror(UI 操作 mirror 不走 native 路径)
|
|
4659
|
+
*/
|
|
4660
|
+
originOwnerPrincipalId: external_exports.string().min(1).optional(),
|
|
4624
4661
|
createdAt: external_exports.string().min(1),
|
|
4625
4662
|
updatedAt: external_exports.string().min(1)
|
|
4626
4663
|
});
|
|
@@ -4976,6 +5013,14 @@ var init_schemas = __esm({
|
|
|
4976
5013
|
sessionId: external_exports.string().min(1),
|
|
4977
5014
|
pinned: external_exports.boolean()
|
|
4978
5015
|
});
|
|
5016
|
+
PeerSessionUpsertArgs = SessionFileSchema;
|
|
5017
|
+
PeerSessionUpsertResponseSchema = external_exports.object({
|
|
5018
|
+
type: external_exports.literal("peerSession:upsert:ok")
|
|
5019
|
+
});
|
|
5020
|
+
PeerSessionRemoveArgs = external_exports.object({ sessionId: external_exports.string().min(1) });
|
|
5021
|
+
PeerSessionRemoveResponseSchema = external_exports.object({
|
|
5022
|
+
type: external_exports.literal("peerSession:remove:ok")
|
|
5023
|
+
});
|
|
4979
5024
|
SessionReorderPinsArgs = external_exports.object({
|
|
4980
5025
|
orderedIds: external_exports.array(external_exports.string().min(1)).min(1)
|
|
4981
5026
|
});
|
|
@@ -22940,6 +22985,30 @@ var SessionManager = class {
|
|
|
22940
22985
|
const file = this.getFile(args.sessionId);
|
|
22941
22986
|
return { response: file, broadcast: [] };
|
|
22942
22987
|
}
|
|
22988
|
+
// mirror peer sessions (2026-05-26):把来自朋友 daemon 的 SessionFile(originOwnerPrincipalId
|
|
22989
|
+
// 非空)持久化到本机 default store。dumb write,**不广播 push 帧**——UI 是写入唯一源,
|
|
22990
|
+
// 双写完成后通过 cache.setData 同步 sidebar 本地 state。
|
|
22991
|
+
//
|
|
22992
|
+
// 强制走 deps.store(即 default scope),不走 scopeForFile:mirror 物理落 default 即可。
|
|
22993
|
+
// 远端 creator / origin 字段原值保留(不被本机 ctx 派生覆写)。
|
|
22994
|
+
//
|
|
22995
|
+
// strip 远端 personaId:mirror SessionFile 上的 ownerPersonaId 是朋友 daemon 的 persona
|
|
22996
|
+
// 目录 id,本机不持有对应 persona。留着会让按 ownerPersonaId 反查的本机消费者
|
|
22997
|
+
// (MyPersonasSection 等)把 mirror 误聚到同 id persona 下。写入前清掉。
|
|
22998
|
+
//
|
|
22999
|
+
// 与 manager.create / manager.update 区别:
|
|
23000
|
+
// - 不走 newRunner / attachObserver / cwd 校验(mirror 是纯 metadata 层)
|
|
23001
|
+
// - 不发 session:info 帧(manager.create / .update 通过 reducer/wireCollector 发 push)
|
|
23002
|
+
mirrorUpsert(file) {
|
|
23003
|
+
const { ownerPersonaId: _stripped, ...rest } = file;
|
|
23004
|
+
return this.deps.store.write(rest);
|
|
23005
|
+
}
|
|
23006
|
+
// mirror peer sessions:删本机 mirror SessionFile。mirror 一律落 default(mirrorUpsert
|
|
23007
|
+
// 强制走 deps.store + strip ownerPersonaId),删也只删 default。idempotent:找不到
|
|
23008
|
+
// 不 throw(store.delete 内部 ENOENT 兜底返 false 不 throw)。**不广播 session:deleted**。
|
|
23009
|
+
mirrorRemove(sessionId) {
|
|
23010
|
+
this.deps.store.delete(sessionId);
|
|
23011
|
+
}
|
|
22943
23012
|
// observer 上报"jsonl 写入了一条 user 行"时调用:在 buffer 里找到与之对应的、
|
|
22944
23013
|
// 还没建立映射的最早一条 synth user_text,记下 synth → real 映射。
|
|
22945
23014
|
// 找不到匹配的 synth(runner 不存在 / buffer 已被 /clear 清空 / 真 uuid 来自纯 history
|
|
@@ -29102,6 +29171,28 @@ function buildSessionHandlers(deps) {
|
|
|
29102
29171
|
}
|
|
29103
29172
|
};
|
|
29104
29173
|
};
|
|
29174
|
+
const peerSessionUpsert = async (frame, _client, ctx) => {
|
|
29175
|
+
if (ctx && ctx.principal.kind !== "owner") {
|
|
29176
|
+
throw new ClawdError(
|
|
29177
|
+
ERROR_CODES.UNAUTHORIZED,
|
|
29178
|
+
`principal ${ctx.principal.kind}:${ctx.principal.id} cannot peerSession:upsert`
|
|
29179
|
+
);
|
|
29180
|
+
}
|
|
29181
|
+
const file = PeerSessionUpsertArgs.parse(frame);
|
|
29182
|
+
manager.mirrorUpsert(file);
|
|
29183
|
+
return { response: { type: "peerSession:upsert:ok" }, broadcast: [] };
|
|
29184
|
+
};
|
|
29185
|
+
const peerSessionRemove = async (frame, _client, ctx) => {
|
|
29186
|
+
if (ctx && ctx.principal.kind !== "owner") {
|
|
29187
|
+
throw new ClawdError(
|
|
29188
|
+
ERROR_CODES.UNAUTHORIZED,
|
|
29189
|
+
`principal ${ctx.principal.kind}:${ctx.principal.id} cannot peerSession:remove`
|
|
29190
|
+
);
|
|
29191
|
+
}
|
|
29192
|
+
const args = PeerSessionRemoveArgs.parse(frame);
|
|
29193
|
+
manager.mirrorRemove(args.sessionId);
|
|
29194
|
+
return { response: { type: "peerSession:remove:ok" }, broadcast: [] };
|
|
29195
|
+
};
|
|
29105
29196
|
return {
|
|
29106
29197
|
"session:create": create,
|
|
29107
29198
|
"session:list": list,
|
|
@@ -29127,7 +29218,9 @@ function buildSessionHandlers(deps) {
|
|
|
29127
29218
|
"session:cancelQuestion": cancelQuestion,
|
|
29128
29219
|
"session:pty:input": ptyInput,
|
|
29129
29220
|
"session:pty:resize": ptyResize,
|
|
29130
|
-
"session:pty:snapshot": ptySnapshot
|
|
29221
|
+
"session:pty:snapshot": ptySnapshot,
|
|
29222
|
+
"peerSession:upsert": peerSessionUpsert,
|
|
29223
|
+
"peerSession:remove": peerSessionRemove
|
|
29131
29224
|
};
|
|
29132
29225
|
}
|
|
29133
29226
|
|
|
@@ -30205,6 +30298,11 @@ var METHOD_GRANT_MAP = {
|
|
|
30205
30298
|
"session:pin": CAPABILITY_SCOPED,
|
|
30206
30299
|
"session:reorderPins": ADMIN_ANY,
|
|
30207
30300
|
// owner 全局操作,无 personaId 维度
|
|
30301
|
+
// mirror peer sessions (2026-05-26):owner-only — guest 不应能写/删本机 mirror SessionFile
|
|
30302
|
+
// (会绕过 #739 隔离规则把伪造身份的 SessionFile 写进 default store)。handler 端内部 ctx
|
|
30303
|
+
// 校验,dispatcher 层一刀切 admin 也兜底。
|
|
30304
|
+
"peerSession:upsert": ADMIN_ANY,
|
|
30305
|
+
"peerSession:remove": ADMIN_ANY,
|
|
30208
30306
|
"permission:respond": CAPABILITY_SCOPED,
|
|
30209
30307
|
"session:answerQuestion": CAPABILITY_SCOPED,
|
|
30210
30308
|
"session:cancelQuestion": CAPABILITY_SCOPED,
|
package/package.json
CHANGED