@adhdev/daemon-standalone 0.8.12 → 0.8.13
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/dist/index.js +1047 -891
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/public/assets/{index-Dg_BtDV6.js → index-BbTwOu3n.js} +19 -19
- package/public/assets/terminal-CKqklWLC.js +13 -0
- package/public/index.html +2 -2
- package/vendor/session-host-daemon/index.js +38 -62
- package/vendor/session-host-daemon/index.js.map +1 -1
- package/vendor/session-host-daemon/index.mjs +25 -49
- package/vendor/session-host-daemon/index.mjs.map +1 -1
- package/public/assets/terminal-PD6SznsC.js +0 -13
package/dist/index.js
CHANGED
|
@@ -9129,6 +9129,591 @@ ${h.join(`
|
|
|
9129
9129
|
}
|
|
9130
9130
|
});
|
|
9131
9131
|
|
|
9132
|
+
// ../session-host-core/dist/index.js
|
|
9133
|
+
var require_dist = __commonJS({
|
|
9134
|
+
"../session-host-core/dist/index.js"(exports2, module2) {
|
|
9135
|
+
"use strict";
|
|
9136
|
+
var __create2 = Object.create;
|
|
9137
|
+
var __defProp2 = Object.defineProperty;
|
|
9138
|
+
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
9139
|
+
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
9140
|
+
var __getProtoOf2 = Object.getPrototypeOf;
|
|
9141
|
+
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
9142
|
+
var __export2 = (target, all) => {
|
|
9143
|
+
for (var name in all)
|
|
9144
|
+
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
9145
|
+
};
|
|
9146
|
+
var __copyProps2 = (to, from, except, desc) => {
|
|
9147
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
9148
|
+
for (let key of __getOwnPropNames2(from))
|
|
9149
|
+
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
9150
|
+
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
9151
|
+
}
|
|
9152
|
+
return to;
|
|
9153
|
+
};
|
|
9154
|
+
var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps2(
|
|
9155
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
9156
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
9157
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
9158
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
9159
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target,
|
|
9160
|
+
mod
|
|
9161
|
+
));
|
|
9162
|
+
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
9163
|
+
var index_exports = {};
|
|
9164
|
+
__export2(index_exports, {
|
|
9165
|
+
SessionHostClient: () => SessionHostClient2,
|
|
9166
|
+
SessionHostRegistry: () => SessionHostRegistry,
|
|
9167
|
+
SessionRingBuffer: () => SessionRingBuffer,
|
|
9168
|
+
applyTerminalColorEnv: () => applyTerminalColorEnv,
|
|
9169
|
+
buildRuntimeDisplayName: () => buildRuntimeDisplayName,
|
|
9170
|
+
buildRuntimeKey: () => buildRuntimeKey,
|
|
9171
|
+
createLineParser: () => createLineParser2,
|
|
9172
|
+
createResponseEnvelope: () => createResponseEnvelope,
|
|
9173
|
+
ensureNodePtySpawnHelperPermissions: () => ensureNodePtySpawnHelperPermissions,
|
|
9174
|
+
formatRuntimeOwner: () => formatRuntimeOwner,
|
|
9175
|
+
getDefaultSessionHostEndpoint: () => getDefaultSessionHostEndpoint2,
|
|
9176
|
+
getWorkspaceLabel: () => getWorkspaceLabel,
|
|
9177
|
+
resolveRuntimeRecord: () => resolveRuntimeRecord,
|
|
9178
|
+
sanitizeSpawnEnv: () => sanitizeSpawnEnv,
|
|
9179
|
+
writeEnvelope: () => writeEnvelope
|
|
9180
|
+
});
|
|
9181
|
+
module2.exports = __toCommonJS2(index_exports);
|
|
9182
|
+
var SessionRingBuffer = class {
|
|
9183
|
+
maxBytes;
|
|
9184
|
+
chunks = [];
|
|
9185
|
+
nextSeq = 1;
|
|
9186
|
+
totalBytes = 0;
|
|
9187
|
+
constructor(options = {}) {
|
|
9188
|
+
this.maxBytes = options.maxBytes ?? 512 * 1024;
|
|
9189
|
+
}
|
|
9190
|
+
append(data) {
|
|
9191
|
+
const normalized = typeof data === "string" ? data : String(data ?? "");
|
|
9192
|
+
const bytes = Buffer.byteLength(normalized, "utf8");
|
|
9193
|
+
const seq = this.nextSeq++;
|
|
9194
|
+
this.chunks.push({ seq, data: normalized, bytes });
|
|
9195
|
+
this.totalBytes += bytes;
|
|
9196
|
+
this.trim();
|
|
9197
|
+
return seq;
|
|
9198
|
+
}
|
|
9199
|
+
snapshot(sinceSeq) {
|
|
9200
|
+
const relevant = typeof sinceSeq === "number" ? this.chunks.filter((chunk) => chunk.seq > sinceSeq) : this.chunks;
|
|
9201
|
+
const text = relevant.map((chunk) => chunk.data).join("");
|
|
9202
|
+
const truncated = !!this.chunks[0] && typeof sinceSeq === "number" && sinceSeq < this.chunks[0].seq - 1;
|
|
9203
|
+
return {
|
|
9204
|
+
seq: this.nextSeq - 1,
|
|
9205
|
+
text,
|
|
9206
|
+
truncated
|
|
9207
|
+
};
|
|
9208
|
+
}
|
|
9209
|
+
getState() {
|
|
9210
|
+
return {
|
|
9211
|
+
scrollbackBytes: this.totalBytes,
|
|
9212
|
+
snapshotSeq: this.nextSeq - 1
|
|
9213
|
+
};
|
|
9214
|
+
}
|
|
9215
|
+
clear() {
|
|
9216
|
+
this.chunks = [];
|
|
9217
|
+
this.totalBytes = 0;
|
|
9218
|
+
this.nextSeq = 1;
|
|
9219
|
+
}
|
|
9220
|
+
restore(snapshot) {
|
|
9221
|
+
this.clear();
|
|
9222
|
+
const text = String(snapshot.text || "");
|
|
9223
|
+
if (!text) {
|
|
9224
|
+
this.nextSeq = Math.max(1, Number(snapshot.seq || 0) + 1);
|
|
9225
|
+
return;
|
|
9226
|
+
}
|
|
9227
|
+
const bytes = Buffer.byteLength(text, "utf8");
|
|
9228
|
+
const seq = Math.max(1, Number(snapshot.seq || 1));
|
|
9229
|
+
this.chunks = [{ seq, data: text, bytes }];
|
|
9230
|
+
this.totalBytes = bytes;
|
|
9231
|
+
this.nextSeq = seq + 1;
|
|
9232
|
+
this.trim();
|
|
9233
|
+
}
|
|
9234
|
+
trim() {
|
|
9235
|
+
while (this.totalBytes > this.maxBytes && this.chunks.length > 1) {
|
|
9236
|
+
const removed = this.chunks.shift();
|
|
9237
|
+
if (!removed) break;
|
|
9238
|
+
this.totalBytes -= removed.bytes;
|
|
9239
|
+
}
|
|
9240
|
+
}
|
|
9241
|
+
};
|
|
9242
|
+
var import_crypto2 = require("crypto");
|
|
9243
|
+
var path5 = __toESM2(require("path"));
|
|
9244
|
+
function normalizeSlug(input) {
|
|
9245
|
+
return input.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48);
|
|
9246
|
+
}
|
|
9247
|
+
function normalizeValue(input) {
|
|
9248
|
+
return input.trim().toLowerCase();
|
|
9249
|
+
}
|
|
9250
|
+
function getWorkspaceLabel(workspace) {
|
|
9251
|
+
const trimmed = workspace.trim();
|
|
9252
|
+
if (!trimmed) return "workspace";
|
|
9253
|
+
const normalized = trimmed.replace(/[\\/]+$/, "");
|
|
9254
|
+
const base = path5.basename(normalized);
|
|
9255
|
+
return base || normalized;
|
|
9256
|
+
}
|
|
9257
|
+
function buildRuntimeDisplayName(payload) {
|
|
9258
|
+
const explicit = payload.displayName?.trim();
|
|
9259
|
+
if (explicit) return explicit;
|
|
9260
|
+
const workspaceLabel = getWorkspaceLabel(payload.workspace);
|
|
9261
|
+
const providerLabel = payload.providerType.trim() || "runtime";
|
|
9262
|
+
return `${providerLabel} @ ${workspaceLabel}`;
|
|
9263
|
+
}
|
|
9264
|
+
function buildRuntimeKey(payload, existingKeys) {
|
|
9265
|
+
const requested = payload.runtimeKey?.trim();
|
|
9266
|
+
const existing = new Set(Array.from(existingKeys, (key) => key.toLowerCase()));
|
|
9267
|
+
const displayName = buildRuntimeDisplayName(payload);
|
|
9268
|
+
const baseKey = normalizeSlug(requested || displayName || getWorkspaceLabel(payload.workspace) || payload.providerType || "runtime") || "runtime";
|
|
9269
|
+
if (!existing.has(baseKey)) return baseKey;
|
|
9270
|
+
let suffix = 2;
|
|
9271
|
+
let candidate = `${baseKey}-${suffix}`;
|
|
9272
|
+
while (existing.has(candidate)) {
|
|
9273
|
+
suffix += 1;
|
|
9274
|
+
candidate = `${baseKey}-${suffix}`;
|
|
9275
|
+
}
|
|
9276
|
+
return candidate;
|
|
9277
|
+
}
|
|
9278
|
+
function uniqueMatch(records, predicate) {
|
|
9279
|
+
const matches = records.filter(predicate);
|
|
9280
|
+
if (matches.length === 1) return matches[0] || null;
|
|
9281
|
+
if (matches.length === 0) return null;
|
|
9282
|
+
const labels = matches.map((record2) => `${record2.runtimeKey} (${record2.sessionId})`).join(", ");
|
|
9283
|
+
throw new Error(`Ambiguous runtime target. Matches: ${labels}`);
|
|
9284
|
+
}
|
|
9285
|
+
function resolveRuntimeRecord(records, identifier) {
|
|
9286
|
+
const target = identifier.trim();
|
|
9287
|
+
if (!target) {
|
|
9288
|
+
throw new Error("Runtime target is required");
|
|
9289
|
+
}
|
|
9290
|
+
const exact = uniqueMatch(
|
|
9291
|
+
records,
|
|
9292
|
+
(record2) => record2.sessionId === target || normalizeValue(record2.runtimeKey) === normalizeValue(target) || normalizeValue(record2.displayName) === normalizeValue(target)
|
|
9293
|
+
);
|
|
9294
|
+
if (exact) return exact;
|
|
9295
|
+
const prefix = uniqueMatch(
|
|
9296
|
+
records,
|
|
9297
|
+
(record2) => record2.sessionId.startsWith(target) || normalizeValue(record2.runtimeKey).startsWith(normalizeValue(target))
|
|
9298
|
+
);
|
|
9299
|
+
if (prefix) return prefix;
|
|
9300
|
+
throw new Error(`Unknown runtime target: ${target}`);
|
|
9301
|
+
}
|
|
9302
|
+
function formatRuntimeOwner(record2) {
|
|
9303
|
+
if (!record2.writeOwner) return "none";
|
|
9304
|
+
return `${record2.writeOwner.ownerType}:${record2.writeOwner.clientId}`;
|
|
9305
|
+
}
|
|
9306
|
+
var SessionHostRegistry = class {
|
|
9307
|
+
sessions = /* @__PURE__ */ new Map();
|
|
9308
|
+
createSession(payload) {
|
|
9309
|
+
const sessionId = payload.sessionId || (0, import_crypto2.randomUUID)();
|
|
9310
|
+
if (this.sessions.has(sessionId)) {
|
|
9311
|
+
throw new Error(`Session already exists: ${sessionId}`);
|
|
9312
|
+
}
|
|
9313
|
+
const now = Date.now();
|
|
9314
|
+
const initialClient = payload.clientId ? [{
|
|
9315
|
+
clientId: payload.clientId,
|
|
9316
|
+
type: payload.clientType || "daemon",
|
|
9317
|
+
readOnly: false,
|
|
9318
|
+
attachedAt: now,
|
|
9319
|
+
lastSeenAt: now
|
|
9320
|
+
}] : [];
|
|
9321
|
+
const record2 = {
|
|
9322
|
+
sessionId,
|
|
9323
|
+
runtimeKey: buildRuntimeKey(
|
|
9324
|
+
payload,
|
|
9325
|
+
Array.from(this.sessions.values(), (state) => state.record.runtimeKey)
|
|
9326
|
+
),
|
|
9327
|
+
displayName: buildRuntimeDisplayName(payload),
|
|
9328
|
+
workspaceLabel: getWorkspaceLabel(payload.workspace),
|
|
9329
|
+
transport: "pty",
|
|
9330
|
+
providerType: payload.providerType,
|
|
9331
|
+
category: payload.category,
|
|
9332
|
+
workspace: payload.workspace,
|
|
9333
|
+
launchCommand: payload.launchCommand,
|
|
9334
|
+
createdAt: now,
|
|
9335
|
+
lastActivityAt: now,
|
|
9336
|
+
lifecycle: "starting",
|
|
9337
|
+
writeOwner: null,
|
|
9338
|
+
attachedClients: initialClient,
|
|
9339
|
+
buffer: {
|
|
9340
|
+
scrollbackBytes: 0,
|
|
9341
|
+
snapshotSeq: 0
|
|
9342
|
+
},
|
|
9343
|
+
meta: payload.meta || {}
|
|
9344
|
+
};
|
|
9345
|
+
record2.meta = {
|
|
9346
|
+
sessionHostCols: payload.cols || 80,
|
|
9347
|
+
sessionHostRows: payload.rows || 24,
|
|
9348
|
+
...record2.meta
|
|
9349
|
+
};
|
|
9350
|
+
this.sessions.set(sessionId, {
|
|
9351
|
+
record: record2,
|
|
9352
|
+
buffer: new SessionRingBuffer()
|
|
9353
|
+
});
|
|
9354
|
+
return this.cloneRecord(record2);
|
|
9355
|
+
}
|
|
9356
|
+
restoreSession(record2, snapshot) {
|
|
9357
|
+
const cloned = this.cloneRecord(record2);
|
|
9358
|
+
this.sessions.set(cloned.sessionId, {
|
|
9359
|
+
record: cloned,
|
|
9360
|
+
buffer: (() => {
|
|
9361
|
+
const buffer = new SessionRingBuffer();
|
|
9362
|
+
if (snapshot) buffer.restore(snapshot);
|
|
9363
|
+
return buffer;
|
|
9364
|
+
})()
|
|
9365
|
+
});
|
|
9366
|
+
return this.cloneRecord(cloned);
|
|
9367
|
+
}
|
|
9368
|
+
listSessions() {
|
|
9369
|
+
return Array.from(this.sessions.values()).map((state) => this.cloneRecord(state.record)).sort((a, b2) => b2.lastActivityAt - a.lastActivityAt);
|
|
9370
|
+
}
|
|
9371
|
+
getSession(sessionId) {
|
|
9372
|
+
const state = this.sessions.get(sessionId);
|
|
9373
|
+
return state ? this.cloneRecord(state.record) : null;
|
|
9374
|
+
}
|
|
9375
|
+
attachClient(payload) {
|
|
9376
|
+
const state = this.requireSession(payload.sessionId);
|
|
9377
|
+
const now = Date.now();
|
|
9378
|
+
let removedDaemonOwner = false;
|
|
9379
|
+
if (payload.clientType === "daemon") {
|
|
9380
|
+
const staleDaemonClientIds = state.record.attachedClients.filter((client) => client.type === "daemon" && client.clientId !== payload.clientId).map((client) => client.clientId);
|
|
9381
|
+
if (staleDaemonClientIds.length > 0) {
|
|
9382
|
+
state.record.attachedClients = state.record.attachedClients.filter(
|
|
9383
|
+
(client) => !(client.type === "daemon" && client.clientId !== payload.clientId)
|
|
9384
|
+
);
|
|
9385
|
+
if (state.record.writeOwner && staleDaemonClientIds.includes(state.record.writeOwner.clientId)) {
|
|
9386
|
+
removedDaemonOwner = true;
|
|
9387
|
+
}
|
|
9388
|
+
}
|
|
9389
|
+
}
|
|
9390
|
+
const existing = state.record.attachedClients.find((client) => client.clientId === payload.clientId);
|
|
9391
|
+
if (existing) {
|
|
9392
|
+
existing.type = payload.clientType;
|
|
9393
|
+
existing.readOnly = !!payload.readOnly;
|
|
9394
|
+
existing.lastSeenAt = now;
|
|
9395
|
+
} else {
|
|
9396
|
+
state.record.attachedClients.push({
|
|
9397
|
+
clientId: payload.clientId,
|
|
9398
|
+
type: payload.clientType,
|
|
9399
|
+
readOnly: !!payload.readOnly,
|
|
9400
|
+
attachedAt: now,
|
|
9401
|
+
lastSeenAt: now
|
|
9402
|
+
});
|
|
9403
|
+
}
|
|
9404
|
+
if (removedDaemonOwner) {
|
|
9405
|
+
state.record.writeOwner = null;
|
|
9406
|
+
}
|
|
9407
|
+
state.record.lastActivityAt = now;
|
|
9408
|
+
return this.cloneRecord(state.record);
|
|
9409
|
+
}
|
|
9410
|
+
detachClient(payload) {
|
|
9411
|
+
const state = this.requireSession(payload.sessionId);
|
|
9412
|
+
state.record.attachedClients = state.record.attachedClients.filter((client) => client.clientId !== payload.clientId);
|
|
9413
|
+
if (state.record.writeOwner?.clientId === payload.clientId) {
|
|
9414
|
+
state.record.writeOwner = null;
|
|
9415
|
+
}
|
|
9416
|
+
state.record.lastActivityAt = Date.now();
|
|
9417
|
+
return this.cloneRecord(state.record);
|
|
9418
|
+
}
|
|
9419
|
+
acquireWrite(payload) {
|
|
9420
|
+
const state = this.requireSession(payload.sessionId);
|
|
9421
|
+
if (state.record.writeOwner && state.record.writeOwner.clientId !== payload.clientId && !payload.force) {
|
|
9422
|
+
throw new Error(`Write owned by ${state.record.writeOwner.clientId}`);
|
|
9423
|
+
}
|
|
9424
|
+
const attachedClient = state.record.attachedClients.find((client) => client.clientId === payload.clientId);
|
|
9425
|
+
if (attachedClient) {
|
|
9426
|
+
attachedClient.readOnly = false;
|
|
9427
|
+
attachedClient.lastSeenAt = Date.now();
|
|
9428
|
+
}
|
|
9429
|
+
state.record.writeOwner = {
|
|
9430
|
+
clientId: payload.clientId,
|
|
9431
|
+
ownerType: payload.ownerType,
|
|
9432
|
+
acquiredAt: Date.now()
|
|
9433
|
+
};
|
|
9434
|
+
state.record.lastActivityAt = Date.now();
|
|
9435
|
+
return this.cloneRecord(state.record);
|
|
9436
|
+
}
|
|
9437
|
+
releaseWrite(payload) {
|
|
9438
|
+
const state = this.requireSession(payload.sessionId);
|
|
9439
|
+
const attachedClient = state.record.attachedClients.find((client) => client.clientId === payload.clientId);
|
|
9440
|
+
if (attachedClient) {
|
|
9441
|
+
attachedClient.readOnly = false;
|
|
9442
|
+
attachedClient.lastSeenAt = Date.now();
|
|
9443
|
+
}
|
|
9444
|
+
if (state.record.writeOwner?.clientId === payload.clientId) {
|
|
9445
|
+
state.record.writeOwner = null;
|
|
9446
|
+
}
|
|
9447
|
+
state.record.lastActivityAt = Date.now();
|
|
9448
|
+
return this.cloneRecord(state.record);
|
|
9449
|
+
}
|
|
9450
|
+
appendOutput(sessionId, data) {
|
|
9451
|
+
const state = this.requireSession(sessionId);
|
|
9452
|
+
const seq = state.buffer.append(data);
|
|
9453
|
+
state.record.buffer = state.buffer.getState();
|
|
9454
|
+
state.record.lastActivityAt = Date.now();
|
|
9455
|
+
return { record: this.cloneRecord(state.record), seq };
|
|
9456
|
+
}
|
|
9457
|
+
getSnapshot(sessionId, sinceSeq) {
|
|
9458
|
+
const state = this.requireSession(sessionId);
|
|
9459
|
+
state.record.buffer = state.buffer.getState();
|
|
9460
|
+
return state.buffer.snapshot(sinceSeq);
|
|
9461
|
+
}
|
|
9462
|
+
clearBuffer(sessionId) {
|
|
9463
|
+
const state = this.requireSession(sessionId);
|
|
9464
|
+
state.buffer.clear();
|
|
9465
|
+
state.record.buffer = state.buffer.getState();
|
|
9466
|
+
state.record.lastActivityAt = Date.now();
|
|
9467
|
+
return this.cloneRecord(state.record);
|
|
9468
|
+
}
|
|
9469
|
+
updateSessionMeta(sessionId, meta3, replace = false) {
|
|
9470
|
+
const state = this.requireSession(sessionId);
|
|
9471
|
+
state.record.meta = replace ? { ...meta3 } : {
|
|
9472
|
+
...state.record.meta || {},
|
|
9473
|
+
...meta3
|
|
9474
|
+
};
|
|
9475
|
+
state.record.lastActivityAt = Date.now();
|
|
9476
|
+
return this.cloneRecord(state.record);
|
|
9477
|
+
}
|
|
9478
|
+
markStarted(sessionId, pid) {
|
|
9479
|
+
const state = this.requireSession(sessionId);
|
|
9480
|
+
state.record.lifecycle = "running";
|
|
9481
|
+
state.record.startedAt = state.record.startedAt || Date.now();
|
|
9482
|
+
if (typeof pid === "number") state.record.osPid = pid;
|
|
9483
|
+
state.record.lastActivityAt = Date.now();
|
|
9484
|
+
return this.cloneRecord(state.record);
|
|
9485
|
+
}
|
|
9486
|
+
markStopped(sessionId, lifecycle = "stopped") {
|
|
9487
|
+
const state = this.requireSession(sessionId);
|
|
9488
|
+
state.record.lifecycle = lifecycle;
|
|
9489
|
+
state.record.lastActivityAt = Date.now();
|
|
9490
|
+
return this.cloneRecord(state.record);
|
|
9491
|
+
}
|
|
9492
|
+
setLifecycle(sessionId, lifecycle) {
|
|
9493
|
+
const state = this.requireSession(sessionId);
|
|
9494
|
+
state.record.lifecycle = lifecycle;
|
|
9495
|
+
state.record.lastActivityAt = Date.now();
|
|
9496
|
+
return this.cloneRecord(state.record);
|
|
9497
|
+
}
|
|
9498
|
+
requireSession(sessionId) {
|
|
9499
|
+
const state = this.sessions.get(sessionId);
|
|
9500
|
+
if (!state) throw new Error(`Unknown session: ${sessionId}`);
|
|
9501
|
+
return state;
|
|
9502
|
+
}
|
|
9503
|
+
cloneRecord(record2) {
|
|
9504
|
+
return {
|
|
9505
|
+
...record2,
|
|
9506
|
+
launchCommand: {
|
|
9507
|
+
...record2.launchCommand,
|
|
9508
|
+
args: [...record2.launchCommand.args],
|
|
9509
|
+
env: record2.launchCommand.env ? { ...record2.launchCommand.env } : void 0
|
|
9510
|
+
},
|
|
9511
|
+
writeOwner: record2.writeOwner ? { ...record2.writeOwner } : null,
|
|
9512
|
+
attachedClients: record2.attachedClients.map((client) => ({ ...client })),
|
|
9513
|
+
buffer: { ...record2.buffer },
|
|
9514
|
+
meta: { ...record2.meta }
|
|
9515
|
+
};
|
|
9516
|
+
}
|
|
9517
|
+
};
|
|
9518
|
+
var os6 = __toESM2(require("os"));
|
|
9519
|
+
var path22 = __toESM2(require("path"));
|
|
9520
|
+
var net3 = __toESM2(require("net"));
|
|
9521
|
+
var import_crypto22 = require("crypto");
|
|
9522
|
+
function getDefaultSessionHostEndpoint2(appName = "adhdev") {
|
|
9523
|
+
if (process.platform === "win32") {
|
|
9524
|
+
return {
|
|
9525
|
+
kind: "pipe",
|
|
9526
|
+
path: `\\\\.\\pipe\\${appName}-session-host`
|
|
9527
|
+
};
|
|
9528
|
+
}
|
|
9529
|
+
return {
|
|
9530
|
+
kind: "unix",
|
|
9531
|
+
path: path22.join(os6.tmpdir(), `${appName}-session-host.sock`)
|
|
9532
|
+
};
|
|
9533
|
+
}
|
|
9534
|
+
function serializeEnvelope3(envelope) {
|
|
9535
|
+
return `${JSON.stringify(envelope)}
|
|
9536
|
+
`;
|
|
9537
|
+
}
|
|
9538
|
+
function createLineParser2(onEnvelope) {
|
|
9539
|
+
let buffer = "";
|
|
9540
|
+
return (chunk) => {
|
|
9541
|
+
buffer += chunk.toString();
|
|
9542
|
+
let newlineIndex = buffer.indexOf("\n");
|
|
9543
|
+
while (newlineIndex >= 0) {
|
|
9544
|
+
const rawLine = buffer.slice(0, newlineIndex).trim();
|
|
9545
|
+
buffer = buffer.slice(newlineIndex + 1);
|
|
9546
|
+
if (rawLine) {
|
|
9547
|
+
onEnvelope(JSON.parse(rawLine));
|
|
9548
|
+
}
|
|
9549
|
+
newlineIndex = buffer.indexOf("\n");
|
|
9550
|
+
}
|
|
9551
|
+
};
|
|
9552
|
+
}
|
|
9553
|
+
var SessionHostClient2 = class {
|
|
9554
|
+
endpoint;
|
|
9555
|
+
socket = null;
|
|
9556
|
+
requestWaiters = /* @__PURE__ */ new Map();
|
|
9557
|
+
eventListeners = /* @__PURE__ */ new Set();
|
|
9558
|
+
constructor(options = {}) {
|
|
9559
|
+
this.endpoint = options.endpoint || getDefaultSessionHostEndpoint2(options.appName || "adhdev");
|
|
9560
|
+
}
|
|
9561
|
+
async connect() {
|
|
9562
|
+
if (this.socket && !this.socket.destroyed) return;
|
|
9563
|
+
if (this.socket) {
|
|
9564
|
+
try {
|
|
9565
|
+
this.socket.destroy();
|
|
9566
|
+
} catch {
|
|
9567
|
+
}
|
|
9568
|
+
this.socket = null;
|
|
9569
|
+
}
|
|
9570
|
+
const socket = net3.createConnection(this.endpoint.path);
|
|
9571
|
+
this.socket = socket;
|
|
9572
|
+
socket.on("data", createLineParser2((envelope) => {
|
|
9573
|
+
if (envelope.kind === "response") {
|
|
9574
|
+
const waiter = this.requestWaiters.get(envelope.requestId);
|
|
9575
|
+
if (waiter) {
|
|
9576
|
+
this.requestWaiters.delete(envelope.requestId);
|
|
9577
|
+
waiter.resolve(envelope.response);
|
|
9578
|
+
}
|
|
9579
|
+
return;
|
|
9580
|
+
}
|
|
9581
|
+
if (envelope.kind === "event") {
|
|
9582
|
+
for (const listener of this.eventListeners) listener(envelope.event);
|
|
9583
|
+
}
|
|
9584
|
+
}));
|
|
9585
|
+
socket.on("error", (error48) => {
|
|
9586
|
+
for (const waiter of this.requestWaiters.values()) {
|
|
9587
|
+
waiter.reject(error48);
|
|
9588
|
+
}
|
|
9589
|
+
this.requestWaiters.clear();
|
|
9590
|
+
if (this.socket === socket) {
|
|
9591
|
+
this.socket = null;
|
|
9592
|
+
}
|
|
9593
|
+
try {
|
|
9594
|
+
socket.destroy();
|
|
9595
|
+
} catch {
|
|
9596
|
+
}
|
|
9597
|
+
});
|
|
9598
|
+
await new Promise((resolve22, reject) => {
|
|
9599
|
+
socket.once("connect", () => resolve22());
|
|
9600
|
+
socket.once("error", reject);
|
|
9601
|
+
});
|
|
9602
|
+
}
|
|
9603
|
+
onEvent(listener) {
|
|
9604
|
+
this.eventListeners.add(listener);
|
|
9605
|
+
return () => {
|
|
9606
|
+
this.eventListeners.delete(listener);
|
|
9607
|
+
};
|
|
9608
|
+
}
|
|
9609
|
+
async request(request) {
|
|
9610
|
+
await this.connect();
|
|
9611
|
+
if (!this.socket) throw new Error("Session host socket unavailable");
|
|
9612
|
+
const requestId = (0, import_crypto22.randomUUID)();
|
|
9613
|
+
const envelope = {
|
|
9614
|
+
kind: "request",
|
|
9615
|
+
requestId,
|
|
9616
|
+
request
|
|
9617
|
+
};
|
|
9618
|
+
const response = await new Promise((resolve22, reject) => {
|
|
9619
|
+
const timeout = setTimeout(() => {
|
|
9620
|
+
this.requestWaiters.delete(requestId);
|
|
9621
|
+
reject(new Error(`Session host request timed out after 30s (${request.type})`));
|
|
9622
|
+
}, 3e4);
|
|
9623
|
+
this.requestWaiters.set(requestId, {
|
|
9624
|
+
resolve: (value) => {
|
|
9625
|
+
clearTimeout(timeout);
|
|
9626
|
+
resolve22(value);
|
|
9627
|
+
},
|
|
9628
|
+
reject: (error48) => {
|
|
9629
|
+
clearTimeout(timeout);
|
|
9630
|
+
reject(error48);
|
|
9631
|
+
}
|
|
9632
|
+
});
|
|
9633
|
+
this.socket?.write(serializeEnvelope3(envelope));
|
|
9634
|
+
});
|
|
9635
|
+
return response;
|
|
9636
|
+
}
|
|
9637
|
+
async close() {
|
|
9638
|
+
if (!this.socket) return;
|
|
9639
|
+
const socket = this.socket;
|
|
9640
|
+
this.socket = null;
|
|
9641
|
+
for (const waiter of this.requestWaiters.values()) {
|
|
9642
|
+
waiter.reject(new Error("Session host client closed"));
|
|
9643
|
+
}
|
|
9644
|
+
this.requestWaiters.clear();
|
|
9645
|
+
await new Promise((resolve22) => {
|
|
9646
|
+
let settled = false;
|
|
9647
|
+
const done = () => {
|
|
9648
|
+
if (settled) return;
|
|
9649
|
+
settled = true;
|
|
9650
|
+
resolve22();
|
|
9651
|
+
};
|
|
9652
|
+
socket.once("close", done);
|
|
9653
|
+
socket.end();
|
|
9654
|
+
socket.destroy();
|
|
9655
|
+
setTimeout(done, 50);
|
|
9656
|
+
});
|
|
9657
|
+
}
|
|
9658
|
+
};
|
|
9659
|
+
function createResponseEnvelope(requestId, response) {
|
|
9660
|
+
return {
|
|
9661
|
+
kind: "response",
|
|
9662
|
+
requestId,
|
|
9663
|
+
response
|
|
9664
|
+
};
|
|
9665
|
+
}
|
|
9666
|
+
function writeEnvelope(socket, envelope) {
|
|
9667
|
+
socket.write(serializeEnvelope3(envelope));
|
|
9668
|
+
}
|
|
9669
|
+
var os22 = __toESM2(require("os"));
|
|
9670
|
+
var path32 = __toESM2(require("path"));
|
|
9671
|
+
function sanitizeSpawnEnv(baseEnv, overrides) {
|
|
9672
|
+
const env = {};
|
|
9673
|
+
const source = { ...baseEnv, ...overrides || {} };
|
|
9674
|
+
for (const [key, value] of Object.entries(source)) {
|
|
9675
|
+
if (typeof value !== "string") continue;
|
|
9676
|
+
env[key] = value;
|
|
9677
|
+
}
|
|
9678
|
+
for (const key of Object.keys(env)) {
|
|
9679
|
+
if (key === "INIT_CWD" || key === "npm_command" || key === "npm_execpath" || key === "npm_node_execpath" || key.startsWith("npm_") || key.startsWith("npm_config_") || key.startsWith("npm_package_") || key.startsWith("npm_lifecycle_") || key.startsWith("PNPM_") || key.startsWith("YARN_") || key.startsWith("BUN_")) {
|
|
9680
|
+
delete env[key];
|
|
9681
|
+
}
|
|
9682
|
+
}
|
|
9683
|
+
applyTerminalColorEnv(env);
|
|
9684
|
+
return env;
|
|
9685
|
+
}
|
|
9686
|
+
function applyTerminalColorEnv(env) {
|
|
9687
|
+
if (env.NO_COLOR) return;
|
|
9688
|
+
if (!env.TERM || env.TERM === "xterm-color") {
|
|
9689
|
+
env.TERM = "xterm-256color";
|
|
9690
|
+
}
|
|
9691
|
+
if (!env.COLORTERM) env.COLORTERM = "truecolor";
|
|
9692
|
+
if (process.platform === "win32") {
|
|
9693
|
+
if (!env.FORCE_COLOR) env.FORCE_COLOR = "1";
|
|
9694
|
+
if (!env.CLICOLOR) env.CLICOLOR = "1";
|
|
9695
|
+
}
|
|
9696
|
+
}
|
|
9697
|
+
function ensureNodePtySpawnHelperPermissions(logFn) {
|
|
9698
|
+
if (os22.platform() === "win32") return;
|
|
9699
|
+
try {
|
|
9700
|
+
const fs4 = require("fs");
|
|
9701
|
+
const ptyDir = path32.resolve(path32.dirname(require.resolve("node-pty")), "..");
|
|
9702
|
+
const platformArch = `${os22.platform()}-${os22.arch()}`;
|
|
9703
|
+
const helper = path32.join(ptyDir, "prebuilds", platformArch, "spawn-helper");
|
|
9704
|
+
if (fs4.existsSync(helper)) {
|
|
9705
|
+
const stat4 = fs4.statSync(helper);
|
|
9706
|
+
if (!(stat4.mode & 73)) {
|
|
9707
|
+
fs4.chmodSync(helper, stat4.mode | 493);
|
|
9708
|
+
logFn?.(`Fixed spawn-helper permissions: ${helper}`);
|
|
9709
|
+
}
|
|
9710
|
+
}
|
|
9711
|
+
} catch {
|
|
9712
|
+
}
|
|
9713
|
+
}
|
|
9714
|
+
}
|
|
9715
|
+
});
|
|
9716
|
+
|
|
9132
9717
|
// ../../node_modules/zod/v4/core/core.js
|
|
9133
9718
|
// @__NO_SIDE_EFFECTS__
|
|
9134
9719
|
function $constructor(name, initializer3, params) {
|
|
@@ -27028,685 +27613,162 @@ var init_chokidar = __esm({
|
|
|
27028
27613
|
writes.get(path5).lastChange = now2;
|
|
27029
27614
|
}
|
|
27030
27615
|
const pw = writes.get(path5);
|
|
27031
|
-
const df = now2 - pw.lastChange;
|
|
27032
|
-
if (df >= threshold) {
|
|
27033
|
-
writes.delete(path5);
|
|
27034
|
-
awfEmit(void 0, curStat);
|
|
27035
|
-
} else {
|
|
27036
|
-
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
|
|
27037
|
-
}
|
|
27038
|
-
});
|
|
27039
|
-
}
|
|
27040
|
-
if (!writes.has(path5)) {
|
|
27041
|
-
writes.set(path5, {
|
|
27042
|
-
lastChange: now,
|
|
27043
|
-
cancelWait: () => {
|
|
27044
|
-
writes.delete(path5);
|
|
27045
|
-
clearTimeout(timeoutHandler);
|
|
27046
|
-
return event;
|
|
27047
|
-
}
|
|
27048
|
-
});
|
|
27049
|
-
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval);
|
|
27050
|
-
}
|
|
27051
|
-
}
|
|
27052
|
-
/**
|
|
27053
|
-
* Determines whether user has asked to ignore this path.
|
|
27054
|
-
*/
|
|
27055
|
-
_isIgnored(path5, stats) {
|
|
27056
|
-
if (this.options.atomic && DOT_RE.test(path5))
|
|
27057
|
-
return true;
|
|
27058
|
-
if (!this._userIgnored) {
|
|
27059
|
-
const { cwd } = this.options;
|
|
27060
|
-
const ign = this.options.ignored;
|
|
27061
|
-
const ignored = (ign || []).map(normalizeIgnored(cwd));
|
|
27062
|
-
const ignoredPaths = [...this._ignoredPaths];
|
|
27063
|
-
const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
|
|
27064
|
-
this._userIgnored = anymatch(list, void 0);
|
|
27065
|
-
}
|
|
27066
|
-
return this._userIgnored(path5, stats);
|
|
27067
|
-
}
|
|
27068
|
-
_isntIgnored(path5, stat4) {
|
|
27069
|
-
return !this._isIgnored(path5, stat4);
|
|
27070
|
-
}
|
|
27071
|
-
/**
|
|
27072
|
-
* Provides a set of common helpers and properties relating to symlink handling.
|
|
27073
|
-
* @param path file or directory pattern being watched
|
|
27074
|
-
*/
|
|
27075
|
-
_getWatchHelpers(path5) {
|
|
27076
|
-
return new WatchHelper(path5, this.options.followSymlinks, this);
|
|
27077
|
-
}
|
|
27078
|
-
// Directory helpers
|
|
27079
|
-
// -----------------
|
|
27080
|
-
/**
|
|
27081
|
-
* Provides directory tracking objects
|
|
27082
|
-
* @param directory path of the directory
|
|
27083
|
-
*/
|
|
27084
|
-
_getWatchedDir(directory) {
|
|
27085
|
-
const dir = sp2.resolve(directory);
|
|
27086
|
-
if (!this._watched.has(dir))
|
|
27087
|
-
this._watched.set(dir, new DirEntry(dir, this._boundRemove));
|
|
27088
|
-
return this._watched.get(dir);
|
|
27089
|
-
}
|
|
27090
|
-
// File helpers
|
|
27091
|
-
// ------------
|
|
27092
|
-
/**
|
|
27093
|
-
* Check for read permissions: https://stackoverflow.com/a/11781404/1358405
|
|
27094
|
-
*/
|
|
27095
|
-
_hasReadPermissions(stats) {
|
|
27096
|
-
if (this.options.ignorePermissionErrors)
|
|
27097
|
-
return true;
|
|
27098
|
-
return Boolean(Number(stats.mode) & 256);
|
|
27099
|
-
}
|
|
27100
|
-
/**
|
|
27101
|
-
* Handles emitting unlink events for
|
|
27102
|
-
* files and directories, and via recursion, for
|
|
27103
|
-
* files and directories within directories that are unlinked
|
|
27104
|
-
* @param directory within which the following item is located
|
|
27105
|
-
* @param item base path of item/directory
|
|
27106
|
-
*/
|
|
27107
|
-
_remove(directory, item, isDirectory) {
|
|
27108
|
-
const path5 = sp2.join(directory, item);
|
|
27109
|
-
const fullPath = sp2.resolve(path5);
|
|
27110
|
-
isDirectory = isDirectory != null ? isDirectory : this._watched.has(path5) || this._watched.has(fullPath);
|
|
27111
|
-
if (!this._throttle("remove", path5, 100))
|
|
27112
|
-
return;
|
|
27113
|
-
if (!isDirectory && this._watched.size === 1) {
|
|
27114
|
-
this.add(directory, item, true);
|
|
27115
|
-
}
|
|
27116
|
-
const wp = this._getWatchedDir(path5);
|
|
27117
|
-
const nestedDirectoryChildren = wp.getChildren();
|
|
27118
|
-
nestedDirectoryChildren.forEach((nested) => this._remove(path5, nested));
|
|
27119
|
-
const parent = this._getWatchedDir(directory);
|
|
27120
|
-
const wasTracked = parent.has(item);
|
|
27121
|
-
parent.remove(item);
|
|
27122
|
-
if (this._symlinkPaths.has(fullPath)) {
|
|
27123
|
-
this._symlinkPaths.delete(fullPath);
|
|
27124
|
-
}
|
|
27125
|
-
let relPath = path5;
|
|
27126
|
-
if (this.options.cwd)
|
|
27127
|
-
relPath = sp2.relative(this.options.cwd, path5);
|
|
27128
|
-
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
|
27129
|
-
const event = this._pendingWrites.get(relPath).cancelWait();
|
|
27130
|
-
if (event === EVENTS.ADD)
|
|
27131
|
-
return;
|
|
27132
|
-
}
|
|
27133
|
-
this._watched.delete(path5);
|
|
27134
|
-
this._watched.delete(fullPath);
|
|
27135
|
-
const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
|
|
27136
|
-
if (wasTracked && !this._isIgnored(path5))
|
|
27137
|
-
this._emit(eventName, path5);
|
|
27138
|
-
this._closePath(path5);
|
|
27139
|
-
}
|
|
27140
|
-
/**
|
|
27141
|
-
* Closes all watchers for a path
|
|
27142
|
-
*/
|
|
27143
|
-
_closePath(path5) {
|
|
27144
|
-
this._closeFile(path5);
|
|
27145
|
-
const dir = sp2.dirname(path5);
|
|
27146
|
-
this._getWatchedDir(dir).remove(sp2.basename(path5));
|
|
27147
|
-
}
|
|
27148
|
-
/**
|
|
27149
|
-
* Closes only file-specific watchers
|
|
27150
|
-
*/
|
|
27151
|
-
_closeFile(path5) {
|
|
27152
|
-
const closers = this._closers.get(path5);
|
|
27153
|
-
if (!closers)
|
|
27154
|
-
return;
|
|
27155
|
-
closers.forEach((closer) => closer());
|
|
27156
|
-
this._closers.delete(path5);
|
|
27157
|
-
}
|
|
27158
|
-
_addPathCloser(path5, closer) {
|
|
27159
|
-
if (!closer)
|
|
27160
|
-
return;
|
|
27161
|
-
let list = this._closers.get(path5);
|
|
27162
|
-
if (!list) {
|
|
27163
|
-
list = [];
|
|
27164
|
-
this._closers.set(path5, list);
|
|
27165
|
-
}
|
|
27166
|
-
list.push(closer);
|
|
27167
|
-
}
|
|
27168
|
-
_readdirp(root, opts) {
|
|
27169
|
-
if (this.closed)
|
|
27170
|
-
return;
|
|
27171
|
-
const options = { type: EVENTS.ALL, alwaysStat: true, lstat: true, ...opts, depth: 0 };
|
|
27172
|
-
let stream = readdirp(root, options);
|
|
27173
|
-
this._streams.add(stream);
|
|
27174
|
-
stream.once(STR_CLOSE, () => {
|
|
27175
|
-
stream = void 0;
|
|
27176
|
-
});
|
|
27177
|
-
stream.once(STR_END, () => {
|
|
27178
|
-
if (stream) {
|
|
27179
|
-
this._streams.delete(stream);
|
|
27180
|
-
stream = void 0;
|
|
27181
|
-
}
|
|
27182
|
-
});
|
|
27183
|
-
return stream;
|
|
27184
|
-
}
|
|
27185
|
-
};
|
|
27186
|
-
chokidar_default = { watch, FSWatcher };
|
|
27187
|
-
}
|
|
27188
|
-
});
|
|
27189
|
-
|
|
27190
|
-
// ../session-host-core/dist/index.js
|
|
27191
|
-
var require_dist = __commonJS({
|
|
27192
|
-
"../session-host-core/dist/index.js"(exports2, module2) {
|
|
27193
|
-
"use strict";
|
|
27194
|
-
var __create2 = Object.create;
|
|
27195
|
-
var __defProp2 = Object.defineProperty;
|
|
27196
|
-
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
27197
|
-
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
27198
|
-
var __getProtoOf2 = Object.getPrototypeOf;
|
|
27199
|
-
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
27200
|
-
var __export2 = (target, all) => {
|
|
27201
|
-
for (var name in all)
|
|
27202
|
-
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
27203
|
-
};
|
|
27204
|
-
var __copyProps2 = (to, from, except, desc) => {
|
|
27205
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
27206
|
-
for (let key of __getOwnPropNames2(from))
|
|
27207
|
-
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
27208
|
-
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
27209
|
-
}
|
|
27210
|
-
return to;
|
|
27211
|
-
};
|
|
27212
|
-
var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps2(
|
|
27213
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
27214
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
27215
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
27216
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
27217
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target,
|
|
27218
|
-
mod
|
|
27219
|
-
));
|
|
27220
|
-
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
27221
|
-
var index_exports = {};
|
|
27222
|
-
__export2(index_exports, {
|
|
27223
|
-
SessionHostClient: () => SessionHostClient2,
|
|
27224
|
-
SessionHostRegistry: () => SessionHostRegistry,
|
|
27225
|
-
SessionRingBuffer: () => SessionRingBuffer,
|
|
27226
|
-
buildRuntimeDisplayName: () => buildRuntimeDisplayName,
|
|
27227
|
-
buildRuntimeKey: () => buildRuntimeKey,
|
|
27228
|
-
createLineParser: () => createLineParser2,
|
|
27229
|
-
createResponseEnvelope: () => createResponseEnvelope,
|
|
27230
|
-
formatRuntimeOwner: () => formatRuntimeOwner,
|
|
27231
|
-
getDefaultSessionHostEndpoint: () => getDefaultSessionHostEndpoint2,
|
|
27232
|
-
getWorkspaceLabel: () => getWorkspaceLabel,
|
|
27233
|
-
resolveRuntimeRecord: () => resolveRuntimeRecord,
|
|
27234
|
-
writeEnvelope: () => writeEnvelope
|
|
27235
|
-
});
|
|
27236
|
-
module2.exports = __toCommonJS2(index_exports);
|
|
27237
|
-
var SessionRingBuffer = class {
|
|
27238
|
-
maxBytes;
|
|
27239
|
-
chunks = [];
|
|
27240
|
-
nextSeq = 1;
|
|
27241
|
-
totalBytes = 0;
|
|
27242
|
-
constructor(options = {}) {
|
|
27243
|
-
this.maxBytes = options.maxBytes ?? 512 * 1024;
|
|
27244
|
-
}
|
|
27245
|
-
append(data) {
|
|
27246
|
-
const normalized = typeof data === "string" ? data : String(data ?? "");
|
|
27247
|
-
const bytes = Buffer.byteLength(normalized, "utf8");
|
|
27248
|
-
const seq = this.nextSeq++;
|
|
27249
|
-
this.chunks.push({ seq, data: normalized, bytes });
|
|
27250
|
-
this.totalBytes += bytes;
|
|
27251
|
-
this.trim();
|
|
27252
|
-
return seq;
|
|
27253
|
-
}
|
|
27254
|
-
snapshot(sinceSeq) {
|
|
27255
|
-
const relevant = typeof sinceSeq === "number" ? this.chunks.filter((chunk) => chunk.seq > sinceSeq) : this.chunks;
|
|
27256
|
-
const text = relevant.map((chunk) => chunk.data).join("");
|
|
27257
|
-
const truncated = !!this.chunks[0] && typeof sinceSeq === "number" && sinceSeq < this.chunks[0].seq - 1;
|
|
27258
|
-
return {
|
|
27259
|
-
seq: this.nextSeq - 1,
|
|
27260
|
-
text,
|
|
27261
|
-
truncated
|
|
27262
|
-
};
|
|
27263
|
-
}
|
|
27264
|
-
getState() {
|
|
27265
|
-
return {
|
|
27266
|
-
scrollbackBytes: this.totalBytes,
|
|
27267
|
-
snapshotSeq: this.nextSeq - 1
|
|
27268
|
-
};
|
|
27269
|
-
}
|
|
27270
|
-
clear() {
|
|
27271
|
-
this.chunks = [];
|
|
27272
|
-
this.totalBytes = 0;
|
|
27273
|
-
this.nextSeq = 1;
|
|
27274
|
-
}
|
|
27275
|
-
restore(snapshot) {
|
|
27276
|
-
this.clear();
|
|
27277
|
-
const text = String(snapshot.text || "");
|
|
27278
|
-
if (!text) {
|
|
27279
|
-
this.nextSeq = Math.max(1, Number(snapshot.seq || 0) + 1);
|
|
27280
|
-
return;
|
|
27281
|
-
}
|
|
27282
|
-
const bytes = Buffer.byteLength(text, "utf8");
|
|
27283
|
-
const seq = Math.max(1, Number(snapshot.seq || 1));
|
|
27284
|
-
this.chunks = [{ seq, data: text, bytes }];
|
|
27285
|
-
this.totalBytes = bytes;
|
|
27286
|
-
this.nextSeq = seq + 1;
|
|
27287
|
-
this.trim();
|
|
27288
|
-
}
|
|
27289
|
-
trim() {
|
|
27290
|
-
while (this.totalBytes > this.maxBytes && this.chunks.length > 1) {
|
|
27291
|
-
const removed = this.chunks.shift();
|
|
27292
|
-
if (!removed) break;
|
|
27293
|
-
this.totalBytes -= removed.bytes;
|
|
27294
|
-
}
|
|
27295
|
-
}
|
|
27296
|
-
};
|
|
27297
|
-
var import_crypto2 = require("crypto");
|
|
27298
|
-
var path5 = __toESM2(require("path"));
|
|
27299
|
-
function normalizeSlug(input) {
|
|
27300
|
-
return input.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48);
|
|
27301
|
-
}
|
|
27302
|
-
function normalizeValue(input) {
|
|
27303
|
-
return input.trim().toLowerCase();
|
|
27304
|
-
}
|
|
27305
|
-
function getWorkspaceLabel(workspace) {
|
|
27306
|
-
const trimmed = workspace.trim();
|
|
27307
|
-
if (!trimmed) return "workspace";
|
|
27308
|
-
const normalized = trimmed.replace(/[\\/]+$/, "");
|
|
27309
|
-
const base = path5.basename(normalized);
|
|
27310
|
-
return base || normalized;
|
|
27311
|
-
}
|
|
27312
|
-
function buildRuntimeDisplayName(payload) {
|
|
27313
|
-
const explicit = payload.displayName?.trim();
|
|
27314
|
-
if (explicit) return explicit;
|
|
27315
|
-
const workspaceLabel = getWorkspaceLabel(payload.workspace);
|
|
27316
|
-
const providerLabel = payload.providerType.trim() || "runtime";
|
|
27317
|
-
return `${providerLabel} @ ${workspaceLabel}`;
|
|
27318
|
-
}
|
|
27319
|
-
function buildRuntimeKey(payload, existingKeys) {
|
|
27320
|
-
const requested = payload.runtimeKey?.trim();
|
|
27321
|
-
const existing = new Set(Array.from(existingKeys, (key) => key.toLowerCase()));
|
|
27322
|
-
const displayName = buildRuntimeDisplayName(payload);
|
|
27323
|
-
const baseKey = normalizeSlug(requested || displayName || getWorkspaceLabel(payload.workspace) || payload.providerType || "runtime") || "runtime";
|
|
27324
|
-
if (!existing.has(baseKey)) return baseKey;
|
|
27325
|
-
let suffix = 2;
|
|
27326
|
-
let candidate = `${baseKey}-${suffix}`;
|
|
27327
|
-
while (existing.has(candidate)) {
|
|
27328
|
-
suffix += 1;
|
|
27329
|
-
candidate = `${baseKey}-${suffix}`;
|
|
27330
|
-
}
|
|
27331
|
-
return candidate;
|
|
27332
|
-
}
|
|
27333
|
-
function uniqueMatch(records, predicate) {
|
|
27334
|
-
const matches = records.filter(predicate);
|
|
27335
|
-
if (matches.length === 1) return matches[0] || null;
|
|
27336
|
-
if (matches.length === 0) return null;
|
|
27337
|
-
const labels = matches.map((record2) => `${record2.runtimeKey} (${record2.sessionId})`).join(", ");
|
|
27338
|
-
throw new Error(`Ambiguous runtime target. Matches: ${labels}`);
|
|
27339
|
-
}
|
|
27340
|
-
function resolveRuntimeRecord(records, identifier) {
|
|
27341
|
-
const target = identifier.trim();
|
|
27342
|
-
if (!target) {
|
|
27343
|
-
throw new Error("Runtime target is required");
|
|
27344
|
-
}
|
|
27345
|
-
const exact = uniqueMatch(
|
|
27346
|
-
records,
|
|
27347
|
-
(record2) => record2.sessionId === target || normalizeValue(record2.runtimeKey) === normalizeValue(target) || normalizeValue(record2.displayName) === normalizeValue(target)
|
|
27348
|
-
);
|
|
27349
|
-
if (exact) return exact;
|
|
27350
|
-
const prefix = uniqueMatch(
|
|
27351
|
-
records,
|
|
27352
|
-
(record2) => record2.sessionId.startsWith(target) || normalizeValue(record2.runtimeKey).startsWith(normalizeValue(target))
|
|
27353
|
-
);
|
|
27354
|
-
if (prefix) return prefix;
|
|
27355
|
-
throw new Error(`Unknown runtime target: ${target}`);
|
|
27356
|
-
}
|
|
27357
|
-
function formatRuntimeOwner(record2) {
|
|
27358
|
-
if (!record2.writeOwner) return "none";
|
|
27359
|
-
return `${record2.writeOwner.ownerType}:${record2.writeOwner.clientId}`;
|
|
27360
|
-
}
|
|
27361
|
-
var SessionHostRegistry = class {
|
|
27362
|
-
sessions = /* @__PURE__ */ new Map();
|
|
27363
|
-
createSession(payload) {
|
|
27364
|
-
const sessionId = payload.sessionId || (0, import_crypto2.randomUUID)();
|
|
27365
|
-
if (this.sessions.has(sessionId)) {
|
|
27366
|
-
throw new Error(`Session already exists: ${sessionId}`);
|
|
27367
|
-
}
|
|
27368
|
-
const now = Date.now();
|
|
27369
|
-
const initialClient = payload.clientId ? [{
|
|
27370
|
-
clientId: payload.clientId,
|
|
27371
|
-
type: payload.clientType || "daemon",
|
|
27372
|
-
readOnly: false,
|
|
27373
|
-
attachedAt: now,
|
|
27374
|
-
lastSeenAt: now
|
|
27375
|
-
}] : [];
|
|
27376
|
-
const record2 = {
|
|
27377
|
-
sessionId,
|
|
27378
|
-
runtimeKey: buildRuntimeKey(
|
|
27379
|
-
payload,
|
|
27380
|
-
Array.from(this.sessions.values(), (state) => state.record.runtimeKey)
|
|
27381
|
-
),
|
|
27382
|
-
displayName: buildRuntimeDisplayName(payload),
|
|
27383
|
-
workspaceLabel: getWorkspaceLabel(payload.workspace),
|
|
27384
|
-
transport: "pty",
|
|
27385
|
-
providerType: payload.providerType,
|
|
27386
|
-
category: payload.category,
|
|
27387
|
-
workspace: payload.workspace,
|
|
27388
|
-
launchCommand: payload.launchCommand,
|
|
27389
|
-
createdAt: now,
|
|
27390
|
-
lastActivityAt: now,
|
|
27391
|
-
lifecycle: "starting",
|
|
27392
|
-
writeOwner: null,
|
|
27393
|
-
attachedClients: initialClient,
|
|
27394
|
-
buffer: {
|
|
27395
|
-
scrollbackBytes: 0,
|
|
27396
|
-
snapshotSeq: 0
|
|
27397
|
-
},
|
|
27398
|
-
meta: payload.meta || {}
|
|
27399
|
-
};
|
|
27400
|
-
record2.meta = {
|
|
27401
|
-
sessionHostCols: payload.cols || 80,
|
|
27402
|
-
sessionHostRows: payload.rows || 24,
|
|
27403
|
-
...record2.meta
|
|
27404
|
-
};
|
|
27405
|
-
this.sessions.set(sessionId, {
|
|
27406
|
-
record: record2,
|
|
27407
|
-
buffer: new SessionRingBuffer()
|
|
27408
|
-
});
|
|
27409
|
-
return this.cloneRecord(record2);
|
|
27410
|
-
}
|
|
27411
|
-
restoreSession(record2, snapshot) {
|
|
27412
|
-
const cloned = this.cloneRecord(record2);
|
|
27413
|
-
this.sessions.set(cloned.sessionId, {
|
|
27414
|
-
record: cloned,
|
|
27415
|
-
buffer: (() => {
|
|
27416
|
-
const buffer = new SessionRingBuffer();
|
|
27417
|
-
if (snapshot) buffer.restore(snapshot);
|
|
27418
|
-
return buffer;
|
|
27419
|
-
})()
|
|
27420
|
-
});
|
|
27421
|
-
return this.cloneRecord(cloned);
|
|
27422
|
-
}
|
|
27423
|
-
listSessions() {
|
|
27424
|
-
return Array.from(this.sessions.values()).map((state) => this.cloneRecord(state.record)).sort((a, b2) => b2.lastActivityAt - a.lastActivityAt);
|
|
27425
|
-
}
|
|
27426
|
-
getSession(sessionId) {
|
|
27427
|
-
const state = this.sessions.get(sessionId);
|
|
27428
|
-
return state ? this.cloneRecord(state.record) : null;
|
|
27429
|
-
}
|
|
27430
|
-
attachClient(payload) {
|
|
27431
|
-
const state = this.requireSession(payload.sessionId);
|
|
27432
|
-
const now = Date.now();
|
|
27433
|
-
let removedDaemonOwner = false;
|
|
27434
|
-
if (payload.clientType === "daemon") {
|
|
27435
|
-
const staleDaemonClientIds = state.record.attachedClients.filter((client) => client.type === "daemon" && client.clientId !== payload.clientId).map((client) => client.clientId);
|
|
27436
|
-
if (staleDaemonClientIds.length > 0) {
|
|
27437
|
-
state.record.attachedClients = state.record.attachedClients.filter(
|
|
27438
|
-
(client) => !(client.type === "daemon" && client.clientId !== payload.clientId)
|
|
27439
|
-
);
|
|
27440
|
-
if (state.record.writeOwner && staleDaemonClientIds.includes(state.record.writeOwner.clientId)) {
|
|
27441
|
-
removedDaemonOwner = true;
|
|
27442
|
-
}
|
|
27443
|
-
}
|
|
27444
|
-
}
|
|
27445
|
-
const existing = state.record.attachedClients.find((client) => client.clientId === payload.clientId);
|
|
27446
|
-
if (existing) {
|
|
27447
|
-
existing.type = payload.clientType;
|
|
27448
|
-
existing.readOnly = !!payload.readOnly;
|
|
27449
|
-
existing.lastSeenAt = now;
|
|
27450
|
-
} else {
|
|
27451
|
-
state.record.attachedClients.push({
|
|
27452
|
-
clientId: payload.clientId,
|
|
27453
|
-
type: payload.clientType,
|
|
27454
|
-
readOnly: !!payload.readOnly,
|
|
27455
|
-
attachedAt: now,
|
|
27456
|
-
lastSeenAt: now
|
|
27616
|
+
const df = now2 - pw.lastChange;
|
|
27617
|
+
if (df >= threshold) {
|
|
27618
|
+
writes.delete(path5);
|
|
27619
|
+
awfEmit(void 0, curStat);
|
|
27620
|
+
} else {
|
|
27621
|
+
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
|
|
27622
|
+
}
|
|
27457
27623
|
});
|
|
27458
27624
|
}
|
|
27459
|
-
if (
|
|
27460
|
-
|
|
27461
|
-
|
|
27462
|
-
|
|
27463
|
-
|
|
27464
|
-
|
|
27465
|
-
|
|
27466
|
-
|
|
27467
|
-
|
|
27468
|
-
|
|
27469
|
-
state.record.writeOwner = null;
|
|
27470
|
-
}
|
|
27471
|
-
state.record.lastActivityAt = Date.now();
|
|
27472
|
-
return this.cloneRecord(state.record);
|
|
27473
|
-
}
|
|
27474
|
-
acquireWrite(payload) {
|
|
27475
|
-
const state = this.requireSession(payload.sessionId);
|
|
27476
|
-
if (state.record.writeOwner && state.record.writeOwner.clientId !== payload.clientId && !payload.force) {
|
|
27477
|
-
throw new Error(`Write owned by ${state.record.writeOwner.clientId}`);
|
|
27478
|
-
}
|
|
27479
|
-
const attachedClient = state.record.attachedClients.find((client) => client.clientId === payload.clientId);
|
|
27480
|
-
if (attachedClient) {
|
|
27481
|
-
attachedClient.readOnly = false;
|
|
27482
|
-
attachedClient.lastSeenAt = Date.now();
|
|
27625
|
+
if (!writes.has(path5)) {
|
|
27626
|
+
writes.set(path5, {
|
|
27627
|
+
lastChange: now,
|
|
27628
|
+
cancelWait: () => {
|
|
27629
|
+
writes.delete(path5);
|
|
27630
|
+
clearTimeout(timeoutHandler);
|
|
27631
|
+
return event;
|
|
27632
|
+
}
|
|
27633
|
+
});
|
|
27634
|
+
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval);
|
|
27483
27635
|
}
|
|
27484
|
-
state.record.writeOwner = {
|
|
27485
|
-
clientId: payload.clientId,
|
|
27486
|
-
ownerType: payload.ownerType,
|
|
27487
|
-
acquiredAt: Date.now()
|
|
27488
|
-
};
|
|
27489
|
-
state.record.lastActivityAt = Date.now();
|
|
27490
|
-
return this.cloneRecord(state.record);
|
|
27491
27636
|
}
|
|
27492
|
-
|
|
27493
|
-
|
|
27494
|
-
|
|
27495
|
-
|
|
27496
|
-
|
|
27497
|
-
|
|
27498
|
-
|
|
27499
|
-
|
|
27500
|
-
|
|
27637
|
+
/**
|
|
27638
|
+
* Determines whether user has asked to ignore this path.
|
|
27639
|
+
*/
|
|
27640
|
+
_isIgnored(path5, stats) {
|
|
27641
|
+
if (this.options.atomic && DOT_RE.test(path5))
|
|
27642
|
+
return true;
|
|
27643
|
+
if (!this._userIgnored) {
|
|
27644
|
+
const { cwd } = this.options;
|
|
27645
|
+
const ign = this.options.ignored;
|
|
27646
|
+
const ignored = (ign || []).map(normalizeIgnored(cwd));
|
|
27647
|
+
const ignoredPaths = [...this._ignoredPaths];
|
|
27648
|
+
const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
|
|
27649
|
+
this._userIgnored = anymatch(list, void 0);
|
|
27501
27650
|
}
|
|
27502
|
-
|
|
27503
|
-
return this.cloneRecord(state.record);
|
|
27504
|
-
}
|
|
27505
|
-
appendOutput(sessionId, data) {
|
|
27506
|
-
const state = this.requireSession(sessionId);
|
|
27507
|
-
const seq = state.buffer.append(data);
|
|
27508
|
-
state.record.buffer = state.buffer.getState();
|
|
27509
|
-
state.record.lastActivityAt = Date.now();
|
|
27510
|
-
return { record: this.cloneRecord(state.record), seq };
|
|
27511
|
-
}
|
|
27512
|
-
getSnapshot(sessionId, sinceSeq) {
|
|
27513
|
-
const state = this.requireSession(sessionId);
|
|
27514
|
-
state.record.buffer = state.buffer.getState();
|
|
27515
|
-
return state.buffer.snapshot(sinceSeq);
|
|
27516
|
-
}
|
|
27517
|
-
clearBuffer(sessionId) {
|
|
27518
|
-
const state = this.requireSession(sessionId);
|
|
27519
|
-
state.buffer.clear();
|
|
27520
|
-
state.record.buffer = state.buffer.getState();
|
|
27521
|
-
state.record.lastActivityAt = Date.now();
|
|
27522
|
-
return this.cloneRecord(state.record);
|
|
27523
|
-
}
|
|
27524
|
-
updateSessionMeta(sessionId, meta3, replace = false) {
|
|
27525
|
-
const state = this.requireSession(sessionId);
|
|
27526
|
-
state.record.meta = replace ? { ...meta3 } : {
|
|
27527
|
-
...state.record.meta || {},
|
|
27528
|
-
...meta3
|
|
27529
|
-
};
|
|
27530
|
-
state.record.lastActivityAt = Date.now();
|
|
27531
|
-
return this.cloneRecord(state.record);
|
|
27532
|
-
}
|
|
27533
|
-
markStarted(sessionId, pid) {
|
|
27534
|
-
const state = this.requireSession(sessionId);
|
|
27535
|
-
state.record.lifecycle = "running";
|
|
27536
|
-
state.record.startedAt = state.record.startedAt || Date.now();
|
|
27537
|
-
if (typeof pid === "number") state.record.osPid = pid;
|
|
27538
|
-
state.record.lastActivityAt = Date.now();
|
|
27539
|
-
return this.cloneRecord(state.record);
|
|
27540
|
-
}
|
|
27541
|
-
markStopped(sessionId, lifecycle = "stopped") {
|
|
27542
|
-
const state = this.requireSession(sessionId);
|
|
27543
|
-
state.record.lifecycle = lifecycle;
|
|
27544
|
-
state.record.lastActivityAt = Date.now();
|
|
27545
|
-
return this.cloneRecord(state.record);
|
|
27651
|
+
return this._userIgnored(path5, stats);
|
|
27546
27652
|
}
|
|
27547
|
-
|
|
27548
|
-
|
|
27549
|
-
state.record.lifecycle = lifecycle;
|
|
27550
|
-
state.record.lastActivityAt = Date.now();
|
|
27551
|
-
return this.cloneRecord(state.record);
|
|
27653
|
+
_isntIgnored(path5, stat4) {
|
|
27654
|
+
return !this._isIgnored(path5, stat4);
|
|
27552
27655
|
}
|
|
27553
|
-
|
|
27554
|
-
|
|
27555
|
-
|
|
27556
|
-
|
|
27656
|
+
/**
|
|
27657
|
+
* Provides a set of common helpers and properties relating to symlink handling.
|
|
27658
|
+
* @param path file or directory pattern being watched
|
|
27659
|
+
*/
|
|
27660
|
+
_getWatchHelpers(path5) {
|
|
27661
|
+
return new WatchHelper(path5, this.options.followSymlinks, this);
|
|
27557
27662
|
}
|
|
27558
|
-
|
|
27559
|
-
|
|
27560
|
-
|
|
27561
|
-
|
|
27562
|
-
|
|
27563
|
-
|
|
27564
|
-
|
|
27565
|
-
|
|
27566
|
-
|
|
27567
|
-
|
|
27568
|
-
|
|
27569
|
-
meta: { ...record2.meta }
|
|
27570
|
-
};
|
|
27663
|
+
// Directory helpers
|
|
27664
|
+
// -----------------
|
|
27665
|
+
/**
|
|
27666
|
+
* Provides directory tracking objects
|
|
27667
|
+
* @param directory path of the directory
|
|
27668
|
+
*/
|
|
27669
|
+
_getWatchedDir(directory) {
|
|
27670
|
+
const dir = sp2.resolve(directory);
|
|
27671
|
+
if (!this._watched.has(dir))
|
|
27672
|
+
this._watched.set(dir, new DirEntry(dir, this._boundRemove));
|
|
27673
|
+
return this._watched.get(dir);
|
|
27571
27674
|
}
|
|
27572
|
-
|
|
27573
|
-
|
|
27574
|
-
|
|
27575
|
-
|
|
27576
|
-
|
|
27577
|
-
|
|
27578
|
-
|
|
27579
|
-
|
|
27580
|
-
|
|
27581
|
-
path: `\\\\.\\pipe\\${appName}-session-host`
|
|
27582
|
-
};
|
|
27675
|
+
// File helpers
|
|
27676
|
+
// ------------
|
|
27677
|
+
/**
|
|
27678
|
+
* Check for read permissions: https://stackoverflow.com/a/11781404/1358405
|
|
27679
|
+
*/
|
|
27680
|
+
_hasReadPermissions(stats) {
|
|
27681
|
+
if (this.options.ignorePermissionErrors)
|
|
27682
|
+
return true;
|
|
27683
|
+
return Boolean(Number(stats.mode) & 256);
|
|
27583
27684
|
}
|
|
27584
|
-
|
|
27585
|
-
|
|
27586
|
-
|
|
27587
|
-
|
|
27588
|
-
|
|
27589
|
-
|
|
27590
|
-
|
|
27591
|
-
|
|
27592
|
-
|
|
27593
|
-
|
|
27594
|
-
|
|
27595
|
-
|
|
27596
|
-
|
|
27597
|
-
|
|
27598
|
-
|
|
27599
|
-
const rawLine = buffer.slice(0, newlineIndex).trim();
|
|
27600
|
-
buffer = buffer.slice(newlineIndex + 1);
|
|
27601
|
-
if (rawLine) {
|
|
27602
|
-
onEnvelope(JSON.parse(rawLine));
|
|
27603
|
-
}
|
|
27604
|
-
newlineIndex = buffer.indexOf("\n");
|
|
27685
|
+
/**
|
|
27686
|
+
* Handles emitting unlink events for
|
|
27687
|
+
* files and directories, and via recursion, for
|
|
27688
|
+
* files and directories within directories that are unlinked
|
|
27689
|
+
* @param directory within which the following item is located
|
|
27690
|
+
* @param item base path of item/directory
|
|
27691
|
+
*/
|
|
27692
|
+
_remove(directory, item, isDirectory) {
|
|
27693
|
+
const path5 = sp2.join(directory, item);
|
|
27694
|
+
const fullPath = sp2.resolve(path5);
|
|
27695
|
+
isDirectory = isDirectory != null ? isDirectory : this._watched.has(path5) || this._watched.has(fullPath);
|
|
27696
|
+
if (!this._throttle("remove", path5, 100))
|
|
27697
|
+
return;
|
|
27698
|
+
if (!isDirectory && this._watched.size === 1) {
|
|
27699
|
+
this.add(directory, item, true);
|
|
27605
27700
|
}
|
|
27606
|
-
|
|
27607
|
-
|
|
27608
|
-
|
|
27609
|
-
|
|
27610
|
-
|
|
27611
|
-
|
|
27612
|
-
|
|
27613
|
-
|
|
27614
|
-
|
|
27615
|
-
|
|
27616
|
-
|
|
27617
|
-
|
|
27618
|
-
|
|
27619
|
-
|
|
27620
|
-
|
|
27621
|
-
if (envelope.kind === "response") {
|
|
27622
|
-
const waiter = this.requestWaiters.get(envelope.requestId);
|
|
27623
|
-
if (waiter) {
|
|
27624
|
-
this.requestWaiters.delete(envelope.requestId);
|
|
27625
|
-
waiter.resolve(envelope.response);
|
|
27626
|
-
}
|
|
27701
|
+
const wp = this._getWatchedDir(path5);
|
|
27702
|
+
const nestedDirectoryChildren = wp.getChildren();
|
|
27703
|
+
nestedDirectoryChildren.forEach((nested) => this._remove(path5, nested));
|
|
27704
|
+
const parent = this._getWatchedDir(directory);
|
|
27705
|
+
const wasTracked = parent.has(item);
|
|
27706
|
+
parent.remove(item);
|
|
27707
|
+
if (this._symlinkPaths.has(fullPath)) {
|
|
27708
|
+
this._symlinkPaths.delete(fullPath);
|
|
27709
|
+
}
|
|
27710
|
+
let relPath = path5;
|
|
27711
|
+
if (this.options.cwd)
|
|
27712
|
+
relPath = sp2.relative(this.options.cwd, path5);
|
|
27713
|
+
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
|
27714
|
+
const event = this._pendingWrites.get(relPath).cancelWait();
|
|
27715
|
+
if (event === EVENTS.ADD)
|
|
27627
27716
|
return;
|
|
27628
|
-
|
|
27629
|
-
|
|
27630
|
-
|
|
27631
|
-
|
|
27632
|
-
|
|
27633
|
-
|
|
27634
|
-
|
|
27635
|
-
waiter.reject(error48);
|
|
27636
|
-
}
|
|
27637
|
-
this.requestWaiters.clear();
|
|
27638
|
-
});
|
|
27639
|
-
await new Promise((resolve4, reject) => {
|
|
27640
|
-
socket.once("connect", () => resolve4());
|
|
27641
|
-
socket.once("error", reject);
|
|
27642
|
-
});
|
|
27717
|
+
}
|
|
27718
|
+
this._watched.delete(path5);
|
|
27719
|
+
this._watched.delete(fullPath);
|
|
27720
|
+
const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
|
|
27721
|
+
if (wasTracked && !this._isIgnored(path5))
|
|
27722
|
+
this._emit(eventName, path5);
|
|
27723
|
+
this._closePath(path5);
|
|
27643
27724
|
}
|
|
27644
|
-
|
|
27645
|
-
|
|
27646
|
-
|
|
27647
|
-
|
|
27648
|
-
|
|
27725
|
+
/**
|
|
27726
|
+
* Closes all watchers for a path
|
|
27727
|
+
*/
|
|
27728
|
+
_closePath(path5) {
|
|
27729
|
+
this._closeFile(path5);
|
|
27730
|
+
const dir = sp2.dirname(path5);
|
|
27731
|
+
this._getWatchedDir(dir).remove(sp2.basename(path5));
|
|
27649
27732
|
}
|
|
27650
|
-
|
|
27651
|
-
|
|
27652
|
-
|
|
27653
|
-
|
|
27654
|
-
const
|
|
27655
|
-
|
|
27656
|
-
|
|
27657
|
-
|
|
27658
|
-
|
|
27659
|
-
const response = await new Promise((resolve4, reject) => {
|
|
27660
|
-
const timeout = setTimeout(() => {
|
|
27661
|
-
this.requestWaiters.delete(requestId);
|
|
27662
|
-
reject(new Error(`Session host request timed out after 30s (${request.type})`));
|
|
27663
|
-
}, 3e4);
|
|
27664
|
-
this.requestWaiters.set(requestId, {
|
|
27665
|
-
resolve: (value) => {
|
|
27666
|
-
clearTimeout(timeout);
|
|
27667
|
-
resolve4(value);
|
|
27668
|
-
},
|
|
27669
|
-
reject: (error48) => {
|
|
27670
|
-
clearTimeout(timeout);
|
|
27671
|
-
reject(error48);
|
|
27672
|
-
}
|
|
27673
|
-
});
|
|
27674
|
-
this.socket?.write(serializeEnvelope3(envelope));
|
|
27675
|
-
});
|
|
27676
|
-
return response;
|
|
27733
|
+
/**
|
|
27734
|
+
* Closes only file-specific watchers
|
|
27735
|
+
*/
|
|
27736
|
+
_closeFile(path5) {
|
|
27737
|
+
const closers = this._closers.get(path5);
|
|
27738
|
+
if (!closers)
|
|
27739
|
+
return;
|
|
27740
|
+
closers.forEach((closer) => closer());
|
|
27741
|
+
this._closers.delete(path5);
|
|
27677
27742
|
}
|
|
27678
|
-
|
|
27679
|
-
if (!
|
|
27680
|
-
|
|
27681
|
-
|
|
27682
|
-
|
|
27683
|
-
|
|
27743
|
+
_addPathCloser(path5, closer) {
|
|
27744
|
+
if (!closer)
|
|
27745
|
+
return;
|
|
27746
|
+
let list = this._closers.get(path5);
|
|
27747
|
+
if (!list) {
|
|
27748
|
+
list = [];
|
|
27749
|
+
this._closers.set(path5, list);
|
|
27684
27750
|
}
|
|
27685
|
-
|
|
27686
|
-
|
|
27687
|
-
|
|
27688
|
-
|
|
27689
|
-
|
|
27690
|
-
|
|
27691
|
-
|
|
27692
|
-
|
|
27693
|
-
|
|
27694
|
-
|
|
27695
|
-
|
|
27696
|
-
|
|
27751
|
+
list.push(closer);
|
|
27752
|
+
}
|
|
27753
|
+
_readdirp(root, opts) {
|
|
27754
|
+
if (this.closed)
|
|
27755
|
+
return;
|
|
27756
|
+
const options = { type: EVENTS.ALL, alwaysStat: true, lstat: true, ...opts, depth: 0 };
|
|
27757
|
+
let stream = readdirp(root, options);
|
|
27758
|
+
this._streams.add(stream);
|
|
27759
|
+
stream.once(STR_CLOSE, () => {
|
|
27760
|
+
stream = void 0;
|
|
27761
|
+
});
|
|
27762
|
+
stream.once(STR_END, () => {
|
|
27763
|
+
if (stream) {
|
|
27764
|
+
this._streams.delete(stream);
|
|
27765
|
+
stream = void 0;
|
|
27766
|
+
}
|
|
27697
27767
|
});
|
|
27768
|
+
return stream;
|
|
27698
27769
|
}
|
|
27699
27770
|
};
|
|
27700
|
-
|
|
27701
|
-
return {
|
|
27702
|
-
kind: "response",
|
|
27703
|
-
requestId,
|
|
27704
|
-
response
|
|
27705
|
-
};
|
|
27706
|
-
}
|
|
27707
|
-
function writeEnvelope(socket, envelope) {
|
|
27708
|
-
socket.write(serializeEnvelope3(envelope));
|
|
27709
|
-
}
|
|
27771
|
+
chokidar_default = { watch, FSWatcher };
|
|
27710
27772
|
}
|
|
27711
27773
|
});
|
|
27712
27774
|
|
|
@@ -28370,6 +28432,13 @@ var require_dist2 = __commonJS({
|
|
|
28370
28432
|
const key = `${preference}:${ghosttyAvailable}:${backendKind}`;
|
|
28371
28433
|
if (loggedTerminalBackends.has(key)) return;
|
|
28372
28434
|
loggedTerminalBackends.add(key);
|
|
28435
|
+
if (backendKind === "xterm" && preference !== "xterm" && !ghosttyAvailable) {
|
|
28436
|
+
LOG2.warn(
|
|
28437
|
+
"Terminal",
|
|
28438
|
+
`[terminal-screen] ghostty-vt unavailable; using xterm fallback (preference=${preference})`
|
|
28439
|
+
);
|
|
28440
|
+
return;
|
|
28441
|
+
}
|
|
28373
28442
|
LOG2.info(
|
|
28374
28443
|
"Terminal",
|
|
28375
28444
|
`[terminal-screen] backend=${backendKind} preference=${preference} ghosttyAvailable=${ghosttyAvailable}`
|
|
@@ -28432,12 +28501,14 @@ var require_dist2 = __commonJS({
|
|
|
28432
28501
|
};
|
|
28433
28502
|
}
|
|
28434
28503
|
});
|
|
28504
|
+
var os7;
|
|
28435
28505
|
var pty;
|
|
28436
28506
|
var NodePtyRuntimeTransport;
|
|
28437
28507
|
var NodePtyTransportFactory;
|
|
28438
28508
|
var init_pty_transport = __esm2({
|
|
28439
28509
|
"src/cli-adapters/pty-transport.ts"() {
|
|
28440
28510
|
"use strict";
|
|
28511
|
+
os7 = __toESM2(require("os"));
|
|
28441
28512
|
try {
|
|
28442
28513
|
pty = require("node-pty");
|
|
28443
28514
|
} catch {
|
|
@@ -28474,11 +28545,21 @@ var require_dist2 = __commonJS({
|
|
|
28474
28545
|
NodePtyTransportFactory = class {
|
|
28475
28546
|
spawn(command, args, options) {
|
|
28476
28547
|
if (!pty) throw new Error("node-pty is not installed");
|
|
28548
|
+
let cwd = options.cwd;
|
|
28549
|
+
if (cwd) {
|
|
28550
|
+
try {
|
|
28551
|
+
const fs15 = require("fs");
|
|
28552
|
+
const stat4 = fs15.statSync(cwd);
|
|
28553
|
+
if (!stat4.isDirectory()) cwd = os7.homedir();
|
|
28554
|
+
} catch {
|
|
28555
|
+
cwd = os7.homedir();
|
|
28556
|
+
}
|
|
28557
|
+
}
|
|
28477
28558
|
const handle = pty.spawn(command, args, {
|
|
28478
28559
|
name: "xterm-256color",
|
|
28479
28560
|
cols: options.cols,
|
|
28480
28561
|
rows: options.rows,
|
|
28481
|
-
cwd
|
|
28562
|
+
cwd,
|
|
28482
28563
|
env: options.env
|
|
28483
28564
|
});
|
|
28484
28565
|
return new NodePtyRuntimeTransport(handle);
|
|
@@ -28486,6 +28567,13 @@ var require_dist2 = __commonJS({
|
|
|
28486
28567
|
};
|
|
28487
28568
|
}
|
|
28488
28569
|
});
|
|
28570
|
+
var import_session_host_core2;
|
|
28571
|
+
var init_spawn_env = __esm2({
|
|
28572
|
+
"src/cli-adapters/spawn-env.ts"() {
|
|
28573
|
+
"use strict";
|
|
28574
|
+
import_session_host_core2 = require_dist();
|
|
28575
|
+
}
|
|
28576
|
+
});
|
|
28489
28577
|
var provider_cli_adapter_exports = {};
|
|
28490
28578
|
__export2(provider_cli_adapter_exports, {
|
|
28491
28579
|
ProviderCliAdapter: () => ProviderCliAdapter,
|
|
@@ -28500,32 +28588,6 @@ var require_dist2 = __commonJS({
|
|
|
28500
28588
|
function sanitizeTerminalText(str) {
|
|
28501
28589
|
return stripTerminalNoise(stripAnsi(str));
|
|
28502
28590
|
}
|
|
28503
|
-
function applyPreferredTerminalColorEnv(env) {
|
|
28504
|
-
if (env.NO_COLOR) return;
|
|
28505
|
-
if (!env.TERM || env.TERM === "xterm-color") {
|
|
28506
|
-
env.TERM = "xterm-256color";
|
|
28507
|
-
}
|
|
28508
|
-
if (!env.COLORTERM) env.COLORTERM = "truecolor";
|
|
28509
|
-
if (process.platform === "win32") {
|
|
28510
|
-
if (!env.FORCE_COLOR) env.FORCE_COLOR = "1";
|
|
28511
|
-
if (!env.CLICOLOR) env.CLICOLOR = "1";
|
|
28512
|
-
}
|
|
28513
|
-
}
|
|
28514
|
-
function buildCliSpawnEnv(baseEnv, overrides) {
|
|
28515
|
-
const env = {};
|
|
28516
|
-
const source = { ...baseEnv, ...overrides || {} };
|
|
28517
|
-
for (const [key, value] of Object.entries(source)) {
|
|
28518
|
-
if (typeof value !== "string") continue;
|
|
28519
|
-
env[key] = value;
|
|
28520
|
-
}
|
|
28521
|
-
for (const key of Object.keys(env)) {
|
|
28522
|
-
if (key === "INIT_CWD" || key === "npm_command" || key === "npm_execpath" || key === "npm_node_execpath" || key.startsWith("npm_") || key.startsWith("npm_config_") || key.startsWith("npm_package_") || key.startsWith("npm_lifecycle_") || key.startsWith("PNPM_") || key.startsWith("YARN_") || key.startsWith("BUN_")) {
|
|
28523
|
-
delete env[key];
|
|
28524
|
-
}
|
|
28525
|
-
}
|
|
28526
|
-
applyPreferredTerminalColorEnv(env);
|
|
28527
|
-
return env;
|
|
28528
|
-
}
|
|
28529
28591
|
function computeTerminalQueryTail(buffer) {
|
|
28530
28592
|
const prefixes = ["\x1B[6n", "\x1B[?6n"];
|
|
28531
28593
|
const maxLength = prefixes.reduce((n, value) => Math.max(n, value.length), 0) - 1;
|
|
@@ -28539,7 +28601,7 @@ var require_dist2 = __commonJS({
|
|
|
28539
28601
|
return "";
|
|
28540
28602
|
}
|
|
28541
28603
|
function findBinary(name) {
|
|
28542
|
-
const isWin =
|
|
28604
|
+
const isWin = os8.platform() === "win32";
|
|
28543
28605
|
try {
|
|
28544
28606
|
const cmd = isWin ? `where ${name}` : `which ${name}`;
|
|
28545
28607
|
return (0, import_child_process4.execSync)(cmd, { encoding: "utf-8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] }).trim().split("\n")[0].trim();
|
|
@@ -28587,7 +28649,7 @@ var require_dist2 = __commonJS({
|
|
|
28587
28649
|
}
|
|
28588
28650
|
function shSingleQuote(arg) {
|
|
28589
28651
|
if (/^[a-zA-Z0-9@%_+=:,./-]+$/.test(arg)) return arg;
|
|
28590
|
-
if (
|
|
28652
|
+
if (os8.platform() === "win32") {
|
|
28591
28653
|
return `"${arg.replace(/"/g, '""')}"`;
|
|
28592
28654
|
}
|
|
28593
28655
|
return `'${arg.replace(/'/g, `'\\''`)}'`;
|
|
@@ -28654,41 +28716,29 @@ var require_dist2 = __commonJS({
|
|
|
28654
28716
|
}
|
|
28655
28717
|
};
|
|
28656
28718
|
}
|
|
28657
|
-
var
|
|
28719
|
+
var os8;
|
|
28658
28720
|
var path7;
|
|
28659
28721
|
var import_child_process4;
|
|
28660
28722
|
var pty2;
|
|
28723
|
+
var buildCliSpawnEnv;
|
|
28661
28724
|
var ProviderCliAdapter;
|
|
28662
28725
|
var init_provider_cli_adapter = __esm2({
|
|
28663
28726
|
"src/cli-adapters/provider-cli-adapter.ts"() {
|
|
28664
28727
|
"use strict";
|
|
28665
|
-
|
|
28728
|
+
os8 = __toESM2(require("os"));
|
|
28666
28729
|
path7 = __toESM2(require("path"));
|
|
28667
28730
|
import_child_process4 = require("child_process");
|
|
28668
28731
|
init_logger();
|
|
28669
28732
|
init_terminal_screen();
|
|
28670
28733
|
init_pty_transport();
|
|
28734
|
+
init_spawn_env();
|
|
28671
28735
|
try {
|
|
28672
28736
|
pty2 = require("node-pty");
|
|
28673
|
-
|
|
28674
|
-
try {
|
|
28675
|
-
const fs15 = require("fs");
|
|
28676
|
-
const ptyDir = path7.resolve(path7.dirname(require.resolve("node-pty")), "..");
|
|
28677
|
-
const platformArch = `${os7.platform()}-${os7.arch()}`;
|
|
28678
|
-
const helper = path7.join(ptyDir, "prebuilds", platformArch, "spawn-helper");
|
|
28679
|
-
if (fs15.existsSync(helper)) {
|
|
28680
|
-
const stat4 = fs15.statSync(helper);
|
|
28681
|
-
if (!(stat4.mode & 73)) {
|
|
28682
|
-
fs15.chmodSync(helper, stat4.mode | 493);
|
|
28683
|
-
LOG2.info("CLI", "[node-pty] Fixed spawn-helper permissions");
|
|
28684
|
-
}
|
|
28685
|
-
}
|
|
28686
|
-
} catch {
|
|
28687
|
-
}
|
|
28688
|
-
}
|
|
28737
|
+
(0, import_session_host_core2.ensureNodePtySpawnHelperPermissions)((msg) => LOG2.info("CLI", msg));
|
|
28689
28738
|
} catch {
|
|
28690
28739
|
LOG2.error("CLI", "[ProviderCliAdapter] node-pty not found. Terminal features disabled.");
|
|
28691
28740
|
}
|
|
28741
|
+
buildCliSpawnEnv = import_session_host_core2.sanitizeSpawnEnv;
|
|
28692
28742
|
ProviderCliAdapter = class _ProviderCliAdapter {
|
|
28693
28743
|
constructor(provider, workingDir, extraArgs = [], transportFactory = new NodePtyTransportFactory()) {
|
|
28694
28744
|
this.extraArgs = extraArgs;
|
|
@@ -28696,7 +28746,7 @@ var require_dist2 = __commonJS({
|
|
|
28696
28746
|
this.transportFactory = transportFactory;
|
|
28697
28747
|
this.cliType = provider.type;
|
|
28698
28748
|
this.cliName = provider.name;
|
|
28699
|
-
this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/,
|
|
28749
|
+
this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/, os8.homedir()) : workingDir;
|
|
28700
28750
|
const t = provider.timeouts || {};
|
|
28701
28751
|
this.timeouts = {
|
|
28702
28752
|
ptyFlush: t.ptyFlush ?? 50,
|
|
@@ -29003,7 +29053,7 @@ var require_dist2 = __commonJS({
|
|
|
29003
29053
|
if (this.ptyProcess) return;
|
|
29004
29054
|
const { spawn: spawnConfig } = this.provider;
|
|
29005
29055
|
const binaryPath = findBinary(spawnConfig.command);
|
|
29006
|
-
const isWin =
|
|
29056
|
+
const isWin = os8.platform() === "win32";
|
|
29007
29057
|
const allArgs = [...spawnConfig.args, ...this.extraArgs];
|
|
29008
29058
|
LOG2.info("CLI", `[${this.cliType}] Spawning in ${this.workingDir}`);
|
|
29009
29059
|
this.resetTraceSession();
|
|
@@ -29055,6 +29105,12 @@ var require_dist2 = __commonJS({
|
|
|
29055
29105
|
shellArgs = ["-l", "-c", fullCmd];
|
|
29056
29106
|
this.ptyProcess = this.transportFactory.spawn(shellCmd, shellArgs, ptyOpts);
|
|
29057
29107
|
} else {
|
|
29108
|
+
if (isWin) {
|
|
29109
|
+
const hint = /error code 267|ERROR_DIRECTORY/i.test(msg) ? " (working directory does not exist or is not a directory)" : /error code 740|elevation/i.test(msg) ? " (requires administrator privileges)" : /error code 2|ENOENT|not found/i.test(msg) ? ` (executable not found: ${shellCmd})` : "";
|
|
29110
|
+
if (hint) {
|
|
29111
|
+
throw new Error(`Failed to spawn CLI${hint}: ${msg}`);
|
|
29112
|
+
}
|
|
29113
|
+
}
|
|
29058
29114
|
throw err;
|
|
29059
29115
|
}
|
|
29060
29116
|
}
|
|
@@ -29229,7 +29285,7 @@ var require_dist2 = __commonJS({
|
|
|
29229
29285
|
`[${this.cliType}] Waiting for interactive prompt: hasPrompt=${hasPrompt} stableMs=${stableMs} recentOutputMs=${recentlyOutput} status=${status} startup=${startupLikelyActive} screen=${JSON.stringify(this.summarizeTraceText(screenText, 220)).slice(0, 260)}`
|
|
29230
29286
|
);
|
|
29231
29287
|
}
|
|
29232
|
-
await new Promise((
|
|
29288
|
+
await new Promise((resolve9) => setTimeout(resolve9, 50));
|
|
29233
29289
|
}
|
|
29234
29290
|
const finalScreenText = this.terminalScreen.getText() || "";
|
|
29235
29291
|
LOG2.warn(
|
|
@@ -29616,7 +29672,7 @@ ${data.message || ""}`.trim();
|
|
|
29616
29672
|
if (this.startupParseGate) {
|
|
29617
29673
|
const deadline = Date.now() + 1e4;
|
|
29618
29674
|
while (this.startupParseGate && Date.now() < deadline) {
|
|
29619
|
-
await new Promise((
|
|
29675
|
+
await new Promise((resolve9) => setTimeout(resolve9, 50));
|
|
29620
29676
|
}
|
|
29621
29677
|
}
|
|
29622
29678
|
if (!this.ready) throw new Error(`${this.cliName} not ready (status: ${this.currentStatus})`);
|
|
@@ -29807,7 +29863,8 @@ ${data.message || ""}`.trim();
|
|
|
29807
29863
|
const payload = stopCommand.endsWith("\r") || stopCommand.endsWith("\n") ? stopCommand : `${stopCommand}${this.sendKey}`;
|
|
29808
29864
|
this.ptyProcess.write(payload);
|
|
29809
29865
|
};
|
|
29810
|
-
|
|
29866
|
+
const interruptGraceMs = typeof resume.interruptGraceMs === "number" ? Math.max(100, resume.interruptGraceMs) : 500;
|
|
29867
|
+
if (wasProcessing) setTimeout(writeCommand, interruptGraceMs);
|
|
29811
29868
|
else writeCommand();
|
|
29812
29869
|
} else {
|
|
29813
29870
|
this.ptyProcess.write("");
|
|
@@ -29823,17 +29880,17 @@ ${data.message || ""}`.trim();
|
|
|
29823
29880
|
}
|
|
29824
29881
|
}
|
|
29825
29882
|
waitForStopped(timeoutMs) {
|
|
29826
|
-
return new Promise((
|
|
29883
|
+
return new Promise((resolve9) => {
|
|
29827
29884
|
const startedAt = Date.now();
|
|
29828
29885
|
const timer = setInterval(() => {
|
|
29829
29886
|
if (!this.ptyProcess || this.currentStatus === "stopped") {
|
|
29830
29887
|
clearInterval(timer);
|
|
29831
|
-
|
|
29888
|
+
resolve9(true);
|
|
29832
29889
|
return;
|
|
29833
29890
|
}
|
|
29834
29891
|
if (Date.now() - startedAt >= timeoutMs) {
|
|
29835
29892
|
clearInterval(timer);
|
|
29836
|
-
|
|
29893
|
+
resolve9(false);
|
|
29837
29894
|
}
|
|
29838
29895
|
}, 100);
|
|
29839
29896
|
});
|
|
@@ -29852,6 +29909,18 @@ ${data.message || ""}`.trim();
|
|
|
29852
29909
|
clearTimeout(this.submitRetryTimer);
|
|
29853
29910
|
this.submitRetryTimer = null;
|
|
29854
29911
|
}
|
|
29912
|
+
if (this.responseTimeout) {
|
|
29913
|
+
clearTimeout(this.responseTimeout);
|
|
29914
|
+
this.responseTimeout = null;
|
|
29915
|
+
}
|
|
29916
|
+
if (this.idleTimeout) {
|
|
29917
|
+
clearTimeout(this.idleTimeout);
|
|
29918
|
+
this.idleTimeout = null;
|
|
29919
|
+
}
|
|
29920
|
+
if (this.pendingScriptStatusTimer) {
|
|
29921
|
+
clearTimeout(this.pendingScriptStatusTimer);
|
|
29922
|
+
this.pendingScriptStatusTimer = null;
|
|
29923
|
+
}
|
|
29855
29924
|
if (this.pendingOutputParseTimer) {
|
|
29856
29925
|
clearTimeout(this.pendingOutputParseTimer);
|
|
29857
29926
|
this.pendingOutputParseTimer = null;
|
|
@@ -29893,6 +29962,18 @@ ${data.message || ""}`.trim();
|
|
|
29893
29962
|
clearTimeout(this.submitRetryTimer);
|
|
29894
29963
|
this.submitRetryTimer = null;
|
|
29895
29964
|
}
|
|
29965
|
+
if (this.responseTimeout) {
|
|
29966
|
+
clearTimeout(this.responseTimeout);
|
|
29967
|
+
this.responseTimeout = null;
|
|
29968
|
+
}
|
|
29969
|
+
if (this.idleTimeout) {
|
|
29970
|
+
clearTimeout(this.idleTimeout);
|
|
29971
|
+
this.idleTimeout = null;
|
|
29972
|
+
}
|
|
29973
|
+
if (this.pendingScriptStatusTimer) {
|
|
29974
|
+
clearTimeout(this.pendingScriptStatusTimer);
|
|
29975
|
+
this.pendingScriptStatusTimer = null;
|
|
29976
|
+
}
|
|
29896
29977
|
if (this.pendingOutputParseTimer) {
|
|
29897
29978
|
clearTimeout(this.pendingOutputParseTimer);
|
|
29898
29979
|
this.pendingOutputParseTimer = null;
|
|
@@ -30476,20 +30557,20 @@ ${data.message || ""}`.trim();
|
|
|
30476
30557
|
return null;
|
|
30477
30558
|
}
|
|
30478
30559
|
async function detectIDEs() {
|
|
30479
|
-
const
|
|
30560
|
+
const os18 = (0, import_os22.platform)();
|
|
30480
30561
|
const results = [];
|
|
30481
30562
|
for (const def of getMergedDefinitions()) {
|
|
30482
30563
|
const cliPath = findCliCommand(def.cli);
|
|
30483
|
-
const appPath = checkPathExists(def.paths[
|
|
30564
|
+
const appPath = checkPathExists(def.paths[os18] || []);
|
|
30484
30565
|
const installed = !!(cliPath || appPath);
|
|
30485
30566
|
let resolvedCli = cliPath;
|
|
30486
|
-
if (!resolvedCli && appPath &&
|
|
30567
|
+
if (!resolvedCli && appPath && os18 === "darwin") {
|
|
30487
30568
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
30488
30569
|
if ((0, import_fs2.existsSync)(bundledCli)) resolvedCli = bundledCli;
|
|
30489
30570
|
}
|
|
30490
|
-
if (!resolvedCli && appPath &&
|
|
30491
|
-
const { dirname:
|
|
30492
|
-
const appDir =
|
|
30571
|
+
if (!resolvedCli && appPath && os18 === "win32") {
|
|
30572
|
+
const { dirname: dirname6 } = await import("path");
|
|
30573
|
+
const appDir = dirname6(appPath);
|
|
30493
30574
|
const candidates = [
|
|
30494
30575
|
`${appDir}\\\\bin\\\\${def.cli}.cmd`,
|
|
30495
30576
|
`${appDir}\\\\bin\\\\${def.cli}`,
|
|
@@ -30525,15 +30606,15 @@ ${data.message || ""}`.trim();
|
|
|
30525
30606
|
return match ? match[1] : raw.split("\n")[0].slice(0, 100);
|
|
30526
30607
|
}
|
|
30527
30608
|
function execAsync(cmd, timeoutMs = 5e3) {
|
|
30528
|
-
return new Promise((
|
|
30609
|
+
return new Promise((resolve9) => {
|
|
30529
30610
|
const child = (0, import_child_process22.exec)(cmd, { encoding: "utf-8", timeout: timeoutMs }, (err, stdout) => {
|
|
30530
30611
|
if (err || !stdout?.trim()) {
|
|
30531
|
-
|
|
30612
|
+
resolve9(null);
|
|
30532
30613
|
} else {
|
|
30533
|
-
|
|
30614
|
+
resolve9(stdout.trim());
|
|
30534
30615
|
}
|
|
30535
30616
|
});
|
|
30536
|
-
child.on("error", () =>
|
|
30617
|
+
child.on("error", () => resolve9(null));
|
|
30537
30618
|
});
|
|
30538
30619
|
}
|
|
30539
30620
|
async function detectCLIs(providerLoader) {
|
|
@@ -30573,6 +30654,39 @@ ${data.message || ""}`.trim();
|
|
|
30573
30654
|
}
|
|
30574
30655
|
async function detectCLI(cliId, providerLoader) {
|
|
30575
30656
|
const resolvedId = providerLoader ? providerLoader.resolveAlias(cliId) : cliId;
|
|
30657
|
+
if (providerLoader) {
|
|
30658
|
+
const cliList = providerLoader.getCliDetectionList();
|
|
30659
|
+
const target = cliList.find((c) => c.id === resolvedId);
|
|
30660
|
+
if (target) {
|
|
30661
|
+
const platform9 = os22.platform();
|
|
30662
|
+
const whichCmd = platform9 === "win32" ? "where" : "which";
|
|
30663
|
+
try {
|
|
30664
|
+
const pathResult = await execAsync(`${whichCmd} ${target.command}`);
|
|
30665
|
+
if (!pathResult) return null;
|
|
30666
|
+
const firstPath = pathResult.split("\n")[0];
|
|
30667
|
+
let version2;
|
|
30668
|
+
try {
|
|
30669
|
+
const versionCommands = [
|
|
30670
|
+
target.versionCommand,
|
|
30671
|
+
`${target.command} --version`,
|
|
30672
|
+
`${target.command} -V`,
|
|
30673
|
+
`${target.command} -v`
|
|
30674
|
+
].filter((v2) => !!v2);
|
|
30675
|
+
for (const versionCommand of versionCommands) {
|
|
30676
|
+
const versionResult = await execAsync(versionCommand, 3e3);
|
|
30677
|
+
if (versionResult) {
|
|
30678
|
+
version2 = parseVersion(versionResult);
|
|
30679
|
+
break;
|
|
30680
|
+
}
|
|
30681
|
+
}
|
|
30682
|
+
} catch {
|
|
30683
|
+
}
|
|
30684
|
+
return { ...target, installed: true, version: version2, path: firstPath };
|
|
30685
|
+
} catch {
|
|
30686
|
+
return null;
|
|
30687
|
+
}
|
|
30688
|
+
}
|
|
30689
|
+
}
|
|
30576
30690
|
const all = await detectCLIs(providerLoader);
|
|
30577
30691
|
return all.find((c) => c.id === resolvedId && c.installed) || null;
|
|
30578
30692
|
}
|
|
@@ -30696,7 +30810,7 @@ ${data.message || ""}`.trim();
|
|
|
30696
30810
|
* Returns multiple entries if multiple IDE windows are open on same port
|
|
30697
30811
|
*/
|
|
30698
30812
|
static listAllTargets(port) {
|
|
30699
|
-
return new Promise((
|
|
30813
|
+
return new Promise((resolve9) => {
|
|
30700
30814
|
const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
|
|
30701
30815
|
let data = "";
|
|
30702
30816
|
res.on("data", (chunk) => data += chunk.toString());
|
|
@@ -30712,16 +30826,16 @@ ${data.message || ""}`.trim();
|
|
|
30712
30826
|
(t) => !isNonMain(t.title || "") && t.url?.includes("workbench.html") && !t.url?.includes("agent")
|
|
30713
30827
|
);
|
|
30714
30828
|
const fallbackPages = pages.filter((t) => !isNonMain(t.title || ""));
|
|
30715
|
-
|
|
30829
|
+
resolve9(mainPages.length > 0 ? mainPages : fallbackPages);
|
|
30716
30830
|
} catch {
|
|
30717
|
-
|
|
30831
|
+
resolve9([]);
|
|
30718
30832
|
}
|
|
30719
30833
|
});
|
|
30720
30834
|
});
|
|
30721
|
-
req.on("error", () =>
|
|
30835
|
+
req.on("error", () => resolve9([]));
|
|
30722
30836
|
req.setTimeout(2e3, () => {
|
|
30723
30837
|
req.destroy();
|
|
30724
|
-
|
|
30838
|
+
resolve9([]);
|
|
30725
30839
|
});
|
|
30726
30840
|
});
|
|
30727
30841
|
}
|
|
@@ -30761,7 +30875,7 @@ ${data.message || ""}`.trim();
|
|
|
30761
30875
|
}
|
|
30762
30876
|
}
|
|
30763
30877
|
findTargetOnPort(port) {
|
|
30764
|
-
return new Promise((
|
|
30878
|
+
return new Promise((resolve9) => {
|
|
30765
30879
|
const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
|
|
30766
30880
|
let data = "";
|
|
30767
30881
|
res.on("data", (chunk) => data += chunk.toString());
|
|
@@ -30772,7 +30886,7 @@ ${data.message || ""}`.trim();
|
|
|
30772
30886
|
(t) => (t.type === "page" || t.type === "browser" || t.type === "Page") && t.webSocketDebuggerUrl
|
|
30773
30887
|
);
|
|
30774
30888
|
if (pages.length === 0) {
|
|
30775
|
-
|
|
30889
|
+
resolve9(targets.find((t) => t.webSocketDebuggerUrl) || null);
|
|
30776
30890
|
return;
|
|
30777
30891
|
}
|
|
30778
30892
|
const mainPages = pages.filter((t) => !this.isNonMainTitle(t.title || ""));
|
|
@@ -30782,24 +30896,24 @@ ${data.message || ""}`.trim();
|
|
|
30782
30896
|
const specific = list.find((t) => t.id === this._targetId);
|
|
30783
30897
|
if (specific) {
|
|
30784
30898
|
this._pageTitle = specific.title || "";
|
|
30785
|
-
|
|
30899
|
+
resolve9(specific);
|
|
30786
30900
|
} else {
|
|
30787
30901
|
this.log(`[CDP] Target ${this._targetId} not found in page list`);
|
|
30788
|
-
|
|
30902
|
+
resolve9(null);
|
|
30789
30903
|
}
|
|
30790
30904
|
return;
|
|
30791
30905
|
}
|
|
30792
30906
|
this._pageTitle = list[0]?.title || "";
|
|
30793
|
-
|
|
30907
|
+
resolve9(list[0]);
|
|
30794
30908
|
} catch {
|
|
30795
|
-
|
|
30909
|
+
resolve9(null);
|
|
30796
30910
|
}
|
|
30797
30911
|
});
|
|
30798
30912
|
});
|
|
30799
|
-
req.on("error", () =>
|
|
30913
|
+
req.on("error", () => resolve9(null));
|
|
30800
30914
|
req.setTimeout(2e3, () => {
|
|
30801
30915
|
req.destroy();
|
|
30802
|
-
|
|
30916
|
+
resolve9(null);
|
|
30803
30917
|
});
|
|
30804
30918
|
});
|
|
30805
30919
|
}
|
|
@@ -30810,7 +30924,7 @@ ${data.message || ""}`.trim();
|
|
|
30810
30924
|
this.extensionProviders = providers;
|
|
30811
30925
|
}
|
|
30812
30926
|
connectToTarget(wsUrl) {
|
|
30813
|
-
return new Promise((
|
|
30927
|
+
return new Promise((resolve9) => {
|
|
30814
30928
|
this.ws = new import_ws2.default(wsUrl);
|
|
30815
30929
|
this.ws.on("open", async () => {
|
|
30816
30930
|
this._connected = true;
|
|
@@ -30820,17 +30934,17 @@ ${data.message || ""}`.trim();
|
|
|
30820
30934
|
}
|
|
30821
30935
|
this.connectBrowserWs().catch(() => {
|
|
30822
30936
|
});
|
|
30823
|
-
|
|
30937
|
+
resolve9(true);
|
|
30824
30938
|
});
|
|
30825
30939
|
this.ws.on("message", (data) => {
|
|
30826
30940
|
try {
|
|
30827
30941
|
const msg = JSON.parse(data.toString());
|
|
30828
30942
|
if (msg.id && this.pending.has(msg.id)) {
|
|
30829
|
-
const { resolve:
|
|
30943
|
+
const { resolve: resolve10, reject } = this.pending.get(msg.id);
|
|
30830
30944
|
this.pending.delete(msg.id);
|
|
30831
30945
|
this.failureCount = 0;
|
|
30832
30946
|
if (msg.error) reject(new Error(msg.error.message));
|
|
30833
|
-
else
|
|
30947
|
+
else resolve10(msg.result);
|
|
30834
30948
|
} else if (msg.method === "Runtime.executionContextCreated") {
|
|
30835
30949
|
this.contexts.add(msg.params.context.id);
|
|
30836
30950
|
} else if (msg.method === "Runtime.executionContextDestroyed") {
|
|
@@ -30853,7 +30967,7 @@ ${data.message || ""}`.trim();
|
|
|
30853
30967
|
this.ws.on("error", (err) => {
|
|
30854
30968
|
this.log(`[CDP] WebSocket error: ${err.message}`);
|
|
30855
30969
|
this._connected = false;
|
|
30856
|
-
|
|
30970
|
+
resolve9(false);
|
|
30857
30971
|
});
|
|
30858
30972
|
});
|
|
30859
30973
|
}
|
|
@@ -30867,7 +30981,7 @@ ${data.message || ""}`.trim();
|
|
|
30867
30981
|
return;
|
|
30868
30982
|
}
|
|
30869
30983
|
this.log(`[CDP] Connecting browser WS for target discovery...`);
|
|
30870
|
-
await new Promise((
|
|
30984
|
+
await new Promise((resolve9, reject) => {
|
|
30871
30985
|
this.browserWs = new import_ws2.default(browserWsUrl);
|
|
30872
30986
|
this.browserWs.on("open", async () => {
|
|
30873
30987
|
this._browserConnected = true;
|
|
@@ -30877,16 +30991,16 @@ ${data.message || ""}`.trim();
|
|
|
30877
30991
|
} catch (e) {
|
|
30878
30992
|
this.log(`[CDP] setDiscoverTargets failed: ${e.message}`);
|
|
30879
30993
|
}
|
|
30880
|
-
|
|
30994
|
+
resolve9();
|
|
30881
30995
|
});
|
|
30882
30996
|
this.browserWs.on("message", (data) => {
|
|
30883
30997
|
try {
|
|
30884
30998
|
const msg = JSON.parse(data.toString());
|
|
30885
30999
|
if (msg.id && this.browserPending.has(msg.id)) {
|
|
30886
|
-
const { resolve:
|
|
31000
|
+
const { resolve: resolve10, reject: reject2 } = this.browserPending.get(msg.id);
|
|
30887
31001
|
this.browserPending.delete(msg.id);
|
|
30888
31002
|
if (msg.error) reject2(new Error(msg.error.message));
|
|
30889
|
-
else
|
|
31003
|
+
else resolve10(msg.result);
|
|
30890
31004
|
}
|
|
30891
31005
|
} catch {
|
|
30892
31006
|
}
|
|
@@ -30906,31 +31020,31 @@ ${data.message || ""}`.trim();
|
|
|
30906
31020
|
}
|
|
30907
31021
|
}
|
|
30908
31022
|
getBrowserWsUrl() {
|
|
30909
|
-
return new Promise((
|
|
31023
|
+
return new Promise((resolve9) => {
|
|
30910
31024
|
const req = http.get(`http://127.0.0.1:${this.port}/json/version`, (res) => {
|
|
30911
31025
|
let data = "";
|
|
30912
31026
|
res.on("data", (chunk) => data += chunk.toString());
|
|
30913
31027
|
res.on("end", () => {
|
|
30914
31028
|
try {
|
|
30915
31029
|
const info = JSON.parse(data);
|
|
30916
|
-
|
|
31030
|
+
resolve9(info.webSocketDebuggerUrl || null);
|
|
30917
31031
|
} catch {
|
|
30918
|
-
|
|
31032
|
+
resolve9(null);
|
|
30919
31033
|
}
|
|
30920
31034
|
});
|
|
30921
31035
|
});
|
|
30922
|
-
req.on("error", () =>
|
|
31036
|
+
req.on("error", () => resolve9(null));
|
|
30923
31037
|
req.setTimeout(3e3, () => {
|
|
30924
31038
|
req.destroy();
|
|
30925
|
-
|
|
31039
|
+
resolve9(null);
|
|
30926
31040
|
});
|
|
30927
31041
|
});
|
|
30928
31042
|
}
|
|
30929
31043
|
sendBrowser(method, params = {}, timeoutMs = 15e3) {
|
|
30930
|
-
return new Promise((
|
|
31044
|
+
return new Promise((resolve9, reject) => {
|
|
30931
31045
|
if (!this.browserWs || !this._browserConnected) return reject(new Error("Browser WS not connected"));
|
|
30932
31046
|
const id = this.browserMsgId++;
|
|
30933
|
-
this.browserPending.set(id, { resolve:
|
|
31047
|
+
this.browserPending.set(id, { resolve: resolve9, reject });
|
|
30934
31048
|
this.browserWs.send(JSON.stringify({ id, method, params }));
|
|
30935
31049
|
setTimeout(() => {
|
|
30936
31050
|
if (this.browserPending.has(id)) {
|
|
@@ -30970,11 +31084,11 @@ ${data.message || ""}`.trim();
|
|
|
30970
31084
|
}
|
|
30971
31085
|
// ─── CDP Protocol ────────────────────────────────────────
|
|
30972
31086
|
sendInternal(method, params = {}, timeoutMs = 15e3) {
|
|
30973
|
-
return new Promise((
|
|
31087
|
+
return new Promise((resolve9, reject) => {
|
|
30974
31088
|
if (!this.ws || !this._connected) return reject(new Error("CDP not connected"));
|
|
30975
31089
|
if (this.ws.readyState !== import_ws2.default.OPEN) return reject(new Error("WebSocket not open"));
|
|
30976
31090
|
const id = this.msgId++;
|
|
30977
|
-
this.pending.set(id, { resolve:
|
|
31091
|
+
this.pending.set(id, { resolve: resolve9, reject });
|
|
30978
31092
|
this.ws.send(JSON.stringify({ id, method, params }));
|
|
30979
31093
|
setTimeout(() => {
|
|
30980
31094
|
if (this.pending.has(id)) {
|
|
@@ -31223,7 +31337,7 @@ ${data.message || ""}`.trim();
|
|
|
31223
31337
|
const browserWs = this.browserWs;
|
|
31224
31338
|
let msgId = this.browserMsgId;
|
|
31225
31339
|
const sendWs = (method, params = {}, sessionId) => {
|
|
31226
|
-
return new Promise((
|
|
31340
|
+
return new Promise((resolve9, reject) => {
|
|
31227
31341
|
const mid = msgId++;
|
|
31228
31342
|
this.browserMsgId = msgId;
|
|
31229
31343
|
const handler = (raw) => {
|
|
@@ -31232,7 +31346,7 @@ ${data.message || ""}`.trim();
|
|
|
31232
31346
|
if (msg.id === mid) {
|
|
31233
31347
|
browserWs.removeListener("message", handler);
|
|
31234
31348
|
if (msg.error) reject(new Error(msg.error.message || JSON.stringify(msg.error)));
|
|
31235
|
-
else
|
|
31349
|
+
else resolve9(msg.result);
|
|
31236
31350
|
}
|
|
31237
31351
|
} catch {
|
|
31238
31352
|
}
|
|
@@ -31423,14 +31537,14 @@ ${data.message || ""}`.trim();
|
|
|
31423
31537
|
if (!ws2 || ws2.readyState !== import_ws2.default.OPEN) {
|
|
31424
31538
|
throw new Error("CDP not connected");
|
|
31425
31539
|
}
|
|
31426
|
-
return new Promise((
|
|
31540
|
+
return new Promise((resolve9, reject) => {
|
|
31427
31541
|
const id = getNextId();
|
|
31428
31542
|
pendingMap.set(id, {
|
|
31429
31543
|
resolve: (result) => {
|
|
31430
31544
|
if (result?.result?.subtype === "error") {
|
|
31431
31545
|
reject(new Error(result.result.description));
|
|
31432
31546
|
} else {
|
|
31433
|
-
|
|
31547
|
+
resolve9(result?.result?.value);
|
|
31434
31548
|
}
|
|
31435
31549
|
},
|
|
31436
31550
|
reject
|
|
@@ -31462,10 +31576,10 @@ ${data.message || ""}`.trim();
|
|
|
31462
31576
|
throw new Error("CDP not connected");
|
|
31463
31577
|
}
|
|
31464
31578
|
const sendViaSession = (method, params = {}) => {
|
|
31465
|
-
return new Promise((
|
|
31579
|
+
return new Promise((resolve9, reject) => {
|
|
31466
31580
|
const pendingMap = this._browserConnected ? this.browserPending : this.pending;
|
|
31467
31581
|
const id = this._browserConnected ? this.browserMsgId++ : this.msgId++;
|
|
31468
|
-
pendingMap.set(id, { resolve:
|
|
31582
|
+
pendingMap.set(id, { resolve: resolve9, reject });
|
|
31469
31583
|
ws2.send(JSON.stringify({ id, sessionId, method, params }));
|
|
31470
31584
|
setTimeout(() => {
|
|
31471
31585
|
if (pendingMap.has(id)) {
|
|
@@ -35432,7 +35546,7 @@ ${data.message || ""}`.trim();
|
|
|
35432
35546
|
try {
|
|
35433
35547
|
const http3 = await import("http");
|
|
35434
35548
|
const postData = JSON.stringify(body);
|
|
35435
|
-
const result = await new Promise((
|
|
35549
|
+
const result = await new Promise((resolve9, reject) => {
|
|
35436
35550
|
const req = http3.request({
|
|
35437
35551
|
hostname: "127.0.0.1",
|
|
35438
35552
|
port: 19280,
|
|
@@ -35444,9 +35558,9 @@ ${data.message || ""}`.trim();
|
|
|
35444
35558
|
res.on("data", (chunk) => data += chunk);
|
|
35445
35559
|
res.on("end", () => {
|
|
35446
35560
|
try {
|
|
35447
|
-
|
|
35561
|
+
resolve9(JSON.parse(data));
|
|
35448
35562
|
} catch {
|
|
35449
|
-
|
|
35563
|
+
resolve9({ raw: data });
|
|
35450
35564
|
}
|
|
35451
35565
|
});
|
|
35452
35566
|
});
|
|
@@ -35464,15 +35578,15 @@ ${data.message || ""}`.trim();
|
|
|
35464
35578
|
if (!providerType) return { success: false, error: "providerType required" };
|
|
35465
35579
|
try {
|
|
35466
35580
|
const http3 = await import("http");
|
|
35467
|
-
const result = await new Promise((
|
|
35581
|
+
const result = await new Promise((resolve9, reject) => {
|
|
35468
35582
|
http3.get(`http://127.0.0.1:19280/api/providers/${providerType}/${endpoint}`, (res) => {
|
|
35469
35583
|
let data = "";
|
|
35470
35584
|
res.on("data", (chunk) => data += chunk);
|
|
35471
35585
|
res.on("end", () => {
|
|
35472
35586
|
try {
|
|
35473
|
-
|
|
35587
|
+
resolve9(JSON.parse(data));
|
|
35474
35588
|
} catch {
|
|
35475
|
-
|
|
35589
|
+
resolve9({ raw: data });
|
|
35476
35590
|
}
|
|
35477
35591
|
});
|
|
35478
35592
|
}).on("error", reject);
|
|
@@ -35486,7 +35600,7 @@ ${data.message || ""}`.trim();
|
|
|
35486
35600
|
try {
|
|
35487
35601
|
const http3 = await import("http");
|
|
35488
35602
|
const postData = JSON.stringify(args || {});
|
|
35489
|
-
const result = await new Promise((
|
|
35603
|
+
const result = await new Promise((resolve9, reject) => {
|
|
35490
35604
|
const req = http3.request({
|
|
35491
35605
|
hostname: "127.0.0.1",
|
|
35492
35606
|
port: 19280,
|
|
@@ -35498,9 +35612,9 @@ ${data.message || ""}`.trim();
|
|
|
35498
35612
|
res.on("data", (chunk) => data += chunk);
|
|
35499
35613
|
res.on("end", () => {
|
|
35500
35614
|
try {
|
|
35501
|
-
|
|
35615
|
+
resolve9(JSON.parse(data));
|
|
35502
35616
|
} catch {
|
|
35503
|
-
|
|
35617
|
+
resolve9({ raw: data });
|
|
35504
35618
|
}
|
|
35505
35619
|
});
|
|
35506
35620
|
});
|
|
@@ -35514,13 +35628,13 @@ ${data.message || ""}`.trim();
|
|
|
35514
35628
|
}
|
|
35515
35629
|
}
|
|
35516
35630
|
};
|
|
35517
|
-
var
|
|
35631
|
+
var os10 = __toESM2(require("os"));
|
|
35518
35632
|
var path9 = __toESM2(require("path"));
|
|
35519
35633
|
var crypto4 = __toESM2(require("crypto"));
|
|
35520
35634
|
var import_chalk = __toESM2(require("chalk"));
|
|
35521
35635
|
init_provider_cli_adapter();
|
|
35522
35636
|
init_config();
|
|
35523
|
-
var
|
|
35637
|
+
var os9 = __toESM2(require("os"));
|
|
35524
35638
|
var path8 = __toESM2(require("path"));
|
|
35525
35639
|
var crypto3 = __toESM2(require("crypto"));
|
|
35526
35640
|
var fs5 = __toESM2(require("fs"));
|
|
@@ -35609,17 +35723,60 @@ ${data.message || ""}`.trim();
|
|
|
35609
35723
|
async onTick() {
|
|
35610
35724
|
if (this.providerSessionId) return;
|
|
35611
35725
|
let probedSessionId = null;
|
|
35612
|
-
|
|
35613
|
-
|
|
35614
|
-
|
|
35615
|
-
|
|
35616
|
-
|
|
35617
|
-
|
|
35726
|
+
const probeConfig = this.provider.sessionProbe;
|
|
35727
|
+
if (probeConfig) {
|
|
35728
|
+
probedSessionId = this.probeSessionIdFromConfig(probeConfig);
|
|
35729
|
+
} else {
|
|
35730
|
+
if (this.type === "opencode-cli") {
|
|
35731
|
+
probedSessionId = this.probeSessionIdFromConfig({
|
|
35732
|
+
dbPath: "~/.local/share/opencode/opencode.db",
|
|
35733
|
+
query: "select id from session where directory in ({dirs}) and time_created >= ? and time_archived is null order by time_updated desc limit 1",
|
|
35734
|
+
timestampFormat: "unix_ms"
|
|
35735
|
+
});
|
|
35736
|
+
} else if (this.type === "codex-cli") {
|
|
35737
|
+
probedSessionId = this.probeSessionIdFromConfig({
|
|
35738
|
+
dbPath: "~/.codex/state_5.sqlite",
|
|
35739
|
+
query: "select id from threads where cwd in ({dirs}) and created_at >= ? and archived = 0 order by created_at desc limit 1",
|
|
35740
|
+
timestampFormat: "unix_s"
|
|
35741
|
+
});
|
|
35742
|
+
} else if (this.type === "goose-cli") {
|
|
35743
|
+
probedSessionId = this.probeSessionIdFromConfig({
|
|
35744
|
+
dbPath: "~/.local/share/goose/sessions/sessions.db",
|
|
35745
|
+
query: "select id from sessions where working_dir in ({dirs}) and created_at >= ? order by updated_at desc limit 1",
|
|
35746
|
+
timestampFormat: "iso"
|
|
35747
|
+
});
|
|
35748
|
+
}
|
|
35618
35749
|
}
|
|
35619
35750
|
if (probedSessionId) {
|
|
35620
35751
|
this.promoteProviderSessionId(probedSessionId);
|
|
35621
35752
|
}
|
|
35622
35753
|
}
|
|
35754
|
+
/**
|
|
35755
|
+
* Generic session ID probe using declarative ProviderSessionProbe config.
|
|
35756
|
+
* Replaces the previously duplicated probeOpenCode/Codex/Goose functions.
|
|
35757
|
+
*/
|
|
35758
|
+
probeSessionIdFromConfig(probe) {
|
|
35759
|
+
const resolvedDbPath = probe.dbPath.replace(/^~/, os9.homedir());
|
|
35760
|
+
if (!fs5.existsSync(resolvedDbPath)) return null;
|
|
35761
|
+
const directories = this.getProbeDirectories();
|
|
35762
|
+
const minCreatedAt = Math.max(0, this.startedAt - 6e4);
|
|
35763
|
+
const tsFormat = probe.timestampFormat || "unix_ms";
|
|
35764
|
+
let timestampParam;
|
|
35765
|
+
if (tsFormat === "unix_s") {
|
|
35766
|
+
timestampParam = Math.floor(minCreatedAt / 1e3);
|
|
35767
|
+
} else if (tsFormat === "iso") {
|
|
35768
|
+
timestampParam = new Date(minCreatedAt).toISOString().slice(0, 19).replace("T", " ");
|
|
35769
|
+
} else {
|
|
35770
|
+
timestampParam = minCreatedAt;
|
|
35771
|
+
}
|
|
35772
|
+
const placeholders = this.buildSqlPlaceholderList(directories.length);
|
|
35773
|
+
const query = probe.query.replace("{dirs}", placeholders);
|
|
35774
|
+
try {
|
|
35775
|
+
return this.querySqliteText(resolvedDbPath, query, [...directories, timestampParam]);
|
|
35776
|
+
} catch {
|
|
35777
|
+
return null;
|
|
35778
|
+
}
|
|
35779
|
+
}
|
|
35623
35780
|
getState() {
|
|
35624
35781
|
const adapterStatus = this.adapter.getStatus();
|
|
35625
35782
|
const parsedStatus = this.adapter.getScriptParsedStatus?.() || null;
|
|
@@ -35917,34 +36074,6 @@ ${data.message || ""}`.trim();
|
|
|
35917
36074
|
});
|
|
35918
36075
|
LOG2.info("CLI", `[${this.type}] discovered provider session id: ${nextSessionId}`);
|
|
35919
36076
|
}
|
|
35920
|
-
probeOpenCodeSessionId() {
|
|
35921
|
-
const dbPath = path8.join(os8.homedir(), ".local", "share", "opencode", "opencode.db");
|
|
35922
|
-
if (!fs5.existsSync(dbPath)) return null;
|
|
35923
|
-
const minCreatedAt = Math.max(0, this.startedAt - 6e4);
|
|
35924
|
-
const directories = this.getProbeDirectories();
|
|
35925
|
-
const query = `select id from session where directory in (${this.buildSqlPlaceholderList(directories.length)}) and time_created >= ? and time_archived is null order by time_updated desc limit 1;`;
|
|
35926
|
-
return this.querySqliteText(dbPath, query, [...directories, minCreatedAt]);
|
|
35927
|
-
}
|
|
35928
|
-
probeCodexSessionId() {
|
|
35929
|
-
const dbPath = path8.join(os8.homedir(), ".codex", "state_5.sqlite");
|
|
35930
|
-
if (!fs5.existsSync(dbPath)) return null;
|
|
35931
|
-
const minCreatedAt = Math.max(0, Math.floor((this.startedAt - 6e4) / 1e3));
|
|
35932
|
-
const directories = this.getProbeDirectories();
|
|
35933
|
-
const query = `select id from threads where cwd in (${this.buildSqlPlaceholderList(directories.length)}) and created_at >= ? and archived = 0 order by created_at desc limit 1;`;
|
|
35934
|
-
return this.querySqliteText(dbPath, query, [...directories, minCreatedAt]);
|
|
35935
|
-
}
|
|
35936
|
-
probeGooseSessionId() {
|
|
35937
|
-
const dbPath = path8.join(os8.homedir(), ".local", "share", "goose", "sessions", "sessions.db");
|
|
35938
|
-
if (!fs5.existsSync(dbPath)) return null;
|
|
35939
|
-
const minCreatedAtIso = new Date(Math.max(0, this.startedAt - 6e4)).toISOString().slice(0, 19).replace("T", " ");
|
|
35940
|
-
const directories = this.getProbeDirectories();
|
|
35941
|
-
const query = `select id from sessions where working_dir in (${this.buildSqlPlaceholderList(directories.length)}) and created_at >= ? order by updated_at desc limit 1;`;
|
|
35942
|
-
try {
|
|
35943
|
-
return this.querySqliteText(dbPath, query, [...directories, minCreatedAtIso]);
|
|
35944
|
-
} catch {
|
|
35945
|
-
return null;
|
|
35946
|
-
}
|
|
35947
|
-
}
|
|
35948
36077
|
getProbeDirectories() {
|
|
35949
36078
|
const dirs = /* @__PURE__ */ new Set();
|
|
35950
36079
|
const addDir = (value) => {
|
|
@@ -36410,13 +36539,13 @@ ${data.message || ""}`.trim();
|
|
|
36410
36539
|
}
|
|
36411
36540
|
this.currentStatus = "waiting_approval";
|
|
36412
36541
|
this.detectStatusTransition();
|
|
36413
|
-
const approved = await new Promise((
|
|
36414
|
-
this.permissionResolvers.push(
|
|
36542
|
+
const approved = await new Promise((resolve9) => {
|
|
36543
|
+
this.permissionResolvers.push(resolve9);
|
|
36415
36544
|
setTimeout(() => {
|
|
36416
|
-
const idx = this.permissionResolvers.indexOf(
|
|
36545
|
+
const idx = this.permissionResolvers.indexOf(resolve9);
|
|
36417
36546
|
if (idx >= 0) {
|
|
36418
36547
|
this.permissionResolvers.splice(idx, 1);
|
|
36419
|
-
|
|
36548
|
+
resolve9(false);
|
|
36420
36549
|
}
|
|
36421
36550
|
}, 3e5);
|
|
36422
36551
|
});
|
|
@@ -37121,7 +37250,7 @@ ${data.message || ""}`.trim();
|
|
|
37121
37250
|
async startSession(cliType, workingDir, cliArgs, initialModel, options) {
|
|
37122
37251
|
const trimmed = (workingDir || "").trim();
|
|
37123
37252
|
if (!trimmed) throw new Error("working directory required");
|
|
37124
|
-
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/,
|
|
37253
|
+
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os10.homedir()) : path9.resolve(trimmed);
|
|
37125
37254
|
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
37126
37255
|
const provider = this.providerLoader.getByAlias(cliType);
|
|
37127
37256
|
const key = crypto4.randomUUID();
|
|
@@ -37205,7 +37334,19 @@ ${installInfo}`
|
|
|
37205
37334
|
return { runtimeSessionId: sessionId };
|
|
37206
37335
|
}
|
|
37207
37336
|
const cliInfo = await detectCLI(cliType, this.providerLoader);
|
|
37208
|
-
if (!cliInfo)
|
|
37337
|
+
if (!cliInfo) {
|
|
37338
|
+
const installHint = provider?.install || "";
|
|
37339
|
+
const displayName = provider?.displayName || provider?.name || cliType;
|
|
37340
|
+
const spawnCmd = provider?.spawn?.command || cliType;
|
|
37341
|
+
throw new Error(
|
|
37342
|
+
`${displayName} is not installed.
|
|
37343
|
+
Command '${spawnCmd}' not found on PATH.
|
|
37344
|
+
` + (installHint ? `
|
|
37345
|
+
${installHint}
|
|
37346
|
+
` : "") + `
|
|
37347
|
+
Run 'adhdev doctor' for detailed diagnostics.`
|
|
37348
|
+
);
|
|
37349
|
+
}
|
|
37209
37350
|
console.log(colorize("yellow", ` \u26A1 Starting CLI ${cliType} in ${resolvedDir}...`));
|
|
37210
37351
|
if (provider) {
|
|
37211
37352
|
console.log(colorize("cyan", ` \u{1F4E6} Using provider: ${provider.name} (${provider.type})`));
|
|
@@ -37521,8 +37662,9 @@ ${installInfo}`
|
|
|
37521
37662
|
const dir = rdir.path;
|
|
37522
37663
|
if (!cliType) throw new Error("cliType required");
|
|
37523
37664
|
const found = this.findAdapter(cliType, { instanceKey: args?.targetSessionId, dir });
|
|
37665
|
+
const prevCliArgs = found ? found.adapter.extraArgs : void 0;
|
|
37524
37666
|
if (found) await this.stopSession(found.key);
|
|
37525
|
-
await this.startSession(cliType, dir);
|
|
37667
|
+
await this.startSession(cliType, dir, args?.cliArgs || prevCliArgs, args?.initialModel);
|
|
37526
37668
|
return { success: true, restarted: true };
|
|
37527
37669
|
}
|
|
37528
37670
|
case "agent_command": {
|
|
@@ -37555,11 +37697,11 @@ ${installInfo}`
|
|
|
37555
37697
|
};
|
|
37556
37698
|
var import_child_process6 = require("child_process");
|
|
37557
37699
|
var net3 = __toESM2(require("net"));
|
|
37558
|
-
var
|
|
37700
|
+
var os12 = __toESM2(require("os"));
|
|
37559
37701
|
var path11 = __toESM2(require("path"));
|
|
37560
37702
|
var fs6 = __toESM2(require("fs"));
|
|
37561
37703
|
var path10 = __toESM2(require("path"));
|
|
37562
|
-
var
|
|
37704
|
+
var os11 = __toESM2(require("os"));
|
|
37563
37705
|
var chokidar = __toESM2((init_chokidar(), __toCommonJS(chokidar_exports)));
|
|
37564
37706
|
init_logger();
|
|
37565
37707
|
var ProviderLoader = class _ProviderLoader {
|
|
@@ -37579,7 +37721,7 @@ ${installInfo}`
|
|
|
37579
37721
|
static META_FILE = ".meta.json";
|
|
37580
37722
|
constructor(options) {
|
|
37581
37723
|
this.logFn = options?.logFn || LOG2.forComponent("Provider").asLogFn();
|
|
37582
|
-
const defaultProvidersDir = path10.join(
|
|
37724
|
+
const defaultProvidersDir = path10.join(os11.homedir(), ".adhdev", "providers");
|
|
37583
37725
|
if (options?.userDir) {
|
|
37584
37726
|
this.userDir = options.userDir;
|
|
37585
37727
|
this.log(`Config 'providerDir' applied: ${this.userDir}`);
|
|
@@ -38136,7 +38278,7 @@ ${installInfo}`
|
|
|
38136
38278
|
return { updated: false };
|
|
38137
38279
|
}
|
|
38138
38280
|
try {
|
|
38139
|
-
const etag = await new Promise((
|
|
38281
|
+
const etag = await new Promise((resolve9, reject) => {
|
|
38140
38282
|
const options = {
|
|
38141
38283
|
method: "HEAD",
|
|
38142
38284
|
hostname: "github.com",
|
|
@@ -38154,7 +38296,7 @@ ${installInfo}`
|
|
|
38154
38296
|
headers: { "User-Agent": "adhdev-launcher" },
|
|
38155
38297
|
timeout: 1e4
|
|
38156
38298
|
}, (res2) => {
|
|
38157
|
-
|
|
38299
|
+
resolve9(res2.headers.etag || res2.headers["last-modified"] || "");
|
|
38158
38300
|
});
|
|
38159
38301
|
req2.on("error", reject);
|
|
38160
38302
|
req2.on("timeout", () => {
|
|
@@ -38163,7 +38305,7 @@ ${installInfo}`
|
|
|
38163
38305
|
});
|
|
38164
38306
|
req2.end();
|
|
38165
38307
|
} else {
|
|
38166
|
-
|
|
38308
|
+
resolve9(res.headers.etag || res.headers["last-modified"] || "");
|
|
38167
38309
|
}
|
|
38168
38310
|
});
|
|
38169
38311
|
req.on("error", reject);
|
|
@@ -38179,8 +38321,8 @@ ${installInfo}`
|
|
|
38179
38321
|
return { updated: false };
|
|
38180
38322
|
}
|
|
38181
38323
|
this.log("Downloading latest providers from GitHub...");
|
|
38182
|
-
const tmpTar = path10.join(
|
|
38183
|
-
const tmpExtract = path10.join(
|
|
38324
|
+
const tmpTar = path10.join(os11.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
|
|
38325
|
+
const tmpExtract = path10.join(os11.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
|
|
38184
38326
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
38185
38327
|
fs6.mkdirSync(tmpExtract, { recursive: true });
|
|
38186
38328
|
execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
@@ -38227,7 +38369,7 @@ ${installInfo}`
|
|
|
38227
38369
|
downloadFile(url2, destPath) {
|
|
38228
38370
|
const https = require("https");
|
|
38229
38371
|
const http3 = require("http");
|
|
38230
|
-
return new Promise((
|
|
38372
|
+
return new Promise((resolve9, reject) => {
|
|
38231
38373
|
const doRequest = (reqUrl, redirectCount = 0) => {
|
|
38232
38374
|
if (redirectCount > 5) {
|
|
38233
38375
|
reject(new Error("Too many redirects"));
|
|
@@ -38247,7 +38389,7 @@ ${installInfo}`
|
|
|
38247
38389
|
res.pipe(ws2);
|
|
38248
38390
|
ws2.on("finish", () => {
|
|
38249
38391
|
ws2.close();
|
|
38250
|
-
|
|
38392
|
+
resolve9();
|
|
38251
38393
|
});
|
|
38252
38394
|
ws2.on("error", reject);
|
|
38253
38395
|
});
|
|
@@ -38610,17 +38752,17 @@ ${installInfo}`
|
|
|
38610
38752
|
throw new Error("No free port found");
|
|
38611
38753
|
}
|
|
38612
38754
|
function checkPortFree(port) {
|
|
38613
|
-
return new Promise((
|
|
38755
|
+
return new Promise((resolve9) => {
|
|
38614
38756
|
const server = net3.createServer();
|
|
38615
38757
|
server.unref();
|
|
38616
|
-
server.on("error", () =>
|
|
38758
|
+
server.on("error", () => resolve9(false));
|
|
38617
38759
|
server.listen(port, "127.0.0.1", () => {
|
|
38618
|
-
server.close(() =>
|
|
38760
|
+
server.close(() => resolve9(true));
|
|
38619
38761
|
});
|
|
38620
38762
|
});
|
|
38621
38763
|
}
|
|
38622
38764
|
async function isCdpActive(port) {
|
|
38623
|
-
return new Promise((
|
|
38765
|
+
return new Promise((resolve9) => {
|
|
38624
38766
|
const req = require("http").get(`http://127.0.0.1:${port}/json/version`, {
|
|
38625
38767
|
timeout: 2e3
|
|
38626
38768
|
}, (res) => {
|
|
@@ -38629,21 +38771,21 @@ ${installInfo}`
|
|
|
38629
38771
|
res.on("end", () => {
|
|
38630
38772
|
try {
|
|
38631
38773
|
const info = JSON.parse(data);
|
|
38632
|
-
|
|
38774
|
+
resolve9(!!info["WebKit-Version"] || !!info["Browser"]);
|
|
38633
38775
|
} catch {
|
|
38634
|
-
|
|
38776
|
+
resolve9(false);
|
|
38635
38777
|
}
|
|
38636
38778
|
});
|
|
38637
38779
|
});
|
|
38638
|
-
req.on("error", () =>
|
|
38780
|
+
req.on("error", () => resolve9(false));
|
|
38639
38781
|
req.on("timeout", () => {
|
|
38640
38782
|
req.destroy();
|
|
38641
|
-
|
|
38783
|
+
resolve9(false);
|
|
38642
38784
|
});
|
|
38643
38785
|
});
|
|
38644
38786
|
}
|
|
38645
38787
|
async function killIdeProcess(ideId) {
|
|
38646
|
-
const plat =
|
|
38788
|
+
const plat = os12.platform();
|
|
38647
38789
|
const appName = getMacAppIdentifiers()[ideId];
|
|
38648
38790
|
const winProcesses = getWinProcessNames()[ideId];
|
|
38649
38791
|
try {
|
|
@@ -38702,7 +38844,7 @@ ${installInfo}`
|
|
|
38702
38844
|
}
|
|
38703
38845
|
}
|
|
38704
38846
|
function isIdeRunning(ideId) {
|
|
38705
|
-
const plat =
|
|
38847
|
+
const plat = os12.platform();
|
|
38706
38848
|
try {
|
|
38707
38849
|
if (plat === "darwin") {
|
|
38708
38850
|
const appName = getMacAppIdentifiers()[ideId];
|
|
@@ -38738,7 +38880,7 @@ ${installInfo}`
|
|
|
38738
38880
|
}
|
|
38739
38881
|
}
|
|
38740
38882
|
function detectCurrentWorkspace(ideId) {
|
|
38741
|
-
const plat =
|
|
38883
|
+
const plat = os12.platform();
|
|
38742
38884
|
if (plat === "darwin") {
|
|
38743
38885
|
try {
|
|
38744
38886
|
const appName = getMacAppIdentifiers()[ideId];
|
|
@@ -38758,7 +38900,7 @@ ${installInfo}`
|
|
|
38758
38900
|
const appName = appNameMap[ideId];
|
|
38759
38901
|
if (appName) {
|
|
38760
38902
|
const storagePath = path11.join(
|
|
38761
|
-
process.env.APPDATA || path11.join(
|
|
38903
|
+
process.env.APPDATA || path11.join(os12.homedir(), "AppData", "Roaming"),
|
|
38762
38904
|
appName,
|
|
38763
38905
|
"storage.json"
|
|
38764
38906
|
);
|
|
@@ -38780,7 +38922,7 @@ ${installInfo}`
|
|
|
38780
38922
|
return void 0;
|
|
38781
38923
|
}
|
|
38782
38924
|
async function launchWithCdp(options = {}) {
|
|
38783
|
-
const platform9 =
|
|
38925
|
+
const platform9 = os12.platform();
|
|
38784
38926
|
let targetIde;
|
|
38785
38927
|
const ides = await detectIDEs();
|
|
38786
38928
|
if (options.ideId) {
|
|
@@ -38928,8 +39070,8 @@ ${installInfo}`
|
|
|
38928
39070
|
init_logger();
|
|
38929
39071
|
var fs7 = __toESM2(require("fs"));
|
|
38930
39072
|
var path12 = __toESM2(require("path"));
|
|
38931
|
-
var
|
|
38932
|
-
var LOG_DIR2 = process.platform === "win32" ? path12.join(process.env.LOCALAPPDATA || process.env.APPDATA || path12.join(
|
|
39073
|
+
var os13 = __toESM2(require("os"));
|
|
39074
|
+
var LOG_DIR2 = process.platform === "win32" ? path12.join(process.env.LOCALAPPDATA || process.env.APPDATA || path12.join(os13.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path12.join(os13.homedir(), "Library", "Logs", "adhdev") : path12.join(os13.homedir(), ".local", "share", "adhdev", "logs");
|
|
38933
39075
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
38934
39076
|
var MAX_DAYS = 7;
|
|
38935
39077
|
try {
|
|
@@ -39060,7 +39202,7 @@ ${installInfo}`
|
|
|
39060
39202
|
}
|
|
39061
39203
|
cleanOldFiles();
|
|
39062
39204
|
init_logger();
|
|
39063
|
-
var
|
|
39205
|
+
var os14 = __toESM2(require("os"));
|
|
39064
39206
|
init_config();
|
|
39065
39207
|
init_terminal_screen();
|
|
39066
39208
|
init_logger();
|
|
@@ -39176,16 +39318,16 @@ ${installInfo}`
|
|
|
39176
39318
|
version: options.version,
|
|
39177
39319
|
daemonMode: options.daemonMode,
|
|
39178
39320
|
machine: {
|
|
39179
|
-
hostname:
|
|
39180
|
-
platform:
|
|
39181
|
-
arch:
|
|
39182
|
-
cpus:
|
|
39321
|
+
hostname: os14.hostname(),
|
|
39322
|
+
platform: os14.platform(),
|
|
39323
|
+
arch: os14.arch(),
|
|
39324
|
+
cpus: os14.cpus().length,
|
|
39183
39325
|
totalMem: memSnap.totalMem,
|
|
39184
39326
|
freeMem: memSnap.freeMem,
|
|
39185
39327
|
availableMem: memSnap.availableMem,
|
|
39186
|
-
loadavg:
|
|
39187
|
-
uptime:
|
|
39188
|
-
release:
|
|
39328
|
+
loadavg: os14.loadavg(),
|
|
39329
|
+
uptime: os14.uptime(),
|
|
39330
|
+
release: os14.release()
|
|
39189
39331
|
},
|
|
39190
39332
|
machineNickname: options.machineNickname ?? cfg.machineNickname ?? null,
|
|
39191
39333
|
timestamp: options.timestamp ?? Date.now(),
|
|
@@ -39203,11 +39345,11 @@ ${installInfo}`
|
|
|
39203
39345
|
var import_child_process7 = require("child_process");
|
|
39204
39346
|
var import_child_process8 = require("child_process");
|
|
39205
39347
|
var fs8 = __toESM2(require("fs"));
|
|
39206
|
-
var
|
|
39348
|
+
var os15 = __toESM2(require("os"));
|
|
39207
39349
|
var path13 = __toESM2(require("path"));
|
|
39208
39350
|
var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
|
|
39209
39351
|
function getUpgradeLogPath() {
|
|
39210
|
-
const home =
|
|
39352
|
+
const home = os15.homedir();
|
|
39211
39353
|
const dir = path13.join(home, ".adhdev");
|
|
39212
39354
|
fs8.mkdirSync(dir, { recursive: true });
|
|
39213
39355
|
return path13.join(dir, "daemon-upgrade.log");
|
|
@@ -39240,14 +39382,14 @@ ${installInfo}`
|
|
|
39240
39382
|
while (Date.now() - start < timeoutMs) {
|
|
39241
39383
|
try {
|
|
39242
39384
|
process.kill(pid, 0);
|
|
39243
|
-
await new Promise((
|
|
39385
|
+
await new Promise((resolve9) => setTimeout(resolve9, 250));
|
|
39244
39386
|
} catch {
|
|
39245
39387
|
return;
|
|
39246
39388
|
}
|
|
39247
39389
|
}
|
|
39248
39390
|
}
|
|
39249
39391
|
function stopSessionHostProcesses(appName) {
|
|
39250
|
-
const pidFile = path13.join(
|
|
39392
|
+
const pidFile = path13.join(os15.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
39251
39393
|
try {
|
|
39252
39394
|
if (fs8.existsSync(pidFile)) {
|
|
39253
39395
|
const pid = Number.parseInt(fs8.readFileSync(pidFile, "utf8").trim(), 10);
|
|
@@ -39276,7 +39418,7 @@ ${installInfo}`
|
|
|
39276
39418
|
}
|
|
39277
39419
|
}
|
|
39278
39420
|
function removeDaemonPidFile() {
|
|
39279
|
-
const pidFile = path13.join(
|
|
39421
|
+
const pidFile = path13.join(os15.homedir(), ".adhdev", "daemon.pid");
|
|
39280
39422
|
try {
|
|
39281
39423
|
fs8.unlinkSync(pidFile);
|
|
39282
39424
|
} catch {
|
|
@@ -40766,10 +40908,10 @@ ${installInfo}`
|
|
|
40766
40908
|
};
|
|
40767
40909
|
var fs10 = __toESM2(require("fs"));
|
|
40768
40910
|
var path14 = __toESM2(require("path"));
|
|
40769
|
-
var
|
|
40911
|
+
var os16 = __toESM2(require("os"));
|
|
40770
40912
|
var import_child_process9 = require("child_process");
|
|
40771
40913
|
var import_os3 = require("os");
|
|
40772
|
-
var ARCHIVE_PATH = path14.join(
|
|
40914
|
+
var ARCHIVE_PATH = path14.join(os16.homedir(), ".adhdev", "version-history.json");
|
|
40773
40915
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
40774
40916
|
var VersionArchive = class {
|
|
40775
40917
|
history = {};
|
|
@@ -40856,7 +40998,7 @@ ${installInfo}`
|
|
|
40856
40998
|
function checkPathExists2(paths) {
|
|
40857
40999
|
for (const p of paths) {
|
|
40858
41000
|
if (p.includes("*")) {
|
|
40859
|
-
const home =
|
|
41001
|
+
const home = os16.homedir();
|
|
40860
41002
|
const resolved = p.replace(/\*/g, home.split(path14.sep).pop() || "");
|
|
40861
41003
|
if (fs10.existsSync(resolved)) return resolved;
|
|
40862
41004
|
} else {
|
|
@@ -42443,7 +42585,7 @@ async (params) => {
|
|
|
42443
42585
|
return { target, instance, adapter };
|
|
42444
42586
|
}
|
|
42445
42587
|
function sleep(ms2) {
|
|
42446
|
-
return new Promise((
|
|
42588
|
+
return new Promise((resolve9) => setTimeout(resolve9, ms2));
|
|
42447
42589
|
}
|
|
42448
42590
|
async function waitForCliReady(ctx, type, instanceId, timeoutMs) {
|
|
42449
42591
|
const startedAt = Date.now();
|
|
@@ -43172,7 +43314,7 @@ async (params) => {
|
|
|
43172
43314
|
}
|
|
43173
43315
|
var fs13 = __toESM2(require("fs"));
|
|
43174
43316
|
var path17 = __toESM2(require("path"));
|
|
43175
|
-
var
|
|
43317
|
+
var os17 = __toESM2(require("os"));
|
|
43176
43318
|
function getAutoImplPid(ctx) {
|
|
43177
43319
|
const proc = ctx.autoImplProcess;
|
|
43178
43320
|
return proc && typeof proc.pid === "number" && proc.pid > 0 ? proc.pid : null;
|
|
@@ -43375,7 +43517,7 @@ async (params) => {
|
|
|
43375
43517
|
});
|
|
43376
43518
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
43377
43519
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
43378
|
-
const tmpDir = path17.join(
|
|
43520
|
+
const tmpDir = path17.join(os17.tmpdir(), "adhdev-autoimpl");
|
|
43379
43521
|
if (!fs13.existsSync(tmpDir)) fs13.mkdirSync(tmpDir, { recursive: true });
|
|
43380
43522
|
const promptFile = path17.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
43381
43523
|
fs13.writeFileSync(promptFile, prompt, "utf-8");
|
|
@@ -43529,7 +43671,7 @@ async (params) => {
|
|
|
43529
43671
|
const interactiveFlags = ["--yolo", "--interactive", "-i"];
|
|
43530
43672
|
const baseArgs = [...spawn4.args || []].filter((a) => !interactiveFlags.includes(a));
|
|
43531
43673
|
let shellCmd;
|
|
43532
|
-
const isWin =
|
|
43674
|
+
const isWin = os17.platform() === "win32";
|
|
43533
43675
|
const escapeArg = (a) => isWin ? `"${a.replace(/"/g, '""')}"` : `'${a.replace(/'/g, "'\\''")}'`;
|
|
43534
43676
|
if (command === "claude") {
|
|
43535
43677
|
const args = [...baseArgs, "--dangerously-skip-permissions"];
|
|
@@ -43573,7 +43715,7 @@ async (params) => {
|
|
|
43573
43715
|
try {
|
|
43574
43716
|
const pty3 = require("node-pty");
|
|
43575
43717
|
ctx.log(`Auto-implement spawn (PTY): ${shellCmd}`);
|
|
43576
|
-
const isWin2 =
|
|
43718
|
+
const isWin2 = os17.platform() === "win32";
|
|
43577
43719
|
child = pty3.spawn(isWin2 ? "cmd.exe" : process.env.SHELL || "/bin/zsh", [isWin2 ? "/c" : "-c", shellCmd], {
|
|
43578
43720
|
name: "xterm-256color",
|
|
43579
43721
|
cols: 120,
|
|
@@ -44609,15 +44751,15 @@ data: ${JSON.stringify(msg.data)}
|
|
|
44609
44751
|
this.json(res, 500, { error: e.message });
|
|
44610
44752
|
}
|
|
44611
44753
|
});
|
|
44612
|
-
return new Promise((
|
|
44754
|
+
return new Promise((resolve9, reject) => {
|
|
44613
44755
|
this.server.listen(port, "127.0.0.1", () => {
|
|
44614
44756
|
this.log(`Dev server listening on http://127.0.0.1:${port}`);
|
|
44615
|
-
|
|
44757
|
+
resolve9();
|
|
44616
44758
|
});
|
|
44617
44759
|
this.server.on("error", (e) => {
|
|
44618
44760
|
if (e.code === "EADDRINUSE") {
|
|
44619
44761
|
this.log(`Port ${port} in use, skipping dev server`);
|
|
44620
|
-
|
|
44762
|
+
resolve9();
|
|
44621
44763
|
} else {
|
|
44622
44764
|
reject(e);
|
|
44623
44765
|
}
|
|
@@ -44700,20 +44842,20 @@ data: ${JSON.stringify(msg.data)}
|
|
|
44700
44842
|
child.stderr?.on("data", (d) => {
|
|
44701
44843
|
stderr += d.toString().slice(0, 2e3);
|
|
44702
44844
|
});
|
|
44703
|
-
await new Promise((
|
|
44845
|
+
await new Promise((resolve9) => {
|
|
44704
44846
|
const timer = setTimeout(() => {
|
|
44705
44847
|
child.kill();
|
|
44706
|
-
|
|
44848
|
+
resolve9();
|
|
44707
44849
|
}, 3e3);
|
|
44708
44850
|
child.on("exit", () => {
|
|
44709
44851
|
clearTimeout(timer);
|
|
44710
|
-
|
|
44852
|
+
resolve9();
|
|
44711
44853
|
});
|
|
44712
44854
|
child.stdout?.once("data", () => {
|
|
44713
44855
|
setTimeout(() => {
|
|
44714
44856
|
child.kill();
|
|
44715
44857
|
clearTimeout(timer);
|
|
44716
|
-
|
|
44858
|
+
resolve9();
|
|
44717
44859
|
}, 500);
|
|
44718
44860
|
});
|
|
44719
44861
|
});
|
|
@@ -45222,14 +45364,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
45222
45364
|
child.stderr?.on("data", (d) => {
|
|
45223
45365
|
stderr += d.toString();
|
|
45224
45366
|
});
|
|
45225
|
-
await new Promise((
|
|
45367
|
+
await new Promise((resolve9) => {
|
|
45226
45368
|
const timer = setTimeout(() => {
|
|
45227
45369
|
child.kill();
|
|
45228
|
-
|
|
45370
|
+
resolve9();
|
|
45229
45371
|
}, timeout);
|
|
45230
45372
|
child.on("exit", () => {
|
|
45231
45373
|
clearTimeout(timer);
|
|
45232
|
-
|
|
45374
|
+
resolve9();
|
|
45233
45375
|
});
|
|
45234
45376
|
});
|
|
45235
45377
|
const elapsed = Date.now() - start;
|
|
@@ -45904,14 +46046,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
45904
46046
|
res.end(JSON.stringify(data, null, 2));
|
|
45905
46047
|
}
|
|
45906
46048
|
async readBody(req) {
|
|
45907
|
-
return new Promise((
|
|
46049
|
+
return new Promise((resolve9) => {
|
|
45908
46050
|
let body = "";
|
|
45909
46051
|
req.on("data", (chunk) => body += chunk);
|
|
45910
46052
|
req.on("end", () => {
|
|
45911
46053
|
try {
|
|
45912
|
-
|
|
46054
|
+
resolve9(JSON.parse(body));
|
|
45913
46055
|
} catch {
|
|
45914
|
-
|
|
46056
|
+
resolve9({});
|
|
45915
46057
|
}
|
|
45916
46058
|
});
|
|
45917
46059
|
});
|
|
@@ -45980,12 +46122,12 @@ data: ${JSON.stringify(msg.data)}
|
|
|
45980
46122
|
};
|
|
45981
46123
|
init_provider_cli_adapter();
|
|
45982
46124
|
init_pty_transport();
|
|
45983
|
-
var
|
|
46125
|
+
var import_session_host_core22 = require_dist();
|
|
45984
46126
|
init_logger();
|
|
45985
46127
|
var SessionHostRuntimeTransport = class {
|
|
45986
46128
|
constructor(options) {
|
|
45987
46129
|
this.options = options;
|
|
45988
|
-
this.client = new
|
|
46130
|
+
this.client = new import_session_host_core22.SessionHostClient({
|
|
45989
46131
|
endpoint: options.endpoint,
|
|
45990
46132
|
appName: options.appName
|
|
45991
46133
|
});
|
|
@@ -46352,11 +46494,11 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46352
46494
|
});
|
|
46353
46495
|
}
|
|
46354
46496
|
};
|
|
46355
|
-
var
|
|
46497
|
+
var import_session_host_core3 = require_dist();
|
|
46356
46498
|
var STARTUP_TIMEOUT_MS = 8e3;
|
|
46357
46499
|
var STARTUP_POLL_MS = 200;
|
|
46358
46500
|
async function canConnect(endpoint) {
|
|
46359
|
-
const client = new
|
|
46501
|
+
const client = new import_session_host_core3.SessionHostClient({ endpoint });
|
|
46360
46502
|
try {
|
|
46361
46503
|
await client.connect();
|
|
46362
46504
|
await client.close();
|
|
@@ -46369,19 +46511,19 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46369
46511
|
const deadline = Date.now() + timeoutMs;
|
|
46370
46512
|
while (Date.now() < deadline) {
|
|
46371
46513
|
if (await canConnect(endpoint)) return;
|
|
46372
|
-
await new Promise((
|
|
46514
|
+
await new Promise((resolve9) => setTimeout(resolve9, STARTUP_POLL_MS));
|
|
46373
46515
|
}
|
|
46374
46516
|
throw new Error(`Session host did not become ready within ${timeoutMs}ms`);
|
|
46375
46517
|
}
|
|
46376
46518
|
async function ensureSessionHostReady2(options) {
|
|
46377
|
-
const endpoint = (0,
|
|
46519
|
+
const endpoint = (0, import_session_host_core3.getDefaultSessionHostEndpoint)(options.appName || "adhdev");
|
|
46378
46520
|
if (await canConnect(endpoint)) return endpoint;
|
|
46379
46521
|
options.spawnHost();
|
|
46380
46522
|
await waitForReady(endpoint, options.timeoutMs);
|
|
46381
46523
|
return endpoint;
|
|
46382
46524
|
}
|
|
46383
46525
|
async function listHostedCliRuntimes2(endpoint) {
|
|
46384
|
-
const client = new
|
|
46526
|
+
const client = new import_session_host_core3.SessionHostClient({ endpoint });
|
|
46385
46527
|
try {
|
|
46386
46528
|
const response = await client.request({
|
|
46387
46529
|
type: "list_sessions",
|
|
@@ -46523,10 +46665,10 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46523
46665
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
46524
46666
|
const fs15 = await import("fs");
|
|
46525
46667
|
fs15.writeFileSync(vsixPath, buffer);
|
|
46526
|
-
return new Promise((
|
|
46668
|
+
return new Promise((resolve9) => {
|
|
46527
46669
|
const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
|
|
46528
46670
|
(0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error48, _stdout, stderr) => {
|
|
46529
|
-
|
|
46671
|
+
resolve9({
|
|
46530
46672
|
extensionId: extension.id,
|
|
46531
46673
|
marketplaceId: extension.marketplaceId,
|
|
46532
46674
|
success: !error48,
|
|
@@ -46539,11 +46681,11 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46539
46681
|
} catch (e) {
|
|
46540
46682
|
}
|
|
46541
46683
|
}
|
|
46542
|
-
return new Promise((
|
|
46684
|
+
return new Promise((resolve9) => {
|
|
46543
46685
|
const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
|
|
46544
46686
|
(0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error48, stdout, stderr) => {
|
|
46545
46687
|
if (error48) {
|
|
46546
|
-
|
|
46688
|
+
resolve9({
|
|
46547
46689
|
extensionId: extension.id,
|
|
46548
46690
|
marketplaceId: extension.marketplaceId,
|
|
46549
46691
|
success: false,
|
|
@@ -46551,7 +46693,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46551
46693
|
error: stderr || error48.message
|
|
46552
46694
|
});
|
|
46553
46695
|
} else {
|
|
46554
|
-
|
|
46696
|
+
resolve9({
|
|
46555
46697
|
extensionId: extension.id,
|
|
46556
46698
|
marketplaceId: extension.marketplaceId,
|
|
46557
46699
|
success: true,
|
|
@@ -47029,6 +47171,13 @@ var SessionHostClient = class {
|
|
|
47029
47171
|
}
|
|
47030
47172
|
async connect() {
|
|
47031
47173
|
if (this.socket && !this.socket.destroyed) return;
|
|
47174
|
+
if (this.socket) {
|
|
47175
|
+
try {
|
|
47176
|
+
this.socket.destroy();
|
|
47177
|
+
} catch {
|
|
47178
|
+
}
|
|
47179
|
+
this.socket = null;
|
|
47180
|
+
}
|
|
47032
47181
|
const socket = net.createConnection(this.endpoint.path);
|
|
47033
47182
|
this.socket = socket;
|
|
47034
47183
|
socket.on("data", createLineParser((envelope) => {
|
|
@@ -47049,9 +47198,16 @@ var SessionHostClient = class {
|
|
|
47049
47198
|
waiter.reject(error48);
|
|
47050
47199
|
}
|
|
47051
47200
|
this.requestWaiters.clear();
|
|
47201
|
+
if (this.socket === socket) {
|
|
47202
|
+
this.socket = null;
|
|
47203
|
+
}
|
|
47204
|
+
try {
|
|
47205
|
+
socket.destroy();
|
|
47206
|
+
} catch {
|
|
47207
|
+
}
|
|
47052
47208
|
});
|
|
47053
|
-
await new Promise((
|
|
47054
|
-
socket.once("connect", () =>
|
|
47209
|
+
await new Promise((resolve22, reject) => {
|
|
47210
|
+
socket.once("connect", () => resolve22());
|
|
47055
47211
|
socket.once("error", reject);
|
|
47056
47212
|
});
|
|
47057
47213
|
}
|
|
@@ -47070,7 +47226,7 @@ var SessionHostClient = class {
|
|
|
47070
47226
|
requestId,
|
|
47071
47227
|
request
|
|
47072
47228
|
};
|
|
47073
|
-
const response = await new Promise((
|
|
47229
|
+
const response = await new Promise((resolve22, reject) => {
|
|
47074
47230
|
const timeout = setTimeout(() => {
|
|
47075
47231
|
this.requestWaiters.delete(requestId);
|
|
47076
47232
|
reject(new Error(`Session host request timed out after 30s (${request.type})`));
|
|
@@ -47078,7 +47234,7 @@ var SessionHostClient = class {
|
|
|
47078
47234
|
this.requestWaiters.set(requestId, {
|
|
47079
47235
|
resolve: (value) => {
|
|
47080
47236
|
clearTimeout(timeout);
|
|
47081
|
-
|
|
47237
|
+
resolve22(value);
|
|
47082
47238
|
},
|
|
47083
47239
|
reject: (error48) => {
|
|
47084
47240
|
clearTimeout(timeout);
|
|
@@ -47097,12 +47253,12 @@ var SessionHostClient = class {
|
|
|
47097
47253
|
waiter.reject(new Error("Session host client closed"));
|
|
47098
47254
|
}
|
|
47099
47255
|
this.requestWaiters.clear();
|
|
47100
|
-
await new Promise((
|
|
47256
|
+
await new Promise((resolve22) => {
|
|
47101
47257
|
let settled = false;
|
|
47102
47258
|
const done = () => {
|
|
47103
47259
|
if (settled) return;
|
|
47104
47260
|
settled = true;
|
|
47105
|
-
|
|
47261
|
+
resolve22();
|
|
47106
47262
|
};
|
|
47107
47263
|
socket.once("close", done);
|
|
47108
47264
|
socket.end();
|