pi-maestro-mobile 0.3.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -11
- package/dist/application/application-command-router.d.ts +90 -0
- package/dist/application/application-command-router.d.ts.map +1 -0
- package/dist/application/application-command-router.js +58 -0
- package/dist/application/application-command-router.js.map +1 -0
- package/dist/application/monitor-query-service.d.ts +9 -0
- package/dist/application/monitor-query-service.d.ts.map +1 -0
- package/dist/application/monitor-query-service.js +13 -0
- package/dist/application/monitor-query-service.js.map +1 -0
- package/dist/application/monitor-read-service.d.ts +21 -0
- package/dist/application/monitor-read-service.d.ts.map +1 -0
- package/dist/application/monitor-read-service.js +47 -0
- package/dist/application/monitor-read-service.js.map +1 -0
- package/dist/application/session-command-service.d.ts +33 -0
- package/dist/application/session-command-service.d.ts.map +1 -0
- package/dist/application/session-command-service.js +80 -0
- package/dist/application/session-command-service.js.map +1 -0
- package/dist/application/session-query-service.d.ts +47 -0
- package/dist/application/session-query-service.d.ts.map +1 -0
- package/dist/application/session-query-service.js +373 -0
- package/dist/application/session-query-service.js.map +1 -0
- package/dist/application/session-visibility.d.ts +11 -0
- package/dist/application/session-visibility.d.ts.map +1 -0
- package/dist/application/session-visibility.js +32 -0
- package/dist/application/session-visibility.js.map +1 -0
- package/dist/broker-cli.d.ts +3 -0
- package/dist/broker-cli.d.ts.map +1 -0
- package/dist/broker-cli.js +79 -0
- package/dist/broker-cli.js.map +1 -0
- package/dist/cli.js +52 -6
- package/dist/cli.js.map +1 -1
- package/dist/control/SessionDirectory.d.ts +52 -0
- package/dist/control/SessionDirectory.d.ts.map +1 -0
- package/dist/control/SessionDirectory.js +235 -0
- package/dist/control/SessionDirectory.js.map +1 -0
- package/dist/control/desktop-control-gateway.d.ts +27 -0
- package/dist/control/desktop-control-gateway.d.ts.map +1 -0
- package/dist/control/desktop-control-gateway.js +150 -0
- package/dist/control/desktop-control-gateway.js.map +1 -0
- package/dist/control/idempotency-ledger.d.ts +28 -0
- package/dist/control/idempotency-ledger.d.ts.map +1 -0
- package/dist/control/idempotency-ledger.js +53 -0
- package/dist/control/idempotency-ledger.js.map +1 -0
- package/dist/current-desktop-status.d.ts +37 -0
- package/dist/current-desktop-status.d.ts.map +1 -0
- package/dist/current-desktop-status.js +75 -0
- package/dist/current-desktop-status.js.map +1 -0
- package/dist/event-log.d.ts +3 -1
- package/dist/event-log.d.ts.map +1 -1
- package/dist/event-log.js +16 -6
- package/dist/event-log.js.map +1 -1
- package/dist/extension.d.ts +9 -0
- package/dist/extension.d.ts.map +1 -1
- package/dist/extension.js +119 -19
- package/dist/extension.js.map +1 -1
- package/dist/host-controller.d.ts +85 -13
- package/dist/host-controller.d.ts.map +1 -1
- package/dist/host-controller.js +607 -33
- package/dist/host-controller.js.map +1 -1
- package/dist/jsonl-pager.d.ts +1 -0
- package/dist/jsonl-pager.d.ts.map +1 -1
- package/dist/jsonl-pager.js +56 -8
- package/dist/jsonl-pager.js.map +1 -1
- package/dist/jsonl-tail-watcher.d.ts +9 -1
- package/dist/jsonl-tail-watcher.d.ts.map +1 -1
- package/dist/jsonl-tail-watcher.js +77 -13
- package/dist/jsonl-tail-watcher.js.map +1 -1
- package/dist/monitor-projection.d.ts +17 -6
- package/dist/monitor-projection.d.ts.map +1 -1
- package/dist/monitor-projection.js +163 -14
- package/dist/monitor-projection.js.map +1 -1
- package/dist/pi/pi-sdk-runtime.d.ts +2 -0
- package/dist/pi/pi-sdk-runtime.d.ts.map +1 -1
- package/dist/pi/pi-sdk-runtime.js +5 -1
- package/dist/pi/pi-sdk-runtime.js.map +1 -1
- package/dist/plugin/ask-response-file.d.ts +4 -0
- package/dist/plugin/ask-response-file.d.ts.map +1 -0
- package/dist/plugin/ask-response-file.js +30 -0
- package/dist/plugin/ask-response-file.js.map +1 -0
- package/dist/plugin/desktop-broker-host-ipc.d.ts +91 -0
- package/dist/plugin/desktop-broker-host-ipc.d.ts.map +1 -0
- package/dist/plugin/desktop-broker-host-ipc.js +529 -0
- package/dist/plugin/desktop-broker-host-ipc.js.map +1 -0
- package/dist/plugin/desktop-broker-supervisor.d.ts +42 -0
- package/dist/plugin/desktop-broker-supervisor.d.ts.map +1 -0
- package/dist/plugin/desktop-broker-supervisor.js +394 -0
- package/dist/plugin/desktop-broker-supervisor.js.map +1 -0
- package/dist/plugin/desktop-broker.d.ts +62 -0
- package/dist/plugin/desktop-broker.d.ts.map +1 -0
- package/dist/plugin/desktop-broker.js +407 -0
- package/dist/plugin/desktop-broker.js.map +1 -0
- package/dist/plugin/desktop-flow-ask-adapter.d.ts +38 -0
- package/dist/plugin/desktop-flow-ask-adapter.d.ts.map +1 -0
- package/dist/plugin/desktop-flow-ask-adapter.js +155 -0
- package/dist/plugin/desktop-flow-ask-adapter.js.map +1 -0
- package/dist/plugin/desktop-pi-session-adapter.d.ts +45 -0
- package/dist/plugin/desktop-pi-session-adapter.d.ts.map +1 -0
- package/dist/plugin/desktop-pi-session-adapter.js +128 -0
- package/dist/plugin/desktop-pi-session-adapter.js.map +1 -0
- package/dist/plugin/desktop-plugin-extension.d.ts +12 -0
- package/dist/plugin/desktop-plugin-extension.d.ts.map +1 -0
- package/dist/plugin/desktop-plugin-extension.js +424 -0
- package/dist/plugin/desktop-plugin-extension.js.map +1 -0
- package/dist/plugin/desktop-plugin-ipc.d.ts +104 -0
- package/dist/plugin/desktop-plugin-ipc.d.ts.map +1 -0
- package/dist/plugin/desktop-plugin-ipc.js +610 -0
- package/dist/plugin/desktop-plugin-ipc.js.map +1 -0
- package/dist/plugin/desktop-plugin-registry-store.d.ts +31 -0
- package/dist/plugin/desktop-plugin-registry-store.d.ts.map +1 -0
- package/dist/plugin/desktop-plugin-registry-store.js +79 -0
- package/dist/plugin/desktop-plugin-registry-store.js.map +1 -0
- package/dist/plugin/desktop-plugin-registry.d.ts +58 -0
- package/dist/plugin/desktop-plugin-registry.d.ts.map +1 -0
- package/dist/plugin/desktop-plugin-registry.js +164 -0
- package/dist/plugin/desktop-plugin-registry.js.map +1 -0
- package/dist/plugin/desktop-plugin-runtime-state.d.ts +20 -0
- package/dist/plugin/desktop-plugin-runtime-state.d.ts.map +1 -0
- package/dist/plugin/desktop-plugin-runtime-state.js +41 -0
- package/dist/plugin/desktop-plugin-runtime-state.js.map +1 -0
- package/dist/server/helpers.d.ts.map +1 -1
- package/dist/server/helpers.js +3 -0
- package/dist/server/helpers.js.map +1 -1
- package/dist/server/mobile-host-server.d.ts +20 -1
- package/dist/server/mobile-host-server.d.ts.map +1 -1
- package/dist/server/mobile-host-server.js +361 -326
- package/dist/server/mobile-host-server.js.map +1 -1
- package/dist/session-runner.d.ts +4 -2
- package/dist/session-runner.d.ts.map +1 -1
- package/dist/session-runner.js +120 -29
- package/dist/session-runner.js.map +1 -1
- package/dist/types.d.ts +6 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/vendor/shared/desktop-broker-protocol.d.ts +131 -0
- package/dist/vendor/shared/desktop-broker-protocol.d.ts.map +1 -0
- package/dist/vendor/shared/desktop-broker-protocol.js +158 -0
- package/dist/vendor/shared/desktop-broker-protocol.js.map +1 -0
- package/dist/vendor/shared/desktop-plugin-protocol.d.ts +167 -0
- package/dist/vendor/shared/desktop-plugin-protocol.d.ts.map +1 -0
- package/dist/vendor/shared/desktop-plugin-protocol.js +144 -0
- package/dist/vendor/shared/desktop-plugin-protocol.js.map +1 -0
- package/dist/vendor/shared/index.d.ts +4 -1
- package/dist/vendor/shared/index.d.ts.map +1 -1
- package/dist/vendor/shared/index.js +4 -1
- package/dist/vendor/shared/index.js.map +1 -1
- package/dist/vendor/shared/protocol.d.ts +234 -61
- package/dist/vendor/shared/protocol.d.ts.map +1 -1
- package/dist/vendor/shared/protocol.js +216 -14
- package/dist/vendor/shared/protocol.js.map +1 -1
- package/dist/vendor/shared/release.d.ts +11 -0
- package/dist/vendor/shared/release.d.ts.map +1 -0
- package/dist/vendor/shared/release.js +12 -0
- package/dist/vendor/shared/release.js.map +1 -0
- package/dist/vendor/shared/validation.d.ts +9 -2
- package/dist/vendor/shared/validation.d.ts.map +1 -1
- package/dist/vendor/shared/validation.js +48 -12
- package/dist/vendor/shared/validation.js.map +1 -1
- package/dist/version-detector.d.ts +1 -1
- package/dist/version-detector.d.ts.map +1 -1
- package/dist/version-detector.js +3 -3
- package/dist/version-detector.js.map +1 -1
- package/dist/workspace-telemetry.d.ts.map +1 -1
- package/dist/workspace-telemetry.js +5 -0
- package/dist/workspace-telemetry.js.map +1 -1
- package/package.json +5 -3
- package/dist/live-sessions.d.ts +0 -47
- package/dist/live-sessions.d.ts.map +0 -1
- package/dist/live-sessions.js +0 -218
- package/dist/live-sessions.js.map +0 -1
- package/dist/workspace-peer-injector.d.ts +0 -19
- package/dist/workspace-peer-injector.d.ts.map +0 -1
- package/dist/workspace-peer-injector.js +0 -63
- package/dist/workspace-peer-injector.js.map +0 -1
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
import { normalize } from "node:path";
|
|
2
|
+
import { replayPageBeforeJsonl, replayTailFromJsonl } from "../jsonl-pager.js";
|
|
3
|
+
function asIso(value) {
|
|
4
|
+
const date = new Date(String(value ?? ""));
|
|
5
|
+
return Number.isFinite(date.getTime()) ? date.toISOString() : new Date(0).toISOString();
|
|
6
|
+
}
|
|
7
|
+
function summaryOf(record) {
|
|
8
|
+
const cwd = typeof record.cwd === "string" ? record.cwd : "";
|
|
9
|
+
const title = String(record.firstMessage ?? record.title ?? "");
|
|
10
|
+
return {
|
|
11
|
+
id: String(record.id ?? ""),
|
|
12
|
+
sessionId: String(record.id ?? ""),
|
|
13
|
+
endpointId: "history",
|
|
14
|
+
runtimeStatus: "history",
|
|
15
|
+
cwd,
|
|
16
|
+
cwdName: cwd.split("/").filter(Boolean).at(-1) ?? cwd,
|
|
17
|
+
path: String(record.path ?? record.sessionFile ?? ""),
|
|
18
|
+
title: title.length > 80 ? `${title.slice(0, 80)}…` : title,
|
|
19
|
+
...(typeof record.name === "string" && record.name ? { name: record.name } : {}),
|
|
20
|
+
...(typeof record.model === "string" ? { model: record.model } : {}),
|
|
21
|
+
messageCount: typeof record.messageCount === "number" ? record.messageCount : 0,
|
|
22
|
+
updatedAt: asIso(record.modified ?? record.updatedAt),
|
|
23
|
+
...(record.created || record.createdAt ? { createdAt: asIso(record.created ?? record.createdAt) } : {}),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function targetIdentityKey(identity) {
|
|
27
|
+
return JSON.stringify([identity.sessionId, identity.endpointId, identity.normalizedCwd, identity.processGeneration]);
|
|
28
|
+
}
|
|
29
|
+
function listKey(session) {
|
|
30
|
+
return session.targetKey ?? session.id;
|
|
31
|
+
}
|
|
32
|
+
function cursorFor(session) {
|
|
33
|
+
return Buffer.from(JSON.stringify({ updatedAt: session.updatedAt, id: listKey(session) }), "utf8").toString("base64url");
|
|
34
|
+
}
|
|
35
|
+
function readCursor(cursor) {
|
|
36
|
+
try {
|
|
37
|
+
const parsed = JSON.parse(Buffer.from(cursor, "base64url").toString("utf8"));
|
|
38
|
+
if (typeof parsed.updatedAt !== "string" || typeof parsed.id !== "string")
|
|
39
|
+
throw new Error("invalid cursor");
|
|
40
|
+
return { updatedAt: parsed.updatedAt, id: parsed.id };
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
throw new Error("invalid cursor");
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function readonlyPresentation(revision) {
|
|
47
|
+
return {
|
|
48
|
+
role: "session",
|
|
49
|
+
visibility: "session_list",
|
|
50
|
+
control: {
|
|
51
|
+
mode: "readonly",
|
|
52
|
+
canPrompt: false,
|
|
53
|
+
canSteer: false,
|
|
54
|
+
canFollowUp: false,
|
|
55
|
+
canAbort: false,
|
|
56
|
+
canAnswerAsk: false,
|
|
57
|
+
},
|
|
58
|
+
revision,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/** 已注册的 Desktop socket 即使尚未附着 Host reader,也属于活跃目标。 */
|
|
62
|
+
function runtimeStatusForTarget(target) {
|
|
63
|
+
if (target.kind === "desktop")
|
|
64
|
+
return target.runtimeStatus ?? "idle";
|
|
65
|
+
const runState = target.runner?.state.runState;
|
|
66
|
+
if (!runState)
|
|
67
|
+
return "history";
|
|
68
|
+
return runState === "idle" || runState === "error" ? "idle" : "running";
|
|
69
|
+
}
|
|
70
|
+
function presentationForTarget(target, revision, sourcePresentation) {
|
|
71
|
+
const targetPresentation = target.presentation ?? readonlyPresentation(revision);
|
|
72
|
+
if (!sourcePresentation)
|
|
73
|
+
return targetPresentation;
|
|
74
|
+
return {
|
|
75
|
+
...targetPresentation,
|
|
76
|
+
...sourcePresentation,
|
|
77
|
+
control: targetPresentation.control,
|
|
78
|
+
revision: Math.max(targetPresentation.revision, sourcePresentation.revision),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function summaryForTarget(target, revision, observedAt, base, sourcePresentation) {
|
|
82
|
+
const cwd = target.identity.normalizedCwd;
|
|
83
|
+
const cwdName = cwd.split("/").filter(Boolean).at(-1) ?? cwd;
|
|
84
|
+
const runnerState = target.runner?.state;
|
|
85
|
+
return {
|
|
86
|
+
...base,
|
|
87
|
+
id: target.identity.sessionId,
|
|
88
|
+
sessionId: target.identity.sessionId,
|
|
89
|
+
endpointId: target.identity.endpointId,
|
|
90
|
+
target: { ...target.identity },
|
|
91
|
+
targetKey: targetIdentityKey(target.identity),
|
|
92
|
+
runtimeStatus: runtimeStatusForTarget(target),
|
|
93
|
+
cwd,
|
|
94
|
+
cwdName,
|
|
95
|
+
path: target.sessionFile ?? base?.path ?? runnerState?.sessionFile ?? "",
|
|
96
|
+
title: base?.title || runnerState?.title || cwdName || target.identity.sessionId,
|
|
97
|
+
messageCount: target.messageCount ?? runnerState?.messageCount ?? base?.messageCount ?? 0,
|
|
98
|
+
updatedAt: target.lastActivityAt ?? runnerState?.updatedAt ?? base?.updatedAt ?? observedAt,
|
|
99
|
+
presentation: presentationForTarget(target, revision, sourcePresentation),
|
|
100
|
+
...(target.activeSince ? { activeSince: target.activeSince } : {}),
|
|
101
|
+
...(target.lastActivityAt ? { lastActivityAt: target.lastActivityAt } : {}),
|
|
102
|
+
...(target.summaryRevision !== undefined ? { summaryRevision: target.summaryRevision } : {}),
|
|
103
|
+
...(target.usage ? { usage: target.usage, totalTokens: target.usage.totalTokens, cost: target.usage.cost } : {}),
|
|
104
|
+
...(target.context !== undefined ? { context: target.context } : {}),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
export class SessionQueryService {
|
|
108
|
+
source;
|
|
109
|
+
directory;
|
|
110
|
+
presentationFor;
|
|
111
|
+
now;
|
|
112
|
+
monitorState;
|
|
113
|
+
targetFor;
|
|
114
|
+
desktopHistory = new Map();
|
|
115
|
+
constructor(source, directory, presentationFor, now = Date.now, monitorState, targetFor) {
|
|
116
|
+
this.source = source;
|
|
117
|
+
this.directory = directory;
|
|
118
|
+
this.presentationFor = presentationFor;
|
|
119
|
+
this.now = now;
|
|
120
|
+
this.monitorState = monitorState;
|
|
121
|
+
this.targetFor = targetFor;
|
|
122
|
+
}
|
|
123
|
+
async list(options = {}) {
|
|
124
|
+
const targeted = options.sessionIds !== undefined || options.latestForCwds !== undefined;
|
|
125
|
+
for (const values of [options.sessionIds, options.latestForCwds]) {
|
|
126
|
+
if (values && values.length > 100)
|
|
127
|
+
throw new Error("targeted filters accept at most 100 values");
|
|
128
|
+
if (values?.some((value) => typeof value !== "string" || value.length === 0))
|
|
129
|
+
throw new Error("targeted filters require non-empty strings");
|
|
130
|
+
}
|
|
131
|
+
if (targeted && (options.limit !== undefined || options.cursor !== undefined || options.query !== undefined || options.cwd !== undefined)) {
|
|
132
|
+
throw new Error("targeted session lookup cannot be combined with paging or search filters");
|
|
133
|
+
}
|
|
134
|
+
if (options.cursor && options.limit === undefined)
|
|
135
|
+
throw new Error("cursor requires limit");
|
|
136
|
+
if (options.limit !== undefined && (!Number.isInteger(options.limit) || options.limit < 1 || options.limit > 100)) {
|
|
137
|
+
throw new Error("limit must be between 1 and 100");
|
|
138
|
+
}
|
|
139
|
+
const projectCwds = options.projectCwds?.map((cwd) => normalize(cwd.trim())).filter(Boolean);
|
|
140
|
+
const query = options.query?.trim().toLocaleLowerCase();
|
|
141
|
+
const records = await this.source.listSessions(options.cwd);
|
|
142
|
+
const monitorWindows = this.monitorState ? (await this.monitorState()).windows : [];
|
|
143
|
+
const windowsBySessionId = new Map();
|
|
144
|
+
for (const window of monitorWindows) {
|
|
145
|
+
const windows = windowsBySessionId.get(window.sessionId) ?? [];
|
|
146
|
+
windows.push(window);
|
|
147
|
+
windowsBySessionId.set(window.sessionId, windows);
|
|
148
|
+
}
|
|
149
|
+
const observedAt = new Date(this.now()).toISOString();
|
|
150
|
+
const directoryTargets = this.directory.list();
|
|
151
|
+
const summaries = records.map((record) => summaryOf(record));
|
|
152
|
+
const knownSessionIds = new Set(summaries.map((session) => session.sessionId));
|
|
153
|
+
for (const window of monitorWindows) {
|
|
154
|
+
if (knownSessionIds.has(window.sessionId))
|
|
155
|
+
continue;
|
|
156
|
+
const cwd = window.cwd ?? "";
|
|
157
|
+
summaries.push({
|
|
158
|
+
id: window.sessionId,
|
|
159
|
+
sessionId: window.sessionId,
|
|
160
|
+
endpointId: window.endpointId,
|
|
161
|
+
runtimeStatus: window.runtimeStatus,
|
|
162
|
+
cwd,
|
|
163
|
+
cwdName: cwd.split("/").filter(Boolean).at(-1) ?? cwd,
|
|
164
|
+
path: "",
|
|
165
|
+
title: window.name ?? window.sessionId,
|
|
166
|
+
messageCount: 0,
|
|
167
|
+
updatedAt: observedAt,
|
|
168
|
+
presentation: window.presentation,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
const projectedTargetKeys = new Set();
|
|
172
|
+
let sessions = summaries.flatMap((summary) => {
|
|
173
|
+
const windows = windowsBySessionId.get(summary.sessionId) ?? [];
|
|
174
|
+
const window = windows.length === 1 ? windows[0] : undefined;
|
|
175
|
+
const sourcePresentation = window?.presentation ?? summary.presentation ?? this.presentationFor?.(summary.sessionId);
|
|
176
|
+
const matchingTargets = directoryTargets.filter((candidate) => candidate.identity.sessionId === summary.sessionId);
|
|
177
|
+
if (matchingTargets.length > 0) {
|
|
178
|
+
return matchingTargets.flatMap((target) => {
|
|
179
|
+
const targetKey = targetIdentityKey(target.identity);
|
|
180
|
+
if (projectedTargetKeys.has(targetKey))
|
|
181
|
+
return [];
|
|
182
|
+
projectedTargetKeys.add(targetKey);
|
|
183
|
+
const attributedWindows = windows.filter((candidate) => candidate.endpointId === target.identity.endpointId
|
|
184
|
+
&& candidate.cwd !== undefined && normalize(candidate.cwd) === target.identity.normalizedCwd);
|
|
185
|
+
const sameEndpointTargets = matchingTargets.filter((candidate) => candidate.identity.endpointId === target.identity.endpointId
|
|
186
|
+
&& candidate.identity.normalizedCwd === target.identity.normalizedCwd);
|
|
187
|
+
const presentation = matchingTargets.length === 1 ? sourcePresentation
|
|
188
|
+
: attributedWindows.length === 1 && sameEndpointTargets.length === 1 ? attributedWindows[0].presentation : undefined;
|
|
189
|
+
return [summaryForTarget(target, this.directory.revision, observedAt, summary, presentation)];
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
const target = this.targetFor?.(summary.sessionId);
|
|
193
|
+
if (target) {
|
|
194
|
+
projectedTargetKeys.add(targetIdentityKey(target.identity));
|
|
195
|
+
return [summaryForTarget(target, this.directory.revision, observedAt, summary, sourcePresentation)];
|
|
196
|
+
}
|
|
197
|
+
const directoryPresentation = this.presentationFor?.(summary.sessionId);
|
|
198
|
+
return [window
|
|
199
|
+
? {
|
|
200
|
+
...summary,
|
|
201
|
+
endpointId: window.endpointId,
|
|
202
|
+
runtimeStatus: window.runtimeStatus,
|
|
203
|
+
...(directoryPresentation ?? window.presentation ?? summary.presentation
|
|
204
|
+
? { presentation: directoryPresentation ?? window.presentation ?? summary.presentation }
|
|
205
|
+
: {}),
|
|
206
|
+
}
|
|
207
|
+
: summary];
|
|
208
|
+
});
|
|
209
|
+
for (const target of directoryTargets) {
|
|
210
|
+
const targetKey = targetIdentityKey(target.identity);
|
|
211
|
+
if (projectedTargetKeys.has(targetKey))
|
|
212
|
+
continue;
|
|
213
|
+
sessions.push(summaryForTarget(target, this.directory.revision, observedAt));
|
|
214
|
+
}
|
|
215
|
+
sessions = sessions.filter((session) => {
|
|
216
|
+
const presentation = session.presentation ?? this.presentationFor?.(session.id) ?? readonlyPresentation(this.directory.revision);
|
|
217
|
+
if (!options.includeMonitor && presentation.visibility === "monitor_tab")
|
|
218
|
+
return false;
|
|
219
|
+
if (projectCwds && !projectCwds.includes(session.cwd))
|
|
220
|
+
return false;
|
|
221
|
+
if (!query)
|
|
222
|
+
return true;
|
|
223
|
+
return [session.id, session.cwd, session.title, session.name, session.model]
|
|
224
|
+
.some((value) => value?.toLocaleLowerCase().includes(query));
|
|
225
|
+
});
|
|
226
|
+
sessions.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt) || listKey(b).localeCompare(listKey(a)));
|
|
227
|
+
if (targeted) {
|
|
228
|
+
const selectedSessionIds = new Set(options.sessionIds ?? []);
|
|
229
|
+
const latestForCwds = new Set(options.latestForCwds ?? []);
|
|
230
|
+
const selectedCwds = new Set();
|
|
231
|
+
if (latestForCwds.size > 0) {
|
|
232
|
+
for (const session of sessions) {
|
|
233
|
+
if (latestForCwds.has(session.cwd) && !selectedCwds.has(session.cwd)) {
|
|
234
|
+
selectedCwds.add(session.cwd);
|
|
235
|
+
selectedSessionIds.add(session.sessionId);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return {
|
|
240
|
+
sessions: sessions.filter((session) => selectedSessionIds.has(session.sessionId)).map((session) => this.withPresentation(session)),
|
|
241
|
+
observedAt,
|
|
242
|
+
targeted: true,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
const total = sessions.length;
|
|
246
|
+
let start = 0;
|
|
247
|
+
if (options.cursor) {
|
|
248
|
+
const cursor = readCursor(options.cursor);
|
|
249
|
+
start = sessions.findIndex((session) => session.updatedAt < cursor.updatedAt || (session.updatedAt === cursor.updatedAt && listKey(session) < cursor.id));
|
|
250
|
+
if (start < 0)
|
|
251
|
+
start = sessions.length;
|
|
252
|
+
}
|
|
253
|
+
if (options.limit !== undefined) {
|
|
254
|
+
sessions = sessions.slice(start, start + options.limit);
|
|
255
|
+
const last = sessions.at(-1);
|
|
256
|
+
return {
|
|
257
|
+
sessions: sessions.map((session) => this.withPresentation(session)),
|
|
258
|
+
observedAt,
|
|
259
|
+
hasMore: start + sessions.length < total,
|
|
260
|
+
total,
|
|
261
|
+
...(start + sessions.length < total && last ? { nextCursor: cursorFor(last) } : {}),
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
return { sessions: sessions.map((session) => this.withPresentation(session)), observedAt };
|
|
265
|
+
}
|
|
266
|
+
async snapshot(target) {
|
|
267
|
+
const entry = this.directory.resolve(target);
|
|
268
|
+
if (!entry)
|
|
269
|
+
return { ok: false, status: "unknown", error: { code: "target_unavailable" }, revision: this.directory.revision };
|
|
270
|
+
if (!entry.runner) {
|
|
271
|
+
if (entry.kind !== "desktop")
|
|
272
|
+
return { ok: false, status: "failed", error: { code: "session_readonly_or_unavailable" }, revision: this.directory.revision };
|
|
273
|
+
const runtimeStatus = runtimeStatusForTarget(entry);
|
|
274
|
+
const updatedAt = entry.lastActivityAt ?? new Date(this.now()).toISOString();
|
|
275
|
+
let timeline = [];
|
|
276
|
+
let hasMoreHistory = false;
|
|
277
|
+
if (entry.sessionFile) {
|
|
278
|
+
const page = await replayTailFromJsonl(entry.sessionFile, 80);
|
|
279
|
+
timeline = page.items;
|
|
280
|
+
hasMoreHistory = page.hasMore;
|
|
281
|
+
this.desktopHistory.set(targetIdentityKey(entry.identity), { cursor: page.cursor, totalEntries: page.totalEntries });
|
|
282
|
+
}
|
|
283
|
+
return {
|
|
284
|
+
ok: true,
|
|
285
|
+
value: {
|
|
286
|
+
session: {
|
|
287
|
+
id: entry.identity.sessionId,
|
|
288
|
+
cwd: entry.identity.normalizedCwd,
|
|
289
|
+
title: entry.identity.normalizedCwd.split("/").filter(Boolean).at(-1) ?? entry.identity.sessionId,
|
|
290
|
+
runState: runtimeStatus === "running" ? "streaming" : "idle",
|
|
291
|
+
messageCount: entry.messageCount ?? 0,
|
|
292
|
+
pendingMessageCount: 0,
|
|
293
|
+
updatedAt,
|
|
294
|
+
...(entry.sessionFile ? { sessionFile: entry.sessionFile } : {}),
|
|
295
|
+
...(entry.model ? { model: structuredClone(entry.model) } : {}),
|
|
296
|
+
...(entry.thinkingLevel ? { thinkingLevel: entry.thinkingLevel } : {}),
|
|
297
|
+
presentation: entry.presentation ?? readonlyPresentation(this.directory.revision),
|
|
298
|
+
},
|
|
299
|
+
timeline,
|
|
300
|
+
nextSeq: 0,
|
|
301
|
+
historyAvailable: Boolean(entry.sessionFile),
|
|
302
|
+
hasMoreHistory,
|
|
303
|
+
},
|
|
304
|
+
revision: this.directory.revision,
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
const snapshot = entry.runner.snapshot();
|
|
308
|
+
return {
|
|
309
|
+
ok: true,
|
|
310
|
+
value: {
|
|
311
|
+
...snapshot,
|
|
312
|
+
session: {
|
|
313
|
+
...snapshot.session,
|
|
314
|
+
presentation: entry.presentation ?? readonlyPresentation(this.directory.revision),
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
revision: this.directory.revision,
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
async history(target, count) {
|
|
321
|
+
const entry = this.directory.resolve(target);
|
|
322
|
+
if (!entry)
|
|
323
|
+
return { ok: false, status: "unknown", error: { code: "target_unavailable" }, revision: this.directory.revision };
|
|
324
|
+
if (!entry.runner) {
|
|
325
|
+
if (entry.kind === "desktop" && entry.sessionFile) {
|
|
326
|
+
const key = targetIdentityKey(entry.identity);
|
|
327
|
+
const cursor = this.desktopHistory.get(key)?.cursor ?? (await replayTailFromJsonl(entry.sessionFile, 80)).cursor;
|
|
328
|
+
const page = await replayPageBeforeJsonl(entry.sessionFile, cursor, count ?? 100);
|
|
329
|
+
this.desktopHistory.set(key, { cursor: page.cursor, totalEntries: page.totalEntries });
|
|
330
|
+
return { ok: true, value: { items: page.items, hasMore: page.hasMore, totalEntries: page.totalEntries, historyAvailable: true }, revision: this.directory.revision };
|
|
331
|
+
}
|
|
332
|
+
if (entry.kind === "desktop")
|
|
333
|
+
return { ok: true, value: { items: [], hasMore: false, totalEntries: 0, historyAvailable: false }, revision: this.directory.revision };
|
|
334
|
+
return { ok: false, status: "failed", error: { code: "session_readonly_or_unavailable" }, revision: this.directory.revision };
|
|
335
|
+
}
|
|
336
|
+
return { ok: true, value: await entry.runner.loadMoreHistory(count), revision: this.directory.revision };
|
|
337
|
+
}
|
|
338
|
+
async usage(target) {
|
|
339
|
+
const entry = this.directory.resolve(target);
|
|
340
|
+
if (!entry)
|
|
341
|
+
return { ok: false, status: "unknown", error: { code: "target_unavailable" }, revision: this.directory.revision };
|
|
342
|
+
if (!entry.runner) {
|
|
343
|
+
if (entry.kind === "desktop") {
|
|
344
|
+
const usage = entry.usage;
|
|
345
|
+
return {
|
|
346
|
+
ok: true,
|
|
347
|
+
value: {
|
|
348
|
+
entries: 0,
|
|
349
|
+
input: usage?.input ?? 0,
|
|
350
|
+
output: usage?.output ?? 0,
|
|
351
|
+
cacheRead: usage?.cacheRead ?? 0,
|
|
352
|
+
cacheWrite: usage?.cacheWrite ?? 0,
|
|
353
|
+
reasoning: 0,
|
|
354
|
+
totalTokens: usage?.totalTokens ?? 0,
|
|
355
|
+
cost: usage?.cost ?? 0,
|
|
356
|
+
},
|
|
357
|
+
revision: this.directory.revision,
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
return { ok: false, status: "failed", error: { code: "session_readonly_or_unavailable" }, revision: this.directory.revision };
|
|
361
|
+
}
|
|
362
|
+
if (!entry.runner.getUsage)
|
|
363
|
+
return { ok: false, status: "failed", error: { code: "usage_unavailable" }, revision: this.directory.revision };
|
|
364
|
+
return { ok: true, value: await entry.runner.getUsage(), revision: this.directory.revision };
|
|
365
|
+
}
|
|
366
|
+
withPresentation(session) {
|
|
367
|
+
return {
|
|
368
|
+
...session,
|
|
369
|
+
presentation: session.presentation ?? this.presentationFor?.(session.id) ?? readonlyPresentation(this.directory.revision),
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
//# sourceMappingURL=session-query-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-query-service.js","sourceRoot":"","sources":["../../src/application/session-query-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SessionPresentation } from "../vendor/shared/index.js";
|
|
2
|
+
import type { WorkspaceOwner } from "../workspace-telemetry.js";
|
|
3
|
+
/**
|
|
4
|
+
* 服务端唯一的 owner 角色/可见性分类。
|
|
5
|
+
* telemetry 的 PID 只作为诊断字段存在,不能赋予控制权;没有 Desktop Plugin
|
|
6
|
+
* 精确 endpoint 时,历史窗口默认只读。
|
|
7
|
+
*/
|
|
8
|
+
export declare function isMonitorOwner(owner: WorkspaceOwner): boolean;
|
|
9
|
+
export declare function projectOwnerPresentation(owner: WorkspaceOwner, monitorWindowCount?: number): SessionPresentation;
|
|
10
|
+
export declare function projectOwnerVisibility(owner: WorkspaceOwner): "session_list" | "monitor_tab";
|
|
11
|
+
//# sourceMappingURL=session-visibility.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-visibility.d.ts","sourceRoot":"","sources":["../../src/application/session-visibility.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEhE;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAI7D;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,cAAc,EACrB,kBAAkB,SAAI,GACrB,mBAAmB,CAiBrB;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,GAAG,cAAc,GAAG,aAAa,CAE5F"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 服务端唯一的 owner 角色/可见性分类。
|
|
3
|
+
* telemetry 的 PID 只作为诊断字段存在,不能赋予控制权;没有 Desktop Plugin
|
|
4
|
+
* 精确 endpoint 时,历史窗口默认只读。
|
|
5
|
+
*/
|
|
6
|
+
export function isMonitorOwner(owner) {
|
|
7
|
+
// Role must be explicitly published by the owner producer. Display names and
|
|
8
|
+
// settle text are historical diagnostics, not identity evidence.
|
|
9
|
+
return owner.workspaceRole === "monitor";
|
|
10
|
+
}
|
|
11
|
+
export function projectOwnerPresentation(owner, monitorWindowCount = 0) {
|
|
12
|
+
const monitor = isMonitorOwner(owner);
|
|
13
|
+
return {
|
|
14
|
+
role: monitor ? "monitor" : "session",
|
|
15
|
+
visibility: monitor ? "monitor_tab" : "session_list",
|
|
16
|
+
control: {
|
|
17
|
+
mode: "readonly",
|
|
18
|
+
canPrompt: false,
|
|
19
|
+
canSteer: false,
|
|
20
|
+
canFollowUp: false,
|
|
21
|
+
canAbort: false,
|
|
22
|
+
canAnswerAsk: false,
|
|
23
|
+
},
|
|
24
|
+
// Owner heartbeat timestamps must not become a presentation revision.
|
|
25
|
+
revision: 0,
|
|
26
|
+
...(monitor ? { monitorWindowCount } : {}),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export function projectOwnerVisibility(owner) {
|
|
30
|
+
return isMonitorOwner(owner) ? "monitor_tab" : "session_list";
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=session-visibility.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-visibility.js","sourceRoot":"","sources":["../../src/application/session-visibility.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,KAAqB;IAClD,6EAA6E;IAC7E,iEAAiE;IACjE,OAAO,KAAK,CAAC,aAAa,KAAK,SAAS,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,KAAqB,EACrB,kBAAkB,GAAG,CAAC;IAEtB,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACtC,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;QACrC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,cAAc;QACpD,OAAO,EAAE;YACP,IAAI,EAAE,UAAU;YAChB,SAAS,EAAE,KAAK;YAChB,QAAQ,EAAE,KAAK;YACf,WAAW,EAAE,KAAK;YAClB,QAAQ,EAAE,KAAK;YACf,YAAY,EAAE,KAAK;SACpB;QACD,sEAAsE;QACtE,QAAQ,EAAE,CAAC;QACX,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC3C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,KAAqB;IAC1D,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,cAAc,CAAC;AAChE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broker-cli.d.ts","sourceRoot":"","sources":["../src/broker-cli.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { chmod, readFile, unlink, writeFile } from "node:fs/promises";
|
|
3
|
+
import { DesktopBroker, DesktopBrokerHostClient } from "./plugin/desktop-broker.js";
|
|
4
|
+
import { DEFAULT_DESKTOP_BROKER_HOST_SOCKET, DEFAULT_DESKTOP_BROKER_PID_FILE, DEFAULT_DESKTOP_BROKER_PLUGIN_SOCKET, DEFAULT_DESKTOP_BROKER_REGISTRY_FILE, DEFAULT_DESKTOP_BROKER_SECRET_FILE, } from "./plugin/desktop-broker-supervisor.js";
|
|
5
|
+
function parseArgs(argv) {
|
|
6
|
+
const values = new Map();
|
|
7
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
8
|
+
const arg = argv[index];
|
|
9
|
+
if (!arg.startsWith("--"))
|
|
10
|
+
continue;
|
|
11
|
+
const key = arg.slice(2);
|
|
12
|
+
const value = argv[index + 1];
|
|
13
|
+
if (!value || value.startsWith("--"))
|
|
14
|
+
throw new Error(`missing value for --${key}`);
|
|
15
|
+
values.set(key, value);
|
|
16
|
+
index += 1;
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
secretFile: values.get("secret-file") ?? DEFAULT_DESKTOP_BROKER_SECRET_FILE,
|
|
20
|
+
pluginSocket: values.get("plugin-socket") ?? DEFAULT_DESKTOP_BROKER_PLUGIN_SOCKET,
|
|
21
|
+
hostSocket: values.get("host-socket") ?? DEFAULT_DESKTOP_BROKER_HOST_SOCKET,
|
|
22
|
+
registry: values.get("registry") ?? DEFAULT_DESKTOP_BROKER_REGISTRY_FILE,
|
|
23
|
+
pidFile: values.get("pid-file") ?? DEFAULT_DESKTOP_BROKER_PID_FILE,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
async function readSecret(path) {
|
|
27
|
+
const secret = (await readFile(path, "utf8")).trim();
|
|
28
|
+
if (secret.length < 24)
|
|
29
|
+
throw new Error("desktop broker secret is missing or too short");
|
|
30
|
+
return secret;
|
|
31
|
+
}
|
|
32
|
+
async function main() {
|
|
33
|
+
const args = parseArgs(process.argv.slice(2));
|
|
34
|
+
const secret = await readSecret(args.secretFile);
|
|
35
|
+
const broker = new DesktopBroker({
|
|
36
|
+
pluginSocketPath: args.pluginSocket,
|
|
37
|
+
registryPath: args.registry,
|
|
38
|
+
secret,
|
|
39
|
+
});
|
|
40
|
+
const hostClient = new DesktopBrokerHostClient(broker, { socketPath: args.hostSocket, secret });
|
|
41
|
+
let shuttingDown = false;
|
|
42
|
+
const shutdown = async (reason, exitCode) => {
|
|
43
|
+
if (shuttingDown)
|
|
44
|
+
return;
|
|
45
|
+
shuttingDown = true;
|
|
46
|
+
console.log(`[maestro-mobile-broker] received ${reason}, shutting down...`);
|
|
47
|
+
hostClient.close();
|
|
48
|
+
await broker.close().catch(() => undefined);
|
|
49
|
+
try {
|
|
50
|
+
const current = (await readFile(args.pidFile, "utf8")).trim();
|
|
51
|
+
if (current === String(process.pid))
|
|
52
|
+
await unlink(args.pidFile);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// PID file may have been removed by the supervisor.
|
|
56
|
+
}
|
|
57
|
+
process.exit(exitCode);
|
|
58
|
+
};
|
|
59
|
+
process.on("SIGINT", () => void shutdown("SIGINT", 0));
|
|
60
|
+
process.on("SIGTERM", () => void shutdown("SIGTERM", 0));
|
|
61
|
+
process.on("uncaughtException", (error) => {
|
|
62
|
+
console.error("[maestro-mobile-broker] uncaught exception", error);
|
|
63
|
+
void shutdown("uncaughtException", 1);
|
|
64
|
+
});
|
|
65
|
+
process.on("unhandledRejection", (reason) => {
|
|
66
|
+
console.error("[maestro-mobile-broker] unhandled rejection", reason);
|
|
67
|
+
void shutdown("unhandledRejection", 1);
|
|
68
|
+
});
|
|
69
|
+
await broker.start();
|
|
70
|
+
await writeFile(args.pidFile, `${process.pid}\n`, { mode: 0o600 });
|
|
71
|
+
await chmod(args.pidFile, 0o600);
|
|
72
|
+
hostClient.start();
|
|
73
|
+
console.log(`[maestro-mobile-broker] plugin socket ${args.pluginSocket}`);
|
|
74
|
+
}
|
|
75
|
+
main().catch((error) => {
|
|
76
|
+
console.error("[maestro-mobile-broker] fatal", error);
|
|
77
|
+
process.exit(1);
|
|
78
|
+
});
|
|
79
|
+
//# sourceMappingURL=broker-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broker-cli.js","sourceRoot":"","sources":["../src/broker-cli.ts"],"names":[],"mappings":"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"}
|