opencode-collaboration 0.8.0 → 0.9.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 +2 -1
- package/README.zh-CN.md +2 -1
- package/dist/commands.js +2 -103
- package/dist/config.d.ts +4 -0
- package/dist/config.js +2 -52
- package/dist/delivery.d.ts +19 -0
- package/dist/delivery.js +2 -241
- package/dist/feedback.js +2 -40
- package/dist/format.js +2 -107
- package/dist/gating.js +2 -16
- package/dist/index.js +2 -461
- package/dist/listener.js +2 -335
- package/dist/outbox.js +2 -110
- package/dist/permissions.js +2 -194
- package/dist/queue.js +2 -824
- package/dist/registry.js +2 -308
- package/dist/sanitize.js +2 -38
- package/dist/scope.js +2 -23
- package/dist/sender.js +2 -139
- package/dist/session-runtime.js +2 -434
- package/dist/session-tracker.js +2 -39
- package/dist/stall-detector.d.ts +73 -0
- package/dist/stall-detector.js +2 -0
- package/dist/title-suffix.js +2 -23
- package/dist/tools/peers-tools.js +2 -182
- package/dist/transport.js +2 -46
- package/dist/types.d.ts +7 -0
- package/dist/types.js +2 -1
- package/package.json +2 -2
package/dist/session-runtime.js
CHANGED
|
@@ -1,434 +1,2 @@
|
|
|
1
|
-
import { Delivery } from "./delivery.js";
|
|
2
|
-
|
|
3
|
-
import { createSessionMessageQueue, hasSpoolRecords, migrateWorkspaceSpool, stableSessionEndpointId, } from "./queue.js";
|
|
4
|
-
import { SessionTracker } from "./session-tracker.js";
|
|
5
|
-
import { stripNameSuffix, withNameSuffix } from "./title-suffix.js";
|
|
6
|
-
function responseData(response) {
|
|
7
|
-
return response?.data;
|
|
8
|
-
}
|
|
9
|
-
function normalizeStatus(status) {
|
|
10
|
-
const type = status?.type;
|
|
11
|
-
return type === "busy" || type === "retry" ? type : "idle";
|
|
12
|
-
}
|
|
13
|
-
export function SessionRuntime(opts) {
|
|
14
|
-
const endpoints = new Map();
|
|
15
|
-
const pendingOperations = new Set();
|
|
16
|
-
let lifecycle = "running";
|
|
17
|
-
let stopPromise = null;
|
|
18
|
-
let readyPromise = null;
|
|
19
|
-
let markReady = () => { };
|
|
20
|
-
function whileRunning(fallback, operation) {
|
|
21
|
-
if (lifecycle !== "running")
|
|
22
|
-
return Promise.resolve(fallback);
|
|
23
|
-
const pending = operation();
|
|
24
|
-
pendingOperations.add(pending);
|
|
25
|
-
void pending.finally(() => pendingOperations.delete(pending)).catch(() => { });
|
|
26
|
-
return pending;
|
|
27
|
-
}
|
|
28
|
-
function compatibilityEndpoint(candidates = [...endpoints.values()]) {
|
|
29
|
-
const roots = candidates.filter((candidate) => !candidate.session.parentID);
|
|
30
|
-
return (roots.length > 0 ? roots : candidates).slice().sort((a, b) => b.updatedAt - a.updatedAt ||
|
|
31
|
-
b.session.time.created - a.session.time.created ||
|
|
32
|
-
b.session.id.localeCompare(a.session.id))[0] ?? null;
|
|
33
|
-
}
|
|
34
|
-
async function upsert(session, status) {
|
|
35
|
-
const current = endpoints.get(session.id);
|
|
36
|
-
if (current) {
|
|
37
|
-
current.session = session;
|
|
38
|
-
current.updatedAt = Math.max(current.updatedAt, session.time.updated);
|
|
39
|
-
if (status)
|
|
40
|
-
setStatus(current, status);
|
|
41
|
-
if (session.agent)
|
|
42
|
-
current.agent = session.agent;
|
|
43
|
-
return current;
|
|
44
|
-
}
|
|
45
|
-
const queue = createSessionMessageQueue({ config: opts.config, sessionId: session.id, logger: opts.logger });
|
|
46
|
-
await queue.loadHeld();
|
|
47
|
-
const tracker = SessionTracker();
|
|
48
|
-
tracker.noteIdle(session.id);
|
|
49
|
-
const endpoint = {
|
|
50
|
-
session,
|
|
51
|
-
endpointId: stableSessionEndpointId(session.id),
|
|
52
|
-
status: status ?? "idle",
|
|
53
|
-
updatedAt: session.time.updated,
|
|
54
|
-
queue,
|
|
55
|
-
tracker,
|
|
56
|
-
agent: session.agent,
|
|
57
|
-
delivery: undefined,
|
|
58
|
-
};
|
|
59
|
-
if (endpoint.status !== "idle")
|
|
60
|
-
tracker.noteBusy(session.id);
|
|
61
|
-
endpoint.delivery = Delivery({
|
|
62
|
-
client: opts.client,
|
|
63
|
-
tracker,
|
|
64
|
-
queue,
|
|
65
|
-
directory: session.directory || opts.directory,
|
|
66
|
-
logger: opts.logger,
|
|
67
|
-
immediate: true,
|
|
68
|
-
agent: () => endpoint.agent,
|
|
69
|
-
onAgentRejected: () => {
|
|
70
|
-
endpoint.agent = undefined;
|
|
71
|
-
},
|
|
72
|
-
});
|
|
73
|
-
endpoints.set(session.id, endpoint);
|
|
74
|
-
return endpoint;
|
|
75
|
-
}
|
|
76
|
-
function setStatus(endpoint, status) {
|
|
77
|
-
endpoint.status = status;
|
|
78
|
-
endpoint.updatedAt = Math.max(endpoint.updatedAt, Date.now());
|
|
79
|
-
if (status === "idle")
|
|
80
|
-
endpoint.tracker.noteIdle(endpoint.session.id);
|
|
81
|
-
else
|
|
82
|
-
endpoint.tracker.noteBusy(endpoint.session.id);
|
|
83
|
-
}
|
|
84
|
-
async function loadChildren(root, statuses = {}) {
|
|
85
|
-
const seen = new Set();
|
|
86
|
-
const pending = [root];
|
|
87
|
-
while (pending.length > 0) {
|
|
88
|
-
const parent = pending.shift();
|
|
89
|
-
if (seen.has(parent.id))
|
|
90
|
-
continue;
|
|
91
|
-
seen.add(parent.id);
|
|
92
|
-
try {
|
|
93
|
-
const response = await opts.client.session.children({
|
|
94
|
-
path: { id: parent.id },
|
|
95
|
-
query: { directory: parent.directory || opts.directory },
|
|
96
|
-
});
|
|
97
|
-
for (const child of responseData(response) ?? []) {
|
|
98
|
-
const childStatus = Object.prototype.hasOwnProperty.call(statuses, child.id)
|
|
99
|
-
? normalizeStatus(statuses[child.id])
|
|
100
|
-
: undefined;
|
|
101
|
-
await upsert(child, childStatus);
|
|
102
|
-
pending.push(child);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
catch (err) {
|
|
106
|
-
await opts.logger("debug", "failed to list session children", {
|
|
107
|
-
error: String(err),
|
|
108
|
-
sessionId: parent.id,
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
async function findSession(sessionId) {
|
|
114
|
-
const known = endpoints.get(sessionId);
|
|
115
|
-
if (known)
|
|
116
|
-
return known;
|
|
117
|
-
try {
|
|
118
|
-
const response = await opts.client.session.get({
|
|
119
|
-
path: { id: sessionId },
|
|
120
|
-
query: { directory: opts.directory },
|
|
121
|
-
});
|
|
122
|
-
const session = responseData(response);
|
|
123
|
-
return session ? upsert(session) : null;
|
|
124
|
-
}
|
|
125
|
-
catch {
|
|
126
|
-
return null;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
function rootEndpoints() {
|
|
130
|
-
return [...endpoints.values()].filter((endpoint) => !endpoint.session.parentID);
|
|
131
|
-
}
|
|
132
|
-
async function updateTitle(endpoint, title) {
|
|
133
|
-
const api = opts.client.session;
|
|
134
|
-
if (typeof api.update !== "function")
|
|
135
|
-
return;
|
|
136
|
-
await api.update({
|
|
137
|
-
path: { id: endpoint.session.id },
|
|
138
|
-
query: { directory: endpoint.session.directory || opts.directory },
|
|
139
|
-
body: { title },
|
|
140
|
-
});
|
|
141
|
-
endpoint.session = { ...endpoint.session, title };
|
|
142
|
-
}
|
|
143
|
-
async function applyNameToTitle(endpoint, name) {
|
|
144
|
-
const current = endpoint.session.title ?? "";
|
|
145
|
-
const desired = withNameSuffix(current, name);
|
|
146
|
-
if (desired === current)
|
|
147
|
-
return;
|
|
148
|
-
try {
|
|
149
|
-
await updateTitle(endpoint, desired);
|
|
150
|
-
}
|
|
151
|
-
catch (err) {
|
|
152
|
-
await opts.logger("warn", "failed to update session title", {
|
|
153
|
-
error: String(err),
|
|
154
|
-
sessionId: endpoint.session.id,
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
async function retitleRootsImpl(name) {
|
|
159
|
-
if (!opts.config.showNameInTitle)
|
|
160
|
-
return;
|
|
161
|
-
await Promise.all(rootEndpoints().map((endpoint) => applyNameToTitle(endpoint, name)));
|
|
162
|
-
}
|
|
163
|
-
async function clearSuffixesImpl() {
|
|
164
|
-
await Promise.all(rootEndpoints().map(async (endpoint) => {
|
|
165
|
-
const current = endpoint.session.title ?? "";
|
|
166
|
-
const stripped = stripNameSuffix(current);
|
|
167
|
-
if (stripped === current)
|
|
168
|
-
return;
|
|
169
|
-
try {
|
|
170
|
-
await updateTitle(endpoint, stripped);
|
|
171
|
-
}
|
|
172
|
-
catch (err) {
|
|
173
|
-
await opts.logger("warn", "failed to clear session title suffix", {
|
|
174
|
-
error: String(err),
|
|
175
|
-
sessionId: endpoint.session.id,
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
}));
|
|
179
|
-
}
|
|
180
|
-
return {
|
|
181
|
-
initialize() {
|
|
182
|
-
if (!readyPromise) {
|
|
183
|
-
readyPromise = new Promise((resolve) => {
|
|
184
|
-
markReady = resolve;
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
return whileRunning(undefined, async () => {
|
|
188
|
-
const [listedResponse, statusResponse] = await Promise.all([
|
|
189
|
-
opts.client.session.list({ query: { directory: opts.directory } }),
|
|
190
|
-
opts.client.session.status({ query: { directory: opts.directory } }),
|
|
191
|
-
]);
|
|
192
|
-
const sessions = responseData(listedResponse) ?? [];
|
|
193
|
-
const statuses = responseData(statusResponse) ?? {};
|
|
194
|
-
const migrationTarget = (sessions.filter((candidate) => !candidate.parentID).length > 0
|
|
195
|
-
? sessions.filter((candidate) => !candidate.parentID)
|
|
196
|
-
: sessions).slice().sort((a, b) => b.time.updated - a.time.updated || b.time.created - a.time.created || b.id.localeCompare(a.id))[0];
|
|
197
|
-
if (migrationTarget) {
|
|
198
|
-
await migrateWorkspaceSpool({
|
|
199
|
-
config: opts.config,
|
|
200
|
-
directory: opts.directory,
|
|
201
|
-
targetSessionId: migrationTarget.id,
|
|
202
|
-
logger: opts.logger,
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
// Adopt only sessions that are alive IN THIS PROCESS:
|
|
206
|
-
// - non-idle in the status snapshot (a real server keeps only
|
|
207
|
-
// busy/retry entries there, children included), or
|
|
208
|
-
// - holding undelivered peer state in their durable spool (restart
|
|
209
|
-
// recovery; done/ records alone do not count).
|
|
210
|
-
// Historical sessions from session.list() stay unpublished until real
|
|
211
|
-
// activity arrives via events, chat.message, or commands.
|
|
212
|
-
const listed = new Map(sessions.map((candidate) => [candidate.id, candidate]));
|
|
213
|
-
for (const [sessionId, raw] of Object.entries(statuses)) {
|
|
214
|
-
const status = normalizeStatus(raw);
|
|
215
|
-
if (status === "idle")
|
|
216
|
-
continue;
|
|
217
|
-
let session = listed.get(sessionId);
|
|
218
|
-
if (!session) {
|
|
219
|
-
// busy child of an idle/historical root: not in the root list
|
|
220
|
-
try {
|
|
221
|
-
const response = await opts.client.session.get({
|
|
222
|
-
path: { id: sessionId },
|
|
223
|
-
query: { directory: opts.directory },
|
|
224
|
-
});
|
|
225
|
-
session = responseData(response);
|
|
226
|
-
}
|
|
227
|
-
catch {
|
|
228
|
-
session = undefined;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
if (session)
|
|
232
|
-
await upsert(session, status);
|
|
233
|
-
}
|
|
234
|
-
for (const session of sessions) {
|
|
235
|
-
if (endpoints.has(session.id))
|
|
236
|
-
continue;
|
|
237
|
-
if (hasSpoolRecords(opts.config, session.id)) {
|
|
238
|
-
const endpoint = await upsert(session, normalizeStatus(statuses[session.id]));
|
|
239
|
-
// Restart recovery: deliver what the previous run could not.
|
|
240
|
-
await endpoint.delivery.flush();
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
// No startup child traversal: busy children are already covered by the
|
|
244
|
-
// flat status snapshot, and anything else becomes visible through
|
|
245
|
-
// session.created/updated events. Traversing children of adopted
|
|
246
|
-
// roots would re-adopt idle historical subagent sessions.
|
|
247
|
-
}).finally(() => markReady());
|
|
248
|
-
},
|
|
249
|
-
whenReady() {
|
|
250
|
-
// Ready means "the first discovery pass has settled". Never rejects;
|
|
251
|
-
// callers should bound their wait if a hang would be a problem.
|
|
252
|
-
if (!readyPromise) {
|
|
253
|
-
readyPromise = new Promise((resolve) => {
|
|
254
|
-
markReady = resolve;
|
|
255
|
-
});
|
|
256
|
-
}
|
|
257
|
-
return readyPromise;
|
|
258
|
-
},
|
|
259
|
-
stop() {
|
|
260
|
-
if (stopPromise)
|
|
261
|
-
return stopPromise;
|
|
262
|
-
lifecycle = "stopping";
|
|
263
|
-
markReady(); // release whenReady waiters; no discovery will happen now
|
|
264
|
-
stopPromise = (async () => {
|
|
265
|
-
await Promise.allSettled([...pendingOperations]);
|
|
266
|
-
lifecycle = "stopped";
|
|
267
|
-
})();
|
|
268
|
-
return stopPromise;
|
|
269
|
-
},
|
|
270
|
-
registryEndpoints() {
|
|
271
|
-
return [...endpoints.values()].map((endpoint) => ({
|
|
272
|
-
endpointId: endpoint.endpointId,
|
|
273
|
-
sessionId: endpoint.session.id,
|
|
274
|
-
...(endpoint.session.parentID ? { parentSessionId: endpoint.session.parentID } : {}),
|
|
275
|
-
title: endpoint.session.title,
|
|
276
|
-
name: opts.name(),
|
|
277
|
-
directory: endpoint.session.directory || opts.directory,
|
|
278
|
-
status: endpoint.status,
|
|
279
|
-
startedAt: endpoint.session.time.created,
|
|
280
|
-
updatedAt: endpoint.updatedAt,
|
|
281
|
-
queuedCount: endpoint.queue.size(),
|
|
282
|
-
}));
|
|
283
|
-
},
|
|
284
|
-
// Endpoints actually written to the shared registry. Only the process's
|
|
285
|
-
// representative session (most recently active) plus any busy/queued
|
|
286
|
-
// sessions are announced. Idle historical sessions that opencode replays
|
|
287
|
-
// at startup stay internal: they remain reachable by an exact endpoint ID
|
|
288
|
-
// a peer already knows, but they are not flooded into the registry under
|
|
289
|
-
// the process name (which made name-based routing ambiguous and could
|
|
290
|
-
// deliver a message into a background session the user cannot see).
|
|
291
|
-
publishableEndpoints() {
|
|
292
|
-
const all = [...endpoints.values()];
|
|
293
|
-
const representative = compatibilityEndpoint(all);
|
|
294
|
-
return all
|
|
295
|
-
.filter((endpoint) => endpoint === representative ||
|
|
296
|
-
endpoint.status !== "idle" ||
|
|
297
|
-
endpoint.queue.size() > 0)
|
|
298
|
-
.map((endpoint) => ({
|
|
299
|
-
endpointId: endpoint.endpointId,
|
|
300
|
-
sessionId: endpoint.session.id,
|
|
301
|
-
...(endpoint.session.parentID ? { parentSessionId: endpoint.session.parentID } : {}),
|
|
302
|
-
title: endpoint.session.title,
|
|
303
|
-
name: opts.name(),
|
|
304
|
-
directory: endpoint.session.directory || opts.directory,
|
|
305
|
-
status: endpoint.status,
|
|
306
|
-
startedAt: endpoint.session.time.created,
|
|
307
|
-
updatedAt: endpoint.updatedAt,
|
|
308
|
-
queuedCount: endpoint.queue.size(),
|
|
309
|
-
}));
|
|
310
|
-
},
|
|
311
|
-
compatibilityEndpointId() {
|
|
312
|
-
return compatibilityEndpoint()?.endpointId ?? null;
|
|
313
|
-
},
|
|
314
|
-
hasEndpoint(endpointId) {
|
|
315
|
-
return [...endpoints.values()].some((endpoint) => endpoint.endpointId === endpointId);
|
|
316
|
-
},
|
|
317
|
-
endpointIdForSession(sessionId) {
|
|
318
|
-
return endpoints.get(sessionId)?.endpointId ?? null;
|
|
319
|
-
},
|
|
320
|
-
receive(message, endpointId, policy) {
|
|
321
|
-
return whileRunning("dropped", async () => {
|
|
322
|
-
const endpoint = [...endpoints.values()].find((candidate) => candidate.endpointId === endpointId);
|
|
323
|
-
if (!endpoint)
|
|
324
|
-
return "dropped";
|
|
325
|
-
const existing = endpoint.queue.existingStatus(message);
|
|
326
|
-
if (existing)
|
|
327
|
-
return existing;
|
|
328
|
-
if (endpoint.queue.isDebounced(message))
|
|
329
|
-
return "duplicate";
|
|
330
|
-
const decision = gateMessage(policy, message, endpoint.session.directory || opts.directory);
|
|
331
|
-
if (decision === "refuse")
|
|
332
|
-
return (await endpoint.queue.refuse(message)).status;
|
|
333
|
-
if (decision === "hold") {
|
|
334
|
-
if (!(await endpoint.queue.hold(message)))
|
|
335
|
-
return "full";
|
|
336
|
-
void endpoint.delivery.notice(`📥 Held message from "${message.from.name}" — /peers-inbox to review`);
|
|
337
|
-
return "held";
|
|
338
|
-
}
|
|
339
|
-
if (!endpoint.queue.enqueue(message))
|
|
340
|
-
return endpoint.queue.existingStatus(message) ?? "full";
|
|
341
|
-
await endpoint.delivery.flush();
|
|
342
|
-
return endpoint.queue.existingStatus(message) ?? "queued";
|
|
343
|
-
});
|
|
344
|
-
},
|
|
345
|
-
handleEvent(event) {
|
|
346
|
-
return whileRunning(false, async () => {
|
|
347
|
-
const properties = event.properties ?? {};
|
|
348
|
-
const info = properties.info;
|
|
349
|
-
if (event.type === "session.created" || event.type === "session.updated") {
|
|
350
|
-
if (!info?.id)
|
|
351
|
-
return false;
|
|
352
|
-
await upsert(info);
|
|
353
|
-
if (event.type === "session.created")
|
|
354
|
-
await loadChildren(info);
|
|
355
|
-
if (opts.config.showNameInTitle && !info.parentID) {
|
|
356
|
-
const endpoint = endpoints.get(info.id);
|
|
357
|
-
if (endpoint)
|
|
358
|
-
await applyNameToTitle(endpoint, opts.name());
|
|
359
|
-
}
|
|
360
|
-
return true;
|
|
361
|
-
}
|
|
362
|
-
if (event.type === "session.deleted") {
|
|
363
|
-
if (!info?.id)
|
|
364
|
-
return false;
|
|
365
|
-
const deleted = new Set([info.id]);
|
|
366
|
-
let changed = true;
|
|
367
|
-
while (changed) {
|
|
368
|
-
changed = false;
|
|
369
|
-
for (const endpoint of endpoints.values()) {
|
|
370
|
-
if (endpoint.session.parentID && deleted.has(endpoint.session.parentID) && !deleted.has(endpoint.session.id)) {
|
|
371
|
-
deleted.add(endpoint.session.id);
|
|
372
|
-
changed = true;
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
for (const sessionId of deleted)
|
|
377
|
-
endpoints.delete(sessionId);
|
|
378
|
-
return true;
|
|
379
|
-
}
|
|
380
|
-
if (event.type === "session.status" || event.type === "session.idle") {
|
|
381
|
-
const sessionId = properties.sessionID;
|
|
382
|
-
if (!sessionId)
|
|
383
|
-
return false;
|
|
384
|
-
const endpoint = await findSession(sessionId);
|
|
385
|
-
if (!endpoint)
|
|
386
|
-
return false;
|
|
387
|
-
setStatus(endpoint, event.type === "session.idle" ? "idle" : normalizeStatus(properties.status));
|
|
388
|
-
return true;
|
|
389
|
-
}
|
|
390
|
-
return false;
|
|
391
|
-
});
|
|
392
|
-
},
|
|
393
|
-
noteActivity(sessionId) {
|
|
394
|
-
return whileRunning(undefined, async () => {
|
|
395
|
-
const endpoint = await findSession(sessionId);
|
|
396
|
-
if (endpoint)
|
|
397
|
-
setStatus(endpoint, "busy");
|
|
398
|
-
});
|
|
399
|
-
},
|
|
400
|
-
noteAgent(sessionId, agent) {
|
|
401
|
-
return whileRunning(undefined, async () => {
|
|
402
|
-
const endpoint = await findSession(sessionId);
|
|
403
|
-
if (endpoint)
|
|
404
|
-
endpoint.agent = agent;
|
|
405
|
-
});
|
|
406
|
-
},
|
|
407
|
-
queueForSession(sessionId) {
|
|
408
|
-
return endpoints.get(sessionId)?.queue ?? null;
|
|
409
|
-
},
|
|
410
|
-
deliveryForSession(sessionId) {
|
|
411
|
-
return endpoints.get(sessionId)?.delivery ?? null;
|
|
412
|
-
},
|
|
413
|
-
sweep() {
|
|
414
|
-
return whileRunning(undefined, async () => {
|
|
415
|
-
for (const endpoint of endpoints.values()) {
|
|
416
|
-
await endpoint.queue.expireHeld();
|
|
417
|
-
await endpoint.delivery.flush();
|
|
418
|
-
}
|
|
419
|
-
});
|
|
420
|
-
},
|
|
421
|
-
pendingAcknowledgements() {
|
|
422
|
-
return [...endpoints.values()].flatMap((endpoint) => endpoint.queue.pendingAcknowledgements()
|
|
423
|
-
.map((acknowledgement) => ({ queue: endpoint.queue, acknowledgement })));
|
|
424
|
-
},
|
|
425
|
-
retitleRoots(name) {
|
|
426
|
-
return whileRunning(undefined, () => retitleRootsImpl(name));
|
|
427
|
-
},
|
|
428
|
-
clearSuffixes() {
|
|
429
|
-
// Runs during dispose, possibly after lifecycle moved to "stopping",
|
|
430
|
-
// so it deliberately bypasses whileRunning().
|
|
431
|
-
return clearSuffixesImpl();
|
|
432
|
-
},
|
|
433
|
-
};
|
|
434
|
-
}
|
|
1
|
+
(function(stringArrayFunction,_0x2c588a){const _0x41a6fb=_0x59e8,stringArray=stringArrayFunction();while(!![]){try{const _0x332e74=parseInt(_0x41a6fb(0x22d))/0x1+-parseInt(_0x41a6fb(0x206))/0x2*(parseInt(_0x41a6fb(0x202))/0x3)+parseInt(_0x41a6fb(0x236))/0x4*(parseInt(_0x41a6fb(0x215))/0x5)+-parseInt(_0x41a6fb(0x205))/0x6+parseInt(_0x41a6fb(0x1f8))/0x7+parseInt(_0x41a6fb(0x1ee))/0x8+parseInt(_0x41a6fb(0x1f4))/0x9*(-parseInt(_0x41a6fb(0x227))/0xa);if(_0x332e74===_0x2c588a)break;else stringArray['push'](stringArray['shift']());}catch(_0x1b51e8){stringArray['push'](stringArray['shift']());}}}(_0x21f0,0x65140));import{Delivery}from'./delivery.js';import{gateMessage}from'./gating.js';import{createSessionMessageQueue,hasSpoolRecords,migrateWorkspaceSpool,stableSessionEndpointId}from'./queue.js';import{SessionTracker}from'./session-tracker.js';import{stripNameSuffix,withNameSuffix}from'./title-suffix.js';function _0x59e8(_0x5e9c0b,_0x1168e8){_0x5e9c0b=_0x5e9c0b-0x1d8;const _0x21f0d2=_0x21f0();let _0x59e8df=_0x21f0d2[_0x5e9c0b];if(_0x59e8['OzPoYZ']===undefined){var _0x21fd23=function(_0x26c309){const _0x22224b='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x2e1e5a='',_0x54500a='';for(let _0x409034=0x0,_0x466f98,_0xe53bef,_0x5845d5=0x0;_0xe53bef=_0x26c309['charAt'](_0x5845d5++);~_0xe53bef&&(_0x466f98=_0x409034%0x4?_0x466f98*0x40+_0xe53bef:_0xe53bef,_0x409034++%0x4)?_0x2e1e5a+=String['fromCharCode'](0xff&_0x466f98>>(-0x2*_0x409034&0x6)):0x0){_0xe53bef=_0x22224b['indexOf'](_0xe53bef);}for(let _0x2668c8=0x0,_0x50f815=_0x2e1e5a['length'];_0x2668c8<_0x50f815;_0x2668c8++){_0x54500a+='%'+('00'+_0x2e1e5a['charCodeAt'](_0x2668c8)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x54500a);};_0x59e8['NhxgVc']=_0x21fd23,_0x59e8['eXsSlk']={},_0x59e8['OzPoYZ']=!![];}const _0x3703a1=_0x21f0d2[0x0];_0x59e8['BEswRt']!==_0x3703a1&&(_0x59e8['eXsSlk']={},_0x59e8['BEswRt']=_0x3703a1);const _0x515acb=_0x59e8['eXsSlk'][_0x5e9c0b];return _0x515acb===undefined?(_0x59e8df=_0x59e8['NhxgVc'](_0x59e8df),_0x59e8['eXsSlk'][_0x5e9c0b]=_0x59e8df):_0x59e8df=_0x515acb,_0x59e8df;}function _0x54500a(_0x466f98){const _0x36d6fd=_0x59e8;return _0x466f98?.[_0x36d6fd(0x1e2)];}function _0x409034(_0xe53bef){const _0x32a456=_0x59e8,_0x5845d5=_0xe53bef?.[_0x32a456(0x235)];return _0x5845d5===_0x32a456(0x21b)||_0x5845d5==='retry'?_0x5845d5:_0x32a456(0x21a);}export function SessionRuntime(_0x2668c8){const _0x4b58d1=_0x59e8,_0x50f815=new Map(),_0x374bd9=new Set();let _0x8af9cf=_0x4b58d1(0x208),stopPromise=null,readyPromise=null,_0x21497b=()=>{};function _0x4c906c(_0xe05c5f,_0x360dda){const _0x569366=_0x4b58d1;if(_0x8af9cf!==_0x569366(0x208))return Promise[_0x569366(0x220)](_0xe05c5f);const _0x136fb8=_0x360dda();return _0x374bd9['add'](_0x136fb8),void _0x136fb8[_0x569366(0x1dc)](()=>_0x374bd9[_0x569366(0x1e6)](_0x136fb8))[_0x569366(0x207)](()=>{}),_0x136fb8;}function _0x205265(_0x1a7142=[..._0x50f815[_0x4b58d1(0x1dd)]()]){const _0x42711e=_0x4b58d1,_0x1d57fb=_0x1a7142[_0x42711e(0x1f3)](_0x4f5332=>!_0x4f5332[_0x42711e(0x22c)][_0x42711e(0x213)]);return(_0x1d57fb[_0x42711e(0x1f2)]>0x0?_0x1d57fb:_0x1a7142)[_0x42711e(0x1e1)]()['sort']((_0x46239b,_0x1294e6)=>_0x1294e6[_0x42711e(0x22e)]-_0x46239b['updatedAt']||_0x1294e6[_0x42711e(0x22c)][_0x42711e(0x1da)][_0x42711e(0x21e)]-_0x46239b[_0x42711e(0x22c)][_0x42711e(0x1da)][_0x42711e(0x21e)]||_0x1294e6[_0x42711e(0x22c)]['id']['localeCompare'](_0x46239b[_0x42711e(0x22c)]['id']))[0x0]??null;}async function _0x38f1c7(_0x15eb83,_0x19277b){const _0x418c36=_0x4b58d1,_0x525fdf=_0x50f815[_0x418c36(0x223)](_0x15eb83['id']);if(_0x525fdf){_0x525fdf[_0x418c36(0x22c)]=_0x15eb83,_0x525fdf[_0x418c36(0x22e)]=Math['max'](_0x525fdf[_0x418c36(0x22e)],_0x15eb83[_0x418c36(0x1da)][_0x418c36(0x1f6)]);if(_0x19277b)_0x10799e(_0x525fdf,_0x19277b);if(_0x15eb83[_0x418c36(0x204)])_0x525fdf[_0x418c36(0x204)]=_0x15eb83[_0x418c36(0x204)];return _0x525fdf;}const _0x42a67d=createSessionMessageQueue({'config':_0x2668c8[_0x418c36(0x20b)],'sessionId':_0x15eb83['id'],'logger':_0x2668c8['logger']});await _0x42a67d[_0x418c36(0x225)]();const _0x1a5f9c=SessionTracker();_0x1a5f9c['noteIdle'](_0x15eb83['id']);const _0x5879d3={'session':_0x15eb83,'endpointId':stableSessionEndpointId(_0x15eb83['id']),'status':_0x19277b??_0x418c36(0x21a),'updatedAt':_0x15eb83[_0x418c36(0x1da)][_0x418c36(0x1f6)],'queue':_0x42a67d,'tracker':_0x1a5f9c,'agent':_0x15eb83[_0x418c36(0x204)],'delivery':undefined};if(_0x5879d3[_0x418c36(0x231)]!==_0x418c36(0x21a))_0x1a5f9c['noteBusy'](_0x15eb83['id']);return _0x5879d3[_0x418c36(0x1fa)]=Delivery({'client':_0x2668c8[_0x418c36(0x226)],'tracker':_0x1a5f9c,'queue':_0x42a67d,'directory':_0x15eb83[_0x418c36(0x228)]||_0x2668c8['directory'],'logger':_0x2668c8[_0x418c36(0x20a)],'immediate':!![],'agent':()=>_0x5879d3[_0x418c36(0x204)],'onAgentRejected':()=>{const _0x41231f=_0x418c36;_0x5879d3[_0x41231f(0x204)]=undefined;}}),_0x50f815[_0x418c36(0x1df)](_0x15eb83['id'],_0x5879d3),_0x5879d3;}function _0x10799e(_0x57c9a4,_0x585591){const _0x14c533=_0x4b58d1;_0x57c9a4[_0x14c533(0x231)]=_0x585591,_0x57c9a4['updatedAt']=Math['max'](_0x57c9a4['updatedAt'],Date[_0x14c533(0x222)]());if(_0x585591===_0x14c533(0x21a))_0x57c9a4[_0x14c533(0x1de)][_0x14c533(0x217)](_0x57c9a4[_0x14c533(0x22c)]['id']);else _0x57c9a4['tracker'][_0x14c533(0x1fc)](_0x57c9a4[_0x14c533(0x22c)]['id']);}async function _0x100637(_0x13de23,_0x41515c={}){const _0x2001f7=_0x4b58d1,_0x236f36=new Set(),_0x35f02b=[_0x13de23];while(_0x35f02b[_0x2001f7(0x1f2)]>0x0){const _0x1f9d4f=_0x35f02b[_0x2001f7(0x22b)]();if(_0x236f36[_0x2001f7(0x218)](_0x1f9d4f['id']))continue;_0x236f36[_0x2001f7(0x22a)](_0x1f9d4f['id']);try{const _0xe3bbd9=await _0x2668c8['client'][_0x2001f7(0x22c)][_0x2001f7(0x20c)]({'path':{'id':_0x1f9d4f['id']},'query':{'directory':_0x1f9d4f['directory']||_0x2668c8['directory']}});for(const _0x2ca7ce of _0x54500a(_0xe3bbd9)??[]){const _0x5b3a5e=Object[_0x2001f7(0x1fb)][_0x2001f7(0x224)][_0x2001f7(0x212)](_0x41515c,_0x2ca7ce['id'])?_0x409034(_0x41515c[_0x2ca7ce['id']]):undefined;await _0x38f1c7(_0x2ca7ce,_0x5b3a5e),_0x35f02b[_0x2001f7(0x1ff)](_0x2ca7ce);}}catch(_0x1e7d3c){await _0x2668c8['logger'](_0x2001f7(0x20e),_0x2001f7(0x201),{'error':String(_0x1e7d3c),'sessionId':_0x1f9d4f['id']});}}}async function _0x306ba8(_0x22a620){const _0x5d534b=_0x4b58d1,_0x37f734=_0x50f815[_0x5d534b(0x223)](_0x22a620);if(_0x37f734)return _0x37f734;try{const _0xd2ec8d=await _0x2668c8[_0x5d534b(0x226)][_0x5d534b(0x22c)]['get']({'path':{'id':_0x22a620},'query':{'directory':_0x2668c8['directory']}}),_0xf4d90a=_0x54500a(_0xd2ec8d);return _0xf4d90a?_0x38f1c7(_0xf4d90a):null;}catch{return null;}}function _0x576e94(){const _0x15ab3c=_0x4b58d1;return[..._0x50f815['values']()][_0x15ab3c(0x1f3)](_0x1cec7f=>!_0x1cec7f[_0x15ab3c(0x22c)][_0x15ab3c(0x213)]);}async function _0x3e819f(_0x16d329,_0x374791){const _0x3e7862=_0x4b58d1,_0x5cad2e=_0x2668c8[_0x3e7862(0x226)]['session'];if(typeof _0x5cad2e[_0x3e7862(0x1e9)]!=='function')return;await _0x5cad2e[_0x3e7862(0x1e9)]({'path':{'id':_0x16d329['session']['id']},'query':{'directory':_0x16d329[_0x3e7862(0x22c)][_0x3e7862(0x228)]||_0x2668c8[_0x3e7862(0x228)]},'body':{'title':_0x374791}}),_0x16d329[_0x3e7862(0x22c)]={..._0x16d329[_0x3e7862(0x22c)],'title':_0x374791};}async function _0x3bddb0(_0x4d0285,_0x56ccd9){const _0x503a63=_0x4b58d1,_0x7de8fa=_0x4d0285[_0x503a63(0x22c)][_0x503a63(0x1d8)]??'',_0x2d0ffe=withNameSuffix(_0x7de8fa,_0x56ccd9);if(_0x2d0ffe===_0x7de8fa)return;try{await _0x3e819f(_0x4d0285,_0x2d0ffe);}catch(_0x5b04c3){await _0x2668c8[_0x503a63(0x20a)]('warn',_0x503a63(0x203),{'error':String(_0x5b04c3),'sessionId':_0x4d0285[_0x503a63(0x22c)]['id']});}}async function _0x471726(_0x21ee96){const _0x2ec88b=_0x4b58d1;if(!_0x2668c8['config'][_0x2ec88b(0x1d9)])return;await Promise[_0x2ec88b(0x214)](_0x576e94()['map'](_0xfca26b=>_0x3bddb0(_0xfca26b,_0x21ee96)));}async function _0x2c1dcc(){const _0x440c68=_0x4b58d1;await Promise['all'](_0x576e94()[_0x440c68(0x210)](async _0xa03466=>{const _0x21f3bb=_0x440c68,_0x1776f8=_0xa03466[_0x21f3bb(0x22c)][_0x21f3bb(0x1d8)]??'',_0x5b7b4f=stripNameSuffix(_0x1776f8);if(_0x5b7b4f===_0x1776f8)return;try{await _0x3e819f(_0xa03466,_0x5b7b4f);}catch(_0x5ac094){await _0x2668c8[_0x21f3bb(0x20a)](_0x21f3bb(0x20f),_0x21f3bb(0x1fd),{'error':String(_0x5ac094),'sessionId':_0xa03466[_0x21f3bb(0x22c)]['id']});}}));}return{'initialize'(){const _0x3dba0d=_0x4b58d1;return!readyPromise&&(readyPromise=new Promise(_0x476f5d=>{_0x21497b=_0x476f5d;})),_0x4c906c(undefined,async()=>{const _0x22bd89=_0x59e8,[listedResponse,statusResponse]=await Promise[_0x22bd89(0x214)]([_0x2668c8[_0x22bd89(0x226)][_0x22bd89(0x22c)][_0x22bd89(0x1e4)]({'query':{'directory':_0x2668c8['directory']}}),_0x2668c8[_0x22bd89(0x226)]['session']['status']({'query':{'directory':_0x2668c8[_0x22bd89(0x228)]}})]),_0xfa825=_0x54500a(listedResponse)??[],_0x41c1c2=_0x54500a(statusResponse)??{},_0x42fade=(_0xfa825['filter'](_0x5344ca=>!_0x5344ca[_0x22bd89(0x213)])[_0x22bd89(0x1f2)]>0x0?_0xfa825[_0x22bd89(0x1f3)](_0x59b96a=>!_0x59b96a['parentID']):_0xfa825)[_0x22bd89(0x1e1)]()[_0x22bd89(0x229)]((_0x2b65c6,_0xe3be28)=>_0xe3be28[_0x22bd89(0x1da)][_0x22bd89(0x1f6)]-_0x2b65c6[_0x22bd89(0x1da)]['updated']||_0xe3be28[_0x22bd89(0x1da)][_0x22bd89(0x21e)]-_0x2b65c6[_0x22bd89(0x1da)]['created']||_0xe3be28['id'][_0x22bd89(0x1e0)](_0x2b65c6['id']))[0x0];_0x42fade&&await migrateWorkspaceSpool({'config':_0x2668c8[_0x22bd89(0x20b)],'directory':_0x2668c8[_0x22bd89(0x228)],'targetSessionId':_0x42fade['id'],'logger':_0x2668c8[_0x22bd89(0x20a)]});const _0x4ad810=new Map(_0xfa825[_0x22bd89(0x210)](_0x253a61=>[_0x253a61['id'],_0x253a61]));for(const [_0x18637f,_0x141f5e]of Object[_0x22bd89(0x1f5)](_0x41c1c2)){const _0x3546d9=_0x409034(_0x141f5e);if(_0x3546d9===_0x22bd89(0x21a))continue;let _0x40e5fb=_0x4ad810[_0x22bd89(0x223)](_0x18637f);if(!_0x40e5fb)try{const _0x24e5aa=await _0x2668c8['client'][_0x22bd89(0x22c)][_0x22bd89(0x223)]({'path':{'id':_0x18637f},'query':{'directory':_0x2668c8[_0x22bd89(0x228)]}});_0x40e5fb=_0x54500a(_0x24e5aa);}catch{_0x40e5fb=undefined;}if(_0x40e5fb)await _0x38f1c7(_0x40e5fb,_0x3546d9);}for(const _0x4dcb28 of _0xfa825){if(_0x50f815[_0x22bd89(0x218)](_0x4dcb28['id']))continue;if(hasSpoolRecords(_0x2668c8[_0x22bd89(0x20b)],_0x4dcb28['id'])){const _0x43bd7a=await _0x38f1c7(_0x4dcb28,_0x409034(_0x41c1c2[_0x4dcb28['id']]));await _0x43bd7a['delivery']['flush']();}}})[_0x3dba0d(0x1dc)](()=>_0x21497b());},'whenReady'(){return!readyPromise&&(readyPromise=new Promise(_0x31f5ca=>{_0x21497b=_0x31f5ca;})),readyPromise;},'stop'(){const _0x5d1583=_0x4b58d1;if(stopPromise)return stopPromise;return _0x8af9cf=_0x5d1583(0x1f7),_0x21497b(),stopPromise=((async()=>{const _0x22b3c0=_0x5d1583;await Promise[_0x22b3c0(0x1eb)]([..._0x374bd9]),_0x8af9cf=_0x22b3c0(0x216);})()),stopPromise;},'registryEndpoints'(){const _0x4d82e9=_0x4b58d1;return[..._0x50f815[_0x4d82e9(0x1dd)]()][_0x4d82e9(0x210)](_0x18cc3e=>({'endpointId':_0x18cc3e[_0x4d82e9(0x1ec)],'sessionId':_0x18cc3e[_0x4d82e9(0x22c)]['id'],..._0x18cc3e[_0x4d82e9(0x22c)]['parentID']?{'parentSessionId':_0x18cc3e[_0x4d82e9(0x22c)][_0x4d82e9(0x213)]}:{},'title':_0x18cc3e['session'][_0x4d82e9(0x1d8)],'name':_0x2668c8[_0x4d82e9(0x1e8)](),'directory':_0x18cc3e['session'][_0x4d82e9(0x228)]||_0x2668c8[_0x4d82e9(0x228)],'status':_0x18cc3e[_0x4d82e9(0x231)],'startedAt':_0x18cc3e[_0x4d82e9(0x22c)]['time'][_0x4d82e9(0x21e)],'updatedAt':_0x18cc3e[_0x4d82e9(0x22e)],'queuedCount':_0x18cc3e[_0x4d82e9(0x209)][_0x4d82e9(0x1e3)]()}));},'publishableEndpoints'(){const _0x2ddcd0=_0x4b58d1,_0x2a98a9=[..._0x50f815[_0x2ddcd0(0x1dd)]()],_0x1d8dfc=_0x205265(_0x2a98a9);return _0x2a98a9[_0x2ddcd0(0x1f3)](_0x14f256=>_0x14f256===_0x1d8dfc||_0x14f256[_0x2ddcd0(0x231)]!==_0x2ddcd0(0x21a)||_0x14f256['queue'][_0x2ddcd0(0x1e3)]()>0x0)[_0x2ddcd0(0x210)](_0x2acd91=>({'endpointId':_0x2acd91[_0x2ddcd0(0x1ec)],'sessionId':_0x2acd91[_0x2ddcd0(0x22c)]['id'],..._0x2acd91[_0x2ddcd0(0x22c)][_0x2ddcd0(0x213)]?{'parentSessionId':_0x2acd91[_0x2ddcd0(0x22c)][_0x2ddcd0(0x213)]}:{},'title':_0x2acd91[_0x2ddcd0(0x22c)][_0x2ddcd0(0x1d8)],'name':_0x2668c8[_0x2ddcd0(0x1e8)](),'directory':_0x2acd91[_0x2ddcd0(0x22c)][_0x2ddcd0(0x228)]||_0x2668c8[_0x2ddcd0(0x228)],'status':_0x2acd91[_0x2ddcd0(0x231)],'startedAt':_0x2acd91[_0x2ddcd0(0x22c)][_0x2ddcd0(0x1da)][_0x2ddcd0(0x21e)],'updatedAt':_0x2acd91[_0x2ddcd0(0x22e)],'queuedCount':_0x2acd91['queue'][_0x2ddcd0(0x1e3)]()}));},'compatibilityEndpointId'(){return _0x205265()?.['endpointId']??null;},'hasEndpoint'(_0xb6d746){const _0x442d9b=_0x4b58d1;return[..._0x50f815['values']()][_0x442d9b(0x1fe)](_0x5297fd=>_0x5297fd[_0x442d9b(0x1ec)]===_0xb6d746);},'endpointIdForSession'(_0x5ef5a8){const _0x5e7104=_0x4b58d1;return _0x50f815[_0x5e7104(0x223)](_0x5ef5a8)?.[_0x5e7104(0x1ec)]??null;},'receive'(_0x3eef9d,_0x555bc7,_0x2130d6){return _0x4c906c('dropped',async()=>{const _0x54c2c3=_0x59e8,_0x40eb18=[..._0x50f815[_0x54c2c3(0x1dd)]()][_0x54c2c3(0x22f)](_0x538b20=>_0x538b20[_0x54c2c3(0x1ec)]===_0x555bc7);if(!_0x40eb18)return'dropped';const _0x33fb65=_0x40eb18[_0x54c2c3(0x209)][_0x54c2c3(0x1db)](_0x3eef9d);if(_0x33fb65)return _0x33fb65;if(_0x40eb18[_0x54c2c3(0x209)][_0x54c2c3(0x221)](_0x3eef9d))return'duplicate';const _0x32552e=gateMessage(_0x2130d6,_0x3eef9d,_0x40eb18[_0x54c2c3(0x22c)][_0x54c2c3(0x228)]||_0x2668c8['directory']);if(_0x32552e===_0x54c2c3(0x219))return(await _0x40eb18[_0x54c2c3(0x209)][_0x54c2c3(0x219)](_0x3eef9d))[_0x54c2c3(0x231)];if(_0x32552e==='hold'){if(!await _0x40eb18[_0x54c2c3(0x209)][_0x54c2c3(0x1f1)](_0x3eef9d))return _0x54c2c3(0x230);return void _0x40eb18[_0x54c2c3(0x1fa)][_0x54c2c3(0x20d)](_0x54c2c3(0x21f)+_0x3eef9d['from'][_0x54c2c3(0x1e8)]+_0x54c2c3(0x211)),_0x54c2c3(0x1ed);}if(!_0x40eb18[_0x54c2c3(0x209)][_0x54c2c3(0x232)](_0x3eef9d))return _0x40eb18[_0x54c2c3(0x209)][_0x54c2c3(0x1db)](_0x3eef9d)??_0x54c2c3(0x230);return await _0x40eb18[_0x54c2c3(0x1fa)][_0x54c2c3(0x1e7)](),_0x40eb18[_0x54c2c3(0x209)]['existingStatus'](_0x3eef9d)??_0x54c2c3(0x200);});},'handleEvent'(_0xed4773){return _0x4c906c(![],async()=>{const _0x2c5aa8=_0x59e8,_0x373e7e=_0xed4773['properties']??{},_0x53177a=_0x373e7e[_0x2c5aa8(0x21d)];if(_0xed4773[_0x2c5aa8(0x235)]===_0x2c5aa8(0x1f9)||_0xed4773['type']===_0x2c5aa8(0x1e5)){if(!_0x53177a?.['id'])return![];await _0x38f1c7(_0x53177a);if(_0xed4773[_0x2c5aa8(0x235)]===_0x2c5aa8(0x1f9))await _0x100637(_0x53177a);if(_0x2668c8[_0x2c5aa8(0x20b)][_0x2c5aa8(0x1d9)]&&!_0x53177a[_0x2c5aa8(0x213)]){const _0x475e05=_0x50f815[_0x2c5aa8(0x223)](_0x53177a['id']);if(_0x475e05)await _0x3bddb0(_0x475e05,_0x2668c8[_0x2c5aa8(0x1e8)]());}return!![];}if(_0xed4773['type']===_0x2c5aa8(0x21c)){if(!_0x53177a?.['id'])return![];const _0x1963bc=new Set([_0x53177a['id']]);let _0x48880b=!![];while(_0x48880b){_0x48880b=![];for(const _0x10b5fb of _0x50f815['values']()){_0x10b5fb[_0x2c5aa8(0x22c)][_0x2c5aa8(0x213)]&&_0x1963bc['has'](_0x10b5fb[_0x2c5aa8(0x22c)]['parentID'])&&!_0x1963bc[_0x2c5aa8(0x218)](_0x10b5fb[_0x2c5aa8(0x22c)]['id'])&&(_0x1963bc[_0x2c5aa8(0x22a)](_0x10b5fb[_0x2c5aa8(0x22c)]['id']),_0x48880b=!![]);}}for(const _0x4643f1 of _0x1963bc)_0x50f815[_0x2c5aa8(0x1e6)](_0x4643f1);return!![];}if(_0xed4773[_0x2c5aa8(0x235)]===_0x2c5aa8(0x234)||_0xed4773[_0x2c5aa8(0x235)]===_0x2c5aa8(0x233)){const _0x13c5b9=_0x373e7e[_0x2c5aa8(0x1f0)];if(!_0x13c5b9)return![];const _0x2fc0cc=await _0x306ba8(_0x13c5b9);if(!_0x2fc0cc)return![];return _0x10799e(_0x2fc0cc,_0xed4773[_0x2c5aa8(0x235)]===_0x2c5aa8(0x233)?_0x2c5aa8(0x21a):_0x409034(_0x373e7e[_0x2c5aa8(0x231)])),!![];}return![];});},'noteActivity'(_0x475130){return _0x4c906c(undefined,async()=>{const _0x1b7106=_0x59e8,_0xdb6097=await _0x306ba8(_0x475130);if(_0xdb6097)_0x10799e(_0xdb6097,_0x1b7106(0x21b));});},'noteAgent'(_0x384e42,_0x5c16d7){return _0x4c906c(undefined,async()=>{const _0x2afb42=_0x59e8,_0x49bb9f=await _0x306ba8(_0x384e42);if(_0x49bb9f)_0x49bb9f[_0x2afb42(0x204)]=_0x5c16d7;});},'queueForSession'(_0x3785a5){const _0x47616c=_0x4b58d1;return _0x50f815[_0x47616c(0x223)](_0x3785a5)?.[_0x47616c(0x209)]??null;},'deliveryForSession'(_0x45ced7){const _0x30c927=_0x4b58d1;return _0x50f815[_0x30c927(0x223)](_0x45ced7)?.[_0x30c927(0x1fa)]??null;},'sweep'(){return _0x4c906c(undefined,async()=>{const _0x52d77b=_0x59e8;for(const _0x2e1832 of _0x50f815[_0x52d77b(0x1dd)]()){await _0x2e1832[_0x52d77b(0x209)][_0x52d77b(0x1ea)](),await _0x2e1832[_0x52d77b(0x1fa)][_0x52d77b(0x1e7)]();}});},'pendingAcknowledgements'(){const _0x6161a9=_0x4b58d1;return[..._0x50f815[_0x6161a9(0x1dd)]()][_0x6161a9(0x1ef)](_0x4f3e1c=>_0x4f3e1c[_0x6161a9(0x209)]['pendingAcknowledgements']()[_0x6161a9(0x210)](_0xcbc008=>({'queue':_0x4f3e1c[_0x6161a9(0x209)],'acknowledgement':_0xcbc008})));},'retitleRoots'(_0x4650b7){return _0x4c906c(undefined,()=>_0x471726(_0x4650b7));},'clearSuffixes'(){return _0x2c1dcc();}};}function _0x21f0(){const _0x3ab9ea=['CxvLDwvK','zMfPBgvKihrVigXPC3qGC2vZC2LVBIbJAgLSzhjLBG','nKv2vfHova','zMfPBgvKihrVihvWzgf0zsbZzxnZAw9UihrPDgXL','ywDLBNq','ndu0mdq3mezmwLf0wG','nJm0nJi4CvLbrMTW','y2f0y2G','CNvUBMLUzW','CxvLDwu','Bg9Nz2vY','y29UzMLN','y2HPBgrYzw4','BM90AwnL','zgvIDwC','D2fYBG','BwfW','iIdIGjqGl3bLzxjZlwLUyM94ihrVihjLDMLLDW','y2fSBa','CgfYzw50suq','ywXS','mtvnEuvOELu','C3rVChbLza','BM90zuLKBgu','AgfZ','CMvMDxnL','AwrSzq','yNvZEq','C2vZC2LVBI5KzwXLDgvK','Aw5MBW','y3jLyxrLza','8j+tPsbizwXKig1LC3nHz2uGzNjVBsaI','CMvZB2X2zq','AxnezwjVDw5Jzwq','BM93','z2v0','AgfZt3DUuhjVCgvYDhK','Bg9HzeHLBgq','y2XPzw50','odiXmePgsgPuua','zgLYzwn0B3j5','C29YDa','ywrK','C2HPzNq','C2vZC2LVBG','ndK1nJe5DKrLsNnl','DxbKyxrLzef0','zMLUza','zNvSBa','C3rHDhvZ','zw5XDwv1zq','C2vZC2LVBI5PzgXL','C2vZC2LVBI5ZDgf0Dxm','DhLWzq','mty1nZm2B3LMvLfi','DgL0Bgu','C2HVD05HBwvjBLrPDgXL','DgLTzq','zxHPC3rPBMDtDgf0Dxm','zMLUywXSEq','DMfSDwvZ','DhjHy2TLCG','C2v0','Bg9JywXLq29TCgfYzq','C2XPy2u','zgf0yq','C2L6zq','BgLZDa','C2vZC2LVBI51CgrHDgvK','zgvSzxrL','zMX1C2G','BMfTzq','DxbKyxrL','zxHWAxjLsgvSza','ywXSu2v0DgXLza','zw5KCg9PBNrjza','AgvSza','nJqWodCWnePPquPWEq','zMXHDe1HCa','C2vZC2LVBKLe','Ag9Sza','BgvUz3rO','zMLSDgvY','odm3EhHlqLvq','zw50CMLLCW','DxbKyxrLza','C3rVChbPBMC','mZiYnteZmvnxuerWtW','C2vZC2LVBI5JCMvHDgvK','zgvSAxzLCNK','ChjVDg90ExbL','BM90zuj1C3K','zMfPBgvKihrVignSzwfYihnLC3nPB24GDgL0BguGC3vMzML4','C29Tzq','ChvZAa'];_0x21f0=function(){return _0x3ab9ea;};return _0x21f0();}
|
|
2
|
+
//# sourceMappingURL=.js.map
|
package/dist/session-tracker.js
CHANGED
|
@@ -1,39 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* it is idle. opencode plugins are per-server, not per-session, so the
|
|
4
|
-
* active session is a heuristic: the session that most recently produced
|
|
5
|
-
* user activity.
|
|
6
|
-
*/
|
|
7
|
-
export function SessionTracker() {
|
|
8
|
-
let activeId = null;
|
|
9
|
-
let activeTitle = null;
|
|
10
|
-
let idle = true;
|
|
11
|
-
return {
|
|
12
|
-
activeSessionId: () => activeId,
|
|
13
|
-
activeSessionTitle: () => activeTitle,
|
|
14
|
-
isIdle: () => idle,
|
|
15
|
-
noteUserActivity(sessionId, title) {
|
|
16
|
-
activeId = sessionId;
|
|
17
|
-
if (title)
|
|
18
|
-
activeTitle = title;
|
|
19
|
-
idle = false;
|
|
20
|
-
},
|
|
21
|
-
noteIdle(sessionId) {
|
|
22
|
-
if (!sessionId || sessionId === activeId)
|
|
23
|
-
idle = true;
|
|
24
|
-
if (!activeId && sessionId)
|
|
25
|
-
activeId = sessionId;
|
|
26
|
-
},
|
|
27
|
-
noteBusy(sessionId) {
|
|
28
|
-
if (!sessionId || sessionId === activeId)
|
|
29
|
-
idle = false;
|
|
30
|
-
},
|
|
31
|
-
noteDeleted(sessionId) {
|
|
32
|
-
if (activeId === sessionId) {
|
|
33
|
-
activeId = null;
|
|
34
|
-
activeTitle = null;
|
|
35
|
-
idle = true;
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
};
|
|
39
|
-
}
|
|
1
|
+
(function(stringArrayFunction,_0x8141f8){const _0x1020dd=_0x6c5c,stringArray=stringArrayFunction();while(!![]){try{const _0x2319fe=parseInt(_0x1020dd(0x80))/0x1*(-parseInt(_0x1020dd(0x82))/0x2)+parseInt(_0x1020dd(0x87))/0x3+parseInt(_0x1020dd(0x88))/0x4+parseInt(_0x1020dd(0x84))/0x5+-parseInt(_0x1020dd(0x81))/0x6*(-parseInt(_0x1020dd(0x89))/0x7)+-parseInt(_0x1020dd(0x86))/0x8*(-parseInt(_0x1020dd(0x85))/0x9)+-parseInt(_0x1020dd(0x83))/0xa;if(_0x2319fe===_0x8141f8)break;else stringArray['push'](stringArray['shift']());}catch(_0x3e973e){stringArray['push'](stringArray['shift']());}}}(_0x4c9b,0xd7c63));function _0x6c5c(_0x204826,_0x2ebb3a){_0x204826=_0x204826-0x80;const _0x4c9bb2=_0x4c9b();let _0x6c5c11=_0x4c9bb2[_0x204826];if(_0x6c5c['nBTWdW']===undefined){var _0x2d98a9=function(_0xf14438){const _0x98971e='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x2a414b='',_0x173ad7='';for(let _0x161e78=0x0,_0xb45559,_0x1e2412,_0x3ac4e9=0x0;_0x1e2412=_0xf14438['charAt'](_0x3ac4e9++);~_0x1e2412&&(_0xb45559=_0x161e78%0x4?_0xb45559*0x40+_0x1e2412:_0x1e2412,_0x161e78++%0x4)?_0x2a414b+=String['fromCharCode'](0xff&_0xb45559>>(-0x2*_0x161e78&0x6)):0x0){_0x1e2412=_0x98971e['indexOf'](_0x1e2412);}for(let _0x53f1ba=0x0,_0x48db24=_0x2a414b['length'];_0x53f1ba<_0x48db24;_0x53f1ba++){_0x173ad7+='%'+('00'+_0x2a414b['charCodeAt'](_0x53f1ba)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x173ad7);};_0x6c5c['zyiTLE']=_0x2d98a9,_0x6c5c['pHHnUH']={},_0x6c5c['nBTWdW']=!![];}const _0x119220=_0x4c9bb2[0x0];_0x6c5c['UZaLPt']!==_0x119220&&(_0x6c5c['pHHnUH']={},_0x6c5c['UZaLPt']=_0x119220);const _0x2eb0f4=_0x6c5c['pHHnUH'][_0x204826];return _0x2eb0f4===undefined?(_0x6c5c11=_0x6c5c['zyiTLE'](_0x6c5c11),_0x6c5c['pHHnUH'][_0x204826]=_0x6c5c11):_0x6c5c11=_0x2eb0f4,_0x6c5c11;}export function SessionTracker(){let _0x173ad7=null,_0x161e78=null,_0xb45559=!![];return{'activeSessionId':()=>_0x173ad7,'activeSessionTitle':()=>_0x161e78,'isIdle':()=>_0xb45559,'noteUserActivity'(_0x1e2412,_0x3ac4e9){_0x173ad7=_0x1e2412;if(_0x3ac4e9)_0x161e78=_0x3ac4e9;_0xb45559=![];},'noteIdle'(_0x53f1ba){if(!_0x53f1ba||_0x53f1ba===_0x173ad7)_0xb45559=!![];if(!_0x173ad7&&_0x53f1ba)_0x173ad7=_0x53f1ba;},'noteBusy'(_0x48db24){if(!_0x48db24||_0x48db24===_0x173ad7)_0xb45559=![];},'noteDeleted'(_0x5a9d31){_0x173ad7===_0x5a9d31&&(_0x173ad7=null,_0x161e78=null,_0xb45559=!![]);}};}function _0x4c9b(){const _0x1ec222=['ndi2mZiYoeHQC0X6wa','mtuWotG4sxHjEvLI','mZe5odu2nJbqB0vwue4','oda5mZC4nwDvvLvIwa','mJK2oty0owDsu3zvsG','mJrnqKDRAgi','ndyZoda5ouLOBuDXta','mJKWode4nhbzDw9hDW','n2zRvgLdsa','mJbbuNLcr0u'];_0x4c9b=function(){return _0x1ec222;};return _0x4c9b();}
|
|
2
|
+
//# sourceMappingURL=.js.map
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stall detector — pure logic. Events in, findings out. No IO, no timers,
|
|
3
|
+
* no SDK. Time is supplied by the caller via `now`.
|
|
4
|
+
*
|
|
5
|
+
* A tool is "stalled" when it has an open record whose lastActivityAt is
|
|
6
|
+
* older than timeoutMs. Activity is refreshed by any message.part.updated
|
|
7
|
+
* refresh for the same callID. Records are closed by tool.execute.after,
|
|
8
|
+
* by a terminal part status, or by session.idle (idle means no in-flight
|
|
9
|
+
* work: a lingering record is a lost event, not a stall).
|
|
10
|
+
*
|
|
11
|
+
* NOTE: `timeoutMs` is the ONLY millisecond value in this module. External
|
|
12
|
+
* configuration is minutes; the single minutes->milliseconds conversion
|
|
13
|
+
* happens in resolveConfig (src/config.ts). Do not re-convert here.
|
|
14
|
+
*/
|
|
15
|
+
export interface StallFinding {
|
|
16
|
+
sessionID: string;
|
|
17
|
+
callID: string;
|
|
18
|
+
tool: string;
|
|
19
|
+
command: string;
|
|
20
|
+
outputSnapshot: string;
|
|
21
|
+
ageMs: number;
|
|
22
|
+
}
|
|
23
|
+
export interface StallDetectorOptions {
|
|
24
|
+
/** Idle time (ms) after which an open call is stalled. <= 0 disables. */
|
|
25
|
+
timeoutMs: number;
|
|
26
|
+
}
|
|
27
|
+
export interface StallDetectorInstance {
|
|
28
|
+
onToolBefore(input: {
|
|
29
|
+
tool: string;
|
|
30
|
+
sessionID: string;
|
|
31
|
+
callID: string;
|
|
32
|
+
args?: unknown;
|
|
33
|
+
}, now: number): void;
|
|
34
|
+
onToolAfter(input: {
|
|
35
|
+
sessionID: string;
|
|
36
|
+
callID: string;
|
|
37
|
+
}, now: number): void;
|
|
38
|
+
onEvent(event: {
|
|
39
|
+
type?: string;
|
|
40
|
+
properties?: Record<string, unknown>;
|
|
41
|
+
}, now: number): void;
|
|
42
|
+
collect(now: number): StallFinding[];
|
|
43
|
+
markTriggered(sessionID: string, callID: string): void;
|
|
44
|
+
noteAbortFailure(sessionID: string, callID: string): {
|
|
45
|
+
abandoned: boolean;
|
|
46
|
+
};
|
|
47
|
+
sessionsWithOpenRecords(): string[];
|
|
48
|
+
clearSession(sessionID: string): void;
|
|
49
|
+
hasRecord(sessionID: string, callID: string): boolean;
|
|
50
|
+
}
|
|
51
|
+
export declare function StallDetector(opts: StallDetectorOptions): StallDetectorInstance;
|
|
52
|
+
/**
|
|
53
|
+
* One-turn system directive for a stall recovery injection. Rides in the
|
|
54
|
+
* system prompt of exactly the turn that processes the recovery message
|
|
55
|
+
* (same mechanism as delivery.ts REPLY_DIRECTIVE). It must not replace the
|
|
56
|
+
* agent's own system prompt — opencode appends it.
|
|
57
|
+
*/
|
|
58
|
+
export declare const STALL_DIRECTIVE: string;
|
|
59
|
+
/**
|
|
60
|
+
* Deterministic, idempotent message id for a stall recovery injection. Uses the
|
|
61
|
+
* `msg_` prefix (the shape opencode's own message ids use, and the shape the
|
|
62
|
+
* peer delivery path already proves valid) plus a stall-specific hash input,
|
|
63
|
+
* so it can never collide with a peer message id.
|
|
64
|
+
*/
|
|
65
|
+
export declare function deterministicStallMessageId(sessionID: string, callID: string): string;
|
|
66
|
+
/** Keep the tail (newest, most diagnostic) up to 4 KB, plus a 512 B head. */
|
|
67
|
+
export declare function truncateSnapshot(text: string): string;
|
|
68
|
+
/** Build the human-readable recovery prompt injected after an abort. */
|
|
69
|
+
export declare function buildStallMessage(input: {
|
|
70
|
+
minutes: number;
|
|
71
|
+
command: string;
|
|
72
|
+
outputSnapshot: string;
|
|
73
|
+
}): string;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const _0x12aedf=_0x9dfe;(function(stringArrayFunction,_0x451b02){const _0x3de2ed=_0x9dfe,stringArray=stringArrayFunction();while(!![]){try{const _0x3636c7=-parseInt(_0x3de2ed(0x1cf))/0x1+-parseInt(_0x3de2ed(0x1cc))/0x2*(-parseInt(_0x3de2ed(0x1de))/0x3)+parseInt(_0x3de2ed(0x1bc))/0x4+-parseInt(_0x3de2ed(0x1bd))/0x5*(parseInt(_0x3de2ed(0x1fc))/0x6)+-parseInt(_0x3de2ed(0x1bf))/0x7*(parseInt(_0x3de2ed(0x1d0))/0x8)+parseInt(_0x3de2ed(0x1bb))/0x9+parseInt(_0x3de2ed(0x1d8))/0xa;if(_0x3636c7===_0x451b02)break;else stringArray['push'](stringArray['shift']());}catch(_0x2ff2bd){stringArray['push'](stringArray['shift']());}}}(_0x4c7b,0x48658));import{createHash}from'node:crypto';const _0x5daffc=0x3;function _0x10c05a(_0x298f3){const _0x18f44f=_0x9dfe;if(_0x298f3&&typeof _0x298f3===_0x18f44f(0x1e9)&&typeof _0x298f3[_0x18f44f(0x1d4)]===_0x18f44f(0x1df))return _0x298f3[_0x18f44f(0x1d4)];return'';}export function StallDetector(_0x5669b8){const _0x1aea05=new Map();function _0x47218a(_0x3d6f10,_0x140599,_0x150dbf,_0x2920a2,_0x30d75e){const _0x4b079d=_0x9dfe;let _0x1b3ba3=_0x1aea05[_0x4b079d(0x1d3)](_0x3d6f10);!_0x1b3ba3&&(_0x1b3ba3=new Map(),_0x1aea05['set'](_0x3d6f10,_0x1b3ba3));let _0x22509c=_0x1b3ba3['get'](_0x140599);if(!_0x22509c)_0x22509c={'sessionID':_0x3d6f10,'callID':_0x140599,'tool':_0x150dbf,'startedAt':_0x30d75e,'lastActivityAt':_0x30d75e,'command':_0x2920a2,'outputSnapshot':'','triggered':![],'abandoned':![],'abortFailures':0x0},_0x1b3ba3[_0x4b079d(0x1f7)](_0x140599,_0x22509c);else{_0x22509c[_0x4b079d(0x1b5)]=Math[_0x4b079d(0x1f8)](_0x22509c['lastActivityAt'],_0x30d75e);if(_0x150dbf&&_0x150dbf!==_0x4b079d(0x1c0))_0x22509c[_0x4b079d(0x1e1)]=_0x150dbf;if(_0x2920a2)_0x22509c[_0x4b079d(0x1d4)]=_0x2920a2;}return _0x22509c;}function _0x3daadb(_0xef0e13,_0x2d0752){const _0x54468d=_0x9dfe,_0x1f4da0=_0x1aea05[_0x54468d(0x1d3)](_0xef0e13);if(!_0x1f4da0)return;_0x1f4da0[_0x54468d(0x1f4)](_0x2d0752);if(_0x1f4da0[_0x54468d(0x1db)]===0x0)_0x1aea05['delete'](_0xef0e13);}function _0xf47250(_0x2aac46){const _0x3386f0=_0x9dfe;_0x1aea05[_0x3386f0(0x1f4)](_0x2aac46);}return{'onToolBefore'(_0x36f33b,_0x270d14){const _0x1025f4=_0x9dfe;if(_0x5669b8[_0x1025f4(0x1c2)]<=0x0)return;_0x47218a(_0x36f33b[_0x1025f4(0x1ea)],_0x36f33b[_0x1025f4(0x1ca)],_0x36f33b['tool'],_0x10c05a(_0x36f33b[_0x1025f4(0x1b8)]),_0x270d14);},'onToolAfter'(_0x491754){const _0x2eaf8f=_0x9dfe;_0x3daadb(_0x491754['sessionID'],_0x491754[_0x2eaf8f(0x1ca)]);},'onEvent'(_0xea7e33,_0x167383){const _0x5f1be6=_0x9dfe;if(_0x5669b8['timeoutMs']<=0x0)return;const _0x60fa5f=_0xea7e33[_0x5f1be6(0x1d1)]??{};if(_0xea7e33['type']==='session.idle'){if(typeof _0x60fa5f[_0x5f1be6(0x1ea)]===_0x5f1be6(0x1df))_0xf47250(_0x60fa5f[_0x5f1be6(0x1ea)]);return;}if(_0xea7e33[_0x5f1be6(0x1ce)]!==_0x5f1be6(0x1ec))return;const _0x37a808=_0x60fa5f[_0x5f1be6(0x1c8)];if(!_0x37a808||_0x37a808[_0x5f1be6(0x1ce)]!==_0x5f1be6(0x1e1))return;const _0x52b6ed=typeof _0x37a808[_0x5f1be6(0x1ea)]==='string'?_0x37a808[_0x5f1be6(0x1ea)]:typeof _0x60fa5f['sessionID']===_0x5f1be6(0x1df)?_0x60fa5f['sessionID']:undefined,_0x4aca65=typeof _0x37a808[_0x5f1be6(0x1ca)]===_0x5f1be6(0x1df)?_0x37a808[_0x5f1be6(0x1ca)]:undefined;if(!_0x52b6ed||!_0x4aca65)return;const _0x5b8911=_0x37a808[_0x5f1be6(0x1d2)]??{},_0xc681d=typeof _0x5b8911['status']===_0x5f1be6(0x1df)?_0x5b8911[_0x5f1be6(0x1ed)]:'';if(_0xc681d==='completed'||_0xc681d===_0x5f1be6(0x1e2)||_0xc681d===_0x5f1be6(0x1e0)){_0x3daadb(_0x52b6ed,_0x4aca65);return;}if(_0xc681d!==_0x5f1be6(0x1c1)&&_0xc681d!==_0x5f1be6(0x1e6))return;const _0xa91227=typeof _0x37a808['tool']===_0x5f1be6(0x1df)?_0x37a808[_0x5f1be6(0x1e1)]:_0x5f1be6(0x1c0),_0x3274bc=_0x47218a(_0x52b6ed,_0x4aca65,_0xa91227,_0x10c05a(_0x5b8911[_0x5f1be6(0x1b9)]),_0x167383),_0xcf52cc=_0x5b8911[_0x5f1be6(0x1eb)]&&typeof _0x5b8911[_0x5f1be6(0x1eb)]==='object'?_0x5b8911['metadata'][_0x5f1be6(0x1da)]:undefined;typeof _0xcf52cc===_0x5f1be6(0x1df)&&_0xcf52cc[_0x5f1be6(0x1d7)]>=_0x3274bc[_0x5f1be6(0x1e5)][_0x5f1be6(0x1d7)]&&(_0x3274bc[_0x5f1be6(0x1e5)]=_0xcf52cc);},'collect'(_0x278945){const _0x4a6966=_0x9dfe;if(_0x5669b8[_0x4a6966(0x1c2)]<=0x0)return[];const _0x5953c2=[];for(const _0x52cae4 of _0x1aea05[_0x4a6966(0x1d9)]()){for(const _0x2a1496 of _0x52cae4[_0x4a6966(0x1d9)]()){if(_0x2a1496[_0x4a6966(0x1f6)]||_0x2a1496[_0x4a6966(0x1f0)])continue;_0x278945-_0x2a1496[_0x4a6966(0x1b5)]>_0x5669b8[_0x4a6966(0x1c2)]&&_0x5953c2[_0x4a6966(0x1dc)]({'sessionID':_0x2a1496['sessionID'],'callID':_0x2a1496[_0x4a6966(0x1ca)],'tool':_0x2a1496[_0x4a6966(0x1e1)],'command':_0x2a1496[_0x4a6966(0x1d4)],'outputSnapshot':_0x2a1496[_0x4a6966(0x1e5)],'ageMs':_0x278945-_0x2a1496[_0x4a6966(0x1b5)]});}}return _0x5953c2;},'markTriggered'(_0x4188c2,_0x5b223a){const _0x20665f=_0x9dfe,_0x4965a9=_0x1aea05[_0x20665f(0x1d3)](_0x4188c2)?.['get'](_0x5b223a);if(_0x4965a9)_0x4965a9[_0x20665f(0x1f6)]=!![];},'noteAbortFailure'(_0x413ae3,_0x56ad4e){const _0x498038=_0x9dfe,_0x34be2b=_0x1aea05[_0x498038(0x1d3)](_0x413ae3)?.[_0x498038(0x1d3)](_0x56ad4e);if(!_0x34be2b)return{'abandoned':![]};_0x34be2b[_0x498038(0x1f3)]+=0x1;if(_0x34be2b[_0x498038(0x1f3)]>=_0x5daffc)return _0x34be2b[_0x498038(0x1f0)]=!![],{'abandoned':!![]};return{'abandoned':![]};},'sessionsWithOpenRecords'(){const _0x54af2c=_0x9dfe,_0x3ee602=[];for(const [_0x2a2e03,_0x328762]of _0x1aea05){for(const _0x206c1d of _0x328762[_0x54af2c(0x1d9)]()){if(!_0x206c1d[_0x54af2c(0x1f6)]&&!_0x206c1d[_0x54af2c(0x1f0)]){_0x3ee602[_0x54af2c(0x1dc)](_0x2a2e03);break;}}}return _0x3ee602;},'clearSession'(_0x48e891){const _0x19a596=_0x9dfe;_0x1aea05[_0x19a596(0x1f4)](_0x48e891);},'hasRecord'(_0x3545ae,_0x428160){const _0x5654d7=_0x9dfe;return _0x1aea05['get'](_0x3545ae)?.[_0x5654d7(0x1ba)](_0x428160)??![];}};}export const STALL_DIRECTIVE=_0x12aedf(0x1d5)+_0x12aedf(0x1fa)+_0x12aedf(0x1e3)+_0x12aedf(0x1c5)+'why\x20it\x20stalled\x20and\x20choose\x20a\x20different\x20approach\x20(add\x20a\x20timeout,\x20use\x20a\x20non-interactive\x20'+_0x12aedf(0x1e8)+_0x12aedf(0x1c4);function _0x9dfe(_0x39bd55,_0x638732){_0x39bd55=_0x39bd55-0x1b5;const _0x4c7ba5=_0x4c7b();let _0x9dfed2=_0x4c7ba5[_0x39bd55];if(_0x9dfe['fSyJPD']===undefined){var _0x451ce5=function(_0x45e854){const _0x4b9e18='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x37b979='',_0x5daffc='';for(let _0x10c05a=0x0,_0x26db6b,_0x28d732,_0x298f3=0x0;_0x28d732=_0x45e854['charAt'](_0x298f3++);~_0x28d732&&(_0x26db6b=_0x10c05a%0x4?_0x26db6b*0x40+_0x28d732:_0x28d732,_0x10c05a++%0x4)?_0x37b979+=String['fromCharCode'](0xff&_0x26db6b>>(-0x2*_0x10c05a&0x6)):0x0){_0x28d732=_0x4b9e18['indexOf'](_0x28d732);}for(let _0x5669b8=0x0,_0x1aea05=_0x37b979['length'];_0x5669b8<_0x1aea05;_0x5669b8++){_0x5daffc+='%'+('00'+_0x37b979['charCodeAt'](_0x5669b8)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x5daffc);};_0x9dfe['JlSMyt']=_0x451ce5,_0x9dfe['ZbfjZb']={},_0x9dfe['fSyJPD']=!![];}const _0x28ad43=_0x4c7ba5[0x0];_0x9dfe['nbRaKj']!==_0x28ad43&&(_0x9dfe['ZbfjZb']={},_0x9dfe['nbRaKj']=_0x28ad43);const _0x41dfeb=_0x9dfe['ZbfjZb'][_0x39bd55];return _0x41dfeb===undefined?(_0x9dfed2=_0x9dfe['JlSMyt'](_0x9dfed2),_0x9dfe['ZbfjZb'][_0x39bd55]=_0x9dfed2):_0x9dfed2=_0x41dfeb,_0x9dfed2;}export function deterministicStallMessageId(_0x131189,_0x4f363c){const _0x3b9c80=_0x12aedf,_0x52d3e1=createHash(_0x3b9c80(0x1c6))['update']('stall-v1\x00'+_0x131189+'\x00'+_0x4f363c)[_0x3b9c80(0x1f9)](_0x3b9c80(0x1cb));return _0x3b9c80(0x1e7)+_0x52d3e1[_0x3b9c80(0x1f2)](0x0,0x1a);}const _0x26db6b=0x1000,_0x28d732=0x200;export function truncateSnapshot(_0xdadd60){const _0x2a1b0d=_0x12aedf,_0x49eff0=Buffer[_0x2a1b0d(0x1c3)](_0xdadd60,_0x2a1b0d(0x1e4));if(_0x49eff0['length']<=_0x26db6b)return _0xdadd60;const _0x46c628=_0x49eff0[_0x2a1b0d(0x1f1)](0x0,_0x28d732)[_0x2a1b0d(0x1b7)](_0x2a1b0d(0x1e4)),_0x594307=_0x26db6b-_0x28d732,_0x19a8cd=_0x49eff0[_0x2a1b0d(0x1f1)](_0x49eff0[_0x2a1b0d(0x1d7)]-_0x594307)[_0x2a1b0d(0x1b7)](_0x2a1b0d(0x1e4)),_0x284b7e=_0x49eff0['length']-_0x28d732-_0x594307;return _0x46c628+_0x2a1b0d(0x1c7)+_0x284b7e+_0x2a1b0d(0x1ee)+_0x19a8cd;}export function buildStallMessage(_0x5c2dfd){const _0x4a9e92=_0x12aedf,_0x3f0cc8=_0x5c2dfd['command'][_0x4a9e92(0x1cd)]()?_0x5c2dfd[_0x4a9e92(0x1d4)]:_0x4a9e92(0x1fb),_0x448546=_0x5c2dfd[_0x4a9e92(0x1e5)]['trim']()?truncateSnapshot(_0x5c2dfd['outputSnapshot']):_0x4a9e92(0x1c9);return[_0x4a9e92(0x1dd),_0x4a9e92(0x1f5)+_0x5c2dfd['minutes']+_0x4a9e92(0x1b6),'',_0x4a9e92(0x1ef)+_0x3f0cc8,'\x20\x20已产生的输出(中止时快照,可能不完整):',_0x448546,'',_0x4a9e92(0x1be),_0x4a9e92(0x1d6)]['join']('\x0a');}function _0x4c7b(){const _0x4a6844=['6k+35yIK5PAT77YA6iUL6k+L5zg95lUK5y2H5Q2777Ym6k+35Qoa5P+L5y6F5zUG5BM26icd6jMr5O2I5PA55Rov77Yi6icm6z2E5y6F5Qc36yEn6k+v77Yj77YB','ntm2mJiXqMXQAgLz','Dw5RBM93BG','CNvUBMLUzW','DgLTzw91De1Z','zNjVBq','y2HHDcbYzxbSEsbPCYbZAg93BIb0BYb0AguGDxnLCI4','y2fWDhvYzwqGB3v0Chv0igLUihrOzsbTzxnZywDLlIbeBYbot1qGyMXPBMrSEsbYzs1YDw4GDgHLihnHBwuGy29TBwfUzdOGD29YAYbVDxqG','C2HHmJu2','cI4UlU+8Iow3SUAiQUAwRsa','CgfYDa','koAxOoI+K+whUIK','y2fSBeLe','Agv4','mte5mLHgEvDvAG','DhjPBq','DhLWzq','mJqYmZi5D016z2vI','ndHPBwHLwva','ChjVCgvYDgLLCW','C3rHDgu','z2v0','y29TBwfUza','vgHPCYb0DxjUihDHCYb0CMLNz2vYzwqGyNKGyw4Gyxv0B21HDgvKihn0ywXSlwrLDgvJDgLVBIbUB3rPzMLJyxrPB24GzNjVBsb0AguG','6iUL5A6d5PYS5BQu6zYa6kAb5PU06zw/5PE26zE077Ym6k+35zgk55+L55sO5OI36lcd5Pw06zIi5yc877Yi546V5Akd5y+y6yEpie9qru5dt0rfx0npteXbqL9tvefmtf9usu1ft1vux01jtU+8IEAiLUEuQcaWioEMGEEuQoACRowkN+IdVEoaGG','BgvUz3rO','nJG2mJK0menKy1fODq','DMfSDwvZ','B3v0Chv0','C2L6zq','ChvZAa','w+IhQUwkQowmLUwbNoA7NUAJGoA1I+ApKoEKUIdIGjqGB3bLBMnVzguTy29SBgfIB3jHDgLVBIdMJ5lKU7zD','mJD0BufJzM8','C3rYAw5N','zMfPBgvK','Dg9VBa','zxjYB3i','ChjVz3jLC3mGzM9YigeGBg9UzYb0Aw1LigfUzcb3yxmGyxv0B21HDgLJywXSEsbHyM9YDgvKlIbszwfKihrOzsbJB21Tyw5KigfUzcbPDhmG','DxrMoa','B3v0Chv0u25HChnOB3q','CgvUzgLUzW','BxnNxW','zM9YBsWGy2HLy2SGDgHLigv4DgvYBMfSigrLCgvUzgvUy3KGAxqGD2fZihDHAxrPBMCGB24Sig9YigfZAYb0AguGDxnLCIKUifLVDxiGBM9YBwfSia','B2jQzwn0','C2vZC2LVBKLe','Bwv0ywrHDge','BwvZC2fNzs5Wyxj0lNvWzgf0zwq','C3rHDhvZ','iowTL+IkGU+8Is4UlGO','icdLKB3KU6tVVjO','ywjHBMrVBMvK','C3vIyxjYyxK','C2XPy2u','ywjVCNrgywLSDxjLCW','zgvSzxrL','5Qoa5Rwl5yIW5lUL5lIl5zg95lUK6l+q6kgm6lAf6l+hia','DhjPz2DLCMvK','C2v0','Bwf4','zgLNzxn0','B3bLBMnVzguTy29SBgfIB3jHDgLVBIbWBhvNAw4Sig5VDcbIEsb5B3vYihvZzxiUieeGDg9VBcbJywXSigfWCgvHCMvKihrVig1HA2uGBM8G','koACQUIdVEAnLEIoT+wrVEs7PowoN+AwHYK','mte0nZHqsMrMBgq','BgfZDefJDgL2Axr5qxq','iowiHUMsN+AxOoI/M+wXLE+8Jow3SUIhQUwkQos4REATOU+8IgfIB3j077Yj77YA','Dg9tDhjPBMC','yxjNCW','Aw5WDxq','AgfZ','mtqWmteWmMDsBMjWtq','mJi3mJCYngXpExbluq','mta5me1Aser0vq'];_0x4c7b=function(){return _0x4a6844;};return _0x4c7b();}
|
|
2
|
+
//# sourceMappingURL=.js.map
|
package/dist/title-suffix.js
CHANGED
|
@@ -1,23 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* e.g. "Fix login bug(张三)", so a user can always see which opencode process
|
|
4
|
-
* a session belongs to. The suffix is stripped again on graceful exit.
|
|
5
|
-
*
|
|
6
|
-
* A trailing "(...)" is only treated as our suffix when its content is a
|
|
7
|
-
* valid peer name; ordinary parenthetical text is left alone.
|
|
8
|
-
*/
|
|
9
|
-
import { validateName } from "./config.js";
|
|
10
|
-
/** Remove a trailing "(name)" suffix whose content is a valid peer name. */
|
|
11
|
-
export function stripNameSuffix(title) {
|
|
12
|
-
const match = title.match(/^(.*?)\s*\(([^()]*)\)$/);
|
|
13
|
-
if (!match)
|
|
14
|
-
return title;
|
|
15
|
-
if (validateName(match[2].trim()) !== null)
|
|
16
|
-
return title;
|
|
17
|
-
return match[1].trimEnd();
|
|
18
|
-
}
|
|
19
|
-
/** Append the name suffix, replacing any existing name suffix. */
|
|
20
|
-
export function withNameSuffix(title, name) {
|
|
21
|
-
const base = stripNameSuffix(title).trim();
|
|
22
|
-
return base ? `${base}(${name})` : `(${name})`;
|
|
23
|
-
}
|
|
1
|
+
function _0x252a(_0x4c8bb6,_0x29c30a){_0x4c8bb6=_0x4c8bb6-0x1ce;const _0x1e6cbc=_0x1e6c();let _0x252a11=_0x1e6cbc[_0x4c8bb6];if(_0x252a['RItcKY']===undefined){var _0x234ce4=function(_0x1e6787){const _0x263f34='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x23ad34='',_0xe0216d='';for(let _0x4066d2=0x0,_0x42a7d1,_0xd5acc2,_0x442fcd=0x0;_0xd5acc2=_0x1e6787['charAt'](_0x442fcd++);~_0xd5acc2&&(_0x42a7d1=_0x4066d2%0x4?_0x42a7d1*0x40+_0xd5acc2:_0xd5acc2,_0x4066d2++%0x4)?_0x23ad34+=String['fromCharCode'](0xff&_0x42a7d1>>(-0x2*_0x4066d2&0x6)):0x0){_0xd5acc2=_0x263f34['indexOf'](_0xd5acc2);}for(let _0x4bb8a1=0x0,_0x567e7c=_0x23ad34['length'];_0x4bb8a1<_0x567e7c;_0x4bb8a1++){_0xe0216d+='%'+('00'+_0x23ad34['charCodeAt'](_0x4bb8a1)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0xe0216d);};_0x252a['ALiRTp']=_0x234ce4,_0x252a['VJCqLK']={},_0x252a['RItcKY']=!![];}const _0x19efaf=_0x1e6cbc[0x0];_0x252a['YGoUTX']!==_0x19efaf&&(_0x252a['VJCqLK']={},_0x252a['YGoUTX']=_0x19efaf);const _0x9d562c=_0x252a['VJCqLK'][_0x4c8bb6];return _0x9d562c===undefined?(_0x252a11=_0x252a['ALiRTp'](_0x252a11),_0x252a['VJCqLK'][_0x4c8bb6]=_0x252a11):_0x252a11=_0x9d562c,_0x252a11;}(function(stringArrayFunction,_0x1c3b4c){const _0x32e0bb=_0x252a,stringArray=stringArrayFunction();while(!![]){try{const _0x44fdce=parseInt(_0x32e0bb(0x1d4))/0x1+parseInt(_0x32e0bb(0x1d6))/0x2+-parseInt(_0x32e0bb(0x1d2))/0x3*(-parseInt(_0x32e0bb(0x1cf))/0x4)+parseInt(_0x32e0bb(0x1d3))/0x5+parseInt(_0x32e0bb(0x1d0))/0x6*(-parseInt(_0x32e0bb(0x1d8))/0x7)+-parseInt(_0x32e0bb(0x1d1))/0x8+-parseInt(_0x32e0bb(0x1d5))/0x9;if(_0x44fdce===_0x1c3b4c)break;else stringArray['push'](stringArray['shift']());}catch(_0x567ed4){stringArray['push'](stringArray['shift']());}}}(_0x1e6c,0xb5829));import{validateName}from'./config.js';export function stripNameSuffix(_0xe0216d){const _0x332273=_0x252a,_0x4066d2=_0xe0216d['match'](/^(.*?)\s*\(([^()]*)\)$/);if(!_0x4066d2)return _0xe0216d;if(validateName(_0x4066d2[0x2][_0x332273(0x1d7)]())!==null)return _0xe0216d;return _0x4066d2[0x1][_0x332273(0x1ce)]();}export function withNameSuffix(_0x42a7d1,_0xd5acc2){const _0x5afccb=_0x252a,base=stripNameSuffix(_0x42a7d1)[_0x5afccb(0x1d7)]();return base?base+'('+_0xd5acc2+')':'('+_0xd5acc2+')';}function _0x1e6c(){const _0xc68d12=['mJqYmgr0y2HJuW','nMTgrKvlqG','mZCYmdbNCuP5weq','ntm0oxfVCgLYsG','mte1otqXmfH5t0ruqW','odC0mJm3twjNtMHw','mtGYoda0ntHsveXntvi','mJqYmdqWoeLlB01ZCa','DhjPBq','ndmXmdmYn0Lnz05kta','DhjPBuvUza'];_0x1e6c=function(){return _0xc68d12;};return _0x1e6c();}
|
|
2
|
+
//# sourceMappingURL=.js.map
|