pi-maestro-mobile 0.1.2

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 (110) hide show
  1. package/README.md +85 -0
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +84 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/event-log.d.ts +18 -0
  7. package/dist/event-log.d.ts.map +1 -0
  8. package/dist/event-log.js +31 -0
  9. package/dist/event-log.js.map +1 -0
  10. package/dist/extension.d.ts +3 -0
  11. package/dist/extension.d.ts.map +1 -0
  12. package/dist/extension.js +118 -0
  13. package/dist/extension.js.map +1 -0
  14. package/dist/host-controller.d.ts +69 -0
  15. package/dist/host-controller.d.ts.map +1 -0
  16. package/dist/host-controller.js +195 -0
  17. package/dist/host-controller.js.map +1 -0
  18. package/dist/index.d.ts +11 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +12 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/jsonl-index.d.ts +19 -0
  23. package/dist/jsonl-index.d.ts.map +1 -0
  24. package/dist/jsonl-index.js +84 -0
  25. package/dist/jsonl-index.js.map +1 -0
  26. package/dist/jsonl-pager.d.ts +29 -0
  27. package/dist/jsonl-pager.d.ts.map +1 -0
  28. package/dist/jsonl-pager.js +237 -0
  29. package/dist/jsonl-pager.js.map +1 -0
  30. package/dist/jsonl-replay.d.ts +9 -0
  31. package/dist/jsonl-replay.d.ts.map +1 -0
  32. package/dist/jsonl-replay.js +140 -0
  33. package/dist/jsonl-replay.js.map +1 -0
  34. package/dist/live-sessions.d.ts +47 -0
  35. package/dist/live-sessions.d.ts.map +1 -0
  36. package/dist/live-sessions.js +201 -0
  37. package/dist/live-sessions.js.map +1 -0
  38. package/dist/maestro-settings.d.ts +40 -0
  39. package/dist/maestro-settings.d.ts.map +1 -0
  40. package/dist/maestro-settings.js +122 -0
  41. package/dist/maestro-settings.js.map +1 -0
  42. package/dist/maestro-state.d.ts +31 -0
  43. package/dist/maestro-state.d.ts.map +1 -0
  44. package/dist/maestro-state.js +219 -0
  45. package/dist/maestro-state.js.map +1 -0
  46. package/dist/mobile-agent.d.ts +86 -0
  47. package/dist/mobile-agent.d.ts.map +1 -0
  48. package/dist/mobile-agent.js +2 -0
  49. package/dist/mobile-agent.js.map +1 -0
  50. package/dist/mobile-ui-context.d.ts +26 -0
  51. package/dist/mobile-ui-context.d.ts.map +1 -0
  52. package/dist/mobile-ui-context.js +164 -0
  53. package/dist/mobile-ui-context.js.map +1 -0
  54. package/dist/monitor-projection.d.ts +19 -0
  55. package/dist/monitor-projection.d.ts.map +1 -0
  56. package/dist/monitor-projection.js +79 -0
  57. package/dist/monitor-projection.js.map +1 -0
  58. package/dist/pi/pi-sdk-runtime.d.ts +17 -0
  59. package/dist/pi/pi-sdk-runtime.d.ts.map +1 -0
  60. package/dist/pi/pi-sdk-runtime.js +57 -0
  61. package/dist/pi/pi-sdk-runtime.js.map +1 -0
  62. package/dist/server/helpers.d.ts +23 -0
  63. package/dist/server/helpers.d.ts.map +1 -0
  64. package/dist/server/helpers.js +179 -0
  65. package/dist/server/helpers.js.map +1 -0
  66. package/dist/server/mobile-host-server.d.ts +43 -0
  67. package/dist/server/mobile-host-server.d.ts.map +1 -0
  68. package/dist/server/mobile-host-server.js +715 -0
  69. package/dist/server/mobile-host-server.js.map +1 -0
  70. package/dist/server/ws-command-handlers.d.ts +18 -0
  71. package/dist/server/ws-command-handlers.d.ts.map +1 -0
  72. package/dist/server/ws-command-handlers.js +173 -0
  73. package/dist/server/ws-command-handlers.js.map +1 -0
  74. package/dist/session-runner.d.ts +130 -0
  75. package/dist/session-runner.d.ts.map +1 -0
  76. package/dist/session-runner.js +576 -0
  77. package/dist/session-runner.js.map +1 -0
  78. package/dist/types.d.ts +83 -0
  79. package/dist/types.d.ts.map +1 -0
  80. package/dist/types.js +2 -0
  81. package/dist/types.js.map +1 -0
  82. package/dist/usage-reader.d.ts +49 -0
  83. package/dist/usage-reader.d.ts.map +1 -0
  84. package/dist/usage-reader.js +189 -0
  85. package/dist/usage-reader.js.map +1 -0
  86. package/dist/vendor/shared/index.d.ts +4 -0
  87. package/dist/vendor/shared/index.d.ts.map +1 -0
  88. package/dist/vendor/shared/index.js +4 -0
  89. package/dist/vendor/shared/index.js.map +1 -0
  90. package/dist/vendor/shared/protocol.d.ts +471 -0
  91. package/dist/vendor/shared/protocol.d.ts.map +1 -0
  92. package/dist/vendor/shared/protocol.js +34 -0
  93. package/dist/vendor/shared/protocol.js.map +1 -0
  94. package/dist/vendor/shared/timeline.d.ts +15 -0
  95. package/dist/vendor/shared/timeline.d.ts.map +1 -0
  96. package/dist/vendor/shared/timeline.js +21 -0
  97. package/dist/vendor/shared/timeline.js.map +1 -0
  98. package/dist/vendor/shared/validation.d.ts +8 -0
  99. package/dist/vendor/shared/validation.d.ts.map +1 -0
  100. package/dist/vendor/shared/validation.js +25 -0
  101. package/dist/vendor/shared/validation.js.map +1 -0
  102. package/dist/version-detector.d.ts +36 -0
  103. package/dist/version-detector.d.ts.map +1 -0
  104. package/dist/version-detector.js +141 -0
  105. package/dist/version-detector.js.map +1 -0
  106. package/dist/workspace-telemetry.d.ts +10 -0
  107. package/dist/workspace-telemetry.d.ts.map +1 -0
  108. package/dist/workspace-telemetry.js +84 -0
  109. package/dist/workspace-telemetry.js.map +1 -0
  110. package/package.json +64 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-controller.js","sourceRoot":"","sources":["../src/host-controller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Maestro Mobile — Host 入口
3
+ *
4
+ * 启动流程:
5
+ * 1. 解析命令行参数
6
+ * 2. 创建 HostController(管理 Pi SDK AgentSession)
7
+ * 3. 创建 MaestroStateReader(读取 flow-schedule 状态)
8
+ * 4. 启动 WebSocket Server(HTTP + WS 统一端口)
9
+ * 5. 注册信号处理和优雅关闭
10
+ */
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ /**
3
+ * Maestro Mobile — Host 入口
4
+ *
5
+ * 启动流程:
6
+ * 1. 解析命令行参数
7
+ * 2. 创建 HostController(管理 Pi SDK AgentSession)
8
+ * 3. 创建 MaestroStateReader(读取 flow-schedule 状态)
9
+ * 4. 启动 WebSocket Server(HTTP + WS 统一端口)
10
+ * 5. 注册信号处理和优雅关闭
11
+ */
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG"}
@@ -0,0 +1,19 @@
1
+ export interface JsonlIndex {
2
+ /** 每条 message 行的 [startOffset, endOffset)(endOffset 含换行符后的下一行起点) */
3
+ messageOffsets: number[];
4
+ /** message 总数 */
5
+ totalEntries: number;
6
+ /** 索引建立时的文件大小(追加写入检测用) */
7
+ size: number;
8
+ mtimeMs: number;
9
+ }
10
+ export declare function getCachedIndex(filePath: string, size: number, mtimeMs: number): JsonlIndex | undefined;
11
+ export declare function putCachedIndex(filePath: string, index: JsonlIndex): void;
12
+ /**
13
+ * 建立(或读取缓存的)message 行偏移索引。
14
+ * 只记录「type":"message」行的起始 offset;与 jsonl-pager 的行判定一致。
15
+ */
16
+ export declare function buildMessageIndex(filePath: string): Promise<JsonlIndex>;
17
+ /** 清除某文件的索引(测试用) */
18
+ export declare function invalidateIndex(filePath: string): void;
19
+ //# sourceMappingURL=jsonl-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl-index.d.ts","sourceRoot":"","sources":["../src/jsonl-index.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,UAAU;IACzB,oEAAoE;IACpE,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,iBAAiB;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAKD,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAItG;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI,CAOxE;AAKD;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA2C7E;AAED,oBAAoB;AACpB,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAEtD"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * jsonl-index — 会话文件 message 行偏移索引(H8 性能修复)
3
+ *
4
+ * 问题:replayPageFromJsonl 每页都从 pos=0 流式扫描整个文件,
5
+ * 连续翻页成本 O(页数 × 文件大小)。
6
+ *
7
+ * 方案:首次扫描时记录每条 message 行的 byte offset(按行界对齐),
8
+ * 后续页直接从 offset 区间读取对应行,成本 O(页大小)。
9
+ * 索引以 (path, size, mtimeMs) 为键做模块级 LRU 缓存(容量 8),
10
+ * 文件被 Pi 追加写入后 size 变化自动失效重建。
11
+ */
12
+ import { open } from "node:fs/promises";
13
+ const MAX_INDEXED_FILES = 8;
14
+ const indexCache = new Map();
15
+ export function getCachedIndex(filePath, size, mtimeMs) {
16
+ const hit = indexCache.get(filePath);
17
+ if (hit && hit.size === size && hit.mtimeMs === mtimeMs)
18
+ return hit;
19
+ return undefined;
20
+ }
21
+ export function putCachedIndex(filePath, index) {
22
+ indexCache.set(filePath, index);
23
+ if (indexCache.size > MAX_INDEXED_FILES) {
24
+ // Map 迭代序 = 插入序,删最旧
25
+ const oldest = indexCache.keys().next().value;
26
+ if (oldest !== undefined)
27
+ indexCache.delete(oldest);
28
+ }
29
+ }
30
+ const READ_CHUNK = 512 * 1024;
31
+ const MAX_LINE_BYTES = 4 * 1024 * 1024;
32
+ /**
33
+ * 建立(或读取缓存的)message 行偏移索引。
34
+ * 只记录「type":"message」行的起始 offset;与 jsonl-pager 的行判定一致。
35
+ */
36
+ export async function buildMessageIndex(filePath) {
37
+ const fd = await open(filePath, "r");
38
+ try {
39
+ const stat = await fd.stat();
40
+ const cached = getCachedIndex(filePath, stat.size, stat.mtimeMs);
41
+ if (cached)
42
+ return cached;
43
+ const messageOffsets = [];
44
+ let pos = 0;
45
+ let buf = "";
46
+ let bufStart = 0; // buf[0] 对应的文件 offset
47
+ while (pos < stat.size) {
48
+ const readLen = Math.min(READ_CHUNK, stat.size - pos);
49
+ const chunk = Buffer.alloc(readLen);
50
+ await fd.read(chunk, 0, readLen, pos);
51
+ pos += readLen;
52
+ buf += chunk.toString("utf8");
53
+ let nl;
54
+ while ((nl = buf.indexOf("\n")) !== -1) {
55
+ const line = buf.slice(0, nl);
56
+ if (line.trim() && line.length <= MAX_LINE_BYTES && line.includes('"type":"message"')) {
57
+ messageOffsets.push(bufStart);
58
+ }
59
+ buf = buf.slice(nl + 1);
60
+ bufStart += nl + 1;
61
+ }
62
+ }
63
+ // 末尾无换行的残行
64
+ if (buf.trim() && buf.length <= MAX_LINE_BYTES && buf.includes('"type":"message"')) {
65
+ messageOffsets.push(bufStart);
66
+ }
67
+ const index = {
68
+ messageOffsets,
69
+ totalEntries: messageOffsets.length,
70
+ size: stat.size,
71
+ mtimeMs: stat.mtimeMs,
72
+ };
73
+ putCachedIndex(filePath, index);
74
+ return index;
75
+ }
76
+ finally {
77
+ await fd.close();
78
+ }
79
+ }
80
+ /** 清除某文件的索引(测试用) */
81
+ export function invalidateIndex(filePath) {
82
+ indexCache.delete(filePath);
83
+ }
84
+ //# sourceMappingURL=jsonl-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl-index.js","sourceRoot":"","sources":["../src/jsonl-index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { TimelineItem } from "./vendor/shared/index.js";
2
+ export interface PageResult {
3
+ items: TimelineItem[];
4
+ hasMore: boolean;
5
+ /** 新的 cursor = 已消费尾部条数 */
6
+ cursor: number;
7
+ totalEntries: number;
8
+ }
9
+ /** 首次加载:取最后 limit 条(此时 cursor=0,skip=0) */
10
+ export declare function replayTailFromJsonl(filePath: string, limit?: number): Promise<PageResult>;
11
+ /**
12
+ * 继续向前翻页:已发 cursor 条(尾部),再取更早的 limit 条。
13
+ * 等价于 window = [total - cursor - limit, total - cursor)
14
+ */
15
+ export declare function replayPageFromJsonl(filePath: string, cursor: number, count?: number): Promise<PageResult>;
16
+ export declare function parseMessageLine(line: string, index: number, seenToolResults: Set<string>): TimelineItem | undefined;
17
+ /**
18
+ * 搜索 jsonl 中匹配关键词的消息(返回文件顺序中的匹配项 + 其 timeline 下标范围)
19
+ * 返回匹配消息的序号(从 0 开始,按文件 message 顺序)和文本片段。
20
+ */
21
+ export declare function searchInJsonl(filePath: string, keyword: string, maxResults?: number): Promise<{
22
+ matches: {
23
+ index: number;
24
+ text: string;
25
+ kind: string;
26
+ }[];
27
+ totalEntries: number;
28
+ }>;
29
+ //# sourceMappingURL=jsonl-pager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl-pager.d.ts","sourceRoot":"","sources":["../src/jsonl-pager.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,0BAA0B;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB;AAKD,2CAA2C;AAC3C,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,SAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAE5F;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,KAAK,SAAM,GACV,OAAO,CAAC,UAAU,CAAC,CAGrB;AA8ED,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,GAC3B,YAAY,GAAG,SAAS,CAsD1B;AAED;;;GAGG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,UAAU,SAAK,GACd,OAAO,CAAC;IAAE,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,CAiD7F"}
@@ -0,0 +1,237 @@
1
+ /**
2
+ * jsonl-pager — jsonl 会话文件的分页读取(懒加载核心)
3
+ *
4
+ * 长会话不再一次性解析全部:
5
+ * - 首次只取尾部 limit 条(tail)
6
+ * - 滚动到顶部时,按批次向前取更早的(page)
7
+ *
8
+ * 实现:
9
+ * 正向分块扫描整文件,但只保留两条信息:
10
+ * 1. ring buffer:最后 limit+skip 条 item(用于 tail / page 返回)
11
+ * 2. 文件 message 总数
12
+ * 扫描是流式的(分块读),内存只保留窗口大小,不驻留全量。
13
+ *
14
+ * cursor 语义:已经发给客户端的历史条数(从尾部往前数)。
15
+ * cursor=0 表示还没发过任何历史(首次 tail)
16
+ * cursor=N 表示尾部 N 条已发,下一页往前取更早的。
17
+ */
18
+ import { open } from "node:fs/promises";
19
+ const MAX_LINE_BYTES = 4 * 1024 * 1024;
20
+ const READ_CHUNK = 512 * 1024;
21
+ /** 首次加载:取最后 limit 条(此时 cursor=0,skip=0) */
22
+ export async function replayTailFromJsonl(filePath, limit = 100) {
23
+ return scanWindow(filePath, { limit, skip: 0 });
24
+ }
25
+ /**
26
+ * 继续向前翻页:已发 cursor 条(尾部),再取更早的 limit 条。
27
+ * 等价于 window = [total - cursor - limit, total - cursor)
28
+ */
29
+ export async function replayPageFromJsonl(filePath, cursor, count = 100) {
30
+ if (cursor <= 0)
31
+ return { items: [], hasMore: false, cursor: 0, totalEntries: 0 };
32
+ return scanWindow(filePath, { limit: count, skip: cursor });
33
+ }
34
+ async function scanWindow(filePath, opts) {
35
+ // ring 容量(按 message 数计,与 cursor 语义一致):需要返回窗口 + 1 前瞻
36
+ const want = opts.limit + opts.skip + 1;
37
+ let fd;
38
+ try {
39
+ let opened = true;
40
+ try {
41
+ fd = await open(filePath, "r");
42
+ }
43
+ catch {
44
+ opened = false;
45
+ }
46
+ if (!opened || !fd) {
47
+ return { items: [], hasMore: false, cursor: 0, totalEntries: 0 };
48
+ }
49
+ // ring 保存 TimelineItem | null(null = message 未产生可渲染 item,如重复 toolResult);
50
+ // 长度按 message 数维护,cursor/hasMore 因此与 message 序号一致。
51
+ const ring = [];
52
+ const seenToolResults = new Set();
53
+ let totalEntries = 0;
54
+ let buf = "";
55
+ const handleLine = (line) => {
56
+ if (!line.trim() || line.length > MAX_LINE_BYTES)
57
+ return;
58
+ if (!line.trimStart().startsWith("{"))
59
+ return;
60
+ // 只有 message 类型计入总数(session/model_change 等忽略)
61
+ if (!line.includes('"type":"message"'))
62
+ return;
63
+ totalEntries++;
64
+ // ring 按 message 数保留最后 want 条(含 null 占位)
65
+ if (ring.length >= want) {
66
+ ring.shift();
67
+ }
68
+ const item = parseMessageLine(line, totalEntries - 1, seenToolResults);
69
+ ring.push(item ?? null);
70
+ };
71
+ const { size } = await fd.stat();
72
+ if (size === 0)
73
+ return { items: [], hasMore: false, cursor: 0, totalEntries: 0 };
74
+ let pos = 0;
75
+ while (pos < size) {
76
+ const readLen = Math.min(READ_CHUNK, size - pos);
77
+ const chunk = Buffer.alloc(readLen);
78
+ await fd.read(chunk, 0, readLen, pos);
79
+ pos += readLen;
80
+ buf += chunk.toString("utf8");
81
+ // 处理完整行
82
+ let nl;
83
+ while ((nl = buf.indexOf("\n")) !== -1) {
84
+ const line = buf.slice(0, nl);
85
+ buf = buf.slice(nl + 1);
86
+ handleLine(line);
87
+ }
88
+ }
89
+ if (buf.trim())
90
+ handleLine(buf); // 最后无换行的行
91
+ // ring 现在 = 最后 want 条 message(含 null 占位)。返回窗口 [skip, skip+limit) 的 item
92
+ const end = Math.max(0, ring.length - opts.skip);
93
+ const start = Math.max(0, end - opts.limit);
94
+ const items = ring
95
+ .slice(start, end)
96
+ .filter((x) => x !== null);
97
+ // hasMore:ring 里还有比窗口更早的 message(含占位)
98
+ const hasMore = start > 0;
99
+ const cursor = opts.skip + (end - start);
100
+ return { items, hasMore, cursor, totalEntries };
101
+ }
102
+ finally {
103
+ await fd?.close();
104
+ }
105
+ }
106
+ export function parseMessageLine(line, index, seenToolResults) {
107
+ let entry;
108
+ try {
109
+ entry = JSON.parse(line);
110
+ }
111
+ catch {
112
+ return undefined;
113
+ }
114
+ if (entry.type !== "message")
115
+ return undefined;
116
+ const msg = (entry.message ?? {});
117
+ const role = String(msg.role ?? "");
118
+ const timestamp = typeof msg.timestamp === "number" ? msg.timestamp : 0;
119
+ const createdAt = timestamp > 0 ? new Date(timestamp).toISOString() : "";
120
+ if (role === "toolResult") {
121
+ const toolCallId = String(msg.toolCallId ?? "");
122
+ if (toolCallId && seenToolResults.has(toolCallId))
123
+ return undefined;
124
+ if (toolCallId)
125
+ seenToolResults.add(toolCallId);
126
+ const text = extractText(msg.content);
127
+ if (!text)
128
+ return undefined;
129
+ return {
130
+ id: `replay-tool-${index}`,
131
+ kind: "tool",
132
+ text,
133
+ createdAt,
134
+ toolName: String(msg.toolName ?? "tool"),
135
+ toolCallId,
136
+ isError: msg.isError === true,
137
+ };
138
+ }
139
+ if (role === "tool" || role === "toolCall") {
140
+ const toolName = String(msg.toolName ?? "tool");
141
+ const text = extractText(msg.content);
142
+ return {
143
+ id: `replay-toolcall-${index}`,
144
+ kind: "tool",
145
+ text: text || `调用 ${toolName}`,
146
+ createdAt,
147
+ toolName,
148
+ };
149
+ }
150
+ const text = extractText(msg.content);
151
+ if (role === "user") {
152
+ return { id: `replay-user-${index}`, kind: "user", text, createdAt };
153
+ }
154
+ if (role === "assistant" || role === "system") {
155
+ if (!text)
156
+ return undefined;
157
+ return { id: `replay-assistant-${index}`, kind: "assistant", text, createdAt };
158
+ }
159
+ if (role === "thinking") {
160
+ if (!text)
161
+ return undefined;
162
+ return { id: `replay-thinking-${index}`, kind: "thinking", text, createdAt };
163
+ }
164
+ return undefined;
165
+ }
166
+ /**
167
+ * 搜索 jsonl 中匹配关键词的消息(返回文件顺序中的匹配项 + 其 timeline 下标范围)
168
+ * 返回匹配消息的序号(从 0 开始,按文件 message 顺序)和文本片段。
169
+ */
170
+ export async function searchInJsonl(filePath, keyword, maxResults = 50) {
171
+ if (!keyword.trim())
172
+ return { matches: [], totalEntries: 0 };
173
+ const kw = keyword.toLowerCase();
174
+ let fd;
175
+ try {
176
+ fd = await open(filePath, "r");
177
+ const { size } = await fd.stat();
178
+ const matches = [];
179
+ let totalEntries = 0;
180
+ let buf = "";
181
+ const handleLine = (line) => {
182
+ if (!line.trim() || !line.includes('"type":"message"'))
183
+ return;
184
+ totalEntries++;
185
+ if (matches.length >= maxResults)
186
+ return;
187
+ try {
188
+ const entry = JSON.parse(line);
189
+ const role = entry.message?.role ?? "";
190
+ const text = extractText(entry.message?.content ?? "");
191
+ if (text.toLowerCase().includes(kw)) {
192
+ matches.push({
193
+ index: totalEntries - 1,
194
+ text: text.slice(0, 120),
195
+ kind: role,
196
+ });
197
+ }
198
+ }
199
+ catch {
200
+ // ignore
201
+ }
202
+ };
203
+ let pos = 0;
204
+ while (pos < size) {
205
+ const readLen = Math.min(READ_CHUNK, size - pos);
206
+ const chunk = Buffer.alloc(readLen);
207
+ await fd.read(chunk, 0, readLen, pos);
208
+ pos += readLen;
209
+ buf += chunk.toString("utf8");
210
+ let nl;
211
+ while ((nl = buf.indexOf("\n")) !== -1) {
212
+ handleLine(buf.slice(0, nl));
213
+ buf = buf.slice(nl + 1);
214
+ }
215
+ }
216
+ if (buf.trim())
217
+ handleLine(buf);
218
+ return { matches, totalEntries };
219
+ }
220
+ finally {
221
+ await fd?.close();
222
+ }
223
+ }
224
+ function extractText(content) {
225
+ if (typeof content === "string")
226
+ return content;
227
+ if (!Array.isArray(content))
228
+ return "";
229
+ const parts = [];
230
+ for (const block of content) {
231
+ const b = block;
232
+ if (typeof b.text === "string")
233
+ parts.push(b.text);
234
+ }
235
+ return parts.join("\n");
236
+ }
237
+ //# sourceMappingURL=jsonl-pager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl-pager.js","sourceRoot":"","sources":["../src/jsonl-pager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { TimelineItem } from "./vendor/shared/index.js";
2
+ export interface JsonlReplayResult {
3
+ items: TimelineItem[];
4
+ /** 解析的原始消息条数 */
5
+ totalEntries: number;
6
+ }
7
+ /** 从 jsonl 文件解析完整 timeline(按文件顺序) */
8
+ export declare function replayFromJsonl(filePath: string): Promise<JsonlReplayResult>;
9
+ //# sourceMappingURL=jsonl-replay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl-replay.d.ts","sourceRoot":"","sources":["../src/jsonl-replay.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,gBAAgB;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,qCAAqC;AACrC,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA+ElF"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * jsonl-replay — 从 Pi 会话 jsonl 文件直接解析历史消息(只读)
3
+ *
4
+ * 为什么需要:SDK 的 session.messages 只保留 LLM 上下文内的消息,
5
+ * tool 输出(bash 表格/截图路径)和早期消息会被裁剪。
6
+ * 直接解析 jsonl 文件可拿到完整历史,包括:
7
+ * - toolResult(bash 输出、图片路径)
8
+ * - user 粘贴的图片路径
9
+ * - thinking、assistant、toolCall
10
+ */
11
+ import { readFile } from "node:fs/promises";
12
+ /** 从 jsonl 文件解析完整 timeline(按文件顺序) */
13
+ export async function replayFromJsonl(filePath) {
14
+ let content;
15
+ try {
16
+ content = await readFile(filePath, "utf8");
17
+ }
18
+ catch {
19
+ return { items: [], totalEntries: 0 };
20
+ }
21
+ const items = [];
22
+ const seenToolResults = new Set();
23
+ let totalEntries = 0;
24
+ for (const line of content.split("\n")) {
25
+ if (!line.trim())
26
+ continue;
27
+ let entry;
28
+ try {
29
+ entry = JSON.parse(line);
30
+ }
31
+ catch {
32
+ continue;
33
+ }
34
+ if (entry.type !== "message")
35
+ continue;
36
+ totalEntries++;
37
+ const msg = (entry.message ?? {});
38
+ const role = String(msg.role ?? "");
39
+ const timestamp = typeof msg.timestamp === "number" ? msg.timestamp : 0;
40
+ const createdAt = timestamp > 0 ? new Date(timestamp).toISOString() : "";
41
+ if (role === "toolResult") {
42
+ const toolCallId = String(msg.toolCallId ?? "");
43
+ if (toolCallId && seenToolResults.has(toolCallId))
44
+ continue;
45
+ if (toolCallId)
46
+ seenToolResults.add(toolCallId);
47
+ const toolName = String(msg.toolName ?? "tool");
48
+ const text = extractText(msg.content);
49
+ if (!text)
50
+ continue;
51
+ items.push({
52
+ id: `replay-tool-${items.length}`,
53
+ kind: "tool",
54
+ text,
55
+ createdAt,
56
+ toolName,
57
+ toolCallId,
58
+ isError: msg.isError === true,
59
+ });
60
+ continue;
61
+ }
62
+ if (role === "tool" || role === "toolCall") {
63
+ const toolName = String(msg.toolName ?? "tool");
64
+ const text = extractText(msg.content);
65
+ items.push({
66
+ id: `replay-toolcall-${items.length}`,
67
+ kind: "tool",
68
+ text: text || `调用 ${toolName}`,
69
+ createdAt,
70
+ toolName,
71
+ });
72
+ continue;
73
+ }
74
+ const text = extractText(msg.content);
75
+ if (role === "user") {
76
+ items.push({ id: `replay-user-${items.length}`, kind: "user", text, createdAt });
77
+ }
78
+ else if (role === "assistant" || role === "system") {
79
+ if (!text)
80
+ continue;
81
+ items.push({ id: `replay-assistant-${items.length}`, kind: "assistant", text, createdAt });
82
+ // assistant 消息里可能嵌 toolCall(read 图片等)——提取图片参数渲染为 tool 项
83
+ const callItems = toolCallImageItems(msg.content);
84
+ for (const callItem of callItems) {
85
+ items.push({ ...callItem, id: `replay-toolcall-${items.length}` });
86
+ }
87
+ }
88
+ else if (role === "thinking") {
89
+ if (!text)
90
+ continue;
91
+ items.push({ id: `replay-thinking-${items.length}`, kind: "thinking", text, createdAt });
92
+ }
93
+ // toolResult 已在上面处理;其余角色忽略
94
+ }
95
+ return { items, totalEntries };
96
+ }
97
+ const TOOL_IMAGE_EXT = /\.(png|jpe?g|gif|webp|bmp)$/i;
98
+ /** 从 assistant content 里提取 toolCall 中读图片的调用,转为 tool 项(文本=图片路径) */
99
+ function toolCallImageItems(content) {
100
+ if (!Array.isArray(content))
101
+ return [];
102
+ const items = [];
103
+ for (const block of content) {
104
+ const b = block;
105
+ if (b.type !== "toolCall")
106
+ continue;
107
+ const name = String(b.name ?? "");
108
+ const args = b.arguments;
109
+ if (!args || typeof args !== "object")
110
+ continue;
111
+ // read 工具的 path 参数;若为图片路径则渲染
112
+ if (name === "read") {
113
+ const path = args.path;
114
+ if (typeof path === "string" && TOOL_IMAGE_EXT.test(path.trim())) {
115
+ items.push({
116
+ id: "",
117
+ kind: "tool",
118
+ text: path.trim(),
119
+ createdAt: "",
120
+ toolName: "read",
121
+ });
122
+ }
123
+ }
124
+ }
125
+ return items;
126
+ }
127
+ function extractText(content) {
128
+ if (typeof content === "string")
129
+ return content;
130
+ if (!Array.isArray(content))
131
+ return "";
132
+ const parts = [];
133
+ for (const block of content) {
134
+ const b = block;
135
+ if (typeof b.text === "string")
136
+ parts.push(b.text);
137
+ }
138
+ return parts.join("\n");
139
+ }
140
+ //# sourceMappingURL=jsonl-replay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl-replay.js","sourceRoot":"","sources":["../src/jsonl-replay.ts"],"names":[],"mappings":"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"}