botmux 3.16.0 → 3.16.1
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/.runtime-build-id +1 -1
- package/dist/core/dashboard-url.d.ts +10 -1
- package/dist/core/dashboard-url.d.ts.map +1 -1
- package/dist/core/dashboard-url.js +12 -2
- package/dist/core/dashboard-url.js.map +1 -1
- package/dist/core/plugins/mcp/gateway.d.ts +27 -3
- package/dist/core/plugins/mcp/gateway.d.ts.map +1 -1
- package/dist/core/plugins/mcp/gateway.js +272 -26
- package/dist/core/plugins/mcp/gateway.js.map +1 -1
- package/dist/core/plugins/mcp/host.d.ts +18 -0
- package/dist/core/plugins/mcp/host.d.ts.map +1 -1
- package/dist/core/plugins/mcp/host.js +80 -16
- package/dist/core/plugins/mcp/host.js.map +1 -1
- package/dist/core/plugins/mcp/launch-record.d.ts +14 -0
- package/dist/core/plugins/mcp/launch-record.d.ts.map +1 -0
- package/dist/core/plugins/mcp/launch-record.js +63 -0
- package/dist/core/plugins/mcp/launch-record.js.map +1 -0
- package/dist/core/worker-pool.d.ts +10 -2
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +30 -3
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/dashboard/control-csrf.d.ts.map +1 -1
- package/dist/dashboard/control-csrf.js +6 -1
- package/dist/dashboard/control-csrf.js.map +1 -1
- package/dist/dashboard/terminal-front-proxy.d.ts.map +1 -1
- package/dist/dashboard/terminal-front-proxy.js +19 -1
- package/dist/dashboard/terminal-front-proxy.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +1 -0
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +1 -0
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/card-handler.d.ts.map +1 -1
- package/dist/im/lark/card-handler.js +65 -4
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/platform/binding.d.ts +27 -0
- package/dist/platform/binding.d.ts.map +1 -1
- package/dist/platform/binding.js +40 -0
- package/dist/platform/binding.js.map +1 -1
- package/dist/services/bridge-turn-journal.d.ts +63 -0
- package/dist/services/bridge-turn-journal.d.ts.map +1 -0
- package/dist/services/bridge-turn-journal.js +149 -0
- package/dist/services/bridge-turn-journal.js.map +1 -0
- package/dist/services/bridge-turn-queue.d.ts +8 -1
- package/dist/services/bridge-turn-queue.d.ts.map +1 -1
- package/dist/services/bridge-turn-queue.js +2 -1
- package/dist/services/bridge-turn-queue.js.map +1 -1
- package/dist/worker.js +270 -19
- package/dist/worker.js.map +1 -1
- package/package.json +1 -1
|
@@ -33,6 +33,33 @@ export declare function clearPlatformBinding(): void;
|
|
|
33
33
|
* (公开仓库不写死平台域名);前缀 `m-` 是平台约定。未绑定返回 null。
|
|
34
34
|
*/
|
|
35
35
|
export declare function platformMachineBaseUrl(): string | null;
|
|
36
|
+
/**
|
|
37
|
+
* 平台面向浏览器的、本机可信子域 authority 列表(`host` 形式,不含 scheme)。
|
|
38
|
+
*
|
|
39
|
+
* 中心平台把本机放在 `<前缀>-<machineId>.<平台域名>` 子域下,再经隧道反代回本机
|
|
40
|
+
* dashboard——反代时把 `Host` 改写成回环上游、且**不带 `X-Forwarded-Host`**,于是
|
|
41
|
+
* 浏览器发的管理类 WS/请求携带的 `Origin: https://<前缀>-<machineId>.<平台域名>`
|
|
42
|
+
* 在 dashboard 的同源校验里找不到匹配的候选 authority(见 dashboard/control-csrf.ts
|
|
43
|
+
* 的 `requestAuthorities`),被判跨站拒掉——平台浏览器终端 disconnected。
|
|
44
|
+
*
|
|
45
|
+
* 这里由本机 `platform.json`(0600 host-authority,machineId 平台签发、跨站页面
|
|
46
|
+
* **伪造不进**)派生出**精确前缀**的可信 authority,交给 `requestAuthorities` 并入
|
|
47
|
+
* 候选。为什么**枚举** `m-`/`t-` 精确前缀而非通配 `<任意前缀>-<machineId>`:
|
|
48
|
+
* • 安全门须 fail-closed。枚举只依赖「这 2 个前缀反代到本机」这条弱不变量;通配
|
|
49
|
+
* `*-<machineId>` 依赖「**任何**前缀标签都不会落到攻击者可控源」——强得多、且
|
|
50
|
+
* 本进程无从验证(平台路由表不在部署机上)。
|
|
51
|
+
* • 失败方向相反:枚举漏一个前缀 = 那种终端连不上(响、加一行前缀即修);通配一旦
|
|
52
|
+
* 平台某天把某 `<label>-<machineId>` 挂到多租户/共享源上 = **静默把跨源认成同源**
|
|
53
|
+
* 的 CSRF 洞。宁可响不可哑。
|
|
54
|
+
* `m-` 是仓库既有约定(`platformMachineBaseUrl`);`t-` 是平台给浏览器分享链接实际使用
|
|
55
|
+
* 的独立终端子域(仓库无此字面量,故 #933 的同源门漏了它)。未绑定平台 → 返回空数组,
|
|
56
|
+
* 不放行任何平台 authority(fail-closed)。
|
|
57
|
+
*
|
|
58
|
+
* 每次调用都重读 `platform.json`(不缓存):`botmux bind|unbind` 热重载不重启 daemon
|
|
59
|
+
* (见 worker.ts 亦每请求 uncached 读),缓存会在解绑+machineToken 吊销后仍放行 stale
|
|
60
|
+
* 平台 authority = fail-open;每请求读天然 fail-closed(解绑→文件没了→空数组)。
|
|
61
|
+
*/
|
|
62
|
+
export declare function platformBrowserAuthorities(): string[];
|
|
36
63
|
/**
|
|
37
64
|
* 自建反代对外基址(`BOTMUX_PUBLIC_URL`):没接中心平台、但自己用 nginx 等反代把
|
|
38
65
|
* dashboard 暴露到单一公网/内网域名时,设成 `http://botmux.example.com`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binding.d.ts","sourceRoot":"","sources":["../../src/platform/binding.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,eAAe;IAC9B,aAAa;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;IACvB;;+BAE2B;IAC3B,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,qBAAqB,QAA8C,CAAC;AAEjF,wBAAgB,mBAAmB,IAAI,eAAe,GAAG,IAAI,CAqB5D;AAED,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,eAAe,GAAG,IAAI,CAE7D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAM3C;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,GAAG,IAAI,CAStD;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,GAAG,IAAI,CAIzD;AAED,mDAAmD;AACnD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,YAAY,EAAE,CAMtE"}
|
|
1
|
+
{"version":3,"file":"binding.d.ts","sourceRoot":"","sources":["../../src/platform/binding.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,eAAe;IAC9B,aAAa;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;IACvB;;+BAE2B;IAC3B,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,qBAAqB,QAA8C,CAAC;AAEjF,wBAAgB,mBAAmB,IAAI,eAAe,GAAG,IAAI,CAqB5D;AAED,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,eAAe,GAAG,IAAI,CAE7D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAM3C;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,GAAG,IAAI,CAStD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,EAAE,CAUrD;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,GAAG,IAAI,CAIzD;AAED,mDAAmD;AACnD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,YAAY,EAAE,CAMtE"}
|
package/dist/platform/binding.js
CHANGED
|
@@ -58,6 +58,46 @@ export function platformMachineBaseUrl() {
|
|
|
58
58
|
return null;
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* 平台面向浏览器的、本机可信子域 authority 列表(`host` 形式,不含 scheme)。
|
|
63
|
+
*
|
|
64
|
+
* 中心平台把本机放在 `<前缀>-<machineId>.<平台域名>` 子域下,再经隧道反代回本机
|
|
65
|
+
* dashboard——反代时把 `Host` 改写成回环上游、且**不带 `X-Forwarded-Host`**,于是
|
|
66
|
+
* 浏览器发的管理类 WS/请求携带的 `Origin: https://<前缀>-<machineId>.<平台域名>`
|
|
67
|
+
* 在 dashboard 的同源校验里找不到匹配的候选 authority(见 dashboard/control-csrf.ts
|
|
68
|
+
* 的 `requestAuthorities`),被判跨站拒掉——平台浏览器终端 disconnected。
|
|
69
|
+
*
|
|
70
|
+
* 这里由本机 `platform.json`(0600 host-authority,machineId 平台签发、跨站页面
|
|
71
|
+
* **伪造不进**)派生出**精确前缀**的可信 authority,交给 `requestAuthorities` 并入
|
|
72
|
+
* 候选。为什么**枚举** `m-`/`t-` 精确前缀而非通配 `<任意前缀>-<machineId>`:
|
|
73
|
+
* • 安全门须 fail-closed。枚举只依赖「这 2 个前缀反代到本机」这条弱不变量;通配
|
|
74
|
+
* `*-<machineId>` 依赖「**任何**前缀标签都不会落到攻击者可控源」——强得多、且
|
|
75
|
+
* 本进程无从验证(平台路由表不在部署机上)。
|
|
76
|
+
* • 失败方向相反:枚举漏一个前缀 = 那种终端连不上(响、加一行前缀即修);通配一旦
|
|
77
|
+
* 平台某天把某 `<label>-<machineId>` 挂到多租户/共享源上 = **静默把跨源认成同源**
|
|
78
|
+
* 的 CSRF 洞。宁可响不可哑。
|
|
79
|
+
* `m-` 是仓库既有约定(`platformMachineBaseUrl`);`t-` 是平台给浏览器分享链接实际使用
|
|
80
|
+
* 的独立终端子域(仓库无此字面量,故 #933 的同源门漏了它)。未绑定平台 → 返回空数组,
|
|
81
|
+
* 不放行任何平台 authority(fail-closed)。
|
|
82
|
+
*
|
|
83
|
+
* 每次调用都重读 `platform.json`(不缓存):`botmux bind|unbind` 热重载不重启 daemon
|
|
84
|
+
* (见 worker.ts 亦每请求 uncached 读),缓存会在解绑+machineToken 吊销后仍放行 stale
|
|
85
|
+
* 平台 authority = fail-open;每请求读天然 fail-closed(解绑→文件没了→空数组)。
|
|
86
|
+
*/
|
|
87
|
+
export function platformBrowserAuthorities() {
|
|
88
|
+
const b = readPlatformBinding();
|
|
89
|
+
if (!b)
|
|
90
|
+
return [];
|
|
91
|
+
try {
|
|
92
|
+
const host = new URL(b.platformUrl).host;
|
|
93
|
+
if (!host)
|
|
94
|
+
return [];
|
|
95
|
+
return [`m-${b.machineId}.${host}`, `t-${b.machineId}.${host}`];
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return [];
|
|
99
|
+
}
|
|
100
|
+
}
|
|
61
101
|
/**
|
|
62
102
|
* 自建反代对外基址(`BOTMUX_PUBLIC_URL`):没接中心平台、但自己用 nginx 等反代把
|
|
63
103
|
* dashboard 暴露到单一公网/内网域名时,设成 `http://botmux.example.com`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binding.js","sourceRoot":"","sources":["../../src/platform/binding.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EACL,sBAAsB,EACtB,wBAAwB,EACxB,4BAA4B,EAC5B,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAwB/B,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;AAEjF,MAAM,UAAU,mBAAmB;IACjC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,sBAAsB,CAAC,qBAAqB,CAAC,CAAC;QAC1D,IAAI,GAAG,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,WAAW,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,YAAY,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;YAC5H,OAAO,GAAsB,CAAC;QAChC,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,yEAAyE;QACzE,wEAAwE;QACxE,2EAA2E;QAC3E,wBAAwB;QACxB,IAAI,KAAK,YAAY,4BAA4B,EAAE,CAAC;YAClD,OAAO,CAAC,KAAK,CACX,2BAA2B,qBAAqB,KAAK,KAAK,CAAC,OAAO,EAAE;kBAClE,uFAAuF,CAC1F,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,CAAkB;IACrD,uBAAuB,CAAC,qBAAqB,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACpF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB;IAClC,IAAI,CAAC;QACH,wBAAwB,CAAC,qBAAqB,CAAC,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,YAAY;IACd,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB;IACpC,MAAM,CAAC,GAAG,mBAAmB,EAAE,CAAC;IAChC,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;QACjC,OAAO,GAAG,CAAC,CAAC,QAAQ,OAAO,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,yBAAyB;IACvC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,IAAI,EAAE,CAAC;IAClD,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACjC,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,gBAAgB,CAAC,KAAqB;IACpD,MAAM,CAAC,GAAG,mBAAmB,EAAE,CAAC;IAChC,IAAI,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAClB,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC;IAChB,oBAAoB,CAAC,CAAC,CAAC,CAAC;IACxB,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
1
|
+
{"version":3,"file":"binding.js","sourceRoot":"","sources":["../../src/platform/binding.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export interface BridgeTurnJournalEntry {
|
|
2
|
+
turnId: string;
|
|
3
|
+
dispatchAttempt?: number;
|
|
4
|
+
/** Wall-clock millis of the original mark — restored verbatim so the
|
|
5
|
+
* send-marker window and the split cutoff keep their original bounds. */
|
|
6
|
+
markTimeMs: number;
|
|
7
|
+
fingerprint?: string;
|
|
8
|
+
contentNormalized?: string;
|
|
9
|
+
/** Transcript file the mark was armed against. Restore is scoped to the
|
|
10
|
+
* SAME file — a rotation between generations makes attribution unsafe. */
|
|
11
|
+
jsonlPath: string;
|
|
12
|
+
/** Consumed transcript offset when the mark was armed. The turn's user
|
|
13
|
+
* line can only exist at/after this byte, so restore re-drains from here
|
|
14
|
+
* instead of re-reading the whole file. Always a line boundary. */
|
|
15
|
+
offsetAtMark: number;
|
|
16
|
+
}
|
|
17
|
+
/** Entries older than this are dropped at restore instead of re-marked: a
|
|
18
|
+
* partial answer from days ago posted into a thread that has long moved on
|
|
19
|
+
* is noise, not recovery. */
|
|
20
|
+
export declare const BRIDGE_TURN_RESTORE_MAX_AGE_MS: number;
|
|
21
|
+
export declare function readBridgeTurnJournal(path: string): BridgeTurnJournalEntry[];
|
|
22
|
+
export declare function writeBridgeTurnJournal(path: string, pending: BridgeTurnJournalEntry[]): void;
|
|
23
|
+
export declare function appendBridgeTurnJournalEntry(path: string, entry: BridgeTurnJournalEntry): void;
|
|
24
|
+
export declare function removeBridgeTurnJournalEntry(path: string, turnId: string, dispatchAttempt?: number): void;
|
|
25
|
+
export declare function clearBridgeTurnJournal(path: string): void;
|
|
26
|
+
/** Pure restore filter: which journal entries may be re-marked on this
|
|
27
|
+
* worker generation? Scoped to the same transcript file (rotation between
|
|
28
|
+
* generations makes offset+fingerprint attribution unsafe) and bounded by
|
|
29
|
+
* age (stale partials are noise). */
|
|
30
|
+
export declare function selectRestorableBridgeTurns(entries: readonly BridgeTurnJournalEntry[], opts: {
|
|
31
|
+
currentJsonlPath: string;
|
|
32
|
+
nowMs?: number;
|
|
33
|
+
maxAgeMs?: number;
|
|
34
|
+
}): BridgeTurnJournalEntry[];
|
|
35
|
+
/**
|
|
36
|
+
* One-shot latch that confines journal restore to a worker process's FIRST
|
|
37
|
+
* bridge baseline. Extracted from worker.ts (like InflightInputTracker) so the
|
|
38
|
+
* "restore at most once, only on the first baseline" rule is unit-testable.
|
|
39
|
+
*
|
|
40
|
+
* Why it exists: the journal recovers a plain-IM turn orphaned by a
|
|
41
|
+
* CROSS-process death (daemon restart / worker crash) — there the whole worker
|
|
42
|
+
* is new and no other recovery owner survives. But an IN-worker CLI restart
|
|
43
|
+
* (crash-respawn / cwd-move / durable lease expiry) keeps the process alive, so
|
|
44
|
+
* its InflightInputTracker carryover ALREADY re-delivers the interrupted plain
|
|
45
|
+
* IM input as a full fresh answer. If the journal ALSO restored that turn on the
|
|
46
|
+
* post-restart baseline, the recovered partial and the fresh answer — same
|
|
47
|
+
* turnId, different lastUuid — would both reach Lark (the daemon dedupe can't
|
|
48
|
+
* collapse them). The worker arms this latch on every watcher teardown, so only
|
|
49
|
+
* the first baseline (the one with no competing recovery owner) may restore.
|
|
50
|
+
*/
|
|
51
|
+
export declare class BridgeRestoreGate {
|
|
52
|
+
private consumed;
|
|
53
|
+
/** True only on the first call after construction — the process's first
|
|
54
|
+
* baseline. Every later call (a post-restart baseline) returns false. Does
|
|
55
|
+
* NOT itself consume the latch: an empty-journal first baseline must still
|
|
56
|
+
* arm it via markGenerationRetired so a later restart can't restore. */
|
|
57
|
+
mayRestoreOnThisBaseline(): boolean;
|
|
58
|
+
/** Arm the latch: a CLI generation has ended (watcher torn down), so any
|
|
59
|
+
* future baseline is an in-worker restart, never first-baseline recovery.
|
|
60
|
+
* Idempotent. */
|
|
61
|
+
markGenerationRetired(): void;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=bridge-turn-journal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridge-turn-journal.d.ts","sourceRoot":"","sources":["../../src/services/bridge-turn-journal.ts"],"names":[],"mappings":"AAoCA,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;8EAC0E;IAC1E,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;+EAC2E;IAC3E,SAAS,EAAE,MAAM,CAAC;IAClB;;wEAEoE;IACpE,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;8BAE8B;AAC9B,eAAO,MAAM,8BAA8B,QAAsB,CAAC;AAYlE,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,sBAAsB,EAAE,CAkB5E;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,EAAE,GAAG,IAAI,CAS5F;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,sBAAsB,GAAG,IAAI,CAK9F;AAED,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,eAAe,CAAC,EAAE,MAAM,GACvB,IAAI,CAWN;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAEzD;AAED;;;sCAGsC;AACtC,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,SAAS,sBAAsB,EAAE,EAC1C,IAAI,EAAE;IAAE,gBAAgB,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GACpE,sBAAsB,EAAE,CAgB1B;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAS;IAEzB;;;6EAGyE;IACzE,wBAAwB,IAAI,OAAO;IAInC;;sBAEkB;IAClB,qBAAqB,IAAI,IAAI;CAG9B"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable journal of PENDING (not yet terminalized) Lark bridge turns.
|
|
3
|
+
*
|
|
4
|
+
* The Claude-bridge attribution queue (`BridgeTurnQueue`) lives in worker
|
|
5
|
+
* memory: when the worker dies mid-turn (daemon restart / upgrade / crash),
|
|
6
|
+
* every pending mark is lost, and on respawn the bridge baselines the
|
|
7
|
+
* transcript to EOF — so the interrupted turn's user line AND whatever
|
|
8
|
+
* assistant text the model produced before the kill are silently skipped.
|
|
9
|
+
* The user gets neither a `botmux send` (the model never reached it) nor the
|
|
10
|
+
* transcript-driven fallback (nothing left to harvest). This journal closes
|
|
11
|
+
* that gap:
|
|
12
|
+
*
|
|
13
|
+
* - the worker appends an entry when it marks a Lark turn (delivery time),
|
|
14
|
+
* recording everything the queue needs to re-create the mark PLUS the
|
|
15
|
+
* consumed transcript offset at that moment;
|
|
16
|
+
* - the entry is removed at every turn-terminal outcome (emitted,
|
|
17
|
+
* suppressed, dropped, expired);
|
|
18
|
+
* - on respawn, `bridgeAbsorbBaseline` consults the journal instead of
|
|
19
|
+
* blindly baselining to EOF: surviving entries are re-marked and the
|
|
20
|
+
* transcript is re-drained from the recorded offset, so the interrupted
|
|
21
|
+
* turn's output is attributed and delivered through the NORMAL fallback
|
|
22
|
+
* gate (send-marker dedup still applies — `turn-sends` markers persist
|
|
23
|
+
* across restarts).
|
|
24
|
+
*
|
|
25
|
+
* Removal happens BEFORE the final_output IPC is sent (clear-at-pop): if the
|
|
26
|
+
* worker dies in between, the answer is lost rather than duplicated — the
|
|
27
|
+
* daemon-side dedupe key does not survive restarts, so duplicating would be
|
|
28
|
+
* the worse failure.
|
|
29
|
+
*
|
|
30
|
+
* The whole file is rewritten atomically (tmp + rename) on every mutation;
|
|
31
|
+
* the pending set is tiny (type-ahead depth, single digits), so this is
|
|
32
|
+
* cheaper and simpler than an append-only log with compaction.
|
|
33
|
+
*/
|
|
34
|
+
import { mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
|
|
35
|
+
import { dirname } from 'node:path';
|
|
36
|
+
/** Entries older than this are dropped at restore instead of re-marked: a
|
|
37
|
+
* partial answer from days ago posted into a thread that has long moved on
|
|
38
|
+
* is noise, not recovery. */
|
|
39
|
+
export const BRIDGE_TURN_RESTORE_MAX_AGE_MS = 24 * 60 * 60 * 1000;
|
|
40
|
+
/** Bound on tracked entries — pathological mark storms must not grow the
|
|
41
|
+
* journal unboundedly. Oldest entries are shed first (they are also the
|
|
42
|
+
* first to fail the restore age gate). */
|
|
43
|
+
const MAX_JOURNAL_ENTRIES = 32;
|
|
44
|
+
export function readBridgeTurnJournal(path) {
|
|
45
|
+
let raw;
|
|
46
|
+
try {
|
|
47
|
+
raw = readFileSync(path, 'utf8');
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
const parsed = JSON.parse(raw);
|
|
54
|
+
if (parsed?.version !== 1 || !Array.isArray(parsed.pending))
|
|
55
|
+
return [];
|
|
56
|
+
return parsed.pending.filter(entry => typeof entry?.turnId === 'string'
|
|
57
|
+
&& typeof entry?.markTimeMs === 'number'
|
|
58
|
+
&& typeof entry?.jsonlPath === 'string'
|
|
59
|
+
&& typeof entry?.offsetAtMark === 'number');
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return [];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
export function writeBridgeTurnJournal(path, pending) {
|
|
66
|
+
const bounded = pending.length > MAX_JOURNAL_ENTRIES
|
|
67
|
+
? pending.slice(pending.length - MAX_JOURNAL_ENTRIES)
|
|
68
|
+
: pending;
|
|
69
|
+
const payload = { version: 1, pending: bounded };
|
|
70
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
71
|
+
const tmpPath = `${path}.${process.pid}.tmp`;
|
|
72
|
+
writeFileSync(tmpPath, `${JSON.stringify(payload)}\n`, { mode: 0o600 });
|
|
73
|
+
renameSync(tmpPath, path);
|
|
74
|
+
}
|
|
75
|
+
export function appendBridgeTurnJournalEntry(path, entry) {
|
|
76
|
+
const pending = readBridgeTurnJournal(path)
|
|
77
|
+
.filter(existing => !(existing.turnId === entry.turnId && existing.dispatchAttempt === entry.dispatchAttempt));
|
|
78
|
+
pending.push(entry);
|
|
79
|
+
writeBridgeTurnJournal(path, pending);
|
|
80
|
+
}
|
|
81
|
+
export function removeBridgeTurnJournalEntry(path, turnId, dispatchAttempt) {
|
|
82
|
+
const pending = readBridgeTurnJournal(path);
|
|
83
|
+
const remaining = pending.filter(entry => !(entry.turnId === turnId
|
|
84
|
+
&& (dispatchAttempt === undefined || entry.dispatchAttempt === dispatchAttempt)));
|
|
85
|
+
if (remaining.length === pending.length)
|
|
86
|
+
return;
|
|
87
|
+
if (remaining.length === 0) {
|
|
88
|
+
rmSync(path, { force: true });
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
writeBridgeTurnJournal(path, remaining);
|
|
92
|
+
}
|
|
93
|
+
export function clearBridgeTurnJournal(path) {
|
|
94
|
+
rmSync(path, { force: true });
|
|
95
|
+
}
|
|
96
|
+
/** Pure restore filter: which journal entries may be re-marked on this
|
|
97
|
+
* worker generation? Scoped to the same transcript file (rotation between
|
|
98
|
+
* generations makes offset+fingerprint attribution unsafe) and bounded by
|
|
99
|
+
* age (stale partials are noise). */
|
|
100
|
+
export function selectRestorableBridgeTurns(entries, opts) {
|
|
101
|
+
const nowMs = opts.nowMs ?? Date.now();
|
|
102
|
+
const maxAgeMs = opts.maxAgeMs ?? BRIDGE_TURN_RESTORE_MAX_AGE_MS;
|
|
103
|
+
return entries
|
|
104
|
+
.filter(entry => entry.jsonlPath === opts.currentJsonlPath
|
|
105
|
+
&& nowMs - entry.markTimeMs <= maxAgeMs
|
|
106
|
+
// Only PLAIN Lark IM turns are restorable. Durable turns
|
|
107
|
+
// (dispatchAttempt set) have their own cross-restart recovery owner (the
|
|
108
|
+
// daemon's persisted queuedActivation* write-ahead + receipt
|
|
109
|
+
// auto-redispatch); restoring one from the journal would double-deliver
|
|
110
|
+
// (recovered partial + re-dispatched attempt share a turnId but carry
|
|
111
|
+
// different lastUuids, so the daemon dedupe can't collapse them). The
|
|
112
|
+
// write side already skips journaling them; this is belt-and-braces for a
|
|
113
|
+
// journal file left behind by a pre-fix build across an upgrade.
|
|
114
|
+
&& entry.dispatchAttempt === undefined)
|
|
115
|
+
.sort((a, b) => a.markTimeMs - b.markTimeMs);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* One-shot latch that confines journal restore to a worker process's FIRST
|
|
119
|
+
* bridge baseline. Extracted from worker.ts (like InflightInputTracker) so the
|
|
120
|
+
* "restore at most once, only on the first baseline" rule is unit-testable.
|
|
121
|
+
*
|
|
122
|
+
* Why it exists: the journal recovers a plain-IM turn orphaned by a
|
|
123
|
+
* CROSS-process death (daemon restart / worker crash) — there the whole worker
|
|
124
|
+
* is new and no other recovery owner survives. But an IN-worker CLI restart
|
|
125
|
+
* (crash-respawn / cwd-move / durable lease expiry) keeps the process alive, so
|
|
126
|
+
* its InflightInputTracker carryover ALREADY re-delivers the interrupted plain
|
|
127
|
+
* IM input as a full fresh answer. If the journal ALSO restored that turn on the
|
|
128
|
+
* post-restart baseline, the recovered partial and the fresh answer — same
|
|
129
|
+
* turnId, different lastUuid — would both reach Lark (the daemon dedupe can't
|
|
130
|
+
* collapse them). The worker arms this latch on every watcher teardown, so only
|
|
131
|
+
* the first baseline (the one with no competing recovery owner) may restore.
|
|
132
|
+
*/
|
|
133
|
+
export class BridgeRestoreGate {
|
|
134
|
+
consumed = false;
|
|
135
|
+
/** True only on the first call after construction — the process's first
|
|
136
|
+
* baseline. Every later call (a post-restart baseline) returns false. Does
|
|
137
|
+
* NOT itself consume the latch: an empty-journal first baseline must still
|
|
138
|
+
* arm it via markGenerationRetired so a later restart can't restore. */
|
|
139
|
+
mayRestoreOnThisBaseline() {
|
|
140
|
+
return !this.consumed;
|
|
141
|
+
}
|
|
142
|
+
/** Arm the latch: a CLI generation has ended (watcher torn down), so any
|
|
143
|
+
* future baseline is an in-worker restart, never first-baseline recovery.
|
|
144
|
+
* Idempotent. */
|
|
145
|
+
markGenerationRetired() {
|
|
146
|
+
this.consumed = true;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=bridge-turn-journal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridge-turn-journal.js","sourceRoot":"","sources":["../../src/services/bridge-turn-journal.ts"],"names":[],"mappings":"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"}
|
|
@@ -85,6 +85,11 @@ export interface BridgePendingTurn {
|
|
|
85
85
|
* the turn — short fingerprints ("hello", "test") would otherwise risk
|
|
86
86
|
* matching pre-existing user lines in unrelated sibling jsonls. */
|
|
87
87
|
markTimeMs?: number;
|
|
88
|
+
/** Set when this mark was re-created from the durable turn journal after a
|
|
89
|
+
* worker/daemon restart interrupted the turn. The emit path prefixes the
|
|
90
|
+
* delivered fallback with an "interrupted by restart" notice so the user
|
|
91
|
+
* can tell a recovered partial answer from a live one. */
|
|
92
|
+
restoredFromJournal?: boolean;
|
|
88
93
|
}
|
|
89
94
|
/** Trim a Lark message into a stable fingerprint. Keeps a leading window
|
|
90
95
|
* of non-whitespace-collapsed content; long enough to disambiguate, short
|
|
@@ -133,7 +138,9 @@ export declare class BridgeTurnQueue {
|
|
|
133
138
|
* `markTimeMs` is captured here so the rotation fallback can bound its
|
|
134
139
|
* fingerprint scan to events written after this point — protects short
|
|
135
140
|
* fingerprints from matching old history in unrelated sibling jsonls. */
|
|
136
|
-
mark(turnId: string, contentFingerprint?: string, markTimeMs?: number, contentNormalized?: string, dispatchAttempt?: number
|
|
141
|
+
mark(turnId: string, contentFingerprint?: string, markTimeMs?: number, contentNormalized?: string, dispatchAttempt?: number, opts?: {
|
|
142
|
+
restoredFromJournal?: boolean;
|
|
143
|
+
}): string;
|
|
137
144
|
/** Drop all pending turns. Used when the worker discovers it can't
|
|
138
145
|
* reliably attribute future events (e.g. baseline raced with a turn
|
|
139
146
|
* already in flight) and wants to clear the slate. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge-turn-queue.d.ts","sourceRoot":"","sources":["../../src/services/bridge-turn-queue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,EACL,uBAAuB,EAOvB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACrB,MAAM,wBAAwB,CAAC;AAIhC,OAAO,EAAE,uBAAuB,EAAE,CAAC;AAQnC,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB;;wEAEoE;IACpE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;0EACsE;IACtE,eAAe,CAAC,EAAE,OAAO,CAAC,qBAAqB,EAAE;QAAE,MAAM,EAAE,cAAc,CAAA;KAAE,CAAC,CAAC;IAC7E;;qEAEiE;IACjE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;+EAI2E;IAC3E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;gEAG4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;2DAIuD;IACvD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;oEAMgE;IAChE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;mBAKe;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;wEAGoE;IACpE,UAAU,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"bridge-turn-queue.d.ts","sourceRoot":"","sources":["../../src/services/bridge-turn-queue.ts"],"names":[],"mappings":"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"}
|
|
@@ -109,7 +109,7 @@ export class BridgeTurnQueue {
|
|
|
109
109
|
* `markTimeMs` is captured here so the rotation fallback can bound its
|
|
110
110
|
* fingerprint scan to events written after this point — protects short
|
|
111
111
|
* fingerprints from matching old history in unrelated sibling jsonls. */
|
|
112
|
-
mark(turnId, contentFingerprint, markTimeMs = Date.now(), contentNormalized, dispatchAttempt) {
|
|
112
|
+
mark(turnId, contentFingerprint, markTimeMs = Date.now(), contentNormalized, dispatchAttempt, opts) {
|
|
113
113
|
this.queue.push({
|
|
114
114
|
turnId,
|
|
115
115
|
dispatchAttempt,
|
|
@@ -118,6 +118,7 @@ export class BridgeTurnQueue {
|
|
|
118
118
|
contentFingerprint,
|
|
119
119
|
contentNormalized,
|
|
120
120
|
markTimeMs,
|
|
121
|
+
...(opts?.restoredFromJournal ? { restoredFromJournal: true } : {}),
|
|
121
122
|
});
|
|
122
123
|
return turnId;
|
|
123
124
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge-turn-queue.js","sourceRoot":"","sources":["../../src/services/bridge-turn-queue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,yBAAyB,EACzB,oBAAoB,EACpB,yBAAyB,EACzB,0BAA0B,EAC1B,2BAA2B,GAG5B,MAAM,wBAAwB,CAAC;AAEhC,wEAAwE;AACxE,yEAAyE;AACzE,OAAO,EAAE,uBAAuB,EAAE,CAAC;AAEnC,SAAS,uBAAuB,CAAC,OAAgB;IAC/C,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;IAC3D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,KAAU,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,KAAK,MAAM,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACzH,CAAC;
|
|
1
|
+
{"version":3,"file":"bridge-turn-queue.js","sourceRoot":"","sources":["../../src/services/bridge-turn-queue.ts"],"names":[],"mappings":"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"}
|