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.
- package/README.md +85 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +84 -0
- package/dist/cli.js.map +1 -0
- package/dist/event-log.d.ts +18 -0
- package/dist/event-log.d.ts.map +1 -0
- package/dist/event-log.js +31 -0
- package/dist/event-log.js.map +1 -0
- package/dist/extension.d.ts +3 -0
- package/dist/extension.d.ts.map +1 -0
- package/dist/extension.js +118 -0
- package/dist/extension.js.map +1 -0
- package/dist/host-controller.d.ts +69 -0
- package/dist/host-controller.d.ts.map +1 -0
- package/dist/host-controller.js +195 -0
- package/dist/host-controller.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/jsonl-index.d.ts +19 -0
- package/dist/jsonl-index.d.ts.map +1 -0
- package/dist/jsonl-index.js +84 -0
- package/dist/jsonl-index.js.map +1 -0
- package/dist/jsonl-pager.d.ts +29 -0
- package/dist/jsonl-pager.d.ts.map +1 -0
- package/dist/jsonl-pager.js +237 -0
- package/dist/jsonl-pager.js.map +1 -0
- package/dist/jsonl-replay.d.ts +9 -0
- package/dist/jsonl-replay.d.ts.map +1 -0
- package/dist/jsonl-replay.js +140 -0
- package/dist/jsonl-replay.js.map +1 -0
- package/dist/live-sessions.d.ts +47 -0
- package/dist/live-sessions.d.ts.map +1 -0
- package/dist/live-sessions.js +201 -0
- package/dist/live-sessions.js.map +1 -0
- package/dist/maestro-settings.d.ts +40 -0
- package/dist/maestro-settings.d.ts.map +1 -0
- package/dist/maestro-settings.js +122 -0
- package/dist/maestro-settings.js.map +1 -0
- package/dist/maestro-state.d.ts +31 -0
- package/dist/maestro-state.d.ts.map +1 -0
- package/dist/maestro-state.js +219 -0
- package/dist/maestro-state.js.map +1 -0
- package/dist/mobile-agent.d.ts +86 -0
- package/dist/mobile-agent.d.ts.map +1 -0
- package/dist/mobile-agent.js +2 -0
- package/dist/mobile-agent.js.map +1 -0
- package/dist/mobile-ui-context.d.ts +26 -0
- package/dist/mobile-ui-context.d.ts.map +1 -0
- package/dist/mobile-ui-context.js +164 -0
- package/dist/mobile-ui-context.js.map +1 -0
- package/dist/monitor-projection.d.ts +19 -0
- package/dist/monitor-projection.d.ts.map +1 -0
- package/dist/monitor-projection.js +79 -0
- package/dist/monitor-projection.js.map +1 -0
- package/dist/pi/pi-sdk-runtime.d.ts +17 -0
- package/dist/pi/pi-sdk-runtime.d.ts.map +1 -0
- package/dist/pi/pi-sdk-runtime.js +57 -0
- package/dist/pi/pi-sdk-runtime.js.map +1 -0
- package/dist/server/helpers.d.ts +23 -0
- package/dist/server/helpers.d.ts.map +1 -0
- package/dist/server/helpers.js +179 -0
- package/dist/server/helpers.js.map +1 -0
- package/dist/server/mobile-host-server.d.ts +43 -0
- package/dist/server/mobile-host-server.d.ts.map +1 -0
- package/dist/server/mobile-host-server.js +715 -0
- package/dist/server/mobile-host-server.js.map +1 -0
- package/dist/server/ws-command-handlers.d.ts +18 -0
- package/dist/server/ws-command-handlers.d.ts.map +1 -0
- package/dist/server/ws-command-handlers.js +173 -0
- package/dist/server/ws-command-handlers.js.map +1 -0
- package/dist/session-runner.d.ts +130 -0
- package/dist/session-runner.d.ts.map +1 -0
- package/dist/session-runner.js +576 -0
- package/dist/session-runner.js.map +1 -0
- package/dist/types.d.ts +83 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/usage-reader.d.ts +49 -0
- package/dist/usage-reader.d.ts.map +1 -0
- package/dist/usage-reader.js +189 -0
- package/dist/usage-reader.js.map +1 -0
- package/dist/vendor/shared/index.d.ts +4 -0
- package/dist/vendor/shared/index.d.ts.map +1 -0
- package/dist/vendor/shared/index.js +4 -0
- package/dist/vendor/shared/index.js.map +1 -0
- package/dist/vendor/shared/protocol.d.ts +471 -0
- package/dist/vendor/shared/protocol.d.ts.map +1 -0
- package/dist/vendor/shared/protocol.js +34 -0
- package/dist/vendor/shared/protocol.js.map +1 -0
- package/dist/vendor/shared/timeline.d.ts +15 -0
- package/dist/vendor/shared/timeline.d.ts.map +1 -0
- package/dist/vendor/shared/timeline.js +21 -0
- package/dist/vendor/shared/timeline.js.map +1 -0
- package/dist/vendor/shared/validation.d.ts +8 -0
- package/dist/vendor/shared/validation.d.ts.map +1 -0
- package/dist/vendor/shared/validation.js +25 -0
- package/dist/vendor/shared/validation.js.map +1 -0
- package/dist/version-detector.d.ts +36 -0
- package/dist/version-detector.d.ts.map +1 -0
- package/dist/version-detector.js +141 -0
- package/dist/version-detector.js.map +1 -0
- package/dist/workspace-telemetry.d.ts +10 -0
- package/dist/workspace-telemetry.d.ts.map +1 -0
- package/dist/workspace-telemetry.js +84 -0
- package/dist/workspace-telemetry.js.map +1 -0
- package/package.json +64 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { SessionState, SessionSnapshot, HostEvent, TimelineItem } from "./vendor/shared/index.js";
|
|
2
|
+
import type { MobileAgentRuntime } from "./mobile-agent.js";
|
|
3
|
+
export type HostEventListener = (event: HostEvent) => void;
|
|
4
|
+
export interface OpenSessionRequest {
|
|
5
|
+
cwd: string;
|
|
6
|
+
mode?: "create" | "continue";
|
|
7
|
+
sessionFile?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface SessionRunner {
|
|
10
|
+
readonly id: string;
|
|
11
|
+
readonly state: SessionState;
|
|
12
|
+
readonly hasMoreHistory: boolean;
|
|
13
|
+
snapshot(): SessionSnapshot;
|
|
14
|
+
eventsSince(seq: number): HostEvent[];
|
|
15
|
+
loadMoreHistory(count?: number): Promise<{
|
|
16
|
+
items: TimelineItem[];
|
|
17
|
+
hasMore: boolean;
|
|
18
|
+
totalEntries: number;
|
|
19
|
+
}>;
|
|
20
|
+
searchHistory(keyword: string, maxResults?: number, previewLength?: number): Promise<{
|
|
21
|
+
matches: {
|
|
22
|
+
index: number;
|
|
23
|
+
text: string;
|
|
24
|
+
kind: string;
|
|
25
|
+
}[];
|
|
26
|
+
totalEntries: number;
|
|
27
|
+
}>;
|
|
28
|
+
prompt(message: string, streamingBehavior?: "steer" | "followUp", images?: unknown[]): Promise<void>;
|
|
29
|
+
steer(message: string): Promise<void>;
|
|
30
|
+
followUp(message: string): Promise<void>;
|
|
31
|
+
abort(): Promise<void>;
|
|
32
|
+
/** SDK 实时上下文用量(不可用时返回 null) */
|
|
33
|
+
getContextUsage?(): {
|
|
34
|
+
tokens: number | null;
|
|
35
|
+
contextWindow: number;
|
|
36
|
+
percent: number | null;
|
|
37
|
+
} | null;
|
|
38
|
+
/** 会话 token 用量(JSONL 聚合) */
|
|
39
|
+
getUsage?(): Promise<{
|
|
40
|
+
entries: number;
|
|
41
|
+
input: number;
|
|
42
|
+
output: number;
|
|
43
|
+
cacheRead: number;
|
|
44
|
+
cacheWrite: number;
|
|
45
|
+
reasoning: number;
|
|
46
|
+
totalTokens: number;
|
|
47
|
+
cost: number;
|
|
48
|
+
}>;
|
|
49
|
+
listModels?(): {
|
|
50
|
+
id: string;
|
|
51
|
+
provider: string;
|
|
52
|
+
name: string;
|
|
53
|
+
reasoning: boolean;
|
|
54
|
+
vision: boolean;
|
|
55
|
+
}[];
|
|
56
|
+
listLoadedSkills?(): {
|
|
57
|
+
name: string;
|
|
58
|
+
description?: string;
|
|
59
|
+
}[];
|
|
60
|
+
setModel?(modelId: string): Promise<{
|
|
61
|
+
ok: boolean;
|
|
62
|
+
error?: string;
|
|
63
|
+
}>;
|
|
64
|
+
setThinking?(level: string): {
|
|
65
|
+
ok: boolean;
|
|
66
|
+
error?: string;
|
|
67
|
+
};
|
|
68
|
+
compact?(customInstructions?: string): Promise<{
|
|
69
|
+
ok: boolean;
|
|
70
|
+
error?: string;
|
|
71
|
+
}>;
|
|
72
|
+
renameSession?(name: string): {
|
|
73
|
+
ok: boolean;
|
|
74
|
+
error?: string;
|
|
75
|
+
};
|
|
76
|
+
respondToExtensionUi(requestId: string, response: unknown): boolean;
|
|
77
|
+
dispose(): Promise<void>;
|
|
78
|
+
}
|
|
79
|
+
export interface RuntimeFactory {
|
|
80
|
+
createRuntime(request: OpenSessionRequest): Promise<MobileAgentRuntime>;
|
|
81
|
+
listSessions(cwd?: string): Promise<unknown[]>;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export interface UsageTotals {
|
|
2
|
+
/** assistant 轮次(含 usage 的 message 条目数,已去重) */
|
|
3
|
+
entries: number;
|
|
4
|
+
input: number;
|
|
5
|
+
output: number;
|
|
6
|
+
cacheRead: number;
|
|
7
|
+
cacheWrite: number;
|
|
8
|
+
reasoning: number;
|
|
9
|
+
/** input+output+cacheRead+cacheWrite+reasoning 之和(参考值) */
|
|
10
|
+
totalTokens: number;
|
|
11
|
+
/** 累计成本(美元,模型定价;免费模型为 0) */
|
|
12
|
+
cost: number;
|
|
13
|
+
}
|
|
14
|
+
export interface SessionUsage {
|
|
15
|
+
sessionId: string;
|
|
16
|
+
/** JSONL 文件路径(不存在时 path 为空) */
|
|
17
|
+
path: string;
|
|
18
|
+
totals: UsageTotals;
|
|
19
|
+
}
|
|
20
|
+
export declare const EMPTY_TOTALS: UsageTotals;
|
|
21
|
+
/** 单条 JSONL 行 → UsageTotals(非 message 条目 / 无 usage / 数值异常均返回零) */
|
|
22
|
+
export declare function parseUsageLine(line: string): UsageTotals;
|
|
23
|
+
/**
|
|
24
|
+
* 聚合一个 JSONL 文件的 usage(全量读取;大文件流式逐行,按 id 去重)
|
|
25
|
+
* 返回 EMPTY_TOTALS 也可能是「文件存在但无 usage」——调用方用 stat 区分
|
|
26
|
+
*/
|
|
27
|
+
export declare function readSessionUsage(sessionFile: string): Promise<UsageTotals>;
|
|
28
|
+
/**
|
|
29
|
+
* 按时间过滤聚合多个会话文件(Dashboard「今日/7 天」用)
|
|
30
|
+
* sinceMs: 只统计 mtime >= 该时间戳的文件(文件级过滤,不逐条按时间过滤——
|
|
31
|
+
* 会话文件的 usage 是全程累积的,按条目时间切割需要完整解析,成本高且语义偏移)
|
|
32
|
+
*/
|
|
33
|
+
export declare function readRecentUsage(files: {
|
|
34
|
+
path: string;
|
|
35
|
+
mtimeMs: number;
|
|
36
|
+
}[], sinceMs: number): Promise<{
|
|
37
|
+
totals: UsageTotals;
|
|
38
|
+
files: number;
|
|
39
|
+
}>;
|
|
40
|
+
/** 列出全部会话 JSONL(mtime 降序;扫描失败安全返回空) */
|
|
41
|
+
export declare function listSessionFiles(sessionsRoot?: string): Promise<{
|
|
42
|
+
path: string;
|
|
43
|
+
mtimeMs: number;
|
|
44
|
+
}[]>;
|
|
45
|
+
/** 从 sessionId 反查 JSONL 路径(telemetry owner → sessionFile) */
|
|
46
|
+
export declare function resolveSessionFile(sessionId: string, sessionsRoot?: string): Promise<string | undefined>;
|
|
47
|
+
/** sessionId 提取:文件路径 → basename 去掉 .jsonl */
|
|
48
|
+
export declare function sessionIdFromPath(sessionFile: string): string;
|
|
49
|
+
//# sourceMappingURL=usage-reader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage-reader.d.ts","sourceRoot":"","sources":["../src/usage-reader.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,WAAW;IAC1B,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,WAAW,EAAE,MAAM,CAAC;IACpB,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,eAAO,MAAM,YAAY,EAAE,WAE1B,CAAC;AAeF,kEAAkE;AAClE,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CA8BxD;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA0BhF;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,EAC1C,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CASjD;AAED,uCAAuC;AACvC,wBAAsB,gBAAgB,CAAC,YAAY,SAA8C,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CA8B/I;AAED,6DAA6D;AAC7D,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,SAA8C,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAmBnJ;AAED,6CAA6C;AAC7C,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE7D"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* usage-reader — 会话 JSONL 的 token usage 聚合(纯函数模块,可单测)
|
|
3
|
+
*
|
|
4
|
+
* 数据源合同(已实证):
|
|
5
|
+
* ~/.pi/agent/sessions/<--cwd--dir>/<sessionId>.jsonl
|
|
6
|
+
* 每条 {"type":"message", "id":..., "message":{"role":"assistant","model":...,
|
|
7
|
+
* "usage":{"input":N,"output":N,"cacheRead":N,"cacheWrite":N,"reasoning":N,
|
|
8
|
+
* "totalTokens":N,"cost":{"input":..,"output":..,"total":..}}}}
|
|
9
|
+
*
|
|
10
|
+
* 聚合语义(实测验证):
|
|
11
|
+
* - totalTokens = input + output + cacheRead + cacheWrite + reasoning(各部分之和,非独立增量)
|
|
12
|
+
* - input 每轮重复计入上下文,「今日消耗」以 output/cost 为主指标、totalTokens 做参考
|
|
13
|
+
* - 条目 id 可能因流式补写重复出现,必须按 id 去重
|
|
14
|
+
* - usage 缺失(用户消息/工具消息)直接跳过
|
|
15
|
+
*/
|
|
16
|
+
import { readFile, readdir, stat } from "node:fs/promises";
|
|
17
|
+
import { join, basename } from "node:path";
|
|
18
|
+
import { homedir } from "node:os";
|
|
19
|
+
export const EMPTY_TOTALS = {
|
|
20
|
+
entries: 0, input: 0, output: 0, cacheRead: 0, cacheWrite: 0, reasoning: 0, totalTokens: 0, cost: 0,
|
|
21
|
+
};
|
|
22
|
+
function addTotals(a, b) {
|
|
23
|
+
return {
|
|
24
|
+
entries: a.entries + b.entries,
|
|
25
|
+
input: a.input + b.input,
|
|
26
|
+
output: a.output + b.output,
|
|
27
|
+
cacheRead: a.cacheRead + b.cacheRead,
|
|
28
|
+
cacheWrite: a.cacheWrite + b.cacheWrite,
|
|
29
|
+
reasoning: a.reasoning + b.reasoning,
|
|
30
|
+
totalTokens: a.totalTokens + b.totalTokens,
|
|
31
|
+
cost: a.cost + b.cost,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/** 单条 JSONL 行 → UsageTotals(非 message 条目 / 无 usage / 数值异常均返回零) */
|
|
35
|
+
export function parseUsageLine(line) {
|
|
36
|
+
if (!line.includes('"usage"'))
|
|
37
|
+
return EMPTY_TOTALS;
|
|
38
|
+
let d;
|
|
39
|
+
try {
|
|
40
|
+
d = JSON.parse(line);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return EMPTY_TOTALS;
|
|
44
|
+
}
|
|
45
|
+
if (!d || typeof d !== "object")
|
|
46
|
+
return EMPTY_TOTALS;
|
|
47
|
+
const rec = d;
|
|
48
|
+
if (rec.type !== "message")
|
|
49
|
+
return EMPTY_TOTALS;
|
|
50
|
+
const message = rec.message;
|
|
51
|
+
const usage = message?.usage;
|
|
52
|
+
if (!usage || typeof usage !== "object")
|
|
53
|
+
return EMPTY_TOTALS;
|
|
54
|
+
// token/cost 要求非负有限:损坏行产生负 totals 或精度失真会污染聚合
|
|
55
|
+
const num = (k) => {
|
|
56
|
+
const v = usage[k];
|
|
57
|
+
return typeof v === "number" && Number.isFinite(v) && v >= 0 ? v : 0;
|
|
58
|
+
};
|
|
59
|
+
const costObj = usage.cost;
|
|
60
|
+
const costRaw = costObj?.total;
|
|
61
|
+
const cost = typeof costRaw === "number" && Number.isFinite(costRaw) && costRaw >= 0 ? costRaw : 0;
|
|
62
|
+
const input = num("input"), output = num("output"), cacheRead = num("cacheRead"), cacheWrite = num("cacheWrite"), reasoning = num("reasoning");
|
|
63
|
+
return {
|
|
64
|
+
entries: 1,
|
|
65
|
+
input, output, cacheRead, cacheWrite, reasoning,
|
|
66
|
+
totalTokens: input + output + cacheRead + cacheWrite + reasoning,
|
|
67
|
+
cost,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* 聚合一个 JSONL 文件的 usage(全量读取;大文件流式逐行,按 id 去重)
|
|
72
|
+
* 返回 EMPTY_TOTALS 也可能是「文件存在但无 usage」——调用方用 stat 区分
|
|
73
|
+
*/
|
|
74
|
+
export async function readSessionUsage(sessionFile) {
|
|
75
|
+
let raw;
|
|
76
|
+
try {
|
|
77
|
+
raw = await readFile(sessionFile, "utf8");
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return EMPTY_TOTALS;
|
|
81
|
+
}
|
|
82
|
+
const seenIds = new Set();
|
|
83
|
+
let totals = EMPTY_TOTALS;
|
|
84
|
+
for (const line of raw.split("\n")) {
|
|
85
|
+
if (!line.includes('"usage"'))
|
|
86
|
+
continue;
|
|
87
|
+
// id 去重:流式补写同一条 message 可能重复出现
|
|
88
|
+
let id;
|
|
89
|
+
try {
|
|
90
|
+
const parsed = JSON.parse(line);
|
|
91
|
+
if (typeof parsed.id === "string")
|
|
92
|
+
id = parsed.id;
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
// 解析失败仍尝试聚合 usage 行本身
|
|
96
|
+
}
|
|
97
|
+
if (id) {
|
|
98
|
+
if (seenIds.has(id))
|
|
99
|
+
continue;
|
|
100
|
+
seenIds.add(id);
|
|
101
|
+
}
|
|
102
|
+
totals = addTotals(totals, parseUsageLine(line));
|
|
103
|
+
}
|
|
104
|
+
return totals;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* 按时间过滤聚合多个会话文件(Dashboard「今日/7 天」用)
|
|
108
|
+
* sinceMs: 只统计 mtime >= 该时间戳的文件(文件级过滤,不逐条按时间过滤——
|
|
109
|
+
* 会话文件的 usage 是全程累积的,按条目时间切割需要完整解析,成本高且语义偏移)
|
|
110
|
+
*/
|
|
111
|
+
export async function readRecentUsage(files, sinceMs) {
|
|
112
|
+
let totals = EMPTY_TOTALS;
|
|
113
|
+
let count = 0;
|
|
114
|
+
for (const f of files) {
|
|
115
|
+
if (f.mtimeMs < sinceMs)
|
|
116
|
+
continue;
|
|
117
|
+
totals = addTotals(totals, await readSessionUsage(f.path));
|
|
118
|
+
count++;
|
|
119
|
+
}
|
|
120
|
+
return { totals, files: count };
|
|
121
|
+
}
|
|
122
|
+
/** 列出全部会话 JSONL(mtime 降序;扫描失败安全返回空) */
|
|
123
|
+
export async function listSessionFiles(sessionsRoot = join(homedir(), ".pi", "agent", "sessions")) {
|
|
124
|
+
const out = [];
|
|
125
|
+
let cwdDirs;
|
|
126
|
+
try {
|
|
127
|
+
cwdDirs = await readdir(sessionsRoot);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return out;
|
|
131
|
+
}
|
|
132
|
+
for (const dir of cwdDirs) {
|
|
133
|
+
if (!dir.startsWith("--"))
|
|
134
|
+
continue;
|
|
135
|
+
const dirPath = join(sessionsRoot, dir);
|
|
136
|
+
let files;
|
|
137
|
+
try {
|
|
138
|
+
files = await readdir(dirPath);
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
for (const f of files) {
|
|
144
|
+
if (!f.endsWith(".jsonl"))
|
|
145
|
+
continue;
|
|
146
|
+
const path = join(dirPath, f);
|
|
147
|
+
try {
|
|
148
|
+
const s = await stat(path);
|
|
149
|
+
out.push({ path, mtimeMs: s.mtimeMs });
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
// skip
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
out.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
157
|
+
return out;
|
|
158
|
+
}
|
|
159
|
+
/** 从 sessionId 反查 JSONL 路径(telemetry owner → sessionFile) */
|
|
160
|
+
export async function resolveSessionFile(sessionId, sessionsRoot = join(homedir(), ".pi", "agent", "sessions")) {
|
|
161
|
+
if (!sessionId)
|
|
162
|
+
return undefined;
|
|
163
|
+
let cwdDirs;
|
|
164
|
+
try {
|
|
165
|
+
cwdDirs = await readdir(sessionsRoot);
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
return undefined;
|
|
169
|
+
}
|
|
170
|
+
for (const dir of cwdDirs) {
|
|
171
|
+
if (!dir.startsWith("--"))
|
|
172
|
+
continue;
|
|
173
|
+
const candidate = join(sessionsRoot, dir, `${sessionId}.jsonl`);
|
|
174
|
+
try {
|
|
175
|
+
const s = await stat(candidate);
|
|
176
|
+
if (s.isFile())
|
|
177
|
+
return candidate;
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
// continue
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return undefined;
|
|
184
|
+
}
|
|
185
|
+
/** sessionId 提取:文件路径 → basename 去掉 .jsonl */
|
|
186
|
+
export function sessionIdFromPath(sessionFile) {
|
|
187
|
+
return basename(sessionFile, ".jsonl");
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=usage-reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage-reader.js","sourceRoot":"","sources":["../src/usage-reader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/vendor/shared/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/vendor/shared/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC"}
|