@clawos-dev/clawd 0.2.196 → 0.2.197-beta.396.cf8bb30
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 +190 -42
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -28978,7 +28978,7 @@ var require_websocket = __commonJS({
|
|
|
28978
28978
|
var http3 = require("http");
|
|
28979
28979
|
var net3 = require("net");
|
|
28980
28980
|
var tls = require("tls");
|
|
28981
|
-
var { randomBytes, createHash:
|
|
28981
|
+
var { randomBytes, createHash: createHash3 } = require("crypto");
|
|
28982
28982
|
var { Duplex, Readable: Readable3 } = require("stream");
|
|
28983
28983
|
var { URL: URL2 } = require("url");
|
|
28984
28984
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
@@ -29638,7 +29638,7 @@ var require_websocket = __commonJS({
|
|
|
29638
29638
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
29639
29639
|
return;
|
|
29640
29640
|
}
|
|
29641
|
-
const digest =
|
|
29641
|
+
const digest = createHash3("sha1").update(key + GUID).digest("base64");
|
|
29642
29642
|
if (res.headers["sec-websocket-accept"] !== digest) {
|
|
29643
29643
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
29644
29644
|
return;
|
|
@@ -30005,7 +30005,7 @@ var require_websocket_server = __commonJS({
|
|
|
30005
30005
|
var EventEmitter3 = require("events");
|
|
30006
30006
|
var http3 = require("http");
|
|
30007
30007
|
var { Duplex } = require("stream");
|
|
30008
|
-
var { createHash:
|
|
30008
|
+
var { createHash: createHash3 } = require("crypto");
|
|
30009
30009
|
var extension2 = require_extension();
|
|
30010
30010
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
30011
30011
|
var subprotocol2 = require_subprotocol();
|
|
@@ -30306,7 +30306,7 @@ var require_websocket_server = __commonJS({
|
|
|
30306
30306
|
);
|
|
30307
30307
|
}
|
|
30308
30308
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
30309
|
-
const digest =
|
|
30309
|
+
const digest = createHash3("sha1").update(key + GUID).digest("base64");
|
|
30310
30310
|
const headers = [
|
|
30311
30311
|
"HTTP/1.1 101 Switching Protocols",
|
|
30312
30312
|
"Upgrade: websocket",
|
|
@@ -40779,6 +40779,18 @@ function createLogger(opts = {}) {
|
|
|
40779
40779
|
);
|
|
40780
40780
|
return wrap(base);
|
|
40781
40781
|
}
|
|
40782
|
+
function createFileOnlyLogger(opts) {
|
|
40783
|
+
const level = opts.level ?? "debug";
|
|
40784
|
+
try {
|
|
40785
|
+
import_node_fs2.default.mkdirSync(import_node_path2.default.dirname(opts.file), { recursive: true });
|
|
40786
|
+
} catch {
|
|
40787
|
+
}
|
|
40788
|
+
const base = (0, import_pino.default)(
|
|
40789
|
+
{ level, base: {} },
|
|
40790
|
+
import_pino.default.destination({ dest: opts.file, mkdir: true, sync: true })
|
|
40791
|
+
);
|
|
40792
|
+
return wrap(base);
|
|
40793
|
+
}
|
|
40782
40794
|
function pinoLevelToString(n) {
|
|
40783
40795
|
if (typeof n !== "number") return null;
|
|
40784
40796
|
if (n >= 50) return "error";
|
|
@@ -43286,6 +43298,14 @@ var SessionManager = class {
|
|
|
43286
43298
|
routeFromRunner(frame, target) {
|
|
43287
43299
|
const compressed = compressFrameForWire(frame);
|
|
43288
43300
|
if (!compressed) return;
|
|
43301
|
+
if (compressed.type === "session:status") {
|
|
43302
|
+
const s = compressed;
|
|
43303
|
+
this.deps.screenIdleProbeLogger?.info("session:status wire emit", {
|
|
43304
|
+
sessionId: s.sessionId,
|
|
43305
|
+
status: s.status,
|
|
43306
|
+
target
|
|
43307
|
+
});
|
|
43308
|
+
}
|
|
43289
43309
|
if (compressed.type === "session:event" || compressed.type === "session:status") {
|
|
43290
43310
|
const sid = compressed.sessionId;
|
|
43291
43311
|
if (sid) {
|
|
@@ -44291,12 +44311,24 @@ var SessionManager = class {
|
|
|
44291
44311
|
const toolSessionId = runnerState.file.toolSessionId;
|
|
44292
44312
|
const adapter = this.deps.getAdapter(runnerState.file.tool ?? "claude");
|
|
44293
44313
|
const gateOpen = !adapter.canAcceptTurnEnd || !toolSessionId ? true : adapter.canAcceptTurnEnd(toolSessionId);
|
|
44314
|
+
this.deps.screenIdleProbeLogger?.info("feedObserverEvents turn_end batch received", {
|
|
44315
|
+
sessionId,
|
|
44316
|
+
toolSessionId,
|
|
44317
|
+
batchKinds: outEvents.map((e) => e.kind),
|
|
44318
|
+
gateOpen,
|
|
44319
|
+
hasCanAcceptGate: !!adapter.canAcceptTurnEnd
|
|
44320
|
+
});
|
|
44294
44321
|
if (!gateOpen) {
|
|
44295
44322
|
this.deps.logger?.info("drop turn_end (adapter gate closed)", {
|
|
44296
44323
|
sessionId,
|
|
44297
44324
|
toolSessionId,
|
|
44298
44325
|
reason: "tui-screen-not-idle"
|
|
44299
44326
|
});
|
|
44327
|
+
this.deps.screenIdleProbeLogger?.info("drop turn_end: adapter gate closed", {
|
|
44328
|
+
sessionId,
|
|
44329
|
+
toolSessionId,
|
|
44330
|
+
reason: "tui-screen-not-idle"
|
|
44331
|
+
});
|
|
44300
44332
|
feedEvents = outEvents.filter((e) => e.kind !== "turn_end");
|
|
44301
44333
|
} else {
|
|
44302
44334
|
const ev = this.peekTurnEvidence(runner);
|
|
@@ -44306,7 +44338,19 @@ var SessionManager = class {
|
|
|
44306
44338
|
...ev,
|
|
44307
44339
|
batchKinds: outEvents.map((e) => e.kind)
|
|
44308
44340
|
});
|
|
44341
|
+
this.deps.screenIdleProbeLogger?.info("drop turn_end: empty turn (Fix B)", {
|
|
44342
|
+
sessionId,
|
|
44343
|
+
toolSessionId,
|
|
44344
|
+
...ev,
|
|
44345
|
+
batchKinds: outEvents.map((e) => e.kind)
|
|
44346
|
+
});
|
|
44309
44347
|
feedEvents = outEvents.filter((e) => e.kind !== "turn_end");
|
|
44348
|
+
} else {
|
|
44349
|
+
this.deps.screenIdleProbeLogger?.info("turn_end passed all filters \u2192 fed to reducer", {
|
|
44350
|
+
sessionId,
|
|
44351
|
+
toolSessionId,
|
|
44352
|
+
...ev
|
|
44353
|
+
});
|
|
44310
44354
|
}
|
|
44311
44355
|
}
|
|
44312
44356
|
}
|
|
@@ -44586,15 +44630,30 @@ var SessionManager = class {
|
|
|
44586
44630
|
if (this.deps.mode !== "tui") return;
|
|
44587
44631
|
const sid = this.sessionIdByToolSid(toolSessionId);
|
|
44588
44632
|
const runner = sid ? this.runners.get(sid) : void 0;
|
|
44589
|
-
if (!runner)
|
|
44633
|
+
if (!runner) {
|
|
44634
|
+
this.deps.screenIdleProbeLogger?.warn("dispatchTurnIdle: no runner for toolSessionId", {
|
|
44635
|
+
toolSessionId
|
|
44636
|
+
});
|
|
44637
|
+
return;
|
|
44638
|
+
}
|
|
44590
44639
|
const ev = this.peekTurnEvidence(runner);
|
|
44591
44640
|
if (!ev.turnEndSeenThisTurn) {
|
|
44592
44641
|
this.deps.logger?.debug("screen-idle compensation skipped (no prior turn_end this turn)", {
|
|
44593
44642
|
sessionId: sid,
|
|
44594
44643
|
...ev
|
|
44595
44644
|
});
|
|
44645
|
+
this.deps.screenIdleProbeLogger?.info("dispatchTurnIdle skip: no prior turn_end this turn", {
|
|
44646
|
+
sessionId: sid,
|
|
44647
|
+
toolSessionId,
|
|
44648
|
+
...ev
|
|
44649
|
+
});
|
|
44596
44650
|
return;
|
|
44597
44651
|
}
|
|
44652
|
+
this.deps.screenIdleProbeLogger?.info("dispatchTurnIdle inject turn_end (screen-idle compensation)", {
|
|
44653
|
+
sessionId: sid,
|
|
44654
|
+
toolSessionId,
|
|
44655
|
+
...ev
|
|
44656
|
+
});
|
|
44598
44657
|
runner.input({ kind: "inject-events", events: [{ kind: "turn_end" }] });
|
|
44599
44658
|
}
|
|
44600
44659
|
/**
|
|
@@ -46379,6 +46438,7 @@ var CodexAdapter = class {
|
|
|
46379
46438
|
};
|
|
46380
46439
|
|
|
46381
46440
|
// src/tools/claude-tui.ts
|
|
46441
|
+
var import_node_crypto5 = require("crypto");
|
|
46382
46442
|
var import_node_fs16 = __toESM(require("fs"), 1);
|
|
46383
46443
|
var import_node_os7 = __toESM(require("os"), 1);
|
|
46384
46444
|
var import_node_path14 = __toESM(require("path"), 1);
|
|
@@ -47189,22 +47249,56 @@ function observeScreenIdle(surface, opts) {
|
|
|
47189
47249
|
timer = null;
|
|
47190
47250
|
if (disposed) return;
|
|
47191
47251
|
if (opts.getPopupVisible()) {
|
|
47252
|
+
opts.probeLogger?.info("screen-idle fire suppressed: popup visible", {
|
|
47253
|
+
label: opts.probeLabel
|
|
47254
|
+
});
|
|
47192
47255
|
timer = setTimeout(fire, opts.idleMs);
|
|
47193
47256
|
return;
|
|
47194
47257
|
}
|
|
47195
47258
|
const obsWait = opts.getObserverWaitMs?.() ?? 0;
|
|
47196
47259
|
if (obsWait > 0) {
|
|
47260
|
+
opts.probeLogger?.info("screen-idle fire suppressed: observer not idle", {
|
|
47261
|
+
label: opts.probeLabel,
|
|
47262
|
+
obsWait
|
|
47263
|
+
});
|
|
47197
47264
|
timer = setTimeout(fire, Math.max(obsWait, REWAIT_MIN_MS));
|
|
47198
47265
|
return;
|
|
47199
47266
|
}
|
|
47200
|
-
if (armed)
|
|
47267
|
+
if (armed) {
|
|
47268
|
+
opts.probeLogger?.debug("screen-idle fire noop: already armed", {
|
|
47269
|
+
label: opts.probeLabel
|
|
47270
|
+
});
|
|
47271
|
+
return;
|
|
47272
|
+
}
|
|
47201
47273
|
armed = true;
|
|
47274
|
+
opts.probeLogger?.info("screen-idle fire triggered \u2192 armed=true, calling onIdle", {
|
|
47275
|
+
label: opts.probeLabel
|
|
47276
|
+
});
|
|
47202
47277
|
opts.onIdle();
|
|
47203
47278
|
};
|
|
47204
47279
|
const unsub = surface.onTick((lines) => {
|
|
47205
47280
|
if (disposed) return;
|
|
47206
47281
|
const snap = snapOf(lines);
|
|
47207
47282
|
if (snap === lastSnap) return;
|
|
47283
|
+
if (opts.probeLogger) {
|
|
47284
|
+
const prev = lastSnap;
|
|
47285
|
+
const meta = {
|
|
47286
|
+
label: opts.probeLabel,
|
|
47287
|
+
prevHash: prev === null ? null : shortHash(prev),
|
|
47288
|
+
nextHash: shortHash(snap),
|
|
47289
|
+
prevLen: prev?.length ?? 0,
|
|
47290
|
+
nextLen: snap.length
|
|
47291
|
+
};
|
|
47292
|
+
if (prev !== null) {
|
|
47293
|
+
const diff2 = firstLineDiff(prev, snap);
|
|
47294
|
+
if (diff2) {
|
|
47295
|
+
meta.diffRow = diff2.row;
|
|
47296
|
+
meta.prevRow = diff2.prev;
|
|
47297
|
+
meta.nextRow = diff2.next;
|
|
47298
|
+
}
|
|
47299
|
+
}
|
|
47300
|
+
opts.probeLogger.info("screen-idle tick snap changed", meta);
|
|
47301
|
+
}
|
|
47208
47302
|
lastSnap = snap;
|
|
47209
47303
|
armed = false;
|
|
47210
47304
|
clear();
|
|
@@ -47217,13 +47311,38 @@ function observeScreenIdle(surface, opts) {
|
|
|
47217
47311
|
clear();
|
|
47218
47312
|
},
|
|
47219
47313
|
isIdle() {
|
|
47220
|
-
|
|
47221
|
-
if (opts.getPopupVisible()) return false;
|
|
47314
|
+
const popupVisible = opts.getPopupVisible();
|
|
47222
47315
|
const obsWait = opts.getObserverWaitMs?.() ?? 0;
|
|
47223
|
-
|
|
47316
|
+
const idle = armed && !popupVisible && obsWait <= 0;
|
|
47317
|
+
if (opts.probeLogger) {
|
|
47318
|
+
opts.probeLogger.info("screen-idle isIdle check", {
|
|
47319
|
+
label: opts.probeLabel,
|
|
47320
|
+
idle,
|
|
47321
|
+
armed,
|
|
47322
|
+
popupVisible,
|
|
47323
|
+
obsWait
|
|
47324
|
+
});
|
|
47325
|
+
}
|
|
47326
|
+
return idle;
|
|
47224
47327
|
}
|
|
47225
47328
|
};
|
|
47226
47329
|
}
|
|
47330
|
+
function shortHash(s) {
|
|
47331
|
+
return (0, import_node_crypto5.createHash)("sha1").update(s).digest("hex").slice(0, 8);
|
|
47332
|
+
}
|
|
47333
|
+
function firstLineDiff(prev, next) {
|
|
47334
|
+
const p2 = prev.split("\n");
|
|
47335
|
+
const n = next.split("\n");
|
|
47336
|
+
const rows = Math.max(p2.length, n.length);
|
|
47337
|
+
for (let i = 0; i < rows; i++) {
|
|
47338
|
+
const pl = p2[i] ?? "";
|
|
47339
|
+
const nl = n[i] ?? "";
|
|
47340
|
+
if (pl !== nl) {
|
|
47341
|
+
return { row: i, prev: pl.slice(0, 60), next: nl.slice(0, 60) };
|
|
47342
|
+
}
|
|
47343
|
+
}
|
|
47344
|
+
return null;
|
|
47345
|
+
}
|
|
47227
47346
|
var BYPASS_SETTLE_MS = 300;
|
|
47228
47347
|
var SCREEN_IDLE_MS = 5e3;
|
|
47229
47348
|
function createBootGate(pty, logger) {
|
|
@@ -47320,8 +47439,19 @@ var ClaudeTuiAdapter = class extends ClaudeAdapter {
|
|
|
47320
47439
|
*/
|
|
47321
47440
|
canAcceptTurnEnd(toolSessionId) {
|
|
47322
47441
|
const state = this.tuiStates.get(toolSessionId);
|
|
47323
|
-
if (!state)
|
|
47324
|
-
|
|
47442
|
+
if (!state) {
|
|
47443
|
+
this.tuiOpts.screenIdleProbeLogger?.info(
|
|
47444
|
+
"canAcceptTurnEnd: no tuiState \u2192 pass (\u672A\u8DDF\u8E2A)",
|
|
47445
|
+
{ toolSessionId }
|
|
47446
|
+
);
|
|
47447
|
+
return true;
|
|
47448
|
+
}
|
|
47449
|
+
const result = state.screenIdle.isIdle();
|
|
47450
|
+
this.tuiOpts.screenIdleProbeLogger?.info("canAcceptTurnEnd", {
|
|
47451
|
+
toolSessionId,
|
|
47452
|
+
result
|
|
47453
|
+
});
|
|
47454
|
+
return result;
|
|
47325
47455
|
}
|
|
47326
47456
|
spawn(ctx) {
|
|
47327
47457
|
const args = buildTuiSpawnArgs(ctx, jsonlExistsForCtx(ctx));
|
|
@@ -47387,7 +47517,12 @@ var ClaudeTuiAdapter = class extends ClaudeAdapter {
|
|
|
47387
47517
|
getPopupVisible: () => popupObserver.visibleKind !== null,
|
|
47388
47518
|
// observer 还需静止多久才满 SCREEN_IDLE_MS(复合条件 AND):屏幕静止后精确等这段剩余再补
|
|
47389
47519
|
// turn_end,确保它排在尾段 text + turn_duration 全部 poll 落盘之后 = buffer 末条。
|
|
47390
|
-
getObserverWaitMs: () => ctx.toolSessionId ? this.tuiOpts.getObserverWaitMs?.(ctx.toolSessionId, SCREEN_IDLE_MS) ?? 0 : 0
|
|
47520
|
+
getObserverWaitMs: () => ctx.toolSessionId ? this.tuiOpts.getObserverWaitMs?.(ctx.toolSessionId, SCREEN_IDLE_MS) ?? 0 : 0,
|
|
47521
|
+
// 取证 probe(可选,装配处传独立 file-only logger,跟主 daemon.log 解耦)
|
|
47522
|
+
...this.tuiOpts.screenIdleProbeLogger ? {
|
|
47523
|
+
probeLogger: this.tuiOpts.screenIdleProbeLogger,
|
|
47524
|
+
probeLabel: ctx.toolSessionId ?? "<no-tsid>"
|
|
47525
|
+
} : {}
|
|
47391
47526
|
});
|
|
47392
47527
|
if (ctx.toolSessionId && this.tuiOpts.onSurfaceRegister) {
|
|
47393
47528
|
this.tuiOpts.onSurfaceRegister(ctx.toolSessionId, surface);
|
|
@@ -47728,7 +47863,7 @@ async function writeInboxMcpConfig(args) {
|
|
|
47728
47863
|
// src/shift/store.ts
|
|
47729
47864
|
var import_promises = __toESM(require("fs/promises"), 1);
|
|
47730
47865
|
var import_node_path19 = __toESM(require("path"), 1);
|
|
47731
|
-
var
|
|
47866
|
+
var import_node_crypto6 = require("crypto");
|
|
47732
47867
|
|
|
47733
47868
|
// src/shift/constants.ts
|
|
47734
47869
|
var MAX_RUNS_PER_SHIFT = 30;
|
|
@@ -47824,7 +47959,7 @@ function createShiftStore(deps) {
|
|
|
47824
47959
|
const nextRunAtMs = computeNextRunAtMs(input.schedule, now) ?? void 0;
|
|
47825
47960
|
const shift = {
|
|
47826
47961
|
...input,
|
|
47827
|
-
id: (0,
|
|
47962
|
+
id: (0, import_node_crypto6.randomUUID)(),
|
|
47828
47963
|
createdAtMs: now,
|
|
47829
47964
|
updatedAtMs: now,
|
|
47830
47965
|
state: { nextRunAtMs },
|
|
@@ -50776,7 +50911,7 @@ function lookupMime(filePathOrName) {
|
|
|
50776
50911
|
}
|
|
50777
50912
|
|
|
50778
50913
|
// src/attachment/sign-url.ts
|
|
50779
|
-
var
|
|
50914
|
+
var import_node_crypto7 = __toESM(require("crypto"), 1);
|
|
50780
50915
|
var HMAC_ALGO = "sha256";
|
|
50781
50916
|
function base64urlEncode(buf) {
|
|
50782
50917
|
const b2 = typeof buf === "string" ? Buffer.from(buf, "utf8") : buf;
|
|
@@ -50793,7 +50928,7 @@ function decodeAbsPathFromUrl(encoded) {
|
|
|
50793
50928
|
}
|
|
50794
50929
|
function computeSig(secret, absPath, e) {
|
|
50795
50930
|
const msg = e === null ? absPath : `${absPath}|${e}`;
|
|
50796
|
-
return
|
|
50931
|
+
return import_node_crypto7.default.createHmac(HMAC_ALGO, secret).update(msg).digest();
|
|
50797
50932
|
}
|
|
50798
50933
|
function signUrlParts(secret, absPath, ttlSeconds, now = Date.now) {
|
|
50799
50934
|
const e = ttlSeconds === null ? null : Math.floor(now() / 1e3) + ttlSeconds;
|
|
@@ -50828,7 +50963,7 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
|
|
|
50828
50963
|
if (provided.length !== expected.length) {
|
|
50829
50964
|
return { ok: false, code: "BAD_SIG" };
|
|
50830
50965
|
}
|
|
50831
|
-
if (!
|
|
50966
|
+
if (!import_node_crypto7.default.timingSafeEqual(provided, expected)) {
|
|
50832
50967
|
return { ok: false, code: "BAD_SIG" };
|
|
50833
50968
|
}
|
|
50834
50969
|
if (e !== null && now() / 1e3 > e) {
|
|
@@ -50840,7 +50975,7 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
|
|
|
50840
50975
|
// src/attachment/upload.ts
|
|
50841
50976
|
var import_node_fs25 = __toESM(require("fs"), 1);
|
|
50842
50977
|
var import_node_path25 = __toESM(require("path"), 1);
|
|
50843
|
-
var
|
|
50978
|
+
var import_node_crypto8 = __toESM(require("crypto"), 1);
|
|
50844
50979
|
var import_promises2 = require("stream/promises");
|
|
50845
50980
|
var UploadError = class extends Error {
|
|
50846
50981
|
constructor(code, message) {
|
|
@@ -50864,11 +50999,11 @@ async function writeUploadedAttachment(args) {
|
|
|
50864
50999
|
} catch (err) {
|
|
50865
51000
|
throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
|
|
50866
51001
|
}
|
|
50867
|
-
const hasher =
|
|
51002
|
+
const hasher = import_node_crypto8.default.createHash("sha256");
|
|
50868
51003
|
let actualSize = 0;
|
|
50869
51004
|
const tmpPath = import_node_path25.default.join(
|
|
50870
51005
|
attachmentsRoot,
|
|
50871
|
-
`.upload-${process.pid}-${Date.now()}-${
|
|
51006
|
+
`.upload-${process.pid}-${Date.now()}-${import_node_crypto8.default.randomBytes(4).toString("hex")}`
|
|
50872
51007
|
);
|
|
50873
51008
|
try {
|
|
50874
51009
|
await (0, import_promises2.pipeline)(
|
|
@@ -51744,7 +51879,7 @@ function runAttachmentGc(args) {
|
|
|
51744
51879
|
// src/attachment/group.ts
|
|
51745
51880
|
var import_node_fs28 = __toESM(require("fs"), 1);
|
|
51746
51881
|
var import_node_path29 = __toESM(require("path"), 1);
|
|
51747
|
-
var
|
|
51882
|
+
var import_node_crypto9 = __toESM(require("crypto"), 1);
|
|
51748
51883
|
init_protocol();
|
|
51749
51884
|
var GroupFileStore = class {
|
|
51750
51885
|
dataDir;
|
|
@@ -51833,7 +51968,7 @@ var GroupFileStore = class {
|
|
|
51833
51968
|
entries[idx] = next;
|
|
51834
51969
|
} else {
|
|
51835
51970
|
next = {
|
|
51836
|
-
id: `gf-${
|
|
51971
|
+
id: `gf-${import_node_crypto9.default.randomBytes(6).toString("base64url")}`,
|
|
51837
51972
|
relPath: input.relPath,
|
|
51838
51973
|
from: input.from,
|
|
51839
51974
|
label: input.label,
|
|
@@ -51952,7 +52087,7 @@ function readDaemonSourceFromEnv(env = process.env) {
|
|
|
51952
52087
|
// src/tunnel/tunnel-manager.ts
|
|
51953
52088
|
var import_node_fs33 = __toESM(require("fs"), 1);
|
|
51954
52089
|
var import_node_path34 = __toESM(require("path"), 1);
|
|
51955
|
-
var
|
|
52090
|
+
var import_node_crypto10 = __toESM(require("crypto"), 1);
|
|
51956
52091
|
var import_node_child_process9 = require("child_process");
|
|
51957
52092
|
|
|
51958
52093
|
// src/tunnel/tunnel-store.ts
|
|
@@ -52451,7 +52586,7 @@ var TunnelManager = class {
|
|
|
52451
52586
|
override: this.deps.frpcBinaryOverride ?? void 0
|
|
52452
52587
|
});
|
|
52453
52588
|
const tomlPath = import_node_path34.default.join(this.deps.dataDir, "frpc.toml");
|
|
52454
|
-
const proxyName = `clawd-${t.subdomain}-${localPort}-${
|
|
52589
|
+
const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto10.default.randomBytes(3).toString("hex")}`;
|
|
52455
52590
|
const toml = buildFrpcToml({
|
|
52456
52591
|
serverAddr: t.frpsHost,
|
|
52457
52592
|
serverPort: t.frpsPort,
|
|
@@ -52550,7 +52685,7 @@ async function waitForFrpcReady(proc, timeoutMs) {
|
|
|
52550
52685
|
// src/tunnel/device-key.ts
|
|
52551
52686
|
var import_node_os14 = __toESM(require("os"), 1);
|
|
52552
52687
|
var import_node_path35 = __toESM(require("path"), 1);
|
|
52553
|
-
var
|
|
52688
|
+
var import_node_crypto11 = __toESM(require("crypto"), 1);
|
|
52554
52689
|
var DERIVE_SALT = "clawd-tunnel-device-v1";
|
|
52555
52690
|
function deriveStableDeviceKey(opts = {}) {
|
|
52556
52691
|
const hostname = opts.hostname ?? import_node_os14.default.hostname();
|
|
@@ -52560,13 +52695,13 @@ function deriveStableDeviceKey(opts = {}) {
|
|
|
52560
52695
|
const normalizedDataDir = opts.dataDir ? import_node_path35.default.resolve(opts.dataDir) : null;
|
|
52561
52696
|
const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
|
|
52562
52697
|
const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
|
|
52563
|
-
return
|
|
52698
|
+
return import_node_crypto11.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
|
|
52564
52699
|
}
|
|
52565
52700
|
|
|
52566
52701
|
// src/auth-store.ts
|
|
52567
52702
|
var import_node_fs34 = __toESM(require("fs"), 1);
|
|
52568
52703
|
var import_node_path36 = __toESM(require("path"), 1);
|
|
52569
|
-
var
|
|
52704
|
+
var import_node_crypto12 = __toESM(require("crypto"), 1);
|
|
52570
52705
|
var AUTH_FILE_NAME = "auth.json";
|
|
52571
52706
|
function authFilePath(dataDir) {
|
|
52572
52707
|
return import_node_path36.default.join(dataDir, AUTH_FILE_NAME);
|
|
@@ -52598,10 +52733,10 @@ function loadOrCreateAuthFile(opts) {
|
|
|
52598
52733
|
return next;
|
|
52599
52734
|
}
|
|
52600
52735
|
function defaultGenerateToken() {
|
|
52601
|
-
return
|
|
52736
|
+
return import_node_crypto12.default.randomBytes(32).toString("base64url");
|
|
52602
52737
|
}
|
|
52603
52738
|
function defaultGenerateOwnerPrincipalId() {
|
|
52604
|
-
return `owner-${
|
|
52739
|
+
return `owner-${import_node_crypto12.default.randomUUID()}`;
|
|
52605
52740
|
}
|
|
52606
52741
|
function readAuthFile(file) {
|
|
52607
52742
|
try {
|
|
@@ -52723,7 +52858,7 @@ var OwnerIdentityStore = class {
|
|
|
52723
52858
|
};
|
|
52724
52859
|
|
|
52725
52860
|
// src/feishu-auth/login-flow.ts
|
|
52726
|
-
var
|
|
52861
|
+
var import_node_crypto13 = __toESM(require("crypto"), 1);
|
|
52727
52862
|
var STATE_TTL_MS = 5 * 60 * 1e3;
|
|
52728
52863
|
var LoginFlow = class {
|
|
52729
52864
|
constructor(deps) {
|
|
@@ -52732,7 +52867,7 @@ var LoginFlow = class {
|
|
|
52732
52867
|
deps;
|
|
52733
52868
|
pendingStates = /* @__PURE__ */ new Map();
|
|
52734
52869
|
start() {
|
|
52735
|
-
const state =
|
|
52870
|
+
const state = import_node_crypto13.default.randomBytes(16).toString("base64url");
|
|
52736
52871
|
const now = (this.deps.now ?? Date.now)();
|
|
52737
52872
|
this.pendingStates.set(state, now);
|
|
52738
52873
|
this.gcExpired(now);
|
|
@@ -54610,7 +54745,7 @@ init_protocol();
|
|
|
54610
54745
|
// src/extension/bundle-zip.ts
|
|
54611
54746
|
var import_promises5 = __toESM(require("fs/promises"), 1);
|
|
54612
54747
|
var import_node_path42 = __toESM(require("path"), 1);
|
|
54613
|
-
var
|
|
54748
|
+
var import_node_crypto14 = __toESM(require("crypto"), 1);
|
|
54614
54749
|
var import_jszip2 = __toESM(require_lib3(), 1);
|
|
54615
54750
|
async function bundleExtensionDir(dir) {
|
|
54616
54751
|
const entries = await listFilesSorted(dir);
|
|
@@ -54625,7 +54760,7 @@ async function bundleExtensionDir(dir) {
|
|
|
54625
54760
|
compression: "DEFLATE",
|
|
54626
54761
|
compressionOptions: { level: 6 }
|
|
54627
54762
|
});
|
|
54628
|
-
const sha256 =
|
|
54763
|
+
const sha256 = import_node_crypto14.default.createHash("sha256").update(buffer).digest("hex");
|
|
54629
54764
|
return { buffer, sha256 };
|
|
54630
54765
|
}
|
|
54631
54766
|
var FIXED_DATE = /* @__PURE__ */ new Date("2020-01-01T00:00:00.000Z");
|
|
@@ -54693,7 +54828,7 @@ function computePublishCheck(args) {
|
|
|
54693
54828
|
var import_promises6 = __toESM(require("fs/promises"), 1);
|
|
54694
54829
|
var import_node_path44 = __toESM(require("path"), 1);
|
|
54695
54830
|
var import_node_os19 = __toESM(require("os"), 1);
|
|
54696
|
-
var
|
|
54831
|
+
var import_node_crypto15 = __toESM(require("crypto"), 1);
|
|
54697
54832
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
54698
54833
|
|
|
54699
54834
|
// src/extension/paths.ts
|
|
@@ -54722,7 +54857,7 @@ var InstallError = class extends Error {
|
|
|
54722
54857
|
};
|
|
54723
54858
|
async function installFromChannel(args, deps) {
|
|
54724
54859
|
const { channelRef, snapshotHash, bundleZip } = args;
|
|
54725
|
-
const computed =
|
|
54860
|
+
const computed = import_node_crypto15.default.createHash("sha256").update(bundleZip).digest("hex");
|
|
54726
54861
|
if (computed !== snapshotHash) {
|
|
54727
54862
|
throw new InstallError(
|
|
54728
54863
|
"HASH_MISMATCH",
|
|
@@ -54814,7 +54949,7 @@ async function installFromChannel(args, deps) {
|
|
|
54814
54949
|
var import_promises7 = __toESM(require("fs/promises"), 1);
|
|
54815
54950
|
var import_node_path45 = __toESM(require("path"), 1);
|
|
54816
54951
|
var import_node_os20 = __toESM(require("os"), 1);
|
|
54817
|
-
var
|
|
54952
|
+
var import_node_crypto16 = __toESM(require("crypto"), 1);
|
|
54818
54953
|
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
54819
54954
|
var UpdateError = class extends Error {
|
|
54820
54955
|
constructor(code, message) {
|
|
@@ -54852,7 +54987,7 @@ async function updateFromChannel(args, deps) {
|
|
|
54852
54987
|
if (e instanceof UpdateError) throw e;
|
|
54853
54988
|
throw e;
|
|
54854
54989
|
}
|
|
54855
|
-
const computed =
|
|
54990
|
+
const computed = import_node_crypto16.default.createHash("sha256").update(bundleZip).digest("hex");
|
|
54856
54991
|
if (computed !== snapshotHash) {
|
|
54857
54992
|
throw new UpdateError(
|
|
54858
54993
|
"HASH_MISMATCH",
|
|
@@ -55557,7 +55692,7 @@ function listPidsOnPort(port) {
|
|
|
55557
55692
|
}
|
|
55558
55693
|
|
|
55559
55694
|
// src/app-builder/publish-registry.ts
|
|
55560
|
-
var
|
|
55695
|
+
var import_node_crypto17 = require("crypto");
|
|
55561
55696
|
var PublishJobRegistry = class {
|
|
55562
55697
|
jobs = /* @__PURE__ */ new Map();
|
|
55563
55698
|
has(name) {
|
|
@@ -55574,7 +55709,7 @@ var PublishJobRegistry = class {
|
|
|
55574
55709
|
if (this.jobs.has(args.name)) {
|
|
55575
55710
|
throw new Error(`already publishing: ${args.name}`);
|
|
55576
55711
|
}
|
|
55577
|
-
const jobId = args.jobId ?? `job-${(0,
|
|
55712
|
+
const jobId = args.jobId ?? `job-${(0, import_node_crypto17.randomUUID)()}`;
|
|
55578
55713
|
this.jobs.set(args.name, {
|
|
55579
55714
|
jobId,
|
|
55580
55715
|
name: args.name,
|
|
@@ -56534,7 +56669,7 @@ async function uninstall(deps) {
|
|
|
56534
56669
|
}
|
|
56535
56670
|
|
|
56536
56671
|
// src/handlers/index.ts
|
|
56537
|
-
var
|
|
56672
|
+
var import_node_crypto18 = require("crypto");
|
|
56538
56673
|
function buildMethodHandlers(deps) {
|
|
56539
56674
|
return {
|
|
56540
56675
|
...buildSessionHandlers({
|
|
@@ -56567,7 +56702,7 @@ function buildMethodHandlers(deps) {
|
|
|
56567
56702
|
const c = deps.contactStore.get(deviceId);
|
|
56568
56703
|
return c ? { deviceId: c.deviceId, remoteUrl: c.remoteUrl, connectToken: c.connectToken } : null;
|
|
56569
56704
|
},
|
|
56570
|
-
genId: () => (0,
|
|
56705
|
+
genId: () => (0, import_node_crypto18.randomUUID)(),
|
|
56571
56706
|
now: () => Date.now(),
|
|
56572
56707
|
forwardInboxPostToPeer,
|
|
56573
56708
|
logger: deps.logger
|
|
@@ -57469,6 +57604,13 @@ async function startDaemon(config) {
|
|
|
57469
57604
|
logClient
|
|
57470
57605
|
});
|
|
57471
57606
|
logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
|
|
57607
|
+
const screenIdleProbeLogger = createFileOnlyLogger({
|
|
57608
|
+
file: import_node_path55.default.join(config.dataDir, "screen-idle-probe.log"),
|
|
57609
|
+
level: "debug"
|
|
57610
|
+
});
|
|
57611
|
+
logger.info("screen-idle probe logger enabled", {
|
|
57612
|
+
file: import_node_path55.default.join(config.dataDir, "screen-idle-probe.log")
|
|
57613
|
+
});
|
|
57472
57614
|
const stateMgr = new StateFileManager({ dataDir: config.dataDir });
|
|
57473
57615
|
const pre = stateMgr.preflight();
|
|
57474
57616
|
if (pre.status === "active") {
|
|
@@ -57745,6 +57887,10 @@ async function startDaemon(config) {
|
|
|
57745
57887
|
// 新布局派生 (sessions/* + personas/<pid>/.clawd/sessions/owner/*)
|
|
57746
57888
|
storeFactory: sessionStoreFactory,
|
|
57747
57889
|
logger,
|
|
57890
|
+
// 取证 probe(可选,CLAWD_SCREEN_IDLE_PROBE=1 时启用):manager turn_end 判定链
|
|
57891
|
+
// 的所有决策点打到独立文件,跟 adapter 的 observeScreenIdle probe 共用同一份 file logger,
|
|
57892
|
+
// 便于 grep sessionId 时 tui 层 + manager 层交叉时序都在同一文件里
|
|
57893
|
+
...screenIdleProbeLogger ? { screenIdleProbeLogger } : {},
|
|
57748
57894
|
getAdapter,
|
|
57749
57895
|
historyReader: history,
|
|
57750
57896
|
dataDir: config.dataDir,
|
|
@@ -57865,7 +58011,9 @@ async function startDaemon(config) {
|
|
|
57865
58011
|
// 屏幕静止 → 补权威 turn_end(修 turn_duration 尾随 text 覆盖 lastEventKind)
|
|
57866
58012
|
onTurnIdle: (tsid) => manager.dispatchTurnIdle(tsid),
|
|
57867
58013
|
// 复合条件闸:observer 还需静止多久才满 idleMs(屏幕静止后精确等这段剩余再补 turn_end)
|
|
57868
|
-
getObserverWaitMs: (tsid, idleMs) => manager.observerIdleWaitMs(tsid, idleMs)
|
|
58014
|
+
getObserverWaitMs: (tsid, idleMs) => manager.observerIdleWaitMs(tsid, idleMs),
|
|
58015
|
+
// 取证 probe(可选,CLAWD_SCREEN_IDLE_PROBE=1 时启用;生产默认 undefined 不打)
|
|
58016
|
+
...screenIdleProbeLogger ? { screenIdleProbeLogger } : {}
|
|
57869
58017
|
}) : new ClaudeAdapter({ logger, historyReader: new ClaudeHistoryReader() });
|
|
57870
58018
|
registerAdapter("claude", claudeAdapter);
|
|
57871
58019
|
registerAdapter("codex", new CodexAdapter({ logger, historyReader: new CodexHistoryReader() }));
|
package/package.json
CHANGED