@clawos-dev/clawd 0.2.428 → 0.2.430
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 +172 -33
- package/dist/dispatch/mcp-server.cjs +22 -2
- package/dist/share-md-viewer-error.html +1 -1
- package/dist/share-md-viewer.html +1 -1
- package/dist/share-ui/assets/guest-Dhztg3h0.css +32 -0
- package/dist/share-ui/assets/{guest-DEjZlGnf.js → guest-DzZs43Fu.js} +143 -141
- package/dist/share-ui/guest.html +2 -2
- package/package.json +1 -1
- package/dist/share-ui/assets/guest-B45i1AP-.css +0 -32
package/dist/cli.cjs
CHANGED
|
@@ -7260,7 +7260,7 @@ var init_principal = __esm({
|
|
|
7260
7260
|
});
|
|
7261
7261
|
|
|
7262
7262
|
// ../protocol/src/schemas.ts
|
|
7263
|
-
var SessionStatusSchema, ContextUsageSchema, sessionMetaShape, SessionMetaSchema, SelectOptionSchema, ModelInfoSchema, ModeInfoSchema, ConfigFieldSchemaSchema, CapabilitiesGetArgs, ToolFeaturesSchema, CapabilitiesResponseSchema, AllowRuleSchema, SessionFileSchema, ParsedEventBase, HistoryUserMetaSchema, SubagentToolStatsSchema, StructuredPatchHunkSchema, ToolResultExtraSchema, MemoryEntrySchema, AskQuestionOptionSchema, AskQuestionItemSchema, TURN_END_REASONS, ParsedEventSchema, SessionCreateArgs, ProjectEntry, ProjectPatchArgs, ProjectRevealArgs, ProjectCreateArgs, SessionImportExternalArgs, SessionListArgs, SessionIdArgs, SessionUpdateArgs, SessionSendArgs, SessionRewindArgs, SessionRewindResponseSchema, SessionRewindDiffArgs, RewindDiffHunkSchema, RewindDiffFileSchema, SessionRewindDiffResponseSchema, SessionRewindableMessageIdsResponseSchema, SessionResumeArgs, SessionForkArgs, SessionForkResponseSchema, SessionObserveArgs, SessionEventsArgs, PermissionRespondArgs, HistoryListArgs, HistoryReadArgs, HistorySubagentsArgs, HistorySubagentReadArgs, WorkspaceListArgs, WorkspaceReadArgs, SkillsListArgs, SkillEntrySchema, AgentEntrySchema, AgentsListArgs, AgentsListResponseSchema, SessionCurrentTurnSenderArgs, SessionSubscribeArgs, SessionPinArgs, SessionArchiveArgs, PeerSessionUpsertArgs, PeerSessionUpsertResponseSchema, PeerSessionRemoveArgs, PeerSessionRemoveResponseSchema, SessionReorderPinsArgs, GitRootArgs, GitRootResponseSchema, GitBranchArgs, GitBranchResponseSchema, GitBranchesArgs, GitBranchesResponseSchema, RecentDirEntrySchema, HistoryRecentDirsResponseSchema, SessionQuestionFrameSchema, SessionQuestionClearedFrameSchema, AnswerQuestionArgs, AnswerQuestionResponseSchema, CancelQuestionArgs, CancelQuestionResponseSchema, ClientInfoSchema, AuthRequestFrameSchema, AuthOkFrameSchema, DeviceConnectionEntrySchema, DeviceConnectionsResponseSchema, 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;
|
|
7263
|
+
var SessionStatusSchema, ContextUsageSchema, sessionMetaShape, SessionMetaSchema, SelectOptionSchema, ModelInfoSchema, ModeInfoSchema, ConfigFieldSchemaSchema, CapabilitiesGetArgs, ToolFeaturesSchema, CapabilitiesResponseSchema, AllowRuleSchema, SessionFileSchema, ParsedEventBase, HistoryUserMetaSchema, SubagentToolStatsSchema, StructuredPatchHunkSchema, ToolResultExtraSchema, MemoryEntrySchema, AskQuestionOptionSchema, AskQuestionItemSchema, TURN_END_REASONS, ParsedEventSchema, SessionCreateArgs, ProjectEntry, ProjectPatchArgs, ProjectRevealArgs, ProjectCreateArgs, SessionImportExternalArgs, SessionListArgs, SessionIdArgs, SessionUpdateArgs, QueuedMessage, SessionSendArgs, SessionDequeueArgs, SessionRewindArgs, SessionRewindResponseSchema, SessionRewindDiffArgs, RewindDiffHunkSchema, RewindDiffFileSchema, SessionRewindDiffResponseSchema, SessionRewindableMessageIdsResponseSchema, SessionResumeArgs, SessionForkArgs, SessionForkResponseSchema, SessionObserveArgs, SessionEventsArgs, PermissionRespondArgs, HistoryListArgs, HistoryReadArgs, HistorySubagentsArgs, HistorySubagentReadArgs, WorkspaceListArgs, WorkspaceReadArgs, SkillsListArgs, SkillEntrySchema, AgentEntrySchema, AgentsListArgs, AgentsListResponseSchema, SessionCurrentTurnSenderArgs, SessionSubscribeArgs, SessionPinArgs, SessionArchiveArgs, PeerSessionUpsertArgs, PeerSessionUpsertResponseSchema, PeerSessionRemoveArgs, PeerSessionRemoveResponseSchema, SessionReorderPinsArgs, GitRootArgs, GitRootResponseSchema, GitBranchArgs, GitBranchResponseSchema, GitBranchesArgs, GitBranchesResponseSchema, RecentDirEntrySchema, HistoryRecentDirsResponseSchema, SessionQuestionFrameSchema, SessionQuestionClearedFrameSchema, AnswerQuestionArgs, AnswerQuestionResponseSchema, CancelQuestionArgs, CancelQuestionResponseSchema, ClientInfoSchema, AuthRequestFrameSchema, AuthOkFrameSchema, DeviceConnectionEntrySchema, DeviceConnectionsResponseSchema, 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;
|
|
7264
7264
|
var init_schemas = __esm({
|
|
7265
7265
|
"../protocol/src/schemas.ts"() {
|
|
7266
7266
|
"use strict";
|
|
@@ -7831,9 +7831,25 @@ var init_schemas = __esm({
|
|
|
7831
7831
|
// 通过 sessionUpdate 修改这个字段。SessionFile 仍保留 appBuilderProject 字段供 daemon 内部 mutate。
|
|
7832
7832
|
})
|
|
7833
7833
|
});
|
|
7834
|
+
QueuedMessage = external_exports.object({
|
|
7835
|
+
id: external_exports.string().min(1),
|
|
7836
|
+
text: external_exports.string(),
|
|
7837
|
+
queuedAt: external_exports.number(),
|
|
7838
|
+
senderDisplayName: external_exports.string().optional()
|
|
7839
|
+
});
|
|
7834
7840
|
SessionSendArgs = external_exports.object({
|
|
7835
7841
|
sessionId: external_exports.string().min(1),
|
|
7836
|
-
text: external_exports.string()
|
|
7842
|
+
text: external_exports.string(),
|
|
7843
|
+
/**
|
|
7844
|
+
* turn 在跑时是入队还是直发。**入队与否由调用方显式声明,daemon 不按来源猜**:
|
|
7845
|
+
* UI 输入框传 true;IM / 飞书 / dispatch 注入不传 = 维持原状直发(老板 2026-08-31:
|
|
7846
|
+
* 其他地方先不加队列)。缺省 false → 行为与本字段引入前逐字一致。
|
|
7847
|
+
*/
|
|
7848
|
+
queueWhileRunning: external_exports.boolean().optional()
|
|
7849
|
+
});
|
|
7850
|
+
SessionDequeueArgs = external_exports.object({
|
|
7851
|
+
sessionId: external_exports.string().min(1),
|
|
7852
|
+
id: external_exports.string().min(1).optional()
|
|
7837
7853
|
});
|
|
7838
7854
|
SessionRewindArgs = external_exports.object({
|
|
7839
7855
|
sessionId: external_exports.string().min(1),
|
|
@@ -8407,9 +8423,13 @@ var init_methods = __esm({
|
|
|
8407
8423
|
args: SessionIdArgs
|
|
8408
8424
|
},
|
|
8409
8425
|
"session:send": {
|
|
8410
|
-
summary: "\u5411\u4F1A\u8BDD\u53D1\u4E00\u6761\u7528\u6237\u6D88\u606F\uFF08\u89E6\u53D1\u65B0\u4E00\u8F6E turn\uFF09",
|
|
8426
|
+
summary: "\u5411\u4F1A\u8BDD\u53D1\u4E00\u6761\u7528\u6237\u6D88\u606F\uFF08\u89E6\u53D1\u65B0\u4E00\u8F6E turn\uFF09\uFF1BqueueWhileRunning=true \u4E14 turn \u5728\u8DD1\u65F6\u6539\u4E3A\u8FDB\u961F\u5217",
|
|
8411
8427
|
args: SessionSendArgs
|
|
8412
8428
|
},
|
|
8429
|
+
"session:dequeue": {
|
|
8430
|
+
summary: "\u64A4\u9500\u6392\u961F\u4E2D\u7684\u6D88\u606F\uFF1A\u5E26 id \u5220\u4E00\u6761\uFF0C\u4E0D\u5E26 id \u6E05\u7A7A\u6574\u961F\uFF08spec 2026-08-31-chat-input-queue-design\uFF09",
|
|
8431
|
+
args: SessionDequeueArgs
|
|
8432
|
+
},
|
|
8413
8433
|
"session:currentTurnSender": {
|
|
8414
8434
|
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",
|
|
8415
8435
|
args: SessionCurrentTurnSenderArgs
|
|
@@ -45116,6 +45136,8 @@ function cloneState(s) {
|
|
|
45116
45136
|
// reduce 内 push/shift 在调用方原 state 上副作用(reducer 纯函数契约)
|
|
45117
45137
|
readyForSend: s.readyForSend,
|
|
45118
45138
|
pendingSend: s.pendingSend.slice(),
|
|
45139
|
+
// 同理浅拷贝:入队 / 出队都在 next 上原地改
|
|
45140
|
+
queuedSends: s.queuedSends.slice(),
|
|
45119
45141
|
// per-turn sender (spec §4.3):SenderInfo 只在 case 'send' 覆盖,其它 kind 直接复用引用
|
|
45120
45142
|
currentTurnSender: s.currentTurnSender
|
|
45121
45143
|
};
|
|
@@ -45150,6 +45172,48 @@ function resetReadyGate(next) {
|
|
|
45150
45172
|
next.pendingSend = [];
|
|
45151
45173
|
next.readyForSend = true;
|
|
45152
45174
|
}
|
|
45175
|
+
function queueFrame(state) {
|
|
45176
|
+
return {
|
|
45177
|
+
kind: "emit-frame",
|
|
45178
|
+
frame: {
|
|
45179
|
+
type: "session:queue",
|
|
45180
|
+
sessionId: state.file.sessionId,
|
|
45181
|
+
items: state.queuedSends.map((q) => ({
|
|
45182
|
+
id: q.id,
|
|
45183
|
+
text: q.text,
|
|
45184
|
+
queuedAt: q.queuedAt,
|
|
45185
|
+
...q.sender.displayName ? { senderDisplayName: q.sender.displayName } : {}
|
|
45186
|
+
}))
|
|
45187
|
+
}
|
|
45188
|
+
};
|
|
45189
|
+
}
|
|
45190
|
+
function clearQueuedSends(next, effects) {
|
|
45191
|
+
if (next.queuedSends.length === 0) return;
|
|
45192
|
+
next.queuedSends = [];
|
|
45193
|
+
effects.push(queueFrame(next));
|
|
45194
|
+
}
|
|
45195
|
+
function deliverUserText(next, args, deps) {
|
|
45196
|
+
const effects = [];
|
|
45197
|
+
next.currentTurnSender = args.sender;
|
|
45198
|
+
const userEvent = {
|
|
45199
|
+
kind: "user_text",
|
|
45200
|
+
text: args.text,
|
|
45201
|
+
uuid: deps.genUuid?.(),
|
|
45202
|
+
sender: args.sender,
|
|
45203
|
+
...args.meta ? { meta: args.meta } : {}
|
|
45204
|
+
};
|
|
45205
|
+
effects.push(...pushEventToBufferInPlace(next, userEvent, deps));
|
|
45206
|
+
if (deps.mode === "tui" && (next.file.tool ?? "claude") === "claude") {
|
|
45207
|
+
next.pendingSend.push(args.text);
|
|
45208
|
+
effects.push(...tryFlushPending(next, deps));
|
|
45209
|
+
} else {
|
|
45210
|
+
effects.push({
|
|
45211
|
+
kind: "write-stdin",
|
|
45212
|
+
payload: deps.encodeStdin(args.text, { sessionId: next.file.sessionId })
|
|
45213
|
+
});
|
|
45214
|
+
}
|
|
45215
|
+
return effects;
|
|
45216
|
+
}
|
|
45153
45217
|
var SEEN_UUID_CAP = 2e3;
|
|
45154
45218
|
function applyEventBatch(state, events, deps) {
|
|
45155
45219
|
if (events.length === 0) return { state, effects: [] };
|
|
@@ -45454,6 +45518,14 @@ function pushEventToBufferInPlace(next, event, deps) {
|
|
|
45454
45518
|
effects.push({ kind: "persist-file", file: next.file });
|
|
45455
45519
|
effects.push(sessionInfoFrame(next.file));
|
|
45456
45520
|
}
|
|
45521
|
+
if (isTurnEnd && next.procAlive && (next.status === "running" || next.status === "spawning") && next.queuedSends.length > 0) {
|
|
45522
|
+
const items = next.queuedSends;
|
|
45523
|
+
next.queuedSends = [];
|
|
45524
|
+
const merged = items.map((q) => q.text).join("\n\n");
|
|
45525
|
+
effects.push(queueFrame(next));
|
|
45526
|
+
effects.push(...deliverUserText(next, { text: merged, sender: items[0].sender }, deps));
|
|
45527
|
+
return effects;
|
|
45528
|
+
}
|
|
45457
45529
|
if (isTurnEnd && next.procAlive && (next.status === "running" || next.status === "spawning")) {
|
|
45458
45530
|
next.status = "running-idle";
|
|
45459
45531
|
effects.push({
|
|
@@ -45504,6 +45576,19 @@ function applyCommand(state, command, deps) {
|
|
|
45504
45576
|
const sessionId = next.file.sessionId;
|
|
45505
45577
|
switch (command.kind) {
|
|
45506
45578
|
case "send": {
|
|
45579
|
+
if (command.queueWhileRunning && (next.status === "running" || next.status === "spawning")) {
|
|
45580
|
+
next.queuedSends = [
|
|
45581
|
+
...next.queuedSends,
|
|
45582
|
+
{
|
|
45583
|
+
id: deps.genUuid?.() ?? `q-${deps.now()}-${next.queuedSends.length}`,
|
|
45584
|
+
text: command.text,
|
|
45585
|
+
queuedAt: deps.now(),
|
|
45586
|
+
sender: command.senderPrincipal
|
|
45587
|
+
}
|
|
45588
|
+
];
|
|
45589
|
+
effects.push(queueFrame(next));
|
|
45590
|
+
return { state: next, effects };
|
|
45591
|
+
}
|
|
45507
45592
|
if (next.status === "running-idle") {
|
|
45508
45593
|
effects.push({ kind: "cancel-idle-kill", sessionId });
|
|
45509
45594
|
next.status = next.procAlive ? "running" : "idle";
|
|
@@ -45540,28 +45625,20 @@ function applyCommand(state, command, deps) {
|
|
|
45540
45625
|
}
|
|
45541
45626
|
});
|
|
45542
45627
|
}
|
|
45543
|
-
next.currentTurnSender = command.senderPrincipal;
|
|
45544
|
-
const userEvent = {
|
|
45545
|
-
kind: "user_text",
|
|
45546
|
-
text: command.text,
|
|
45547
|
-
uuid: deps.genUuid?.(),
|
|
45548
|
-
sender: command.senderPrincipal,
|
|
45549
|
-
// dispatch 来源分型(L2):daemon 自注入的消息在 command 上显式带分型值。
|
|
45550
|
-
// history 侧同一条消息由 classifyUserMessage 从信封解出同一个值 —— 两路必须一致。
|
|
45551
|
-
...command.meta ? { meta: command.meta } : {}
|
|
45552
|
-
};
|
|
45553
|
-
const pushed = pushEventToBuffer(next, userEvent, deps);
|
|
45554
|
-
effects.push(...pushed.effects);
|
|
45555
45628
|
const procAliveBefore = state.procAlive;
|
|
45556
45629
|
const readyBefore = state.readyForSend;
|
|
45557
45630
|
const queueBefore = state.pendingSend.length;
|
|
45558
|
-
|
|
45559
|
-
|
|
45560
|
-
|
|
45561
|
-
|
|
45562
|
-
|
|
45563
|
-
|
|
45564
|
-
|
|
45631
|
+
effects.push(
|
|
45632
|
+
...deliverUserText(
|
|
45633
|
+
next,
|
|
45634
|
+
{
|
|
45635
|
+
text: command.text,
|
|
45636
|
+
sender: command.senderPrincipal,
|
|
45637
|
+
...command.meta ? { meta: command.meta } : {}
|
|
45638
|
+
},
|
|
45639
|
+
deps
|
|
45640
|
+
)
|
|
45641
|
+
);
|
|
45565
45642
|
rgDbg(deps, "send", {
|
|
45566
45643
|
sid: sessionId,
|
|
45567
45644
|
mode: deps.mode ?? "sdk",
|
|
@@ -45572,10 +45649,18 @@ function applyCommand(state, command, deps) {
|
|
|
45572
45649
|
textLen: command.text.length,
|
|
45573
45650
|
preview: command.text.slice(0, 40),
|
|
45574
45651
|
wroteStdin: effects.some((e) => e.kind === "write-stdin"),
|
|
45575
|
-
readyAfter:
|
|
45576
|
-
queueAfter:
|
|
45652
|
+
readyAfter: next.readyForSend,
|
|
45653
|
+
queueAfter: next.pendingSend.length
|
|
45577
45654
|
});
|
|
45578
|
-
return { state:
|
|
45655
|
+
return { state: next, effects };
|
|
45656
|
+
}
|
|
45657
|
+
// 撤队列(spec 2026-08-31-chat-input-queue-design):带 id 删一条,不带 id 清空整队。
|
|
45658
|
+
// 中断也走这条(manager.interrupt 转发),"中断 = 队列作废"是老板拍的语义。
|
|
45659
|
+
case "dequeue": {
|
|
45660
|
+
if (next.queuedSends.length === 0) return { state: next, effects };
|
|
45661
|
+
next.queuedSends = command.id ? next.queuedSends.filter((q) => q.id !== command.id) : [];
|
|
45662
|
+
if (next.queuedSends.length !== state.queuedSends.length) effects.push(queueFrame(next));
|
|
45663
|
+
return { state: next, effects };
|
|
45579
45664
|
}
|
|
45580
45665
|
case "stop": {
|
|
45581
45666
|
for (const toolUseId of Object.keys(state.pendingQuestions ?? {})) {
|
|
@@ -45591,6 +45676,7 @@ function applyCommand(state, command, deps) {
|
|
|
45591
45676
|
next.pendingPermissions = {};
|
|
45592
45677
|
next.pendingQuestions = {};
|
|
45593
45678
|
resetReadyGate(next);
|
|
45679
|
+
clearQueuedSends(next, effects);
|
|
45594
45680
|
if (next.procAlive) {
|
|
45595
45681
|
next.status = "stopping";
|
|
45596
45682
|
effects.push({ kind: "kill", signal: "SIGKILL" });
|
|
@@ -45636,6 +45722,7 @@ function applyCommand(state, command, deps) {
|
|
|
45636
45722
|
next.pendingPermissions = {};
|
|
45637
45723
|
next.pendingQuestions = {};
|
|
45638
45724
|
resetReadyGate(next);
|
|
45725
|
+
clearQueuedSends(next, effects);
|
|
45639
45726
|
if (next.procAlive) {
|
|
45640
45727
|
effects.push({ kind: "kill", signal: "SIGKILL" });
|
|
45641
45728
|
}
|
|
@@ -45700,6 +45787,7 @@ function applyCommand(state, command, deps) {
|
|
|
45700
45787
|
});
|
|
45701
45788
|
}
|
|
45702
45789
|
resetReadyGate(next);
|
|
45790
|
+
clearQueuedSends(next, effects);
|
|
45703
45791
|
if (next.procAlive) {
|
|
45704
45792
|
effects.push({ kind: "kill", signal: "SIGKILL" });
|
|
45705
45793
|
}
|
|
@@ -45737,6 +45825,7 @@ function applyCommand(state, command, deps) {
|
|
|
45737
45825
|
next.freshSpawn = false;
|
|
45738
45826
|
next.seenUuids = [];
|
|
45739
45827
|
resetReadyGate(next);
|
|
45828
|
+
clearQueuedSends(next, effects);
|
|
45740
45829
|
effects.push({ kind: "persist-file", file: nextFile });
|
|
45741
45830
|
effects.push(sessionInfoFrame(nextFile));
|
|
45742
45831
|
effects.push({
|
|
@@ -45793,6 +45882,8 @@ function reduceSessionInner(state, input, deps) {
|
|
|
45793
45882
|
next.pendingBgTasks = [];
|
|
45794
45883
|
const interruptEffects = next.turnOpen ? pushEventToBufferInPlace(next, { kind: "turn_end", reason: "interrupted" }, deps) : [];
|
|
45795
45884
|
resetReadyGate(next);
|
|
45885
|
+
const queueEffects = [];
|
|
45886
|
+
clearQueuedSends(next, queueEffects);
|
|
45796
45887
|
const sessionId = next.file.sessionId;
|
|
45797
45888
|
const clearedEffects = Object.keys(state.pendingQuestions ?? {}).map(
|
|
45798
45889
|
(toolUseId) => ({
|
|
@@ -45818,7 +45909,8 @@ function reduceSessionInner(state, input, deps) {
|
|
|
45818
45909
|
exitCode: input.code
|
|
45819
45910
|
}
|
|
45820
45911
|
},
|
|
45821
|
-
...clearedEffects
|
|
45912
|
+
...clearedEffects,
|
|
45913
|
+
...queueEffects
|
|
45822
45914
|
]
|
|
45823
45915
|
};
|
|
45824
45916
|
}
|
|
@@ -45826,6 +45918,8 @@ function reduceSessionInner(state, input, deps) {
|
|
|
45826
45918
|
const next = cloneState(state);
|
|
45827
45919
|
next.status = "error";
|
|
45828
45920
|
resetReadyGate(next);
|
|
45921
|
+
const queueEffects = [];
|
|
45922
|
+
clearQueuedSends(next, queueEffects);
|
|
45829
45923
|
return {
|
|
45830
45924
|
state: next,
|
|
45831
45925
|
effects: [
|
|
@@ -45837,7 +45931,8 @@ function reduceSessionInner(state, input, deps) {
|
|
|
45837
45931
|
status: next.status,
|
|
45838
45932
|
message: input.message
|
|
45839
45933
|
}
|
|
45840
|
-
}
|
|
45934
|
+
},
|
|
45935
|
+
...queueEffects
|
|
45841
45936
|
]
|
|
45842
45937
|
};
|
|
45843
45938
|
}
|
|
@@ -46640,6 +46735,8 @@ function makeInitialState(file, subSessionMeta) {
|
|
|
46640
46735
|
// TUI 模式由 reducer send 分支按 deps.mode='tui' 主动翻 readyForSend=false
|
|
46641
46736
|
readyForSend: true,
|
|
46642
46737
|
pendingSend: [],
|
|
46738
|
+
// 输入框排队队列(spec 2026-08-31-chat-input-queue-design):初始空
|
|
46739
|
+
queuedSends: [],
|
|
46643
46740
|
// per-turn sender 2026-07-08 spec §4.3:初始 null;case 'send' 首次覆盖
|
|
46644
46741
|
currentTurnSender: null
|
|
46645
46742
|
};
|
|
@@ -47488,12 +47585,34 @@ var SessionManager = class {
|
|
|
47488
47585
|
const { broadcast } = this.withCollector(() => {
|
|
47489
47586
|
runner.input({
|
|
47490
47587
|
kind: "command",
|
|
47491
|
-
command: {
|
|
47588
|
+
command: {
|
|
47589
|
+
kind: "send",
|
|
47590
|
+
text: args.text,
|
|
47591
|
+
senderPrincipal,
|
|
47592
|
+
// 排队与否由调用方显式声明(UI 输入框传 true;IM / dispatch 不传 = 直发)
|
|
47593
|
+
...args.queueWhileRunning ? { queueWhileRunning: true } : {}
|
|
47594
|
+
}
|
|
47492
47595
|
});
|
|
47493
47596
|
});
|
|
47494
47597
|
this.maybeGenerateTitle(existing, args.text);
|
|
47495
47598
|
return { response: { ok: true }, broadcast };
|
|
47496
47599
|
}
|
|
47600
|
+
/**
|
|
47601
|
+
* 撤排队消息(spec 2026-08-31-chat-input-queue-design):带 id 删一条,不带 id 清空整队。
|
|
47602
|
+
* session 没起过 runner = 没有队列,直接返 ok(幂等,不抛)。
|
|
47603
|
+
*/
|
|
47604
|
+
dequeue(args) {
|
|
47605
|
+
this.getFile(args.sessionId);
|
|
47606
|
+
const runner = this.runners.get(args.sessionId);
|
|
47607
|
+
if (!runner) return { response: { ok: true }, broadcast: [] };
|
|
47608
|
+
const { broadcast } = this.withCollector(() => {
|
|
47609
|
+
runner.input({
|
|
47610
|
+
kind: "command",
|
|
47611
|
+
command: { kind: "dequeue", ...args.id ? { id: args.id } : {} }
|
|
47612
|
+
});
|
|
47613
|
+
});
|
|
47614
|
+
return { response: { ok: true }, broadcast };
|
|
47615
|
+
}
|
|
47497
47616
|
/**
|
|
47498
47617
|
* 首条 send 触发的智能标题自产(spec:PR #1196 追加拍板 2026-08-17)。
|
|
47499
47618
|
* 背景见 tools/title-generator.ts 头注释——CC/codex 两条上游标题数据源都等不来
|
|
@@ -47639,17 +47758,27 @@ var SessionManager = class {
|
|
|
47639
47758
|
`session not running: ${args.sessionId}`
|
|
47640
47759
|
);
|
|
47641
47760
|
}
|
|
47761
|
+
const queued = runner.getState().queuedSends.map((q) => ({
|
|
47762
|
+
id: q.id,
|
|
47763
|
+
text: q.text,
|
|
47764
|
+
queuedAt: q.queuedAt,
|
|
47765
|
+
...q.sender.displayName ? { senderDisplayName: q.sender.displayName } : {}
|
|
47766
|
+
}));
|
|
47642
47767
|
const tsid = runner.getState().file.toolSessionId;
|
|
47643
47768
|
const pty = tsid ? this.ptyTransports.get(tsid) : void 0;
|
|
47644
47769
|
if (pty) {
|
|
47645
|
-
|
|
47770
|
+
const stopped = await this.stop({ sessionId: args.sessionId });
|
|
47771
|
+
return { ...stopped, response: { ...stopped.response, queued } };
|
|
47646
47772
|
}
|
|
47773
|
+
const { broadcast } = this.withCollector(() => {
|
|
47774
|
+
runner.input({ kind: "command", command: { kind: "dequeue" } });
|
|
47775
|
+
});
|
|
47647
47776
|
try {
|
|
47648
47777
|
await runner.interrupt();
|
|
47649
47778
|
} catch (err) {
|
|
47650
47779
|
throw new ClawdError(ERROR_CODES.INTERNAL, err.message);
|
|
47651
47780
|
}
|
|
47652
|
-
return { response: { ok: true }, broadcast
|
|
47781
|
+
return { response: { ok: true, queued }, broadcast };
|
|
47653
47782
|
}
|
|
47654
47783
|
// 批量版本:UI 打开 session 时一次性拿到"磁盘和快照有差异"的 user message id 集合,
|
|
47655
47784
|
// 用来在消息流里精准控制 rewind 按钮的显示。session 没 toolSessionId 时返回空
|
|
@@ -60908,8 +61037,15 @@ ${attribution}` } : args;
|
|
|
60908
61037
|
const interrupt = async (frame, _client, ctx) => {
|
|
60909
61038
|
const args = SessionIdArgs.parse(frame);
|
|
60910
61039
|
ensureSessionAccess(ctx, args.sessionId, "send");
|
|
60911
|
-
const { broadcast } = await manager.interrupt(args);
|
|
60912
|
-
|
|
61040
|
+
const { response, broadcast } = await manager.interrupt(args);
|
|
61041
|
+
const queued = response.queued ?? [];
|
|
61042
|
+
return { response: { type: "session:interrupt", ok: true, queued }, broadcast };
|
|
61043
|
+
};
|
|
61044
|
+
const dequeue = async (frame, _client, ctx) => {
|
|
61045
|
+
const args = SessionDequeueArgs.parse(frame);
|
|
61046
|
+
ensureSessionAccess(ctx, args.sessionId, "send");
|
|
61047
|
+
const { broadcast } = manager.dequeue(args);
|
|
61048
|
+
return { response: { type: "session:dequeue", ok: true }, broadcast };
|
|
60913
61049
|
};
|
|
60914
61050
|
const ensureRewindSupported = async (sessionId) => {
|
|
60915
61051
|
const file = manager.get({ sessionId }).response;
|
|
@@ -61146,6 +61282,7 @@ ${attribution}` } : args;
|
|
|
61146
61282
|
"session:update": update,
|
|
61147
61283
|
"session:delete": del,
|
|
61148
61284
|
"session:send": send,
|
|
61285
|
+
"session:dequeue": dequeue,
|
|
61149
61286
|
"session:currentTurnSender": currentTurnSender,
|
|
61150
61287
|
"session:stop": stop,
|
|
61151
61288
|
"session:interrupt": interrupt,
|
|
@@ -62266,6 +62403,8 @@ var METHOD_GRANT_MAP = {
|
|
|
62266
62403
|
"session:update": CAPABILITY_SCOPED,
|
|
62267
62404
|
"session:delete": CAPABILITY_SCOPED,
|
|
62268
62405
|
"session:send": CAPABILITY_SCOPED,
|
|
62406
|
+
// 撤排队消息:能发就能撤(spec 2026-08-31-chat-input-queue-design)
|
|
62407
|
+
"session:dequeue": CAPABILITY_SCOPED,
|
|
62269
62408
|
// per-turn sender 2026-07-08 spec §4.6:dispatcher 层走 'public'(HTTP RPC path 需 dispatcher 放行);
|
|
62270
62409
|
// WS path 的隐私边界(防 guest 猜 sid 枚举 owner feishuUnionId)由 handler 内 ensureSessionAccess
|
|
62271
62410
|
// 显式兜底——见 handlers/session.ts:currentTurnSender。dispatcher 'public' ≠ handler 免检。
|
|
@@ -62495,7 +62634,7 @@ function computeMethodAccess(args) {
|
|
|
62495
62634
|
}
|
|
62496
62635
|
|
|
62497
62636
|
// src/version.ts
|
|
62498
|
-
var version = "0.2.
|
|
62637
|
+
var version = "0.2.430".length > 0 ? "0.2.430" : "dev";
|
|
62499
62638
|
|
|
62500
62639
|
// src/cli-probe/probe.ts
|
|
62501
62640
|
var fs65 = __toESM(require("fs"), 1);
|
|
@@ -22934,9 +22934,25 @@ var SessionUpdateArgs = external_exports.object({
|
|
|
22934
22934
|
// 通过 sessionUpdate 修改这个字段。SessionFile 仍保留 appBuilderProject 字段供 daemon 内部 mutate。
|
|
22935
22935
|
})
|
|
22936
22936
|
});
|
|
22937
|
+
var QueuedMessage = external_exports.object({
|
|
22938
|
+
id: external_exports.string().min(1),
|
|
22939
|
+
text: external_exports.string(),
|
|
22940
|
+
queuedAt: external_exports.number(),
|
|
22941
|
+
senderDisplayName: external_exports.string().optional()
|
|
22942
|
+
});
|
|
22937
22943
|
var SessionSendArgs = external_exports.object({
|
|
22938
22944
|
sessionId: external_exports.string().min(1),
|
|
22939
|
-
text: external_exports.string()
|
|
22945
|
+
text: external_exports.string(),
|
|
22946
|
+
/**
|
|
22947
|
+
* turn 在跑时是入队还是直发。**入队与否由调用方显式声明,daemon 不按来源猜**:
|
|
22948
|
+
* UI 输入框传 true;IM / 飞书 / dispatch 注入不传 = 维持原状直发(老板 2026-08-31:
|
|
22949
|
+
* 其他地方先不加队列)。缺省 false → 行为与本字段引入前逐字一致。
|
|
22950
|
+
*/
|
|
22951
|
+
queueWhileRunning: external_exports.boolean().optional()
|
|
22952
|
+
});
|
|
22953
|
+
var SessionDequeueArgs = external_exports.object({
|
|
22954
|
+
sessionId: external_exports.string().min(1),
|
|
22955
|
+
id: external_exports.string().min(1).optional()
|
|
22940
22956
|
});
|
|
22941
22957
|
var SessionRewindArgs = external_exports.object({
|
|
22942
22958
|
sessionId: external_exports.string().min(1),
|
|
@@ -23467,9 +23483,13 @@ var METHOD_DOCS = {
|
|
|
23467
23483
|
args: SessionIdArgs
|
|
23468
23484
|
},
|
|
23469
23485
|
"session:send": {
|
|
23470
|
-
summary: "\u5411\u4F1A\u8BDD\u53D1\u4E00\u6761\u7528\u6237\u6D88\u606F\uFF08\u89E6\u53D1\u65B0\u4E00\u8F6E turn\uFF09",
|
|
23486
|
+
summary: "\u5411\u4F1A\u8BDD\u53D1\u4E00\u6761\u7528\u6237\u6D88\u606F\uFF08\u89E6\u53D1\u65B0\u4E00\u8F6E turn\uFF09\uFF1BqueueWhileRunning=true \u4E14 turn \u5728\u8DD1\u65F6\u6539\u4E3A\u8FDB\u961F\u5217",
|
|
23471
23487
|
args: SessionSendArgs
|
|
23472
23488
|
},
|
|
23489
|
+
"session:dequeue": {
|
|
23490
|
+
summary: "\u64A4\u9500\u6392\u961F\u4E2D\u7684\u6D88\u606F\uFF1A\u5E26 id \u5220\u4E00\u6761\uFF0C\u4E0D\u5E26 id \u6E05\u7A7A\u6574\u961F\uFF08spec 2026-08-31-chat-input-queue-design\uFF09",
|
|
23491
|
+
args: SessionDequeueArgs
|
|
23492
|
+
},
|
|
23473
23493
|
"session:currentTurnSender": {
|
|
23474
23494
|
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",
|
|
23475
23495
|
args: SessionCurrentTurnSenderArgs
|