@clawos-dev/clawd 0.2.226 → 0.2.228
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
CHANGED
|
@@ -6136,7 +6136,12 @@ var init_dispatch = __esm({
|
|
|
6136
6136
|
prompt: external_exports.string(),
|
|
6137
6137
|
// 跨设备 dispatch:非空 = A 角色,转发到该 contact deviceId 的 peer daemon;
|
|
6138
6138
|
// 省略 = 本地 dispatch / B 角色本地执行。A 转发给 B 时 body 不带此字段。
|
|
6139
|
-
targetDeviceId: external_exports.string().min(1).optional()
|
|
6139
|
+
targetDeviceId: external_exports.string().min(1).optional(),
|
|
6140
|
+
// 可选:override B session 使用的 claude 模型。缺省 = 用 persona 默认。
|
|
6141
|
+
// 合法值集与 claude adapter capabilities.models[].id 一致(见 daemon
|
|
6142
|
+
// tools/claude.ts CLAUDE_MODEL_IDS);handler 层做二次校验,非法值 fail-fast。
|
|
6143
|
+
// protocol 层保持 string 便于未来跨 tool 扩展(届时 union 收合法字面量)。
|
|
6144
|
+
model: external_exports.string().min(1).optional()
|
|
6140
6145
|
});
|
|
6141
6146
|
DispatchCompleteArgsSchema = external_exports.object({
|
|
6142
6147
|
dispatchId: external_exports.string().min(1),
|
|
@@ -12542,7 +12547,7 @@ function encodeClaudeStdin(text) {
|
|
|
12542
12547
|
};
|
|
12543
12548
|
return JSON.stringify(frame) + "\n";
|
|
12544
12549
|
}
|
|
12545
|
-
var import_node_child_process, import_node_child_process2, import_node_fs15, ATTACHMENT_SILENT_SUBTYPES2, unknownTypeHandler, ATTACHMENT_RE, IMAGE_EXT_MIME, CLAUDE_MODELS, CLAUDE_PERMISSION_MODES, CLAUDE_CAPABILITIES, ClaudeAdapter;
|
|
12550
|
+
var import_node_child_process, import_node_child_process2, import_node_fs15, ATTACHMENT_SILENT_SUBTYPES2, unknownTypeHandler, ATTACHMENT_RE, IMAGE_EXT_MIME, CLAUDE_MODEL_IDS, CLAUDE_MODELS, _assertModelIdsAligned, CLAUDE_PERMISSION_MODES, CLAUDE_CAPABILITIES, ClaudeAdapter;
|
|
12546
12551
|
var init_claude = __esm({
|
|
12547
12552
|
"src/tools/claude.ts"() {
|
|
12548
12553
|
"use strict";
|
|
@@ -12568,13 +12573,17 @@ var init_claude = __esm({
|
|
|
12568
12573
|
gif: "image/gif",
|
|
12569
12574
|
webp: "image/webp"
|
|
12570
12575
|
};
|
|
12576
|
+
CLAUDE_MODEL_IDS = ["opus", "fable", "sonnet", "haiku"];
|
|
12571
12577
|
CLAUDE_MODELS = [
|
|
12572
|
-
{ id: "", label: "Default", description: "CLI default model", contextWindowSize:
|
|
12578
|
+
{ id: "", label: "Default", description: "CLI default model", contextWindowSize: 1e6, default: true },
|
|
12573
12579
|
{ id: "opus", label: "Opus", description: "Most capable", contextWindowSize: 1e6 },
|
|
12574
|
-
{ id: "fable", label: "Fable", contextWindowSize:
|
|
12575
|
-
{ id: "sonnet", label: "Sonnet", description: "Fast, balanced", contextWindowSize:
|
|
12576
|
-
{ id: "haiku", label: "Haiku", description: "Fastest, lightest", contextWindowSize:
|
|
12580
|
+
{ id: "fable", label: "Fable", contextWindowSize: 1e6 },
|
|
12581
|
+
{ id: "sonnet", label: "Sonnet", description: "Fast, balanced", contextWindowSize: 1e6 },
|
|
12582
|
+
{ id: "haiku", label: "Haiku", description: "Fastest, lightest", contextWindowSize: 1e6 }
|
|
12577
12583
|
];
|
|
12584
|
+
_assertModelIdsAligned = CLAUDE_MODELS.filter(
|
|
12585
|
+
(m2) => m2.id !== ""
|
|
12586
|
+
).map((m2) => m2.id);
|
|
12578
12587
|
CLAUDE_PERMISSION_MODES = [
|
|
12579
12588
|
{ id: "", label: "Default", description: "Ask for every tool call" },
|
|
12580
12589
|
{ id: "plan", label: "Plan", description: "Read-only, no code changes" },
|
|
@@ -44602,6 +44611,8 @@ var SessionManager = class {
|
|
|
44602
44611
|
creatorPrincipalId: args.guestPrincipalId,
|
|
44603
44612
|
...args.guestDisplayName ? { creatorDisplayName: args.guestDisplayName } : {}
|
|
44604
44613
|
} : {},
|
|
44614
|
+
// T-20:dispatch model override 落盘(reducer spawn 路径读 SessionFile.model 生成 --model flag)
|
|
44615
|
+
...args.model ? { model: args.model } : {},
|
|
44605
44616
|
createdAt: now,
|
|
44606
44617
|
updatedAt: now
|
|
44607
44618
|
};
|
|
@@ -48364,6 +48375,12 @@ function computeNextRunAtMs(schedule, fromMs) {
|
|
|
48364
48375
|
}
|
|
48365
48376
|
|
|
48366
48377
|
// src/shift/store.ts
|
|
48378
|
+
function normalizeSchedule(schedule, nowMs) {
|
|
48379
|
+
if (schedule.kind === "every" && schedule.anchorMs === void 0) {
|
|
48380
|
+
return { ...schedule, anchorMs: nowMs };
|
|
48381
|
+
}
|
|
48382
|
+
return schedule;
|
|
48383
|
+
}
|
|
48367
48384
|
function createShiftStore(deps) {
|
|
48368
48385
|
let shifts = [];
|
|
48369
48386
|
let flushTimer = null;
|
|
@@ -48382,7 +48399,15 @@ function createShiftStore(deps) {
|
|
|
48382
48399
|
if (parsed.version !== 1) {
|
|
48383
48400
|
throw new Error(`shift.json: unsupported version ${parsed.version}`);
|
|
48384
48401
|
}
|
|
48385
|
-
|
|
48402
|
+
const now = deps.now();
|
|
48403
|
+
shifts = (parsed.shifts ?? []).map((s) => {
|
|
48404
|
+
const schedule = normalizeSchedule(s.schedule, s.createdAtMs);
|
|
48405
|
+
if (schedule === s.schedule) return s;
|
|
48406
|
+
const gridNext = computeNextRunAtMs(schedule, now) ?? void 0;
|
|
48407
|
+
const oldNext = s.state.nextRunAtMs;
|
|
48408
|
+
const nextRunAtMs = gridNext !== void 0 && (oldNext === void 0 || gridNext < oldNext) ? gridNext : oldNext;
|
|
48409
|
+
return { ...s, schedule, state: { ...s.state, nextRunAtMs } };
|
|
48410
|
+
});
|
|
48386
48411
|
}
|
|
48387
48412
|
async function flushNow() {
|
|
48388
48413
|
if (flushTimer) {
|
|
@@ -48415,9 +48440,11 @@ function createShiftStore(deps) {
|
|
|
48415
48440
|
}
|
|
48416
48441
|
function add(input) {
|
|
48417
48442
|
const now = deps.now();
|
|
48418
|
-
const
|
|
48443
|
+
const schedule = normalizeSchedule(input.schedule, now);
|
|
48444
|
+
const nextRunAtMs = computeNextRunAtMs(schedule, now) ?? void 0;
|
|
48419
48445
|
const shift = {
|
|
48420
48446
|
...input,
|
|
48447
|
+
schedule,
|
|
48421
48448
|
id: (0, import_node_crypto6.randomUUID)(),
|
|
48422
48449
|
createdAtMs: now,
|
|
48423
48450
|
updatedAtMs: now,
|
|
@@ -48432,8 +48459,8 @@ function createShiftStore(deps) {
|
|
|
48432
48459
|
const idx = shifts.findIndex((s) => s.id === id);
|
|
48433
48460
|
if (idx < 0) throw new Error(`shift not found: ${id}`);
|
|
48434
48461
|
const now = deps.now();
|
|
48435
|
-
const newSchedule = patch.schedule
|
|
48436
|
-
const nextRunAtMs = patch.schedule ? computeNextRunAtMs(
|
|
48462
|
+
const newSchedule = patch.schedule ? normalizeSchedule(patch.schedule, now) : shifts[idx].schedule;
|
|
48463
|
+
const nextRunAtMs = patch.schedule ? computeNextRunAtMs(newSchedule, now) ?? void 0 : shifts[idx].state.nextRunAtMs;
|
|
48437
48464
|
const merged = {
|
|
48438
48465
|
...shifts[idx],
|
|
48439
48466
|
...patch,
|
|
@@ -48529,13 +48556,10 @@ function createShiftScheduler(deps) {
|
|
|
48529
48556
|
async function tickNow() {
|
|
48530
48557
|
const now = deps.now();
|
|
48531
48558
|
if (now < lastTickAtMs || now - lastTickAtMs > CLOCK_JUMP_THRESHOLD_MS) {
|
|
48532
|
-
for (const shift of deps.store.list()) {
|
|
48533
|
-
const next = computeNextRunAtMs(shift.schedule, now) ?? void 0;
|
|
48534
|
-
deps.store.patchState(shift.id, { nextRunAtMs: next });
|
|
48535
|
-
}
|
|
48536
48559
|
deps.logger?.warn("shift.scheduler.clock_jump", {
|
|
48537
48560
|
lastTickAtMs,
|
|
48538
|
-
now
|
|
48561
|
+
now,
|
|
48562
|
+
gapMs: now - lastTickAtMs
|
|
48539
48563
|
});
|
|
48540
48564
|
}
|
|
48541
48565
|
lastTickAtMs = now;
|
|
@@ -48806,12 +48830,19 @@ function canAccessPersona(grants, personaId, action) {
|
|
|
48806
48830
|
}
|
|
48807
48831
|
|
|
48808
48832
|
// src/handlers/persona-dispatch.ts
|
|
48833
|
+
init_claude();
|
|
48809
48834
|
function buildPersonaDispatchHandlers(deps) {
|
|
48810
48835
|
const { personaDispatchManager: mgr, spawnB, logger } = deps;
|
|
48811
48836
|
const run = async (frame, _client, ctx) => {
|
|
48812
48837
|
const { type: _t, requestId: _r, ...rest } = frame;
|
|
48813
48838
|
const sourceSessionId = typeof rest.sessionId === "string" ? rest.sessionId : void 0;
|
|
48814
48839
|
const args = DispatchRunArgsSchema.parse(rest);
|
|
48840
|
+
if (args.model !== void 0 && !CLAUDE_MODEL_IDS.includes(args.model)) {
|
|
48841
|
+
throw new ClawdError(
|
|
48842
|
+
ERROR_CODES.INVALID_PARAM,
|
|
48843
|
+
`model '${args.model}' not supported; allowed: ${CLAUDE_MODEL_IDS.join(", ")}`
|
|
48844
|
+
);
|
|
48845
|
+
}
|
|
48815
48846
|
if (args.targetDeviceId) {
|
|
48816
48847
|
if (ctx?.principal.kind === "guest") {
|
|
48817
48848
|
throw new ClawdError(
|
|
@@ -48829,7 +48860,8 @@ function buildPersonaDispatchHandlers(deps) {
|
|
|
48829
48860
|
const outcome2 = await deps.forwardToPeer({
|
|
48830
48861
|
targetDeviceId: args.targetDeviceId,
|
|
48831
48862
|
targetPersona: args.targetPersona,
|
|
48832
|
-
prompt: args.prompt
|
|
48863
|
+
prompt: args.prompt,
|
|
48864
|
+
...args.model ? { model: args.model } : {}
|
|
48833
48865
|
});
|
|
48834
48866
|
return {
|
|
48835
48867
|
response: { type: "personaDispatch:run:ok", outcome: outcome2 }
|
|
@@ -48859,7 +48891,8 @@ function buildPersonaDispatchHandlers(deps) {
|
|
|
48859
48891
|
targetPersona: args.targetPersona,
|
|
48860
48892
|
prompt: args.prompt,
|
|
48861
48893
|
guestPrincipalId: ctx.principal.id,
|
|
48862
|
-
guestDisplayName: ctx.principal.displayName
|
|
48894
|
+
guestDisplayName: ctx.principal.displayName,
|
|
48895
|
+
...args.model ? { model: args.model } : {}
|
|
48863
48896
|
}).then(() => logger?.info("dispatch.spawnB.ok", { dispatchId: dispatchId2 })).catch((err) => {
|
|
48864
48897
|
const reason = err instanceof Error ? err.message : String(err);
|
|
48865
48898
|
logger?.warn("dispatch.spawnB.failed", { dispatchId: dispatchId2, reason });
|
|
@@ -48892,7 +48925,8 @@ function buildPersonaDispatchHandlers(deps) {
|
|
|
48892
48925
|
dispatchId,
|
|
48893
48926
|
sourceSessionId,
|
|
48894
48927
|
targetPersona: args.targetPersona,
|
|
48895
|
-
prompt: args.prompt
|
|
48928
|
+
prompt: args.prompt,
|
|
48929
|
+
...args.model ? { model: args.model } : {}
|
|
48896
48930
|
}).then(() => {
|
|
48897
48931
|
logger?.info("dispatch.spawnB.ok", { dispatchId });
|
|
48898
48932
|
}).catch((err) => {
|
|
@@ -48950,7 +48984,12 @@ async function forwardDispatchToPeer(args) {
|
|
|
48950
48984
|
authorization: `Bearer ${args.contact.connectToken}`
|
|
48951
48985
|
},
|
|
48952
48986
|
// 注意:不带 targetDeviceId —— B 端据此判定为本地执行(B 角色)。
|
|
48953
|
-
body: JSON.stringify({
|
|
48987
|
+
body: JSON.stringify({
|
|
48988
|
+
targetPersona: args.targetPersona,
|
|
48989
|
+
prompt: args.prompt,
|
|
48990
|
+
// T-20: 条件展开防 undefined 污染 JSON。远端 daemon handler 会再校验一次 model 合法性。
|
|
48991
|
+
...args.model ? { model: args.model } : {}
|
|
48992
|
+
})
|
|
48954
48993
|
});
|
|
48955
48994
|
} catch (err) {
|
|
48956
48995
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -60173,11 +60212,13 @@ async function startDaemon(config) {
|
|
|
60173
60212
|
sourceJsonlPath,
|
|
60174
60213
|
// B 角色(跨设备):非空 → guest scope + creatorPrincipalId/creatorDisplayName = A。
|
|
60175
60214
|
guestPrincipalId: args.guestPrincipalId,
|
|
60176
|
-
guestDisplayName: args.guestDisplayName
|
|
60215
|
+
guestDisplayName: args.guestDisplayName,
|
|
60216
|
+
// T-20: 可选 model override 透到 SessionFile.model
|
|
60217
|
+
...args.model ? { model: args.model } : {}
|
|
60177
60218
|
});
|
|
60178
60219
|
},
|
|
60179
60220
|
// A 角色:从 ContactStore 取 peer 可达 URL + connect token,转发到对端 daemon /rpc。
|
|
60180
|
-
forwardToPeer: async ({ targetDeviceId, targetPersona, prompt }) => {
|
|
60221
|
+
forwardToPeer: async ({ targetDeviceId, targetPersona, prompt, model }) => {
|
|
60181
60222
|
const contact = contactStore.get(targetDeviceId);
|
|
60182
60223
|
if (!contact || !contact.remoteUrl || !contact.connectToken) {
|
|
60183
60224
|
return {
|
|
@@ -60188,7 +60229,9 @@ async function startDaemon(config) {
|
|
|
60188
60229
|
return forwardDispatchToPeer({
|
|
60189
60230
|
contact: { remoteUrl: contact.remoteUrl, connectToken: contact.connectToken },
|
|
60190
60231
|
targetPersona,
|
|
60191
|
-
prompt
|
|
60232
|
+
prompt,
|
|
60233
|
+
// T-20: 跨设备也透 model,让远端 daemon 用同一 claude 模型 spawn B
|
|
60234
|
+
...model ? { model } : {}
|
|
60192
60235
|
});
|
|
60193
60236
|
},
|
|
60194
60237
|
// B 角色:判断 targetPersona 是否 public(跨设备授权边界,private 拒)。
|