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,47 @@
1
+ export interface LiveSessionInfo {
2
+ sessionId: string;
3
+ cwdName: string;
4
+ path: string;
5
+ firstMessage: string;
6
+ entryCount: number;
7
+ messageCount: number;
8
+ updatedAt: number;
9
+ /** 距现在 < liveThresholdMs 视为活跃中 */
10
+ live: boolean;
11
+ liveAgeMs: number;
12
+ }
13
+ export interface LiveSessionList {
14
+ sessions: LiveSessionInfo[];
15
+ observedAt: string;
16
+ /** 活跃会话数 */
17
+ liveCount: number;
18
+ }
19
+ export interface LiveSessionsOptions {
20
+ /** Pi 会话目录,默认 ~/.pi/agent/sessions */
21
+ sessionsRoot?: string;
22
+ /** 视为"活跃"的时间阈值 ms,默认 60s */
23
+ liveThresholdMs?: number;
24
+ /** 每个目录最多读取的会话数(防止巨量扫描) */
25
+ maxPerCwd?: number;
26
+ now?: () => number;
27
+ }
28
+ export declare class LiveSessionsService {
29
+ private readonly sessionsRoot;
30
+ private readonly liveThresholdMs;
31
+ private readonly maxPerCwd;
32
+ private readonly now;
33
+ /** P2-6:entryCount 按 mtime 缓存(文件未变时跳过流式扫描,避免每 5s 全量读盘) */
34
+ private readonly lineCountCache;
35
+ constructor(options?: LiveSessionsOptions);
36
+ get root(): string;
37
+ /** 列出所有会话(按 updatedAt 降序),标记活跃会话 */
38
+ list(): Promise<LiveSessionList>;
39
+ /** 条目数 = 非空行数;mtime 未变时用缓存,变化时流式重扫并更新缓存 */
40
+ private countEntries;
41
+ /** 解析单个会话文件(只读头部 + 行数),标记是否活跃 */
42
+ private readSessionInfo;
43
+ }
44
+ /** 将 --Users-isulewli-Projects-foo-- 解码为 /Users/isulewli/Projects/foo(绝对路径) */
45
+ declare function decodeCwdDir(dir: string): string;
46
+ export { decodeCwdDir };
47
+ //# sourceMappingURL=live-sessions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live-sessions.d.ts","sourceRoot":"","sources":["../src/live-sessions.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY;IACZ,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,sCAAsC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4BAA4B;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,0DAA0D;IAC1D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAyD;gBAE5E,OAAO,GAAE,mBAAwB;IAO7C,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,oCAAoC;IAC9B,IAAI,IAAI,OAAO,CAAC,eAAe,CAAC;IAiDtC,2CAA2C;YAC7B,YAAY;IAgB1B,iCAAiC;YACnB,eAAe;CA0C9B;AAcD,+EAA+E;AAC/E,iBAAS,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGzC;AAkDD,OAAO,EAAE,YAAY,EAAE,CAAC"}
@@ -0,0 +1,201 @@
1
+ /**
2
+ * LiveSessionsService — 只读感知"当前正在运行的 Pi 会话"(vibe coding 中)
3
+ *
4
+ * 核心思路:
5
+ * - 扫描 Pi 的会话文件目录(与 TUI 共享)
6
+ * - 解析每个文件的 updatedAt/entryCount
7
+ * - 最近活跃的会话标记为 live(正在运行)
8
+ *
9
+ * 关键特性:**只读**,不 claim workspace owner,不与真实 Pi 会话冲突。
10
+ */
11
+ import { readdir, stat } from "node:fs/promises";
12
+ import { join, basename } from "node:path";
13
+ import { homedir } from "node:os";
14
+ export class LiveSessionsService {
15
+ sessionsRoot;
16
+ liveThresholdMs;
17
+ maxPerCwd;
18
+ now;
19
+ /** P2-6:entryCount 按 mtime 缓存(文件未变时跳过流式扫描,避免每 5s 全量读盘) */
20
+ lineCountCache = new Map();
21
+ constructor(options = {}) {
22
+ this.sessionsRoot = options.sessionsRoot ?? join(homedir(), ".pi", "agent", "sessions");
23
+ this.liveThresholdMs = options.liveThresholdMs ?? 60_000;
24
+ this.maxPerCwd = options.maxPerCwd ?? 50;
25
+ this.now = options.now ?? Date.now;
26
+ }
27
+ get root() {
28
+ return this.sessionsRoot;
29
+ }
30
+ /** 列出所有会话(按 updatedAt 降序),标记活跃会话 */
31
+ async list() {
32
+ const observedAt = this.now();
33
+ const sessions = [];
34
+ let cwdDirs;
35
+ try {
36
+ cwdDirs = await readdir(this.sessionsRoot);
37
+ }
38
+ catch {
39
+ return { sessions: [], observedAt: new Date(observedAt).toISOString(), liveCount: 0 };
40
+ }
41
+ for (const cwdDir of cwdDirs) {
42
+ if (!cwdDir.startsWith("--"))
43
+ continue; // 只处理 --cwd-- 格式
44
+ const cwdPath = join(this.sessionsRoot, cwdDir);
45
+ const cwdName = decodeCwdDir(cwdDir);
46
+ let files;
47
+ try {
48
+ files = await readdir(cwdPath);
49
+ }
50
+ catch {
51
+ continue;
52
+ }
53
+ const jsonlFiles = files.filter((f) => f.endsWith(".jsonl"));
54
+ // 按修改时间取最新 maxPerCwd 个
55
+ const withMtime = [];
56
+ for (const f of jsonlFiles) {
57
+ try {
58
+ const s = await stat(join(cwdPath, f));
59
+ withMtime.push({ file: f, mtime: s.mtimeMs });
60
+ }
61
+ catch {
62
+ // ignore
63
+ }
64
+ }
65
+ withMtime.sort((a, b) => b.mtime - a.mtime);
66
+ const top = withMtime.slice(0, this.maxPerCwd);
67
+ for (const { file, mtime } of top) {
68
+ const fullPath = join(cwdPath, file);
69
+ const info = await this.readSessionInfo(fullPath, cwdName, mtime);
70
+ if (info)
71
+ sessions.push(info);
72
+ }
73
+ }
74
+ sessions.sort((a, b) => b.updatedAt - a.updatedAt);
75
+ const liveCount = sessions.filter((s) => s.live).length;
76
+ return { sessions, observedAt: new Date(observedAt).toISOString(), liveCount };
77
+ }
78
+ /** 条目数 = 非空行数;mtime 未变时用缓存,变化时流式重扫并更新缓存 */
79
+ async countEntries(path, handle, mtimeMs) {
80
+ const cached = this.lineCountCache.get(path);
81
+ if (cached && cached.mtimeMs === mtimeMs)
82
+ return cached.count;
83
+ try {
84
+ const count = await countLinesStreamed(handle);
85
+ this.lineCountCache.set(path, { mtimeMs, count });
86
+ return count;
87
+ }
88
+ catch {
89
+ return cached?.count ?? 0;
90
+ }
91
+ }
92
+ /** 解析单个会话文件(只读头部 + 行数),标记是否活跃 */
93
+ async readSessionInfo(path, cwdNameFromDir, mtimeMs) {
94
+ try {
95
+ // 读前几行解析 sessionId、cwd 和 firstMessage
96
+ const handle = await import("node:fs/promises").then((m) => m.open(path, "r"));
97
+ try {
98
+ const headBuf = Buffer.alloc(64 * 1024);
99
+ const { bytesRead } = await handle.read(headBuf, 0, headBuf.length, 0);
100
+ const head = headBuf.subarray(0, bytesRead).toString("utf8");
101
+ // sessionId 从文件名取(Pi 格式: <ts>_<uuid>.jsonl)
102
+ const fileName = basename(path, ".jsonl");
103
+ const txid = fileName.match(/_([0-9a-f-]{36})$/i)?.[1];
104
+ const sessionId = txid ?? fileName;
105
+ // cwd 优先从首行 session 记录的 cwd 字段取(目录名有 - 转义歧义)
106
+ const cwd = extractCwdFromHeader(head) ?? cwdNameFromDir;
107
+ const firstMessage = extractFirstMessage(head);
108
+ const entryCount = await this.countEntries(path, handle, mtimeMs);
109
+ const age = this.now() - mtimeMs;
110
+ return {
111
+ sessionId,
112
+ cwdName: cwd,
113
+ path,
114
+ firstMessage,
115
+ entryCount,
116
+ messageCount: entryCount, // 近似
117
+ updatedAt: mtimeMs,
118
+ live: age < this.liveThresholdMs,
119
+ liveAgeMs: Math.max(0, age),
120
+ };
121
+ }
122
+ finally {
123
+ await handle.close();
124
+ }
125
+ }
126
+ catch {
127
+ return undefined;
128
+ }
129
+ }
130
+ }
131
+ /** 从首行 session JSON 提取 cwd(精确路径,无转义歧义) */
132
+ function extractCwdFromHeader(head) {
133
+ const line = head.split("\n")[0];
134
+ if (!line)
135
+ return undefined;
136
+ try {
137
+ const parsed = JSON.parse(line);
138
+ return typeof parsed.cwd === "string" && parsed.cwd.length > 0 ? parsed.cwd : undefined;
139
+ }
140
+ catch {
141
+ return undefined;
142
+ }
143
+ }
144
+ /** 将 --Users-isulewli-Projects-foo-- 解码为 /Users/isulewli/Projects/foo(绝对路径) */
145
+ function decodeCwdDir(dir) {
146
+ const inner = dir.replace(/^--/, "").replace(/--$/, "");
147
+ return `/${inner.replace(/-/g, "/")}`;
148
+ }
149
+ /** 从首行 JSONL 提取第一条消息文本 */
150
+ function extractFirstMessage(head) {
151
+ const line = head.split("\n")[0];
152
+ if (!line)
153
+ return "";
154
+ try {
155
+ const parsed = JSON.parse(line);
156
+ if (typeof parsed.text === "string" && parsed.text.trim())
157
+ return parsed.text.slice(0, 120);
158
+ // 尝试 content 数组
159
+ if (Array.isArray(parsed.content)) {
160
+ const texts = parsed.content
161
+ .map((c) => (c && typeof c === "object" && "text" in c ? String(c.text) : ""))
162
+ .filter(Boolean);
163
+ if (texts.length > 0)
164
+ return texts.join(" ").slice(0, 120);
165
+ }
166
+ return "";
167
+ }
168
+ catch {
169
+ return "";
170
+ }
171
+ }
172
+ /**
173
+ * P2-6:流式分块统计非空行数(等价于整读 split("\n") 的结果,但内存恒定),
174
+ * 并按 mtime 缓存 —— 文件未变化时直接复用上次计数,轮询时不再整读大文件。
175
+ */
176
+ const COUNT_CHUNK_BYTES = 512 * 1024;
177
+ async function countLinesStreamed(handle) {
178
+ const { size } = await handle.stat();
179
+ let count = 0;
180
+ let carry = ""; // 块边界的残行,拼入下一块后再按行处理
181
+ let pos = 0;
182
+ while (pos < size) {
183
+ const readLen = Math.min(COUNT_CHUNK_BYTES, size - pos);
184
+ const chunk = Buffer.alloc(readLen);
185
+ await handle.read(chunk, 0, readLen, pos);
186
+ pos += readLen;
187
+ const text = carry + chunk.toString("utf8");
188
+ const lines = text.split("\n");
189
+ // 最后一段可能是残行(后面还有块),留到下一轮;末块时一并处理
190
+ carry = pos < size ? (lines.pop() ?? "") : (lines.pop() ?? "");
191
+ for (const line of lines) {
192
+ if (line.trim().length > 0)
193
+ count++;
194
+ }
195
+ }
196
+ if (carry.trim().length > 0)
197
+ count++; // 无换行结尾的残行
198
+ return count;
199
+ }
200
+ export { decodeCwdDir };
201
+ //# sourceMappingURL=live-sessions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live-sessions.js","sourceRoot":"","sources":["../src/live-sessions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ export interface SettingsNode {
2
+ key: string;
3
+ label: string;
4
+ path: string;
5
+ /** 浅层 JSON 快照(供展示);敏感文件恒为 {} */
6
+ data: Record<string, unknown>;
7
+ /** 敏感文件(auth/api-manager 等)已脱敏:仅返回存在性与顶层 keys,无任何值 */
8
+ redacted?: boolean;
9
+ /** 敏感文件时返回顶层 key 列表 */
10
+ topLevelKeys?: string[];
11
+ }
12
+ export interface SettingsOverview {
13
+ files: SettingsNode[];
14
+ observedAt: string;
15
+ }
16
+ /** 可安全写入的字段(白名单,防破坏 maestro 运行时状态) */
17
+ declare const WRITABLE_DEFAULTS: readonly ["defaultModel", "defaultProvider", "defaultThinkingLevel", "theme", "hideThinkingBlock"];
18
+ declare const FILES: {
19
+ key: string;
20
+ label: string;
21
+ path: string;
22
+ sub?: string;
23
+ }[];
24
+ /** 读取所有设置文件的浅层快照 */
25
+ export declare function readSettingsOverview(): Promise<SettingsOverview>;
26
+ /** 读取单个设置文件 */
27
+ export declare function readSettingsFile(key: string): Promise<{
28
+ path: string;
29
+ data: Record<string, unknown>;
30
+ } | undefined>;
31
+ /**
32
+ * 安全更新 settings.json 的白名单字段。
33
+ * 写前备份(.bak-<ts>),避免破坏 maestro 运行时配置。
34
+ */
35
+ export declare function updateSettingsJson(patch: Record<string, unknown>): Promise<{
36
+ ok: boolean;
37
+ error?: string;
38
+ }>;
39
+ export { WRITABLE_DEFAULTS, FILES };
40
+ //# sourceMappingURL=maestro-settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"maestro-settings.d.ts","sourceRoot":"","sources":["../src/maestro-settings.ts"],"names":[],"mappings":"AAqBA,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,sDAAsD;IACtD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uBAAuB;IACvB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,sCAAsC;AACtC,QAAA,MAAM,iBAAiB,oGAAqG,CAAC;AAE7H,QAAA,MAAM,KAAK,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,EAWtE,CAAC;AAOF,oBAAoB;AACpB,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAuBtE;AAED,eAAe;AACf,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG,SAAS,CAAC,CASxH;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAmCjH;AAED,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * MaestroSettingsService — 读写 pi-maestro-flow 的配置 JSON 文件(只读安全窗口 + 谨慎写)
3
+ *
4
+ * 覆盖 pi-maestro-flow /maestro-settings /api-manager 持久化的文件:
5
+ * - ~/.pi/agent/settings.json (默认模型/主题/重试/包等)
6
+ * - ~/.pi/agent/models.json (模型定义)
7
+ * - ~/.pi/agent/api-manager.json (api manager:managedProviders/nextSuggest 等)
8
+ * - ~/.pi/agent/mcp.json (MCP 服务器)
9
+ * - ~/.pi/agent/keybindings.json (键位,只读展示)
10
+ * - ~/.pi/maestro-chinese-response-mode.json
11
+ *
12
+ * 写安全:只更新白名单字段(defaultModel/defaultProvider/defaultThinkingLevel/theme),
13
+ * 完整写回前备份。
14
+ */
15
+ import { readFile, writeFile, copyFile } from "node:fs/promises";
16
+ import { join } from "node:path";
17
+ import { homedir } from "node:os";
18
+ const AGENT_DIR = join(homedir(), ".pi", "agent");
19
+ const MAESTRO_DIR = join(homedir(), ".pi");
20
+ /** 可安全写入的字段(白名单,防破坏 maestro 运行时状态) */
21
+ const WRITABLE_DEFAULTS = ["defaultModel", "defaultProvider", "defaultThinkingLevel", "theme", "hideThinkingBlock"];
22
+ const FILES = [
23
+ { key: "settings", label: "Maestro 设置", path: join(AGENT_DIR, "settings.json") },
24
+ { key: "models", label: "模型", path: join(AGENT_DIR, "models.json") },
25
+ { key: "api-manager", label: "API 管理", path: join(AGENT_DIR, "api-manager.json") },
26
+ { key: "mcp", label: "MCP 服务器", path: join(AGENT_DIR, "mcp.json") },
27
+ { key: "auth", label: "认证", path: join(AGENT_DIR, "auth.json") },
28
+ { key: "keybindings", label: "快捷键", path: join(AGENT_DIR, "keybindings.json") },
29
+ { key: "cockpit", label: "Cockpit", path: join(AGENT_DIR, "cockpit.json") },
30
+ { key: "maestro-ui", label: "Maestro UI", path: join(AGENT_DIR, "maestro-ui.json") },
31
+ { key: "lsp", label: "LSP", path: join(AGENT_DIR, "lsp.json") },
32
+ { key: "chinese-mode", label: "中文回复模式", path: join(MAESTRO_DIR, "maestro-chinese-response-mode.json") },
33
+ ];
34
+ /**
35
+ * 敏感文件(P1-4):含 API 密钥的文件只返回存在性与顶层 keys,值永不离开宿主机。
36
+ */
37
+ const SENSITIVE_FILE_KEYS = new Set(["auth", "api-manager"]);
38
+ /** 读取所有设置文件的浅层快照 */
39
+ export async function readSettingsOverview() {
40
+ const files = [];
41
+ for (const f of FILES) {
42
+ try {
43
+ const raw = await readFile(f.path, "utf8");
44
+ const parsed = JSON.parse(raw);
45
+ if (SENSITIVE_FILE_KEYS.has(f.key)) {
46
+ files.push({
47
+ key: f.key,
48
+ label: f.label,
49
+ path: f.path,
50
+ data: {},
51
+ redacted: true,
52
+ topLevelKeys: Object.keys(parsed),
53
+ });
54
+ }
55
+ else {
56
+ files.push({ key: f.key, label: f.label, path: f.path, data: parsed });
57
+ }
58
+ }
59
+ catch {
60
+ // 文件不存在或不可解析 → 跳过
61
+ }
62
+ }
63
+ return { files, observedAt: new Date().toISOString() };
64
+ }
65
+ /** 读取单个设置文件 */
66
+ export async function readSettingsFile(key) {
67
+ const f = FILES.find((x) => x.key === key);
68
+ if (!f)
69
+ return undefined;
70
+ try {
71
+ const raw = await readFile(f.path, "utf8");
72
+ return { path: f.path, data: JSON.parse(raw) };
73
+ }
74
+ catch {
75
+ return undefined;
76
+ }
77
+ }
78
+ /**
79
+ * 安全更新 settings.json 的白名单字段。
80
+ * 写前备份(.bak-<ts>),避免破坏 maestro 运行时配置。
81
+ */
82
+ export async function updateSettingsJson(patch) {
83
+ const path = join(AGENT_DIR, "settings.json");
84
+ let current;
85
+ try {
86
+ current = JSON.parse(await readFile(path, "utf8"));
87
+ }
88
+ catch (e) {
89
+ return { ok: false, error: `读取 settings.json 失败: ${e instanceof Error ? e.message : String(e)}` };
90
+ }
91
+ // 只允许白名单字段
92
+ const allowed = new Set(WRITABLE_DEFAULTS);
93
+ const clean = {};
94
+ for (const [k, v] of Object.entries(patch)) {
95
+ if (!allowed.has(k))
96
+ continue;
97
+ if (typeof v === "string" && v.trim())
98
+ clean[k] = v.trim();
99
+ if (typeof v === "boolean")
100
+ clean[k] = v;
101
+ }
102
+ if (Object.keys(clean).length === 0) {
103
+ return { ok: false, error: "没有可写的白名单字段" };
104
+ }
105
+ // 备份
106
+ try {
107
+ await copyFile(path, `${path}.bak-${Date.now()}`);
108
+ }
109
+ catch {
110
+ // 备份失败不阻塞(尽力而为)
111
+ }
112
+ const next = { ...current, ...clean };
113
+ try {
114
+ await writeFile(path, JSON.stringify(next, null, 2), "utf8");
115
+ return { ok: true };
116
+ }
117
+ catch (e) {
118
+ return { ok: false, error: e instanceof Error ? e.message : String(e) };
119
+ }
120
+ }
121
+ export { WRITABLE_DEFAULTS, FILES };
122
+ //# sourceMappingURL=maestro-settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"maestro-settings.js","sourceRoot":"","sources":["../src/maestro-settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAU,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AAClD,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;AAmB3C,sCAAsC;AACtC,MAAM,iBAAiB,GAAG,CAAC,cAAc,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,OAAO,EAAE,mBAAmB,CAAU,CAAC;AAE7H,MAAM,KAAK,GAAiE;IAC1E,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,EAAE;IAChF,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,EAAE;IACpE,EAAE,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,kBAAkB,CAAC,EAAE;IAClF,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE;IACnE,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE;IAChE,EAAE,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,kBAAkB,CAAC,EAAE;IAC/E,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,EAAE;IAC3E,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE;IACpF,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE;IAC/D,EAAE,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,oCAAoC,CAAC,EAAE;CACxG,CAAC;AAEF;;GAEG;AACH,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;AAE7D,oBAAoB;AACpB,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,MAAM,KAAK,GAAmB,EAAE,CAAC;IACjC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAC;YAC1D,IAAI,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;gBACnC,KAAK,CAAC,IAAI,CAAC;oBACT,GAAG,EAAE,CAAC,CAAC,GAAG;oBACV,KAAK,EAAE,CAAC,CAAC,KAAK;oBACd,IAAI,EAAE,CAAC,CAAC,IAAI;oBACZ,IAAI,EAAE,EAAE;oBACR,QAAQ,EAAE,IAAI;oBACd,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;iBAClC,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YACzE,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,kBAAkB;QACpB,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;AACzD,CAAC;AAED,eAAe;AACf,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,GAAW;IAChD,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;IAC3C,IAAI,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACzB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC3C,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,EAAE,CAAC;IAC5E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,KAA8B;IACrE,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IAC9C,IAAI,OAAgC,CAAC;IACrC,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAA4B,CAAC;IAChF,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,wBAAwB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACpG,CAAC;IAED,WAAW;IACX,MAAM,OAAO,GAAG,IAAI,GAAG,CAAS,iBAAiB,CAAC,CAAC;IACnD,MAAM,KAAK,GAA4B,EAAE,CAAC;IAC1C,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,SAAS;QAC9B,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,EAAE;YAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3D,IAAI,OAAO,CAAC,KAAK,SAAS;YAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC3C,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC;IAC5C,CAAC;IAED,KAAK;IACL,IAAI,CAAC;QACH,MAAM,QAAQ,CAAC,IAAI,EAAE,GAAG,IAAI,QAAQ,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,gBAAgB;IAClB,CAAC;IAED,MAAM,IAAI,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC;IACtC,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QAC7D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1E,CAAC;AACH,CAAC;AAED,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC"}
@@ -0,0 +1,31 @@
1
+ import type { MaestroState } from "./vendor/shared/index.js";
2
+ export interface MaestroReaderOptions {
3
+ /** 项目根路径,默认 process.cwd() */
4
+ projectRoot?: string;
5
+ /** 轮询间隔 ms,默认 5000 */
6
+ pollIntervalMs?: number;
7
+ }
8
+ export declare class MaestroStateReader {
9
+ private readonly projectRoot;
10
+ private readonly schedulesDir;
11
+ private readonly dispatchesDir;
12
+ private lastReadAt;
13
+ private lastStateJson;
14
+ constructor(options?: MaestroReaderOptions);
15
+ get root(): string;
16
+ /** 检测 flow-schedule 目录是否存在(判断是否安装了 pi-maestro-flow) */
17
+ detectMaestro(): Promise<boolean>;
18
+ /** 读取所有活跃的调度快照(带变更检测:状态未变时返回 null)
19
+ * 只比较 schedules 内容,observedAt 每次不同不参与变更检测 */
20
+ readStateChanged(): Promise<MaestroState | null>;
21
+ /** 重置变更检测缓存(会话切换/重连时调用) */
22
+ resetChangeDetection(): void;
23
+ /** 读取所有活跃的调度快照 */
24
+ readState(): Promise<MaestroState>;
25
+ private readAllSchedules;
26
+ private readSchedule;
27
+ private readDispatches;
28
+ private readDispatch;
29
+ private normalizeScheduleState;
30
+ }
31
+ //# sourceMappingURL=maestro-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"maestro-state.d.ts","sourceRoot":"","sources":["../src/maestro-state.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAMV,YAAY,EACb,MAAM,0BAA0B,CAAC;AAOlC,MAAM,WAAW,oBAAoB;IACnC,6BAA6B;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sBAAsB;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,aAAa,CAAqB;gBAE9B,OAAO,GAAE,oBAAyB;IAM9C,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,uDAAuD;IACjD,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC;IAUvC;kDAC8C;IACxC,gBAAgB,IAAI,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAUtD,2BAA2B;IAC3B,oBAAoB,IAAI,IAAI;IAI5B,kBAAkB;IACZ,SAAS,IAAI,OAAO,CAAC,YAAY,CAAC;YAQ1B,gBAAgB;YAkBhB,YAAY;YAwDZ,cAAc;YASd,YAAY;IAiE1B,OAAO,CAAC,sBAAsB;CAa/B"}