lark-remote 0.1.6 → 0.1.7

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 (188) hide show
  1. package/CHANGELOG.md +23 -1
  2. package/README.en.md +9 -1
  3. package/README.md +14 -2
  4. package/dist/bridge/approval-coordinator.d.ts +57 -34
  5. package/dist/bridge/approval-coordinator.js +191 -40
  6. package/dist/bridge/inbound-media.d.ts +62 -0
  7. package/dist/bridge/inbound-media.js +282 -0
  8. package/dist/bridge/index.d.ts +78 -7
  9. package/dist/bridge/index.js +202 -79
  10. package/dist/bridge/queue-manager.d.ts +2 -1
  11. package/dist/bridge/queue-manager.js +1 -0
  12. package/dist/card/approval-render.js +152 -36
  13. package/dist/card/bash-card-session.d.ts +2 -24
  14. package/dist/card/bash-card-session.js +6 -73
  15. package/dist/card/bash-renderer.js +2 -3
  16. package/dist/card/card-budget.js +29 -75
  17. package/dist/card/card-session.d.ts +48 -0
  18. package/dist/card/card-session.js +86 -0
  19. package/dist/card/card-shared.d.ts +1 -12
  20. package/dist/card/card-shared.js +1 -26
  21. package/dist/card/run-card-session.d.ts +2 -55
  22. package/dist/card/run-card-session.js +6 -104
  23. package/dist/card/run-renderer.js +99 -232
  24. package/dist/card/run-state.d.ts +13 -0
  25. package/dist/card/run-state.js +25 -16
  26. package/dist/card/text-truncate.d.ts +13 -12
  27. package/dist/card/text-truncate.js +13 -63
  28. package/dist/common/fs.d.ts +8 -0
  29. package/dist/common/fs.js +17 -0
  30. package/dist/common/guards.d.ts +0 -20
  31. package/dist/common/guards.js +0 -43
  32. package/dist/common/sleep.d.ts +2 -0
  33. package/dist/common/sleep.js +5 -0
  34. package/dist/common/truncate.d.ts +39 -0
  35. package/dist/common/truncate.js +92 -0
  36. package/dist/config/codex-config.d.ts +1 -1
  37. package/dist/config/codex-config.js +1 -1
  38. package/dist/config/index.d.ts +88 -23
  39. package/dist/config/index.js +105 -34
  40. package/dist/connector/index.d.ts +69 -2
  41. package/dist/connector/index.js +107 -1
  42. package/dist/index.js +123 -105
  43. package/dist/instance-lock.js +4 -12
  44. package/dist/order/alias-resolve.d.ts +13 -0
  45. package/dist/order/alias-resolve.js +22 -0
  46. package/dist/order/alias-store.d.ts +38 -0
  47. package/dist/order/alias-store.js +106 -0
  48. package/dist/persistence/atomic-write.d.ts +8 -2
  49. package/dist/persistence/atomic-write.js +23 -7
  50. package/dist/restart.js +2 -1
  51. package/dist/router/card-helpers.d.ts +63 -0
  52. package/dist/router/card-helpers.js +146 -0
  53. package/dist/router/config/claude.js +25 -1
  54. package/dist/router/config/codex.js +29 -50
  55. package/dist/router/config/common/model-patch.d.ts +22 -0
  56. package/dist/router/config/common/model-patch.js +26 -0
  57. package/dist/router/config/common/render.js +5 -4
  58. package/dist/router/config/index.d.ts +12 -0
  59. package/dist/router/config/index.js +25 -1
  60. package/dist/router/config/kimi.d.ts +4 -1
  61. package/dist/router/config/kimi.js +27 -0
  62. package/dist/router/config/opencode.js +18 -5
  63. package/dist/router/config/pi.js +4 -5
  64. package/dist/router/config/types.d.ts +11 -2
  65. package/dist/router/index.d.ts +56 -21
  66. package/dist/router/index.js +373 -548
  67. package/dist/router/utils.d.ts +2 -0
  68. package/dist/router/utils.js +4 -0
  69. package/dist/runner/agent-choices-common.d.ts +16 -0
  70. package/dist/runner/agent-choices-common.js +31 -0
  71. package/dist/runner/claude/runner.d.ts +47 -10
  72. package/dist/runner/claude/runner.js +117 -46
  73. package/dist/runner/claude/session.d.ts +166 -0
  74. package/dist/runner/claude/session.js +749 -0
  75. package/dist/runner/codex/app-server/protocol-types.d.ts +31 -39
  76. package/dist/runner/codex/app-server/protocol-types.js +1 -12
  77. package/dist/runner/codex/app-server/runner.d.ts +42 -59
  78. package/dist/runner/codex/app-server/runner.js +160 -337
  79. package/dist/runner/codex/app-server/translator.d.ts +1 -21
  80. package/dist/runner/codex/app-server/translator.js +0 -18
  81. package/dist/runner/codex/index.d.ts +0 -2
  82. package/dist/runner/codex/index.js +0 -2
  83. package/dist/runner/common/acp/protocol-helpers.d.ts +14 -0
  84. package/dist/runner/common/acp/protocol-helpers.js +21 -0
  85. package/dist/runner/common/acp/protocol-types.d.ts +238 -0
  86. package/dist/runner/common/acp/protocol-types.js +75 -0
  87. package/dist/runner/common/connection-based-runner.d.ts +111 -0
  88. package/dist/runner/common/connection-based-runner.js +261 -0
  89. package/dist/runner/{codex/app-server → common/jsonrpc}/client.d.ts +14 -7
  90. package/dist/runner/{codex/app-server → common/jsonrpc}/client.js +27 -18
  91. package/dist/runner/common/jsonrpc/connection-manager.d.ts +125 -0
  92. package/dist/runner/{codex/app-server → common/jsonrpc}/connection-manager.js +63 -28
  93. package/dist/runner/{codex/app-server → common/jsonrpc}/transport.d.ts +5 -4
  94. package/dist/runner/{codex/app-server → common/jsonrpc}/transport.js +18 -19
  95. package/dist/runner/common/jsonrpc/types.d.ts +32 -0
  96. package/dist/runner/common/jsonrpc/types.js +9 -0
  97. package/dist/runner/common/process-stopper.d.ts +2 -1
  98. package/dist/runner/common/process-stopper.js +1 -0
  99. package/dist/runner/common/runner-utils.d.ts +6 -13
  100. package/dist/runner/common/runner-utils.js +6 -47
  101. package/dist/runner/common/spawning-runner.d.ts +24 -70
  102. package/dist/runner/common/spawning-runner.js +98 -152
  103. package/dist/runner/index.d.ts +4 -4
  104. package/dist/runner/index.js +4 -4
  105. package/dist/runner/kimi/acp/runner.d.ts +106 -0
  106. package/dist/runner/kimi/acp/runner.js +448 -0
  107. package/dist/runner/kimi/acp/translator.d.ts +124 -0
  108. package/dist/runner/kimi/acp/translator.js +336 -0
  109. package/dist/runner/kimi/index.d.ts +1 -1
  110. package/dist/runner/kimi/index.js +1 -1
  111. package/dist/runner/opencode/acp/index.d.ts +1 -0
  112. package/dist/runner/opencode/acp/index.js +2 -0
  113. package/dist/runner/opencode/acp/runner.d.ts +121 -0
  114. package/dist/runner/opencode/acp/runner.js +429 -0
  115. package/dist/runner/opencode/acp/translator.d.ts +119 -0
  116. package/dist/runner/opencode/acp/translator.js +345 -0
  117. package/dist/runner/opencode/index.d.ts +1 -1
  118. package/dist/runner/opencode/index.js +1 -1
  119. package/dist/runner/pi/index.d.ts +1 -1
  120. package/dist/runner/pi/index.js +1 -1
  121. package/dist/runner/pi/rpc/client.d.ts +52 -0
  122. package/dist/runner/pi/rpc/client.js +114 -0
  123. package/dist/runner/pi/rpc/index.d.ts +4 -0
  124. package/dist/runner/pi/rpc/index.js +4 -0
  125. package/dist/runner/pi/rpc/protocol-types.d.ts +127 -0
  126. package/dist/runner/pi/rpc/protocol-types.js +21 -0
  127. package/dist/runner/pi/rpc/runner.d.ts +80 -0
  128. package/dist/runner/pi/rpc/runner.js +199 -0
  129. package/dist/runner/pi/rpc/translator.d.ts +55 -0
  130. package/dist/runner/pi/rpc/translator.js +258 -0
  131. package/dist/runner/registry.d.ts +7 -8
  132. package/dist/runner/registry.js +3 -4
  133. package/dist/runner/resolve-agent-choices.js +18 -59
  134. package/dist/runner/sync-agent-choices.js +16 -67
  135. package/dist/runner/types.d.ts +43 -13
  136. package/dist/session/claude/session-index.js +2 -3
  137. package/dist/session/claude/session-reader.js +3 -6
  138. package/dist/session/claude/sessions.js +6 -13
  139. package/dist/session/codex/rollout-reader.d.ts +2 -2
  140. package/dist/session/codex/rollout-reader.js +14 -17
  141. package/dist/session/codex/sessions.d.ts +1 -1
  142. package/dist/session/codex/sessions.js +2 -2
  143. package/dist/session/common/content-blocks.d.ts +7 -0
  144. package/dist/session/common/content-blocks.js +13 -9
  145. package/dist/session/common/jsonl.d.ts +8 -25
  146. package/dist/session/common/jsonl.js +126 -261
  147. package/dist/session/common/pagination.d.ts +28 -0
  148. package/dist/session/common/pagination.js +33 -0
  149. package/dist/session/kimi/sessions.d.ts +34 -1
  150. package/dist/session/kimi/sessions.js +208 -98
  151. package/dist/session/opencode/sessions.d.ts +17 -3
  152. package/dist/session/opencode/sessions.js +29 -29
  153. package/dist/session/pi/sessions.d.ts +5 -1
  154. package/dist/session/pi/sessions.js +12 -16
  155. package/dist/session/session-store.d.ts +11 -1
  156. package/dist/session/session-store.js +75 -178
  157. package/dist/update/index.d.ts +2 -2
  158. package/dist/update/index.js +2 -2
  159. package/dist/update/install.d.ts +20 -2
  160. package/dist/update/install.js +51 -7
  161. package/package.json +1 -1
  162. package/dist/runner/codex/app-server/connection-manager.d.ts +0 -56
  163. package/dist/runner/codex/argv.d.ts +0 -33
  164. package/dist/runner/codex/argv.js +0 -40
  165. package/dist/runner/codex/factory.d.ts +0 -29
  166. package/dist/runner/codex/factory.js +0 -39
  167. package/dist/runner/codex/jsonl.d.ts +0 -37
  168. package/dist/runner/codex/jsonl.js +0 -221
  169. package/dist/runner/codex/runner.d.ts +0 -66
  170. package/dist/runner/codex/runner.js +0 -129
  171. package/dist/runner/common/exec-translator.d.ts +0 -73
  172. package/dist/runner/common/exec-translator.js +0 -105
  173. package/dist/runner/kimi/jsonl.d.ts +0 -28
  174. package/dist/runner/kimi/jsonl.js +0 -143
  175. package/dist/runner/kimi/runner.d.ts +0 -49
  176. package/dist/runner/kimi/runner.js +0 -105
  177. package/dist/runner/opencode/argv.d.ts +0 -32
  178. package/dist/runner/opencode/argv.js +0 -35
  179. package/dist/runner/opencode/jsonl.d.ts +0 -68
  180. package/dist/runner/opencode/jsonl.js +0 -295
  181. package/dist/runner/opencode/runner.d.ts +0 -61
  182. package/dist/runner/opencode/runner.js +0 -93
  183. package/dist/runner/pi/jsonl.d.ts +0 -128
  184. package/dist/runner/pi/jsonl.js +0 -249
  185. package/dist/runner/pi/runner.d.ts +0 -36
  186. package/dist/runner/pi/runner.js +0 -76
  187. package/dist/session/common/catch-up.d.ts +0 -12
  188. package/dist/session/common/catch-up.js +0 -31
@@ -1,20 +1,27 @@
1
1
  /**
2
2
  * UTF-8 byte-safe text truncation primitives.
3
3
  *
4
- * Shared by the live run renderer (`run-renderer.ts`), the static card budget
5
- * enforcer (`card-budget.ts`), and the opencode session reader
6
- * (`src/session/opencode/sessions.ts`) so that huge tool outputs are folded at a single
7
- * place instead of being reimplemented per consumer.
4
+ * The core `fitUtf8` / `truncateUtf8` / `DEFAULT_TRUNCATE_SUFFIX` primitives
5
+ * live in `src/common/truncate.ts` (shared with session readers to avoid a
6
+ * card→session layer inversion); this module re-exports them and adds the
7
+ * card-specific markdown-table helpers.
8
8
  *
9
9
  * Why byte-safe: Feishu card size limits are measured in UTF-8 bytes, and a
10
10
  * naive `str.slice(0, n)` can split a multi-byte CJK/emoji codepoint, yielding
11
11
  * invalid UTF-8. `fitUtf8` iterates by Unicode codepoint (via `Array.from` /
12
12
  * `for...of`) so it never breaks a surrogate pair or a multi-byte sequence.
13
13
  */
14
+ import { DEFAULT_TRUNCATE_SUFFIX, truncateUtf8 } from '../common/truncate.js';
15
+ export { DEFAULT_TRUNCATE_SUFFIX, truncateUtf8 };
14
16
  /** Feishu 11310 limit: max markdown tables per card. */
15
17
  export declare const FEISHU_MAX_TABLES = 5;
16
- /** Default truncation suffix, shared across all consumers for UX consistency. */
17
- export declare const DEFAULT_TRUNCATE_SUFFIX = "\u2026\uFF08\u5DF2\u622A\u65AD\uFF09";
18
+ /**
19
+ * Feishu 单卡字节上限(安全阈值)。
20
+ *
21
+ * 供 run-renderer(流式卡)、card-budget(静态卡)、bash-renderer(bash 卡)
22
+ * 共用,避免三处各自定义后数值漂移。
23
+ */
24
+ export declare const CARD_BUDGET_BYTES = 28000;
18
25
  /**
19
26
  * Max byte budget for a single session `tool_result` event's content when
20
27
  * replaying an opencode session (L2 pre-fold). The static card budget enforcer
@@ -24,12 +31,6 @@ export declare const DEFAULT_TRUNCATE_SUFFIX = "\u2026\uFF08\u5DF2\u622A\u65AD\u
24
31
  * 500KB file listing) never inflates the replay payload to megabytes.
25
32
  */
26
33
  export declare const TOOL_RESULT_MAX_BYTES = 4000;
27
- /**
28
- * Truncate a UTF-8 string to fit within `maxBytes`, appending `suffix`
29
- * (default `…(已截断)`) when truncation occurs. When `fromEnd` is true, keeps
30
- * the tail and prepends the suffix (useful for "show the most recent N bytes").
31
- */
32
- export declare function truncateUtf8(value: string, maxBytes: number, fromEnd?: boolean, suffix?: string): string;
33
34
  /**
34
35
  * Count the number of markdown tables in a string.
35
36
  *
@@ -1,20 +1,27 @@
1
1
  /**
2
2
  * UTF-8 byte-safe text truncation primitives.
3
3
  *
4
- * Shared by the live run renderer (`run-renderer.ts`), the static card budget
5
- * enforcer (`card-budget.ts`), and the opencode session reader
6
- * (`src/session/opencode/sessions.ts`) so that huge tool outputs are folded at a single
7
- * place instead of being reimplemented per consumer.
4
+ * The core `fitUtf8` / `truncateUtf8` / `DEFAULT_TRUNCATE_SUFFIX` primitives
5
+ * live in `src/common/truncate.ts` (shared with session readers to avoid a
6
+ * card→session layer inversion); this module re-exports them and adds the
7
+ * card-specific markdown-table helpers.
8
8
  *
9
9
  * Why byte-safe: Feishu card size limits are measured in UTF-8 bytes, and a
10
10
  * naive `str.slice(0, n)` can split a multi-byte CJK/emoji codepoint, yielding
11
11
  * invalid UTF-8. `fitUtf8` iterates by Unicode codepoint (via `Array.from` /
12
12
  * `for...of`) so it never breaks a surrogate pair or a multi-byte sequence.
13
13
  */
14
+ import { DEFAULT_TRUNCATE_SUFFIX, truncateUtf8 } from '../common/truncate.js';
15
+ export { DEFAULT_TRUNCATE_SUFFIX, truncateUtf8 };
14
16
  /** Feishu 11310 limit: max markdown tables per card. */
15
17
  export const FEISHU_MAX_TABLES = 5;
16
- /** Default truncation suffix, shared across all consumers for UX consistency. */
17
- export const DEFAULT_TRUNCATE_SUFFIX = '…(已截断)';
18
+ /**
19
+ * Feishu 单卡字节上限(安全阈值)。
20
+ *
21
+ * 供 run-renderer(流式卡)、card-budget(静态卡)、bash-renderer(bash 卡)
22
+ * 共用,避免三处各自定义后数值漂移。
23
+ */
24
+ export const CARD_BUDGET_BYTES = 28_000;
18
25
  /**
19
26
  * Max byte budget for a single session `tool_result` event's content when
20
27
  * replaying an opencode session (L2 pre-fold). The static card budget enforcer
@@ -24,63 +31,6 @@ export const DEFAULT_TRUNCATE_SUFFIX = '…(已截断)';
24
31
  * 500KB file listing) never inflates the replay payload to megabytes.
25
32
  */
26
33
  export const TOOL_RESULT_MAX_BYTES = 4000;
27
- /**
28
- * Fit a UTF-8 string into `maxBytes` by iterating Unicode codepoints, never
29
- * splitting a multi-byte sequence. When `fromEnd` is true, keeps the TAIL
30
- * (useful for logs/tails); otherwise keeps the HEAD.
31
- *
32
- * P1-2 (2026-08-02): 单遍累计单字符字节数,替代逐字符 `Buffer.byteLength(result +
33
- * char)` + `result += char`(后者每轮新建并扫描不断增长的字符串,O(budget²))。
34
- * 字节长度对拼接可加(byteLength(a+b) = byteLength(a) + byteLength(b)),故累计
35
- * 与旧实现的逐字符判断逐字节等价;最后一次 slice/join 物化结果。混合 CJK/emoji
36
- * 样本实测 ~150× 提速(33.7ms/次 → 0.2ms/次,见 tests/anchor/priority/p0-fit-utf8.test.ts)。
37
- */
38
- function fitUtf8(value, maxBytes, fromEnd = false) {
39
- if (fromEnd) {
40
- // tail 分支:需要从末尾找截断起点,Array.from 一次物化(旧实现同样 Array.from().reverse(),
41
- // 无内存回归);数组仅用于定位,之后 slice+join。
42
- const codepoints = Array.from(value);
43
- let bytes = 0;
44
- let start = codepoints.length;
45
- for (let i = codepoints.length - 1; i >= 0; i--) {
46
- const cb = Buffer.byteLength(codepoints[i], 'utf8');
47
- if (bytes + cb > maxBytes)
48
- break;
49
- bytes += cb;
50
- start = i;
51
- }
52
- return codepoints.slice(start).join('');
53
- }
54
- // head 分支:惰性 for-of 迭代 + 字符串索引累计(旧实现同 O(1) 内存)。
55
- // 不物化数组——opencode-sessions 会对 MB 级 tool_result 做 head 截断,
56
- // Array.from 全量分配会引入不必要的瞬态内存。
57
- let bytes = 0;
58
- let end = 0;
59
- for (const char of value) {
60
- const cb = Buffer.byteLength(char, 'utf8');
61
- if (bytes + cb > maxBytes)
62
- break;
63
- bytes += cb;
64
- end += char.length; // for-of 产出完整码点;char.length 为 1 或 2(代理对),
65
- // end 落在码点边界上,value.slice(0, end) 不会切分代理对
66
- }
67
- return value.slice(0, end);
68
- }
69
- /**
70
- * Truncate a UTF-8 string to fit within `maxBytes`, appending `suffix`
71
- * (default `…(已截断)`) when truncation occurs. When `fromEnd` is true, keeps
72
- * the tail and prepends the suffix (useful for "show the most recent N bytes").
73
- */
74
- export function truncateUtf8(value, maxBytes, fromEnd = false, suffix = DEFAULT_TRUNCATE_SUFFIX) {
75
- if (Buffer.byteLength(value, 'utf8') <= maxBytes)
76
- return value;
77
- const suffixBytes = Buffer.byteLength(suffix, 'utf8');
78
- const budget = maxBytes - suffixBytes;
79
- if (budget <= 0)
80
- return suffix;
81
- const truncated = fitUtf8(value, budget, fromEnd);
82
- return fromEnd ? `${suffix}\n${truncated}` : `${truncated}${suffix}`;
83
- }
84
34
  /**
85
35
  * Count the number of markdown tables in a string.
86
36
  *
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Unlink a file, silently ignoring ENOENT and other errors.
3
+ *
4
+ * Use for cleanup paths (pid files, temp files, stale locks) where the
5
+ * file may already be gone or was never created — a missing file is not
6
+ * an error worth propagating.
7
+ */
8
+ export declare function silentlyUnlink(path: string): void;
@@ -0,0 +1,17 @@
1
+ import fs from 'node:fs';
2
+ /**
3
+ * Unlink a file, silently ignoring ENOENT and other errors.
4
+ *
5
+ * Use for cleanup paths (pid files, temp files, stale locks) where the
6
+ * file may already be gone or was never created — a missing file is not
7
+ * an error worth propagating.
8
+ */
9
+ export function silentlyUnlink(path) {
10
+ try {
11
+ fs.unlinkSync(path);
12
+ }
13
+ catch {
14
+ /* ignore — file may not exist */
15
+ }
16
+ }
17
+ //# sourceMappingURL=fs.js.map
@@ -11,27 +11,7 @@
11
11
  * Used as a prerequisite before accessing string-keyed properties.
12
12
  */
13
13
  export declare function isRecord(v: unknown): v is Record<string, unknown>;
14
- /**
15
- * Narrows `v` to `Record<string, unknown>` when it is a non-null object,
16
- * otherwise returns `undefined`.
17
- */
18
- export declare function recordValue(v: unknown): Record<string, unknown> | undefined;
19
14
  /**
20
15
  * Returns the string value when `v` is a `string`, otherwise `undefined`.
21
16
  */
22
17
  export declare function stringValue(v: unknown): string | undefined;
23
- /**
24
- * Returns the number value when `v` is a `number`, otherwise `undefined`.
25
- */
26
- export declare function numberValue(v: unknown): number | undefined;
27
- /**
28
- * Extracts a human-readable error message from an opaque error object.
29
- *
30
- * Priority:
31
- * 1. `raw.message` (string)
32
- * 2. `raw.error.message` (string, when `raw.error` is a record)
33
- * 3. `raw.error.data.message` (string, AI SDK wraps provider errors as {error:{data:{message}}})
34
- * 4. `raw.error` itself (when it is a string)
35
- * 5. `fallback`
36
- */
37
- export declare function extractErrorMessage(raw: Record<string, unknown>, fallback: string): string;
@@ -13,53 +13,10 @@
13
13
  export function isRecord(v) {
14
14
  return typeof v === 'object' && v !== null;
15
15
  }
16
- /**
17
- * Narrows `v` to `Record<string, unknown>` when it is a non-null object,
18
- * otherwise returns `undefined`.
19
- */
20
- export function recordValue(v) {
21
- return isRecord(v) ? v : undefined;
22
- }
23
16
  /**
24
17
  * Returns the string value when `v` is a `string`, otherwise `undefined`.
25
18
  */
26
19
  export function stringValue(v) {
27
20
  return typeof v === 'string' ? v : undefined;
28
21
  }
29
- /**
30
- * Returns the number value when `v` is a `number`, otherwise `undefined`.
31
- */
32
- export function numberValue(v) {
33
- return typeof v === 'number' ? v : undefined;
34
- }
35
- /**
36
- * Extracts a human-readable error message from an opaque error object.
37
- *
38
- * Priority:
39
- * 1. `raw.message` (string)
40
- * 2. `raw.error.message` (string, when `raw.error` is a record)
41
- * 3. `raw.error.data.message` (string, AI SDK wraps provider errors as {error:{data:{message}}})
42
- * 4. `raw.error` itself (when it is a string)
43
- * 5. `fallback`
44
- */
45
- export function extractErrorMessage(raw, fallback) {
46
- const msg = stringValue(raw.message);
47
- if (msg !== undefined)
48
- return msg;
49
- const err = raw.error;
50
- if (isRecord(err)) {
51
- const subMsg = stringValue(err.message);
52
- if (subMsg !== undefined)
53
- return subMsg;
54
- const data = recordValue(err.data);
55
- if (data) {
56
- const dataMsg = stringValue(data.message);
57
- if (dataMsg !== undefined)
58
- return dataMsg;
59
- }
60
- }
61
- if (typeof err === 'string')
62
- return err;
63
- return fallback;
64
- }
65
22
  //# sourceMappingURL=guards.js.map
@@ -0,0 +1,2 @@
1
+ /** Wait for `ms` milliseconds. */
2
+ export declare function sleep(ms: number): Promise<void>;
@@ -0,0 +1,5 @@
1
+ /** Wait for `ms` milliseconds. */
2
+ export function sleep(ms) {
3
+ return new Promise((resolve) => setTimeout(resolve, ms));
4
+ }
5
+ //# sourceMappingURL=sleep.js.map
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Shared text truncation primitives.
3
+ *
4
+ * Centralizes the two truncation utilities previously split across the card
5
+ * layer (`card-shared.ts` char-based `truncate` and `card/text-truncate.ts`
6
+ * byte-safe `truncateUtf8`). Session readers import from here instead of the
7
+ * card layer (fixing the layer inversion), and the card layer re-exports for
8
+ * backward compatibility.
9
+ */
10
+ /** Default truncation suffix, shared across all consumers for UX consistency. */
11
+ export declare const DEFAULT_TRUNCATE_SUFFIX = "\u2026\uFF08\u5DF2\u622A\u65AD\uFF09";
12
+ /**
13
+ * Max byte budget for a single session `tool_result` event's content when
14
+ * replaying an opencode session (L2 pre-fold). Pre-folding here bounds the
15
+ * in-memory `events[]` array and the intermediate card JSON so a single
16
+ * pathological tool_result never inflates the replay payload to megabytes.
17
+ */
18
+ export declare const TOOL_RESULT_MAX_BYTES = 4000;
19
+ /**
20
+ * Fit a UTF-8 string into `maxBytes` by iterating Unicode codepoints, never
21
+ * splitting a multi-byte sequence. When `fromEnd` is true, keeps the TAIL
22
+ * (useful for logs/tails); otherwise keeps the HEAD.
23
+ */
24
+ export declare function fitUtf8(value: string, maxBytes: number, fromEnd?: boolean): string;
25
+ /**
26
+ * Truncate a UTF-8 string to fit within `maxBytes`, appending `suffix`
27
+ * (default `…(已截断)`) when truncation occurs. When `fromEnd` is true, keeps
28
+ * the tail and prepends the suffix (useful for "show the most recent N bytes").
29
+ */
30
+ export declare function truncateUtf8(value: string, maxBytes: number, fromEnd?: boolean, suffix?: string): string;
31
+ interface TruncateOptions {
32
+ suffix?: string;
33
+ normalizeWhitespace?: boolean;
34
+ }
35
+ /** Char-based truncation with optional suffix / whitespace normalization. */
36
+ export declare function truncate(str: string, max: number, options?: TruncateOptions): string;
37
+ /** Char-level tail keep (used for store-time caps, e.g. bash output). */
38
+ export declare function keepTail(value: string, maxChars: number): string;
39
+ export {};
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Shared text truncation primitives.
3
+ *
4
+ * Centralizes the two truncation utilities previously split across the card
5
+ * layer (`card-shared.ts` char-based `truncate` and `card/text-truncate.ts`
6
+ * byte-safe `truncateUtf8`). Session readers import from here instead of the
7
+ * card layer (fixing the layer inversion), and the card layer re-exports for
8
+ * backward compatibility.
9
+ */
10
+ /** Default truncation suffix, shared across all consumers for UX consistency. */
11
+ export const DEFAULT_TRUNCATE_SUFFIX = '…(已截断)';
12
+ /**
13
+ * Max byte budget for a single session `tool_result` event's content when
14
+ * replaying an opencode session (L2 pre-fold). Pre-folding here bounds the
15
+ * in-memory `events[]` array and the intermediate card JSON so a single
16
+ * pathological tool_result never inflates the replay payload to megabytes.
17
+ */
18
+ export const TOOL_RESULT_MAX_BYTES = 4000;
19
+ /**
20
+ * Fit a UTF-8 string into `maxBytes` by iterating Unicode codepoints, never
21
+ * splitting a multi-byte sequence. When `fromEnd` is true, keeps the TAIL
22
+ * (useful for logs/tails); otherwise keeps the HEAD.
23
+ */
24
+ export function fitUtf8(value, maxBytes, fromEnd = false) {
25
+ if (fromEnd) {
26
+ const codepoints = Array.from(value);
27
+ let bytes = 0;
28
+ let start = codepoints.length;
29
+ for (let i = codepoints.length - 1; i >= 0; i--) {
30
+ const cb = Buffer.byteLength(codepoints[i], 'utf8');
31
+ if (bytes + cb > maxBytes)
32
+ break;
33
+ bytes += cb;
34
+ start = i;
35
+ }
36
+ return codepoints.slice(start).join('');
37
+ }
38
+ // head 分支:惰性 for-of 迭代 + 字符串索引累计(O(1) 内存)。
39
+ let bytes = 0;
40
+ let end = 0;
41
+ for (const char of value) {
42
+ const cb = Buffer.byteLength(char, 'utf8');
43
+ if (bytes + cb > maxBytes)
44
+ break;
45
+ bytes += cb;
46
+ end += char.length;
47
+ }
48
+ return value.slice(0, end);
49
+ }
50
+ /**
51
+ * Truncate a UTF-8 string to fit within `maxBytes`, appending `suffix`
52
+ * (default `…(已截断)`) when truncation occurs. When `fromEnd` is true, keeps
53
+ * the tail and prepends the suffix (useful for "show the most recent N bytes").
54
+ */
55
+ export function truncateUtf8(value, maxBytes, fromEnd = false, suffix = DEFAULT_TRUNCATE_SUFFIX) {
56
+ if (Buffer.byteLength(value, 'utf8') <= maxBytes)
57
+ return value;
58
+ const suffixBytes = Buffer.byteLength(suffix, 'utf8');
59
+ const budget = maxBytes - suffixBytes;
60
+ if (budget <= 0)
61
+ return suffix;
62
+ const truncated = fitUtf8(value, budget, fromEnd);
63
+ return fromEnd ? `${suffix}\n${truncated}` : `${truncated}${suffix}`;
64
+ }
65
+ /** Char-based truncation with optional suffix / whitespace normalization. */
66
+ export function truncate(str, max, options) {
67
+ const suffix = options?.suffix ?? '…';
68
+ const normalize = options?.normalizeWhitespace ?? false;
69
+ let s = str;
70
+ if (normalize)
71
+ s = s.replace(/\s+/g, ' ').trim();
72
+ if (s.length <= max)
73
+ return s;
74
+ const suffixLen = suffix.length;
75
+ const budget = max - suffixLen;
76
+ if (budget <= 0)
77
+ return suffix;
78
+ // Iterate by Unicode codepoint (for...of) so the cut never lands inside a
79
+ // surrogate pair (P2-31 anchor: must not emit a lone surrogate).
80
+ let end = 0;
81
+ for (const ch of s) {
82
+ if (end + ch.length > budget)
83
+ break;
84
+ end += ch.length; // 1 (BMP) or 2 (surrogate pair) — slice lands on a boundary
85
+ }
86
+ return s.slice(0, end) + suffix;
87
+ }
88
+ /** Char-level tail keep (used for store-time caps, e.g. bash output). */
89
+ export function keepTail(value, maxChars) {
90
+ return value.length <= maxChars ? value : value.slice(-maxChars);
91
+ }
92
+ //# sourceMappingURL=truncate.js.map
@@ -80,7 +80,7 @@ export declare function getCodexCatalogModels(codexHome?: string): BundledModelI
80
80
  /**
81
81
  * Test utility: clear the catalog cache. Tests that exercise the bundled
82
82
  * command path (`--bundled`) directly use `invalidateCodexBundledTestCache`
83
- * from `codex-bundled-test-helpers.ts`.
83
+ * from `tests/lib/codex-bundled-test-helpers.ts`.
84
84
  */
85
85
  export declare function invalidateCodexBundledCache(): void;
86
86
  /**
@@ -208,7 +208,7 @@ export function getCodexCatalogModels(codexHome) {
208
208
  /**
209
209
  * Test utility: clear the catalog cache. Tests that exercise the bundled
210
210
  * command path (`--bundled`) directly use `invalidateCodexBundledTestCache`
211
- * from `codex-bundled-test-helpers.ts`.
211
+ * from `tests/lib/codex-bundled-test-helpers.ts`.
212
212
  */
213
213
  export function invalidateCodexBundledCache() {
214
214
  catalogCache = null;
@@ -2,6 +2,12 @@ import { z } from 'zod';
2
2
  export { getConfigDir } from './dir.js';
3
3
  /** Valid effort values for Claude */
4
4
  export declare const CLAUDE_EFFORTS: readonly ["low", "medium", "high", "xhigh", "max"];
5
+ /**
6
+ * Claude 官方 --permission-mode 枚举(claude --help 输出,2026-08 实测)。
7
+ * 额外支持 'default':Claude settings.json 的官方未设置值,等价于不传
8
+ * --permission-mode(交互式默认:高风险工具逐个询问)。
9
+ */
10
+ export declare const CLAUDE_PERMISSION_MODES: readonly ["default", "acceptEdits", "auto", "bypassPermissions", "manual", "dontAsk", "plan"];
5
11
  /** Valid thinking levels for Pi */
6
12
  export declare const PI_THINKING_LEVELS: readonly ["off", "minimal", "low", "medium", "high", "xhigh"];
7
13
  /**
@@ -12,6 +18,9 @@ export declare const PI_THINKING_LEVELS: readonly ["off", "minimal", "low", "med
12
18
  export declare const DEFAULT_STOP_GRACE_MS: 5000;
13
19
  /** Codex app-server turn idle timeout default (minutes). */
14
20
  export declare const DEFAULT_TURN_IDLE_TIMEOUT_MINUTES: 10;
21
+ /** 入站媒体默认配置(schema 默认与 connector 兜底共用,避免双源漂移)。 */
22
+ export declare const DEFAULT_INBOUND_MEDIA_DIR_NAME = ".lark-remote-temp";
23
+ export declare const DEFAULT_INBOUND_MEDIA_MAX_SIZE_MB = 50;
15
24
  /** 模型 ID → alias 映射。 */
16
25
  export declare const MODEL_ID_TO_ALIAS: Record<string, string>;
17
26
  /** alias → model ID 反向映射。 */
@@ -20,11 +29,22 @@ declare const ClaudeConfigSchema: z.ZodObject<{
20
29
  model: z.ZodDefault<z.ZodString>;
21
30
  effort: z.ZodDefault<z.ZodEnum<{
22
31
  medium: "medium";
23
- max: "max";
24
32
  low: "low";
25
33
  high: "high";
26
34
  xhigh: "xhigh";
35
+ max: "max";
36
+ }>>;
37
+ permissionMode: z.ZodDefault<z.ZodEnum<{
38
+ default: "default";
39
+ plan: "plan";
40
+ bypassPermissions: "bypassPermissions";
41
+ auto: "auto";
42
+ manual: "manual";
43
+ acceptEdits: "acceptEdits";
44
+ dontAsk: "dontAsk";
27
45
  }>>;
46
+ approvalTimeoutMs: z.ZodDefault<z.ZodNumber>;
47
+ idleTtlMinutes: z.ZodDefault<z.ZodNumber>;
28
48
  stopGraceMs: z.ZodDefault<z.ZodNumber>;
29
49
  }, z.core.$strip>;
30
50
  /** Codex-specific configuration. */
@@ -32,20 +52,15 @@ export declare const CodexConfigSchema: z.ZodObject<{
32
52
  model: z.ZodOptional<z.ZodString>;
33
53
  modelProvider: z.ZodOptional<z.ZodString>;
34
54
  reasoningEffort: z.ZodOptional<z.ZodString>;
35
- stopGraceMs: z.ZodDefault<z.ZodNumber>;
36
- serviceMode: z.ZodOptional<z.ZodEnum<{
37
- exec: "exec";
38
- "app-server": "app-server";
39
- }>>;
40
- approvalPolicy: z.ZodOptional<z.ZodEnum<{
55
+ approvalPolicy: z.ZodDefault<z.ZodEnum<{
41
56
  untrusted: "untrusted";
42
57
  "on-request": "on-request";
43
58
  never: "never";
44
59
  }>>;
45
- sandbox: z.ZodOptional<z.ZodEnum<{
46
- "danger-full-access": "danger-full-access";
60
+ sandbox: z.ZodDefault<z.ZodEnum<{
47
61
  "read-only": "read-only";
48
62
  "workspace-write": "workspace-write";
63
+ "danger-full-access": "danger-full-access";
49
64
  }>>;
50
65
  appServer: z.ZodOptional<z.ZodObject<{
51
66
  binary: z.ZodDefault<z.ZodString>;
@@ -58,6 +73,10 @@ export declare const CodexConfigSchema: z.ZodObject<{
58
73
  declare const OpencodeConfigSchema: z.ZodObject<{
59
74
  providerID: z.ZodDefault<z.ZodString>;
60
75
  modelID: z.ZodDefault<z.ZodString>;
76
+ mode: z.ZodDefault<z.ZodEnum<{
77
+ plan: "plan";
78
+ build: "build";
79
+ }>>;
61
80
  }, z.core.$strip>;
62
81
  /** Pi-specific configuration. pi is a spawn-per-message CLI like Claude. */
63
82
  declare const PiConfigSchema: z.ZodObject<{
@@ -73,14 +92,25 @@ declare const PiConfigSchema: z.ZodObject<{
73
92
  }>>;
74
93
  tools: z.ZodDefault<z.ZodString>;
75
94
  }, z.core.$strip>;
76
- /** Kimi-specific configuration. kimi is a spawn-per-message CLI. */
95
+ /** Kimi-specific configuration. Pure ACP mode (persistent `kimi acp` connection). */
77
96
  declare const KimiConfigSchema: z.ZodObject<{
78
97
  model: z.ZodDefault<z.ZodString>;
79
98
  thinkingEffort: z.ZodDefault<z.ZodEnum<{
80
- max: "max";
81
99
  low: "low";
82
100
  high: "high";
101
+ max: "max";
102
+ }>>;
103
+ permissionMode: z.ZodDefault<z.ZodEnum<{
104
+ auto: "auto";
105
+ yolo: "yolo";
106
+ manual: "manual";
83
107
  }>>;
108
+ acp: z.ZodOptional<z.ZodObject<{
109
+ binary: z.ZodDefault<z.ZodString>;
110
+ requestTimeoutMs: z.ZodDefault<z.ZodNumber>;
111
+ idleTtlMs: z.ZodDefault<z.ZodNumber>;
112
+ turnIdleTimeoutMinutes: z.ZodDefault<z.ZodNumber>;
113
+ }, z.core.$strip>>;
84
114
  }, z.core.$strip>;
85
115
  export declare const AppConfigSchema: z.ZodObject<{
86
116
  feishu: z.ZodObject<{
@@ -91,32 +121,38 @@ export declare const AppConfigSchema: z.ZodObject<{
91
121
  model: z.ZodDefault<z.ZodString>;
92
122
  effort: z.ZodDefault<z.ZodEnum<{
93
123
  medium: "medium";
94
- max: "max";
95
124
  low: "low";
96
125
  high: "high";
97
126
  xhigh: "xhigh";
127
+ max: "max";
98
128
  }>>;
129
+ permissionMode: z.ZodDefault<z.ZodEnum<{
130
+ default: "default";
131
+ plan: "plan";
132
+ bypassPermissions: "bypassPermissions";
133
+ auto: "auto";
134
+ manual: "manual";
135
+ acceptEdits: "acceptEdits";
136
+ dontAsk: "dontAsk";
137
+ }>>;
138
+ approvalTimeoutMs: z.ZodDefault<z.ZodNumber>;
139
+ idleTtlMinutes: z.ZodDefault<z.ZodNumber>;
99
140
  stopGraceMs: z.ZodDefault<z.ZodNumber>;
100
141
  }, z.core.$strip>>;
101
- agents: z.ZodOptional<z.ZodObject<{
102
- codex: z.ZodOptional<z.ZodObject<{
142
+ agents: z.ZodDefault<z.ZodObject<{
143
+ codex: z.ZodDefault<z.ZodObject<{
103
144
  model: z.ZodOptional<z.ZodString>;
104
145
  modelProvider: z.ZodOptional<z.ZodString>;
105
146
  reasoningEffort: z.ZodOptional<z.ZodString>;
106
- stopGraceMs: z.ZodDefault<z.ZodNumber>;
107
- serviceMode: z.ZodOptional<z.ZodEnum<{
108
- exec: "exec";
109
- "app-server": "app-server";
110
- }>>;
111
- approvalPolicy: z.ZodOptional<z.ZodEnum<{
147
+ approvalPolicy: z.ZodDefault<z.ZodEnum<{
112
148
  untrusted: "untrusted";
113
149
  "on-request": "on-request";
114
150
  never: "never";
115
151
  }>>;
116
- sandbox: z.ZodOptional<z.ZodEnum<{
117
- "danger-full-access": "danger-full-access";
152
+ sandbox: z.ZodDefault<z.ZodEnum<{
118
153
  "read-only": "read-only";
119
154
  "workspace-write": "workspace-write";
155
+ "danger-full-access": "danger-full-access";
120
156
  }>>;
121
157
  appServer: z.ZodOptional<z.ZodObject<{
122
158
  binary: z.ZodDefault<z.ZodString>;
@@ -128,6 +164,10 @@ export declare const AppConfigSchema: z.ZodObject<{
128
164
  opencode: z.ZodOptional<z.ZodObject<{
129
165
  providerID: z.ZodDefault<z.ZodString>;
130
166
  modelID: z.ZodDefault<z.ZodString>;
167
+ mode: z.ZodDefault<z.ZodEnum<{
168
+ plan: "plan";
169
+ build: "build";
170
+ }>>;
131
171
  }, z.core.$strip>>;
132
172
  pi: z.ZodOptional<z.ZodObject<{
133
173
  provider: z.ZodDefault<z.ZodString>;
@@ -145,10 +185,21 @@ export declare const AppConfigSchema: z.ZodObject<{
145
185
  kimi: z.ZodOptional<z.ZodObject<{
146
186
  model: z.ZodDefault<z.ZodString>;
147
187
  thinkingEffort: z.ZodDefault<z.ZodEnum<{
148
- max: "max";
149
188
  low: "low";
150
189
  high: "high";
190
+ max: "max";
151
191
  }>>;
192
+ permissionMode: z.ZodDefault<z.ZodEnum<{
193
+ auto: "auto";
194
+ yolo: "yolo";
195
+ manual: "manual";
196
+ }>>;
197
+ acp: z.ZodOptional<z.ZodObject<{
198
+ binary: z.ZodDefault<z.ZodString>;
199
+ requestTimeoutMs: z.ZodDefault<z.ZodNumber>;
200
+ idleTtlMs: z.ZodDefault<z.ZodNumber>;
201
+ turnIdleTimeoutMinutes: z.ZodDefault<z.ZodNumber>;
202
+ }, z.core.$strip>>;
152
203
  }, z.core.$strip>>;
153
204
  }, z.core.$strip>>;
154
205
  agentChoices: z.ZodOptional<z.ZodObject<{
@@ -186,6 +237,11 @@ export declare const AppConfigSchema: z.ZodObject<{
186
237
  error: "error";
187
238
  }>>;
188
239
  }, z.core.$strip>>;
240
+ inboundMedia: z.ZodDefault<z.ZodObject<{
241
+ enabled: z.ZodDefault<z.ZodBoolean>;
242
+ dirName: z.ZodDefault<z.ZodString>;
243
+ maxFileSizeMb: z.ZodDefault<z.ZodNumber>;
244
+ }, z.core.$strip>>;
189
245
  defaultAgent: z.ZodDefault<z.ZodEnum<{
190
246
  claude: "claude";
191
247
  codex: "codex";
@@ -217,6 +273,15 @@ export declare function mapAgentKey(key: string): string;
217
273
  * config 路径中不存在,写/删/读三条路径统一拒绝。
218
274
  */
219
275
  export declare function assertSafeKeyPart(part: string): void;
276
+ /**
277
+ * 按 dot-separated key 下钻到目标键的父容器(不含最后一段)。
278
+ *
279
+ * - create=true:中间缺失/非对象段自动补 `{}`(set 语义)
280
+ * - create=false:中间缺失/非对象段返回 undefined(get/delete 语义)
281
+ *
282
+ * 危险段(__proto__/prototype/constructor)在每段统一拒绝。
283
+ */
284
+ export declare function walkNestedContainer(target: unknown, parts: string[], create: boolean): Record<string, unknown> | undefined;
220
285
  /** Get a nested value from config by dot-separated key, e.g. "feishu.appId" */
221
286
  export declare function getConfigValue(config: AppConfig, key: string): unknown;
222
287
  /** Set a nested value in config by dot-separated key, write back to YAML file */