lark-remote 0.1.12 → 0.2.0

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.
Files changed (160) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.en.md +2 -6
  3. package/README.md +3 -7
  4. package/dist/bridge/final-usage.d.ts +24 -0
  5. package/dist/bridge/final-usage.js +55 -0
  6. package/dist/bridge/inbound-media.d.ts +0 -3
  7. package/dist/bridge/inbound-media.js +0 -1
  8. package/dist/bridge/index.d.ts +7 -7
  9. package/dist/bridge/index.js +100 -133
  10. package/dist/bridge/queue-manager.js +4 -3
  11. package/dist/card/approval-render.js +39 -94
  12. package/dist/card/bash-renderer.js +12 -21
  13. package/dist/card/card-shared.d.ts +14 -5
  14. package/dist/card/card-shared.js +23 -34
  15. package/dist/card/run-renderer.d.ts +0 -22
  16. package/dist/card/run-renderer.js +206 -153
  17. package/dist/card/run-state.d.ts +29 -1
  18. package/dist/card/run-state.js +172 -84
  19. package/dist/card/text-truncate.d.ts +0 -9
  20. package/dist/card/text-truncate.js +0 -9
  21. package/dist/card/tool-render.d.ts +4 -1
  22. package/dist/card/tool-render.js +76 -32
  23. package/dist/cli.js +2 -2
  24. package/dist/common/fs.d.ts +14 -0
  25. package/dist/common/fs.js +57 -3
  26. package/dist/common/truncate.d.ts +0 -6
  27. package/dist/common/truncate.js +1 -1
  28. package/dist/common/ttl-cache.d.ts +24 -0
  29. package/dist/common/ttl-cache.js +53 -0
  30. package/dist/config/codex-config.js +14 -11
  31. package/dist/config/index.d.ts +0 -8
  32. package/dist/config/index.js +0 -16
  33. package/dist/config/kimi-config.d.ts +1 -1
  34. package/dist/config/kimi-config.js +2 -1
  35. package/dist/config/opencode-config.d.ts +1 -1
  36. package/dist/config/opencode-config.js +16 -10
  37. package/dist/config/qr.d.ts +36 -0
  38. package/dist/config/qr.js +124 -0
  39. package/dist/config/wizard.js +69 -27
  40. package/dist/connector/index.d.ts +3 -2
  41. package/dist/connector/index.js +5 -3
  42. package/dist/index.js +14 -41
  43. package/dist/instance-lock.js +7 -0
  44. package/dist/persistence/atomic-write.d.ts +2 -0
  45. package/dist/persistence/atomic-write.js +20 -5
  46. package/dist/persistence/load-json-file.d.ts +1 -2
  47. package/dist/persistence/load-json-file.js +2 -3
  48. package/dist/platform/agent-stopper.d.ts +22 -0
  49. package/dist/platform/agent-stopper.js +19 -0
  50. package/dist/platform/command.d.ts +11 -0
  51. package/dist/platform/command.js +107 -0
  52. package/dist/platform/identity.d.ts +33 -0
  53. package/dist/platform/identity.js +187 -0
  54. package/dist/platform/path.d.ts +24 -0
  55. package/dist/platform/path.js +110 -0
  56. package/dist/platform/select.d.ts +9 -0
  57. package/dist/platform/select.js +12 -0
  58. package/dist/platform/shell.d.ts +51 -0
  59. package/dist/platform/shell.js +75 -0
  60. package/dist/platform/spawn.d.ts +41 -0
  61. package/dist/platform/spawn.js +77 -0
  62. package/dist/platform/terminator-posix.d.ts +38 -0
  63. package/dist/platform/terminator-posix.js +103 -0
  64. package/dist/platform/terminator-win32.d.ts +21 -0
  65. package/dist/platform/terminator-win32.js +110 -0
  66. package/dist/platform/terminator.d.ts +44 -0
  67. package/dist/platform/terminator.js +24 -0
  68. package/dist/platform/types.d.ts +23 -0
  69. package/dist/platform/types.js +5 -0
  70. package/dist/restart.js +4 -2
  71. package/dist/router/card-helpers.d.ts +33 -6
  72. package/dist/router/card-helpers.js +67 -11
  73. package/dist/router/config/common/render.d.ts +1 -1
  74. package/dist/router/config/common/render.js +1 -1
  75. package/dist/router/config-diff.d.ts +4 -0
  76. package/dist/router/config-diff.js +70 -0
  77. package/dist/router/index.d.ts +73 -6
  78. package/dist/router/index.js +663 -590
  79. package/dist/router/utils.d.ts +6 -0
  80. package/dist/router/utils.js +12 -0
  81. package/dist/runner/bash/runner.d.ts +9 -2
  82. package/dist/runner/bash/runner.js +45 -20
  83. package/dist/runner/claude/session.d.ts +4 -4
  84. package/dist/runner/claude/session.js +18 -9
  85. package/dist/runner/codex/app-server/protocol-types.d.ts +35 -1
  86. package/dist/runner/codex/app-server/runner.d.ts +1 -16
  87. package/dist/runner/codex/app-server/runner.js +2 -2
  88. package/dist/runner/codex/app-server/translator.d.ts +18 -0
  89. package/dist/runner/codex/app-server/translator.js +146 -0
  90. package/dist/runner/common/acp/base-acp-runner.d.ts +116 -0
  91. package/dist/runner/common/acp/base-acp-runner.js +248 -0
  92. package/dist/runner/common/acp/base-translator.d.ts +141 -0
  93. package/dist/runner/common/acp/base-translator.js +271 -0
  94. package/dist/runner/common/acp/protocol-helpers.d.ts +70 -0
  95. package/dist/runner/common/acp/protocol-helpers.js +82 -0
  96. package/dist/runner/common/connection-based-runner.d.ts +0 -2
  97. package/dist/runner/common/connection-based-runner.js +1 -1
  98. package/dist/runner/common/jsonrpc/transport.d.ts +2 -0
  99. package/dist/runner/common/jsonrpc/transport.js +25 -5
  100. package/dist/runner/common/process-stopper.d.ts +4 -26
  101. package/dist/runner/common/process-stopper.js +4 -76
  102. package/dist/runner/common/runner-utils.d.ts +0 -5
  103. package/dist/runner/common/runner-utils.js +0 -7
  104. package/dist/runner/common/spawning-runner.d.ts +42 -132
  105. package/dist/runner/common/spawning-runner.js +52 -271
  106. package/dist/runner/common/usage.d.ts +2 -0
  107. package/dist/runner/common/usage.js +2 -0
  108. package/dist/runner/dsh/index.d.ts +0 -2
  109. package/dist/runner/dsh/index.js +0 -2
  110. package/dist/runner/dsh/runner.d.ts +0 -2
  111. package/dist/runner/dsh/runner.js +1 -1
  112. package/dist/runner/index.d.ts +1 -1
  113. package/dist/runner/kimi/acp/runner.d.ts +63 -53
  114. package/dist/runner/kimi/acp/runner.js +189 -334
  115. package/dist/runner/kimi/acp/translator.d.ts +18 -101
  116. package/dist/runner/kimi/acp/translator.js +61 -255
  117. package/dist/runner/opencode/acp/runner.d.ts +22 -46
  118. package/dist/runner/opencode/acp/runner.js +74 -297
  119. package/dist/runner/opencode/acp/translator.d.ts +28 -104
  120. package/dist/runner/opencode/acp/translator.js +54 -249
  121. package/dist/runner/pi/rpc/index.d.ts +0 -2
  122. package/dist/runner/pi/rpc/index.js +0 -2
  123. package/dist/runner/pi/rpc/translator.d.ts +3 -0
  124. package/dist/runner/pi/rpc/translator.js +47 -9
  125. package/dist/runner/probe.d.ts +8 -11
  126. package/dist/runner/probe.js +17 -21
  127. package/dist/runner/registry.d.ts +4 -4
  128. package/dist/runner/registry.js +4 -4
  129. package/dist/runner/resolve-agent-choices.js +6 -2
  130. package/dist/runner/sync-agent-choices.js +1 -1
  131. package/dist/runner/types.d.ts +38 -1
  132. package/dist/session/claude/session-index.js +3 -1
  133. package/dist/session/claude/sessions.js +37 -64
  134. package/dist/session/codex/rollout-reader.d.ts +10 -14
  135. package/dist/session/codex/rollout-reader.js +126 -48
  136. package/dist/session/common/constants.d.ts +7 -0
  137. package/dist/session/common/constants.js +9 -0
  138. package/dist/session/common/pagination.d.ts +0 -2
  139. package/dist/session/common/pagination.js +1 -1
  140. package/dist/session/common/recency.d.ts +7 -0
  141. package/dist/session/common/recency.js +10 -0
  142. package/dist/session/common/two-pass.d.ts +22 -0
  143. package/dist/session/common/two-pass.js +70 -0
  144. package/dist/session/common/usage-accumulator.d.ts +14 -0
  145. package/dist/session/common/usage-accumulator.js +15 -0
  146. package/dist/session/dsh/sessions.js +15 -11
  147. package/dist/session/kimi/sessions.d.ts +24 -4
  148. package/dist/session/kimi/sessions.js +99 -103
  149. package/dist/session/opencode/sessions.d.ts +2 -14
  150. package/dist/session/opencode/sessions.js +35 -15
  151. package/dist/session/pi/sessions.js +64 -95
  152. package/dist/update/index.d.ts +2 -3
  153. package/dist/update/index.js +1 -2
  154. package/dist/update/install.d.ts +2 -1
  155. package/dist/update/install.js +58 -9
  156. package/dist/update/version-check.d.ts +5 -0
  157. package/dist/update/version-check.js +9 -0
  158. package/package.json +9 -7
  159. package/dist/update/startup-hint.d.ts +0 -5
  160. package/dist/update/startup-hint.js +0 -11
@@ -9,3 +9,10 @@
9
9
  * mtime is older than this threshold cannot be from a running process.
10
10
  */
11
11
  export declare const STALE_MS: number;
12
+ /**
13
+ * A session file is stale (cannot be from a running process) when its
14
+ * timestamp is older than STALE_MS. All readers share this single
15
+ * comparison — previously it was re-derived per reader as
16
+ * `Date.now() - mtimeMs > STALE_MS` (or its `< STALE_MS` negation).
17
+ */
18
+ export declare function isStale(timestampMs: number, now?: number): boolean;
@@ -9,4 +9,13 @@
9
9
  * mtime is older than this threshold cannot be from a running process.
10
10
  */
11
11
  export const STALE_MS = 60 * 60 * 1000;
12
+ /**
13
+ * A session file is stale (cannot be from a running process) when its
14
+ * timestamp is older than STALE_MS. All readers share this single
15
+ * comparison — previously it was re-derived per reader as
16
+ * `Date.now() - mtimeMs > STALE_MS` (or its `< STALE_MS` negation).
17
+ */
18
+ export function isStale(timestampMs, now = Date.now()) {
19
+ return now - timestampMs > STALE_MS;
20
+ }
12
21
  //# sourceMappingURL=constants.js.map
@@ -7,8 +7,6 @@
7
7
  * drifted on the default limit). Centralized here so the contract is defined
8
8
  * once: default page limit is 20, matching the majority of readers.
9
9
  */
10
- /** Default page size for listSessions. */
11
- export declare const DEFAULT_LIST_LIMIT = 20;
12
10
  /**
13
11
  * Paginate a (already-ordered) full item list by offset + limit.
14
12
  * Clamps negative offset to 0; caps limit to the remaining items.
@@ -8,7 +8,7 @@
8
8
  * once: default page limit is 20, matching the majority of readers.
9
9
  */
10
10
  /** Default page size for listSessions. */
11
- export const DEFAULT_LIST_LIMIT = 20;
11
+ const DEFAULT_LIST_LIMIT = 20;
12
12
  /**
13
13
  * Paginate a (already-ordered) full item list by offset + limit.
14
14
  * Clamps negative offset to 0; caps limit to the remaining items.
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Session-list ordering invariant shared by every reader: newest first,
3
+ * with a deterministic id tie-break so index rebuilds / walk-order changes
4
+ * never reorder a page (codex red line: never break out of a partial order).
5
+ */
6
+ /** 「时间降序 + id 字典序 tie-break」原地排序(原先 6 处内联拷贝)。 */
7
+ export declare function sortByRecencyDesc<T>(items: T[], time: (item: T) => number, id: (item: T) => string): void;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Session-list ordering invariant shared by every reader: newest first,
3
+ * with a deterministic id tie-break so index rebuilds / walk-order changes
4
+ * never reorder a page (codex red line: never break out of a partial order).
5
+ */
6
+ /** 「时间降序 + id 字典序 tie-break」原地排序(原先 6 处内联拷贝)。 */
7
+ export function sortByRecencyDesc(items, time, id) {
8
+ items.sort((a, b) => time(b) - time(a) || id(a).localeCompare(id(b)));
9
+ }
10
+ //# sourceMappingURL=recency.js.map
@@ -0,0 +1,22 @@
1
+ import type { AgentSessionContentEvent } from '../../runner/types.js';
2
+ /**
3
+ * Byte offset where the tail begins: the start of the line AFTER `line`.
4
+ * `offset` is the byte offset of `line` itself; +1 accounts for the trailing
5
+ * '\n'.
6
+ */
7
+ export declare function tailOffsetAfter(line: string, offset: number): number;
8
+ /**
9
+ * Pass 1: stream the file once, parse each line exactly once (broken lines
10
+ * skipped), and feed the parsed object + raw line + byte offset to `handle`.
11
+ * `handle` may mutate closure state to collect scalars and track the tail
12
+ * offset (via tailOffsetAfter on user lines).
13
+ */
14
+ export declare function scanJsonlOnce(filePath: string, handle: (obj: Record<string, unknown>, line: string, offset: number) => void): void;
15
+ /**
16
+ * Pass 2: re-read only the tail (lines after `tailOffset`; the whole file
17
+ * when tailOffset is -1) and map each parsed line to content events via
18
+ * `mapLine` (return an array — possibly empty — of events; returning null
19
+ * skips the line entirely). `maxEvents` keeps the LAST N events
20
+ * (`maxEvents <= 0` → [], guarding the `slice(-0)` full-array trap).
21
+ */
22
+ export declare function scanTailEvents(filePath: string, tailOffset: number, mapLine: (obj: Record<string, unknown>) => AgentSessionContentEvent[] | null, maxEvents?: number): AgentSessionContentEvent[];
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Two-pass scan skeleton shared by the claude / pi session readers (P2-2 +
3
+ * P2-5/P2-6 lineage): pass 1 STREAMS the whole file once via `scanJsonlLines`
4
+ * (no `string[]` materialized), parsing each line exactly once to collect
5
+ * scalars (usage, tail offset, title) while retaining NO parsed objects; pass
6
+ * 2 re-reads ONLY the tail from the recorded offset and re-parses it for
7
+ * content events — O(tail) memory for both raw line strings and parsed
8
+ * objects, instead of O(whole file).
9
+ *
10
+ * Parse ratio: ≈1.0–1.5× line count when a user message exists (streaming
11
+ * full-file scan + tail re-parse of the usually-short post-user lines). When
12
+ * the session has NO user message, tailOffset stays -1 and the tail IS the
13
+ * whole file → scan(N) + tail(N) = 2.0× — the known asymptotic upper bound of
14
+ * the two-phase design.
15
+ */
16
+ import { scanJsonlLines, readJsonlLinesFromOffset } from './jsonl.js';
17
+ import { capEvents } from './pagination.js';
18
+ /**
19
+ * Byte offset where the tail begins: the start of the line AFTER `line`.
20
+ * `offset` is the byte offset of `line` itself; +1 accounts for the trailing
21
+ * '\n'.
22
+ */
23
+ export function tailOffsetAfter(line, offset) {
24
+ return offset + Buffer.byteLength(line, 'utf-8') + 1;
25
+ }
26
+ /**
27
+ * Pass 1: stream the file once, parse each line exactly once (broken lines
28
+ * skipped), and feed the parsed object + raw line + byte offset to `handle`.
29
+ * `handle` may mutate closure state to collect scalars and track the tail
30
+ * offset (via tailOffsetAfter on user lines).
31
+ */
32
+ export function scanJsonlOnce(filePath, handle) {
33
+ scanJsonlLines(filePath, (line, offset) => {
34
+ let obj;
35
+ try {
36
+ obj = JSON.parse(line);
37
+ }
38
+ catch {
39
+ return;
40
+ }
41
+ handle(obj, line, offset);
42
+ });
43
+ }
44
+ /**
45
+ * Pass 2: re-read only the tail (lines after `tailOffset`; the whole file
46
+ * when tailOffset is -1) and map each parsed line to content events via
47
+ * `mapLine` (return an array — possibly empty — of events; returning null
48
+ * skips the line entirely). `maxEvents` keeps the LAST N events
49
+ * (`maxEvents <= 0` → [], guarding the `slice(-0)` full-array trap).
50
+ */
51
+ export function scanTailEvents(filePath, tailOffset, mapLine, maxEvents) {
52
+ const tailLines = readJsonlLinesFromOffset(filePath, tailOffset >= 0 ? tailOffset : 0);
53
+ const events = [];
54
+ for (const line of tailLines) {
55
+ if (!line.trim())
56
+ continue;
57
+ let obj;
58
+ try {
59
+ obj = JSON.parse(line);
60
+ }
61
+ catch {
62
+ continue;
63
+ }
64
+ const produced = mapLine(obj);
65
+ if (produced)
66
+ events.push(...produced);
67
+ }
68
+ return capEvents(events, maxEvents);
69
+ }
70
+ //# sourceMappingURL=two-pass.js.map
@@ -55,4 +55,18 @@ export declare class UsageAccumulator {
55
55
  */
56
56
  bumpCompact(): void;
57
57
  }
58
+ /** P2-8 统一契约:上下文窗口占用 = 末轮 input + cacheRead + cacheCreation(不含 output/reasoning)。 */
59
+ export declare function contextWindowOccupancy(l: {
60
+ input: number;
61
+ cacheRead: number;
62
+ cacheCreation: number;
63
+ }): number;
64
+ /** P2-8 统一契约:session 全量累计字段组装(4 个 reader 共用:claude/dsh/kimi/pi;
65
+ * codex 走 last_token_usage 口径、opencode 保留自己的条件赋值,原为逐字段复制的 4 连拷贝)。 */
66
+ export declare function cumulativeUsageFields(t: {
67
+ input: number;
68
+ output: number;
69
+ cacheRead: number;
70
+ cacheCreation: number;
71
+ }): Pick<import('../../runner/types.js').AgentSessionUsage, 'cumulativeTotalTokens' | 'cumulativeInputTokens' | 'cumulativeOutputTokens' | 'cumulativeCacheReadTokens' | 'cumulativeCacheCreationTokens'>;
58
72
  export {};
@@ -69,4 +69,19 @@ export class UsageAccumulator {
69
69
  this._compactCount++;
70
70
  }
71
71
  }
72
+ /** P2-8 统一契约:上下文窗口占用 = 末轮 input + cacheRead + cacheCreation(不含 output/reasoning)。 */
73
+ export function contextWindowOccupancy(l) {
74
+ return l.input + l.cacheRead + l.cacheCreation;
75
+ }
76
+ /** P2-8 统一契约:session 全量累计字段组装(4 个 reader 共用:claude/dsh/kimi/pi;
77
+ * codex 走 last_token_usage 口径、opencode 保留自己的条件赋值,原为逐字段复制的 4 连拷贝)。 */
78
+ export function cumulativeUsageFields(t) {
79
+ return {
80
+ cumulativeTotalTokens: t.input + t.output + t.cacheRead + t.cacheCreation,
81
+ cumulativeInputTokens: t.input,
82
+ cumulativeOutputTokens: t.output,
83
+ cumulativeCacheReadTokens: t.cacheRead,
84
+ cumulativeCacheCreationTokens: t.cacheCreation,
85
+ };
86
+ }
72
87
  //# sourceMappingURL=usage-accumulator.js.map
@@ -12,9 +12,12 @@
12
12
  * readSessionContent: session.history → map SessionEvents to display events +
13
13
  * session-wide usage accumulation (assistant/message.usage).
14
14
  */
15
- import { spawnSync } from 'node:child_process';
15
+ import { spawnProcessSync } from '../../platform/spawn.js';
16
+ import { cumulativeUsageFields } from '../common/usage-accumulator.js';
17
+ import { sortByRecencyDesc } from '../common/recency.js';
16
18
  import { getLogger } from '../../logger/index.js';
17
19
  import { DEFAULT_DSH_HOST } from '../../config/index.js';
20
+ import { samePath } from '../../platform/path.js';
18
21
  import { capEvents, paginate } from '../common/pagination.js';
19
22
  import { truncateUtf8, TOOL_RESULT_MAX_BYTES } from '../../common/truncate.js';
20
23
  /**
@@ -32,7 +35,7 @@ function defaultSyncRequest(baseUrl, method, payload) {
32
35
  method,
33
36
  payload,
34
37
  });
35
- const res = spawnSync('curl', [
38
+ const res = spawnProcessSync('curl', [
36
39
  '-s',
37
40
  '-X',
38
41
  'POST',
@@ -47,7 +50,7 @@ function defaultSyncRequest(baseUrl, method, payload) {
47
50
  }
48
51
  let parsed;
49
52
  try {
50
- parsed = JSON.parse(res.stdout);
53
+ parsed = JSON.parse(String(res.stdout));
51
54
  }
52
55
  catch (err) {
53
56
  throw new Error(`DSH ${method} returned non-JSON: ${err.message}`, {
@@ -80,14 +83,14 @@ export class DshSessionReader {
80
83
  const value = this.unary('session.list', {});
81
84
  const items = value.items ?? [];
82
85
  const filtered = items
83
- .filter((i) => i.cwd === cwd)
84
- .sort((a, b) => b.updatedAt - a.updatedAt || String(a.sessionId).localeCompare(String(b.sessionId)))
86
+ .filter((i) => i.cwd !== undefined && samePath(i.cwd, cwd))
85
87
  .map((i) => ({
86
88
  sessionId: String(i.sessionId),
87
89
  summary: '',
88
90
  mtime: i.updatedAt,
89
91
  ...(i.agentPreset ? { agentPreset: i.agentPreset } : {}),
90
92
  }));
93
+ sortByRecencyDesc(filtered, (i) => i.mtime, (i) => i.sessionId);
91
94
  const { items: page, total } = paginate(filtered, opts ?? {});
92
95
  return { sessions: page, total };
93
96
  }
@@ -147,11 +150,12 @@ export class DshSessionReader {
147
150
  cacheReadTokens: cacheRead,
148
151
  cacheCreationTokens: cacheWrite,
149
152
  totalTokens: input + output + cacheRead + cacheWrite,
150
- cumulativeTotalTokens: cumInput + cumOutput + cumCacheRead + cumCacheWrite,
151
- cumulativeInputTokens: cumInput,
152
- cumulativeOutputTokens: cumOutput,
153
- cumulativeCacheReadTokens: cumCacheRead,
154
- cumulativeCacheCreationTokens: cumCacheWrite,
153
+ ...cumulativeUsageFields({
154
+ input: cumInput,
155
+ output: cumOutput,
156
+ cacheRead: cumCacheRead,
157
+ cacheCreation: cumCacheWrite,
158
+ }),
155
159
  };
156
160
  }
157
161
  return {
@@ -170,7 +174,7 @@ export class DshSessionReader {
170
174
  isSessionActive(sessionId, cwd) {
171
175
  try {
172
176
  const value = this.unary('session.list', {});
173
- const found = (value.items ?? []).find((i) => String(i.sessionId) === sessionId && i.cwd === cwd);
177
+ const found = (value.items ?? []).find((i) => String(i.sessionId) === sessionId && i.cwd !== undefined && samePath(i.cwd, cwd));
174
178
  return found?.running === true;
175
179
  }
176
180
  catch (error) {
@@ -19,7 +19,9 @@ export interface KimiSessionState {
19
19
  * `messagesCompacted` 是死字段,真实 record 里不存在——禁止再写。
20
20
  */
21
21
  export interface KimiCompactionRecord {
22
- type: 'full_compaction.complete' | 'context.apply_compaction';
22
+ type: 'full_compaction.begin' | 'full_compaction.complete' | 'full_compaction.cancel' | 'context.apply_compaction';
23
+ /** 压缩来源(仅 full_compaction.begin 携带):'manual' | 'auto'。 */
24
+ source?: string;
23
25
  /** 压缩掉的消息条数(仅 context.apply_compaction 携带)。 */
24
26
  compactedCount?: number;
25
27
  /** 压缩前上下文 token 水位(仅 context.apply_compaction 携带)。 */
@@ -96,13 +98,31 @@ export declare class KimiSessionReader implements AgentSessionReader {
96
98
  maxEvents?: number;
97
99
  }): SessionContent;
98
100
  /**
99
- * Read the compaction records (context.apply_compaction /
100
- * full_compaction.complete) from a session's wire.jsonl.
101
+ * Read the compaction records (full_compaction.begin / complete / cancel /
102
+ * context.apply_compaction) from a session's wire.jsonl.
101
103
  *
102
104
  * Same cwd guard as readSessionContent. Used by KimiAcpRunner.runCompact
103
- * (R2) to wait for the background compaction to land before ending the run.
105
+ * to wait for the background compaction terminal before ending the run, and
106
+ * by readCompactionState to detect an in-flight compaction.
104
107
  */
105
108
  readCompactionRecords(sessionId: string, cwd: string): KimiCompactionRecord[];
109
+ /**
110
+ * 由 begin/terminal 记录重建压缩状态机:最后一次 begin 无更新的 terminal
111
+ * 记录 = 在途(kimi-compact-wait-redesign §5.1)。崩溃墓碑由 kimi resume
112
+ * 时补写 full_compaction.cancel,天然闭合。
113
+ */
114
+ readCompactionState(sessionId: string, cwd: string): {
115
+ inFlight: boolean;
116
+ /** 在途 begin 的 time(epoch ms)。 */
117
+ inFlightSince?: number;
118
+ records: KimiCompactionRecord[];
119
+ };
120
+ /**
121
+ * W2.5 单源:resolveSessionWirePath 与 isSessionActive 共用的 cwd 守卫
122
+ * (realpathSync → state.json workDir/cwd 三态 → index workDir 兜底 →
123
+ * fail-closed)。返回 sessionDir;会话未知或守卫不过返回 null。
124
+ */
125
+ private verifySessionCwd;
106
126
  /**
107
127
  * Resolve the main wire.jsonl path for a session after passing the cwd
108
128
  * guard (state.json + session index fallback). Returns null when the