@adhdev/daemon-standalone 0.8.11 → 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 +1058 -857
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/public/assets/index-BbTwOu3n.js +61 -0
- package/public/assets/index-BrvO5cQG.css +1 -0
- package/public/assets/terminal-CKqklWLC.js +13 -0
- package/public/index.html +3 -3
- package/vendor/session-host-daemon/index.js +39 -55
- package/vendor/session-host-daemon/index.js.map +1 -1
- package/vendor/session-host-daemon/index.mjs +26 -42
- package/vendor/session-host-daemon/index.mjs.map +1 -1
- package/public/assets/index-BUlIITyJ.css +0 -1
- package/public/assets/index-CdUZNwyL.js +0 -61
- 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) {
|
|
@@ -27023,690 +27608,167 @@ var init_chokidar = __esm({
|
|
|
27023
27608
|
awfEmit(err);
|
|
27024
27609
|
return;
|
|
27025
27610
|
}
|
|
27026
|
-
const now2 = Number(/* @__PURE__ */ new Date());
|
|
27027
|
-
if (prevStat && curStat.size !== prevStat.size) {
|
|
27028
|
-
writes.get(path5).lastChange = now2;
|
|
27029
|
-
}
|
|
27030
|
-
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;
|
|
27611
|
+
const now2 = Number(/* @__PURE__ */ new Date());
|
|
27612
|
+
if (prevStat && curStat.size !== prevStat.size) {
|
|
27613
|
+
writes.get(path5).lastChange = now2;
|
|
27614
|
+
}
|
|
27615
|
+
const pw = writes.get(path5);
|
|
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);
|
|
27442
27622
|
}
|
|
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
|
|
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}`
|
|
@@ -28476,11 +28545,21 @@ var require_dist2 = __commonJS({
|
|
|
28476
28545
|
NodePtyTransportFactory = class {
|
|
28477
28546
|
spawn(command, args, options) {
|
|
28478
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
|
+
}
|
|
28479
28558
|
const handle = pty.spawn(command, args, {
|
|
28480
|
-
name:
|
|
28559
|
+
name: "xterm-256color",
|
|
28481
28560
|
cols: options.cols,
|
|
28482
28561
|
rows: options.rows,
|
|
28483
|
-
cwd
|
|
28562
|
+
cwd,
|
|
28484
28563
|
env: options.env
|
|
28485
28564
|
});
|
|
28486
28565
|
return new NodePtyRuntimeTransport(handle);
|
|
@@ -28488,6 +28567,13 @@ var require_dist2 = __commonJS({
|
|
|
28488
28567
|
};
|
|
28489
28568
|
}
|
|
28490
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
|
+
});
|
|
28491
28577
|
var provider_cli_adapter_exports = {};
|
|
28492
28578
|
__export2(provider_cli_adapter_exports, {
|
|
28493
28579
|
ProviderCliAdapter: () => ProviderCliAdapter,
|
|
@@ -28502,20 +28588,6 @@ var require_dist2 = __commonJS({
|
|
|
28502
28588
|
function sanitizeTerminalText(str) {
|
|
28503
28589
|
return stripTerminalNoise(stripAnsi(str));
|
|
28504
28590
|
}
|
|
28505
|
-
function buildCliSpawnEnv(baseEnv, overrides) {
|
|
28506
|
-
const env = {};
|
|
28507
|
-
const source = { ...baseEnv, ...overrides || {} };
|
|
28508
|
-
for (const [key, value] of Object.entries(source)) {
|
|
28509
|
-
if (typeof value !== "string") continue;
|
|
28510
|
-
env[key] = value;
|
|
28511
|
-
}
|
|
28512
|
-
for (const key of Object.keys(env)) {
|
|
28513
|
-
if (key === "INIT_CWD" || key === "NO_COLOR" || key === "FORCE_COLOR" || 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_")) {
|
|
28514
|
-
delete env[key];
|
|
28515
|
-
}
|
|
28516
|
-
}
|
|
28517
|
-
return env;
|
|
28518
|
-
}
|
|
28519
28591
|
function computeTerminalQueryTail(buffer) {
|
|
28520
28592
|
const prefixes = ["\x1B[6n", "\x1B[?6n"];
|
|
28521
28593
|
const maxLength = prefixes.reduce((n, value) => Math.max(n, value.length), 0) - 1;
|
|
@@ -28648,6 +28720,7 @@ var require_dist2 = __commonJS({
|
|
|
28648
28720
|
var path7;
|
|
28649
28721
|
var import_child_process4;
|
|
28650
28722
|
var pty2;
|
|
28723
|
+
var buildCliSpawnEnv;
|
|
28651
28724
|
var ProviderCliAdapter;
|
|
28652
28725
|
var init_provider_cli_adapter = __esm2({
|
|
28653
28726
|
"src/cli-adapters/provider-cli-adapter.ts"() {
|
|
@@ -28658,27 +28731,14 @@ var require_dist2 = __commonJS({
|
|
|
28658
28731
|
init_logger();
|
|
28659
28732
|
init_terminal_screen();
|
|
28660
28733
|
init_pty_transport();
|
|
28734
|
+
init_spawn_env();
|
|
28661
28735
|
try {
|
|
28662
28736
|
pty2 = require("node-pty");
|
|
28663
|
-
|
|
28664
|
-
try {
|
|
28665
|
-
const fs15 = require("fs");
|
|
28666
|
-
const ptyDir = path7.resolve(path7.dirname(require.resolve("node-pty")), "..");
|
|
28667
|
-
const platformArch = `${os8.platform()}-${os8.arch()}`;
|
|
28668
|
-
const helper = path7.join(ptyDir, "prebuilds", platformArch, "spawn-helper");
|
|
28669
|
-
if (fs15.existsSync(helper)) {
|
|
28670
|
-
const stat4 = fs15.statSync(helper);
|
|
28671
|
-
if (!(stat4.mode & 73)) {
|
|
28672
|
-
fs15.chmodSync(helper, stat4.mode | 493);
|
|
28673
|
-
LOG2.info("CLI", "[node-pty] Fixed spawn-helper permissions");
|
|
28674
|
-
}
|
|
28675
|
-
}
|
|
28676
|
-
} catch {
|
|
28677
|
-
}
|
|
28678
|
-
}
|
|
28737
|
+
(0, import_session_host_core2.ensureNodePtySpawnHelperPermissions)((msg) => LOG2.info("CLI", msg));
|
|
28679
28738
|
} catch {
|
|
28680
28739
|
LOG2.error("CLI", "[ProviderCliAdapter] node-pty not found. Terminal features disabled.");
|
|
28681
28740
|
}
|
|
28741
|
+
buildCliSpawnEnv = import_session_host_core2.sanitizeSpawnEnv;
|
|
28682
28742
|
ProviderCliAdapter = class _ProviderCliAdapter {
|
|
28683
28743
|
constructor(provider, workingDir, extraArgs = [], transportFactory = new NodePtyTransportFactory()) {
|
|
28684
28744
|
this.extraArgs = extraArgs;
|
|
@@ -29045,6 +29105,12 @@ var require_dist2 = __commonJS({
|
|
|
29045
29105
|
shellArgs = ["-l", "-c", fullCmd];
|
|
29046
29106
|
this.ptyProcess = this.transportFactory.spawn(shellCmd, shellArgs, ptyOpts);
|
|
29047
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
|
+
}
|
|
29048
29114
|
throw err;
|
|
29049
29115
|
}
|
|
29050
29116
|
}
|
|
@@ -29219,7 +29285,7 @@ var require_dist2 = __commonJS({
|
|
|
29219
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)}`
|
|
29220
29286
|
);
|
|
29221
29287
|
}
|
|
29222
|
-
await new Promise((
|
|
29288
|
+
await new Promise((resolve9) => setTimeout(resolve9, 50));
|
|
29223
29289
|
}
|
|
29224
29290
|
const finalScreenText = this.terminalScreen.getText() || "";
|
|
29225
29291
|
LOG2.warn(
|
|
@@ -29606,7 +29672,7 @@ ${data.message || ""}`.trim();
|
|
|
29606
29672
|
if (this.startupParseGate) {
|
|
29607
29673
|
const deadline = Date.now() + 1e4;
|
|
29608
29674
|
while (this.startupParseGate && Date.now() < deadline) {
|
|
29609
|
-
await new Promise((
|
|
29675
|
+
await new Promise((resolve9) => setTimeout(resolve9, 50));
|
|
29610
29676
|
}
|
|
29611
29677
|
}
|
|
29612
29678
|
if (!this.ready) throw new Error(`${this.cliName} not ready (status: ${this.currentStatus})`);
|
|
@@ -29797,7 +29863,8 @@ ${data.message || ""}`.trim();
|
|
|
29797
29863
|
const payload = stopCommand.endsWith("\r") || stopCommand.endsWith("\n") ? stopCommand : `${stopCommand}${this.sendKey}`;
|
|
29798
29864
|
this.ptyProcess.write(payload);
|
|
29799
29865
|
};
|
|
29800
|
-
|
|
29866
|
+
const interruptGraceMs = typeof resume.interruptGraceMs === "number" ? Math.max(100, resume.interruptGraceMs) : 500;
|
|
29867
|
+
if (wasProcessing) setTimeout(writeCommand, interruptGraceMs);
|
|
29801
29868
|
else writeCommand();
|
|
29802
29869
|
} else {
|
|
29803
29870
|
this.ptyProcess.write("");
|
|
@@ -29813,17 +29880,17 @@ ${data.message || ""}`.trim();
|
|
|
29813
29880
|
}
|
|
29814
29881
|
}
|
|
29815
29882
|
waitForStopped(timeoutMs) {
|
|
29816
|
-
return new Promise((
|
|
29883
|
+
return new Promise((resolve9) => {
|
|
29817
29884
|
const startedAt = Date.now();
|
|
29818
29885
|
const timer = setInterval(() => {
|
|
29819
29886
|
if (!this.ptyProcess || this.currentStatus === "stopped") {
|
|
29820
29887
|
clearInterval(timer);
|
|
29821
|
-
|
|
29888
|
+
resolve9(true);
|
|
29822
29889
|
return;
|
|
29823
29890
|
}
|
|
29824
29891
|
if (Date.now() - startedAt >= timeoutMs) {
|
|
29825
29892
|
clearInterval(timer);
|
|
29826
|
-
|
|
29893
|
+
resolve9(false);
|
|
29827
29894
|
}
|
|
29828
29895
|
}, 100);
|
|
29829
29896
|
});
|
|
@@ -29842,6 +29909,18 @@ ${data.message || ""}`.trim();
|
|
|
29842
29909
|
clearTimeout(this.submitRetryTimer);
|
|
29843
29910
|
this.submitRetryTimer = null;
|
|
29844
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
|
+
}
|
|
29845
29924
|
if (this.pendingOutputParseTimer) {
|
|
29846
29925
|
clearTimeout(this.pendingOutputParseTimer);
|
|
29847
29926
|
this.pendingOutputParseTimer = null;
|
|
@@ -29883,6 +29962,18 @@ ${data.message || ""}`.trim();
|
|
|
29883
29962
|
clearTimeout(this.submitRetryTimer);
|
|
29884
29963
|
this.submitRetryTimer = null;
|
|
29885
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
|
+
}
|
|
29886
29977
|
if (this.pendingOutputParseTimer) {
|
|
29887
29978
|
clearTimeout(this.pendingOutputParseTimer);
|
|
29888
29979
|
this.pendingOutputParseTimer = null;
|
|
@@ -30478,8 +30569,8 @@ ${data.message || ""}`.trim();
|
|
|
30478
30569
|
if ((0, import_fs2.existsSync)(bundledCli)) resolvedCli = bundledCli;
|
|
30479
30570
|
}
|
|
30480
30571
|
if (!resolvedCli && appPath && os18 === "win32") {
|
|
30481
|
-
const { dirname:
|
|
30482
|
-
const appDir =
|
|
30572
|
+
const { dirname: dirname6 } = await import("path");
|
|
30573
|
+
const appDir = dirname6(appPath);
|
|
30483
30574
|
const candidates = [
|
|
30484
30575
|
`${appDir}\\\\bin\\\\${def.cli}.cmd`,
|
|
30485
30576
|
`${appDir}\\\\bin\\\\${def.cli}`,
|
|
@@ -30515,20 +30606,20 @@ ${data.message || ""}`.trim();
|
|
|
30515
30606
|
return match ? match[1] : raw.split("\n")[0].slice(0, 100);
|
|
30516
30607
|
}
|
|
30517
30608
|
function execAsync(cmd, timeoutMs = 5e3) {
|
|
30518
|
-
return new Promise((
|
|
30609
|
+
return new Promise((resolve9) => {
|
|
30519
30610
|
const child = (0, import_child_process22.exec)(cmd, { encoding: "utf-8", timeout: timeoutMs }, (err, stdout) => {
|
|
30520
30611
|
if (err || !stdout?.trim()) {
|
|
30521
|
-
|
|
30612
|
+
resolve9(null);
|
|
30522
30613
|
} else {
|
|
30523
|
-
|
|
30614
|
+
resolve9(stdout.trim());
|
|
30524
30615
|
}
|
|
30525
30616
|
});
|
|
30526
|
-
child.on("error", () =>
|
|
30617
|
+
child.on("error", () => resolve9(null));
|
|
30527
30618
|
});
|
|
30528
30619
|
}
|
|
30529
30620
|
async function detectCLIs(providerLoader) {
|
|
30530
|
-
const
|
|
30531
|
-
const whichCmd =
|
|
30621
|
+
const platform9 = os22.platform();
|
|
30622
|
+
const whichCmd = platform9 === "win32" ? "where" : "which";
|
|
30532
30623
|
const cliList = providerLoader ? providerLoader.getCliDetectionList() : [];
|
|
30533
30624
|
const results = await Promise.all(
|
|
30534
30625
|
cliList.map(async (cli) => {
|
|
@@ -30563,6 +30654,39 @@ ${data.message || ""}`.trim();
|
|
|
30563
30654
|
}
|
|
30564
30655
|
async function detectCLI(cliId, providerLoader) {
|
|
30565
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
|
+
}
|
|
30566
30690
|
const all = await detectCLIs(providerLoader);
|
|
30567
30691
|
return all.find((c) => c.id === resolvedId && c.installed) || null;
|
|
30568
30692
|
}
|
|
@@ -30686,7 +30810,7 @@ ${data.message || ""}`.trim();
|
|
|
30686
30810
|
* Returns multiple entries if multiple IDE windows are open on same port
|
|
30687
30811
|
*/
|
|
30688
30812
|
static listAllTargets(port) {
|
|
30689
|
-
return new Promise((
|
|
30813
|
+
return new Promise((resolve9) => {
|
|
30690
30814
|
const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
|
|
30691
30815
|
let data = "";
|
|
30692
30816
|
res.on("data", (chunk) => data += chunk.toString());
|
|
@@ -30702,16 +30826,16 @@ ${data.message || ""}`.trim();
|
|
|
30702
30826
|
(t) => !isNonMain(t.title || "") && t.url?.includes("workbench.html") && !t.url?.includes("agent")
|
|
30703
30827
|
);
|
|
30704
30828
|
const fallbackPages = pages.filter((t) => !isNonMain(t.title || ""));
|
|
30705
|
-
|
|
30829
|
+
resolve9(mainPages.length > 0 ? mainPages : fallbackPages);
|
|
30706
30830
|
} catch {
|
|
30707
|
-
|
|
30831
|
+
resolve9([]);
|
|
30708
30832
|
}
|
|
30709
30833
|
});
|
|
30710
30834
|
});
|
|
30711
|
-
req.on("error", () =>
|
|
30835
|
+
req.on("error", () => resolve9([]));
|
|
30712
30836
|
req.setTimeout(2e3, () => {
|
|
30713
30837
|
req.destroy();
|
|
30714
|
-
|
|
30838
|
+
resolve9([]);
|
|
30715
30839
|
});
|
|
30716
30840
|
});
|
|
30717
30841
|
}
|
|
@@ -30751,7 +30875,7 @@ ${data.message || ""}`.trim();
|
|
|
30751
30875
|
}
|
|
30752
30876
|
}
|
|
30753
30877
|
findTargetOnPort(port) {
|
|
30754
|
-
return new Promise((
|
|
30878
|
+
return new Promise((resolve9) => {
|
|
30755
30879
|
const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
|
|
30756
30880
|
let data = "";
|
|
30757
30881
|
res.on("data", (chunk) => data += chunk.toString());
|
|
@@ -30762,7 +30886,7 @@ ${data.message || ""}`.trim();
|
|
|
30762
30886
|
(t) => (t.type === "page" || t.type === "browser" || t.type === "Page") && t.webSocketDebuggerUrl
|
|
30763
30887
|
);
|
|
30764
30888
|
if (pages.length === 0) {
|
|
30765
|
-
|
|
30889
|
+
resolve9(targets.find((t) => t.webSocketDebuggerUrl) || null);
|
|
30766
30890
|
return;
|
|
30767
30891
|
}
|
|
30768
30892
|
const mainPages = pages.filter((t) => !this.isNonMainTitle(t.title || ""));
|
|
@@ -30772,24 +30896,24 @@ ${data.message || ""}`.trim();
|
|
|
30772
30896
|
const specific = list.find((t) => t.id === this._targetId);
|
|
30773
30897
|
if (specific) {
|
|
30774
30898
|
this._pageTitle = specific.title || "";
|
|
30775
|
-
|
|
30899
|
+
resolve9(specific);
|
|
30776
30900
|
} else {
|
|
30777
30901
|
this.log(`[CDP] Target ${this._targetId} not found in page list`);
|
|
30778
|
-
|
|
30902
|
+
resolve9(null);
|
|
30779
30903
|
}
|
|
30780
30904
|
return;
|
|
30781
30905
|
}
|
|
30782
30906
|
this._pageTitle = list[0]?.title || "";
|
|
30783
|
-
|
|
30907
|
+
resolve9(list[0]);
|
|
30784
30908
|
} catch {
|
|
30785
|
-
|
|
30909
|
+
resolve9(null);
|
|
30786
30910
|
}
|
|
30787
30911
|
});
|
|
30788
30912
|
});
|
|
30789
|
-
req.on("error", () =>
|
|
30913
|
+
req.on("error", () => resolve9(null));
|
|
30790
30914
|
req.setTimeout(2e3, () => {
|
|
30791
30915
|
req.destroy();
|
|
30792
|
-
|
|
30916
|
+
resolve9(null);
|
|
30793
30917
|
});
|
|
30794
30918
|
});
|
|
30795
30919
|
}
|
|
@@ -30800,7 +30924,7 @@ ${data.message || ""}`.trim();
|
|
|
30800
30924
|
this.extensionProviders = providers;
|
|
30801
30925
|
}
|
|
30802
30926
|
connectToTarget(wsUrl) {
|
|
30803
|
-
return new Promise((
|
|
30927
|
+
return new Promise((resolve9) => {
|
|
30804
30928
|
this.ws = new import_ws2.default(wsUrl);
|
|
30805
30929
|
this.ws.on("open", async () => {
|
|
30806
30930
|
this._connected = true;
|
|
@@ -30810,17 +30934,17 @@ ${data.message || ""}`.trim();
|
|
|
30810
30934
|
}
|
|
30811
30935
|
this.connectBrowserWs().catch(() => {
|
|
30812
30936
|
});
|
|
30813
|
-
|
|
30937
|
+
resolve9(true);
|
|
30814
30938
|
});
|
|
30815
30939
|
this.ws.on("message", (data) => {
|
|
30816
30940
|
try {
|
|
30817
30941
|
const msg = JSON.parse(data.toString());
|
|
30818
30942
|
if (msg.id && this.pending.has(msg.id)) {
|
|
30819
|
-
const { resolve:
|
|
30943
|
+
const { resolve: resolve10, reject } = this.pending.get(msg.id);
|
|
30820
30944
|
this.pending.delete(msg.id);
|
|
30821
30945
|
this.failureCount = 0;
|
|
30822
30946
|
if (msg.error) reject(new Error(msg.error.message));
|
|
30823
|
-
else
|
|
30947
|
+
else resolve10(msg.result);
|
|
30824
30948
|
} else if (msg.method === "Runtime.executionContextCreated") {
|
|
30825
30949
|
this.contexts.add(msg.params.context.id);
|
|
30826
30950
|
} else if (msg.method === "Runtime.executionContextDestroyed") {
|
|
@@ -30843,7 +30967,7 @@ ${data.message || ""}`.trim();
|
|
|
30843
30967
|
this.ws.on("error", (err) => {
|
|
30844
30968
|
this.log(`[CDP] WebSocket error: ${err.message}`);
|
|
30845
30969
|
this._connected = false;
|
|
30846
|
-
|
|
30970
|
+
resolve9(false);
|
|
30847
30971
|
});
|
|
30848
30972
|
});
|
|
30849
30973
|
}
|
|
@@ -30857,7 +30981,7 @@ ${data.message || ""}`.trim();
|
|
|
30857
30981
|
return;
|
|
30858
30982
|
}
|
|
30859
30983
|
this.log(`[CDP] Connecting browser WS for target discovery...`);
|
|
30860
|
-
await new Promise((
|
|
30984
|
+
await new Promise((resolve9, reject) => {
|
|
30861
30985
|
this.browserWs = new import_ws2.default(browserWsUrl);
|
|
30862
30986
|
this.browserWs.on("open", async () => {
|
|
30863
30987
|
this._browserConnected = true;
|
|
@@ -30867,16 +30991,16 @@ ${data.message || ""}`.trim();
|
|
|
30867
30991
|
} catch (e) {
|
|
30868
30992
|
this.log(`[CDP] setDiscoverTargets failed: ${e.message}`);
|
|
30869
30993
|
}
|
|
30870
|
-
|
|
30994
|
+
resolve9();
|
|
30871
30995
|
});
|
|
30872
30996
|
this.browserWs.on("message", (data) => {
|
|
30873
30997
|
try {
|
|
30874
30998
|
const msg = JSON.parse(data.toString());
|
|
30875
30999
|
if (msg.id && this.browserPending.has(msg.id)) {
|
|
30876
|
-
const { resolve:
|
|
31000
|
+
const { resolve: resolve10, reject: reject2 } = this.browserPending.get(msg.id);
|
|
30877
31001
|
this.browserPending.delete(msg.id);
|
|
30878
31002
|
if (msg.error) reject2(new Error(msg.error.message));
|
|
30879
|
-
else
|
|
31003
|
+
else resolve10(msg.result);
|
|
30880
31004
|
}
|
|
30881
31005
|
} catch {
|
|
30882
31006
|
}
|
|
@@ -30896,31 +31020,31 @@ ${data.message || ""}`.trim();
|
|
|
30896
31020
|
}
|
|
30897
31021
|
}
|
|
30898
31022
|
getBrowserWsUrl() {
|
|
30899
|
-
return new Promise((
|
|
31023
|
+
return new Promise((resolve9) => {
|
|
30900
31024
|
const req = http.get(`http://127.0.0.1:${this.port}/json/version`, (res) => {
|
|
30901
31025
|
let data = "";
|
|
30902
31026
|
res.on("data", (chunk) => data += chunk.toString());
|
|
30903
31027
|
res.on("end", () => {
|
|
30904
31028
|
try {
|
|
30905
31029
|
const info = JSON.parse(data);
|
|
30906
|
-
|
|
31030
|
+
resolve9(info.webSocketDebuggerUrl || null);
|
|
30907
31031
|
} catch {
|
|
30908
|
-
|
|
31032
|
+
resolve9(null);
|
|
30909
31033
|
}
|
|
30910
31034
|
});
|
|
30911
31035
|
});
|
|
30912
|
-
req.on("error", () =>
|
|
31036
|
+
req.on("error", () => resolve9(null));
|
|
30913
31037
|
req.setTimeout(3e3, () => {
|
|
30914
31038
|
req.destroy();
|
|
30915
|
-
|
|
31039
|
+
resolve9(null);
|
|
30916
31040
|
});
|
|
30917
31041
|
});
|
|
30918
31042
|
}
|
|
30919
31043
|
sendBrowser(method, params = {}, timeoutMs = 15e3) {
|
|
30920
|
-
return new Promise((
|
|
31044
|
+
return new Promise((resolve9, reject) => {
|
|
30921
31045
|
if (!this.browserWs || !this._browserConnected) return reject(new Error("Browser WS not connected"));
|
|
30922
31046
|
const id = this.browserMsgId++;
|
|
30923
|
-
this.browserPending.set(id, { resolve:
|
|
31047
|
+
this.browserPending.set(id, { resolve: resolve9, reject });
|
|
30924
31048
|
this.browserWs.send(JSON.stringify({ id, method, params }));
|
|
30925
31049
|
setTimeout(() => {
|
|
30926
31050
|
if (this.browserPending.has(id)) {
|
|
@@ -30960,11 +31084,11 @@ ${data.message || ""}`.trim();
|
|
|
30960
31084
|
}
|
|
30961
31085
|
// ─── CDP Protocol ────────────────────────────────────────
|
|
30962
31086
|
sendInternal(method, params = {}, timeoutMs = 15e3) {
|
|
30963
|
-
return new Promise((
|
|
31087
|
+
return new Promise((resolve9, reject) => {
|
|
30964
31088
|
if (!this.ws || !this._connected) return reject(new Error("CDP not connected"));
|
|
30965
31089
|
if (this.ws.readyState !== import_ws2.default.OPEN) return reject(new Error("WebSocket not open"));
|
|
30966
31090
|
const id = this.msgId++;
|
|
30967
|
-
this.pending.set(id, { resolve:
|
|
31091
|
+
this.pending.set(id, { resolve: resolve9, reject });
|
|
30968
31092
|
this.ws.send(JSON.stringify({ id, method, params }));
|
|
30969
31093
|
setTimeout(() => {
|
|
30970
31094
|
if (this.pending.has(id)) {
|
|
@@ -31213,7 +31337,7 @@ ${data.message || ""}`.trim();
|
|
|
31213
31337
|
const browserWs = this.browserWs;
|
|
31214
31338
|
let msgId = this.browserMsgId;
|
|
31215
31339
|
const sendWs = (method, params = {}, sessionId) => {
|
|
31216
|
-
return new Promise((
|
|
31340
|
+
return new Promise((resolve9, reject) => {
|
|
31217
31341
|
const mid = msgId++;
|
|
31218
31342
|
this.browserMsgId = msgId;
|
|
31219
31343
|
const handler = (raw) => {
|
|
@@ -31222,7 +31346,7 @@ ${data.message || ""}`.trim();
|
|
|
31222
31346
|
if (msg.id === mid) {
|
|
31223
31347
|
browserWs.removeListener("message", handler);
|
|
31224
31348
|
if (msg.error) reject(new Error(msg.error.message || JSON.stringify(msg.error)));
|
|
31225
|
-
else
|
|
31349
|
+
else resolve9(msg.result);
|
|
31226
31350
|
}
|
|
31227
31351
|
} catch {
|
|
31228
31352
|
}
|
|
@@ -31413,14 +31537,14 @@ ${data.message || ""}`.trim();
|
|
|
31413
31537
|
if (!ws2 || ws2.readyState !== import_ws2.default.OPEN) {
|
|
31414
31538
|
throw new Error("CDP not connected");
|
|
31415
31539
|
}
|
|
31416
|
-
return new Promise((
|
|
31540
|
+
return new Promise((resolve9, reject) => {
|
|
31417
31541
|
const id = getNextId();
|
|
31418
31542
|
pendingMap.set(id, {
|
|
31419
31543
|
resolve: (result) => {
|
|
31420
31544
|
if (result?.result?.subtype === "error") {
|
|
31421
31545
|
reject(new Error(result.result.description));
|
|
31422
31546
|
} else {
|
|
31423
|
-
|
|
31547
|
+
resolve9(result?.result?.value);
|
|
31424
31548
|
}
|
|
31425
31549
|
},
|
|
31426
31550
|
reject
|
|
@@ -31452,10 +31576,10 @@ ${data.message || ""}`.trim();
|
|
|
31452
31576
|
throw new Error("CDP not connected");
|
|
31453
31577
|
}
|
|
31454
31578
|
const sendViaSession = (method, params = {}) => {
|
|
31455
|
-
return new Promise((
|
|
31579
|
+
return new Promise((resolve9, reject) => {
|
|
31456
31580
|
const pendingMap = this._browserConnected ? this.browserPending : this.pending;
|
|
31457
31581
|
const id = this._browserConnected ? this.browserMsgId++ : this.msgId++;
|
|
31458
|
-
pendingMap.set(id, { resolve:
|
|
31582
|
+
pendingMap.set(id, { resolve: resolve9, reject });
|
|
31459
31583
|
ws2.send(JSON.stringify({ id, sessionId, method, params }));
|
|
31460
31584
|
setTimeout(() => {
|
|
31461
31585
|
if (pendingMap.has(id)) {
|
|
@@ -34645,17 +34769,44 @@ ${data.message || ""}`.trim();
|
|
|
34645
34769
|
const agents = await h.getCdp().discoverAgentWebviews();
|
|
34646
34770
|
return { success: true, agents };
|
|
34647
34771
|
}
|
|
34772
|
+
function normalizeWindowsRequestedPath(requestedPath) {
|
|
34773
|
+
const trimmed = requestedPath.trim();
|
|
34774
|
+
if (!trimmed) return ".";
|
|
34775
|
+
const slashDriveMatch = trimmed.match(/^[/\\]([A-Za-z])(?:[/\\](.*))?$/);
|
|
34776
|
+
if (slashDriveMatch) {
|
|
34777
|
+
const drive = slashDriveMatch[1].toUpperCase();
|
|
34778
|
+
const rest = (slashDriveMatch[2] || "").replace(/[/\\]+/g, "\\");
|
|
34779
|
+
return rest ? `${drive}:\\${rest}` : `${drive}:\\`;
|
|
34780
|
+
}
|
|
34781
|
+
if (/^[A-Za-z]:$/.test(trimmed)) {
|
|
34782
|
+
return `${trimmed[0].toUpperCase()}:\\`;
|
|
34783
|
+
}
|
|
34784
|
+
if (/^[A-Za-z]:[^/\\].*$/.test(trimmed)) {
|
|
34785
|
+
return `${trimmed[0].toUpperCase()}:\\${trimmed.slice(2).replace(/[/\\]+/g, "\\")}`;
|
|
34786
|
+
}
|
|
34787
|
+
if (/^[A-Za-z]:[/\\]/.test(trimmed)) {
|
|
34788
|
+
return `${trimmed[0].toUpperCase()}:${trimmed.slice(2)}`;
|
|
34789
|
+
}
|
|
34790
|
+
return trimmed;
|
|
34791
|
+
}
|
|
34648
34792
|
function resolveSafePath(requestedPath) {
|
|
34793
|
+
const rawPath = typeof requestedPath === "string" ? requestedPath.trim() : "";
|
|
34794
|
+
const inputPath = rawPath || ".";
|
|
34649
34795
|
const home = os62.homedir();
|
|
34650
|
-
|
|
34651
|
-
|
|
34652
|
-
|
|
34653
|
-
|
|
34654
|
-
|
|
34655
|
-
|
|
34656
|
-
|
|
34796
|
+
if (inputPath.startsWith("~")) {
|
|
34797
|
+
return path6.resolve(path6.join(home, inputPath.slice(1)));
|
|
34798
|
+
}
|
|
34799
|
+
if (process.platform === "win32") {
|
|
34800
|
+
const normalized = normalizeWindowsRequestedPath(inputPath);
|
|
34801
|
+
if (path6.win32.isAbsolute(normalized)) {
|
|
34802
|
+
return path6.win32.normalize(normalized);
|
|
34803
|
+
}
|
|
34804
|
+
return path6.win32.resolve(normalized);
|
|
34657
34805
|
}
|
|
34658
|
-
|
|
34806
|
+
if (path6.isAbsolute(inputPath)) {
|
|
34807
|
+
return path6.normalize(inputPath);
|
|
34808
|
+
}
|
|
34809
|
+
return path6.resolve(inputPath);
|
|
34659
34810
|
}
|
|
34660
34811
|
function listDirectoryEntriesSafe(dirPath) {
|
|
34661
34812
|
const entries = fs42.readdirSync(dirPath, { withFileTypes: true });
|
|
@@ -35395,7 +35546,7 @@ ${data.message || ""}`.trim();
|
|
|
35395
35546
|
try {
|
|
35396
35547
|
const http3 = await import("http");
|
|
35397
35548
|
const postData = JSON.stringify(body);
|
|
35398
|
-
const result = await new Promise((
|
|
35549
|
+
const result = await new Promise((resolve9, reject) => {
|
|
35399
35550
|
const req = http3.request({
|
|
35400
35551
|
hostname: "127.0.0.1",
|
|
35401
35552
|
port: 19280,
|
|
@@ -35407,9 +35558,9 @@ ${data.message || ""}`.trim();
|
|
|
35407
35558
|
res.on("data", (chunk) => data += chunk);
|
|
35408
35559
|
res.on("end", () => {
|
|
35409
35560
|
try {
|
|
35410
|
-
|
|
35561
|
+
resolve9(JSON.parse(data));
|
|
35411
35562
|
} catch {
|
|
35412
|
-
|
|
35563
|
+
resolve9({ raw: data });
|
|
35413
35564
|
}
|
|
35414
35565
|
});
|
|
35415
35566
|
});
|
|
@@ -35427,15 +35578,15 @@ ${data.message || ""}`.trim();
|
|
|
35427
35578
|
if (!providerType) return { success: false, error: "providerType required" };
|
|
35428
35579
|
try {
|
|
35429
35580
|
const http3 = await import("http");
|
|
35430
|
-
const result = await new Promise((
|
|
35581
|
+
const result = await new Promise((resolve9, reject) => {
|
|
35431
35582
|
http3.get(`http://127.0.0.1:19280/api/providers/${providerType}/${endpoint}`, (res) => {
|
|
35432
35583
|
let data = "";
|
|
35433
35584
|
res.on("data", (chunk) => data += chunk);
|
|
35434
35585
|
res.on("end", () => {
|
|
35435
35586
|
try {
|
|
35436
|
-
|
|
35587
|
+
resolve9(JSON.parse(data));
|
|
35437
35588
|
} catch {
|
|
35438
|
-
|
|
35589
|
+
resolve9({ raw: data });
|
|
35439
35590
|
}
|
|
35440
35591
|
});
|
|
35441
35592
|
}).on("error", reject);
|
|
@@ -35449,7 +35600,7 @@ ${data.message || ""}`.trim();
|
|
|
35449
35600
|
try {
|
|
35450
35601
|
const http3 = await import("http");
|
|
35451
35602
|
const postData = JSON.stringify(args || {});
|
|
35452
|
-
const result = await new Promise((
|
|
35603
|
+
const result = await new Promise((resolve9, reject) => {
|
|
35453
35604
|
const req = http3.request({
|
|
35454
35605
|
hostname: "127.0.0.1",
|
|
35455
35606
|
port: 19280,
|
|
@@ -35461,9 +35612,9 @@ ${data.message || ""}`.trim();
|
|
|
35461
35612
|
res.on("data", (chunk) => data += chunk);
|
|
35462
35613
|
res.on("end", () => {
|
|
35463
35614
|
try {
|
|
35464
|
-
|
|
35615
|
+
resolve9(JSON.parse(data));
|
|
35465
35616
|
} catch {
|
|
35466
|
-
|
|
35617
|
+
resolve9({ raw: data });
|
|
35467
35618
|
}
|
|
35468
35619
|
});
|
|
35469
35620
|
});
|
|
@@ -35572,17 +35723,60 @@ ${data.message || ""}`.trim();
|
|
|
35572
35723
|
async onTick() {
|
|
35573
35724
|
if (this.providerSessionId) return;
|
|
35574
35725
|
let probedSessionId = null;
|
|
35575
|
-
|
|
35576
|
-
|
|
35577
|
-
|
|
35578
|
-
|
|
35579
|
-
|
|
35580
|
-
|
|
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
|
+
}
|
|
35581
35749
|
}
|
|
35582
35750
|
if (probedSessionId) {
|
|
35583
35751
|
this.promoteProviderSessionId(probedSessionId);
|
|
35584
35752
|
}
|
|
35585
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
|
+
}
|
|
35586
35780
|
getState() {
|
|
35587
35781
|
const adapterStatus = this.adapter.getStatus();
|
|
35588
35782
|
const parsedStatus = this.adapter.getScriptParsedStatus?.() || null;
|
|
@@ -35880,34 +36074,6 @@ ${data.message || ""}`.trim();
|
|
|
35880
36074
|
});
|
|
35881
36075
|
LOG2.info("CLI", `[${this.type}] discovered provider session id: ${nextSessionId}`);
|
|
35882
36076
|
}
|
|
35883
|
-
probeOpenCodeSessionId() {
|
|
35884
|
-
const dbPath = path8.join(os9.homedir(), ".local", "share", "opencode", "opencode.db");
|
|
35885
|
-
if (!fs5.existsSync(dbPath)) return null;
|
|
35886
|
-
const minCreatedAt = Math.max(0, this.startedAt - 6e4);
|
|
35887
|
-
const directories = this.getProbeDirectories();
|
|
35888
|
-
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;`;
|
|
35889
|
-
return this.querySqliteText(dbPath, query, [...directories, minCreatedAt]);
|
|
35890
|
-
}
|
|
35891
|
-
probeCodexSessionId() {
|
|
35892
|
-
const dbPath = path8.join(os9.homedir(), ".codex", "state_5.sqlite");
|
|
35893
|
-
if (!fs5.existsSync(dbPath)) return null;
|
|
35894
|
-
const minCreatedAt = Math.max(0, Math.floor((this.startedAt - 6e4) / 1e3));
|
|
35895
|
-
const directories = this.getProbeDirectories();
|
|
35896
|
-
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;`;
|
|
35897
|
-
return this.querySqliteText(dbPath, query, [...directories, minCreatedAt]);
|
|
35898
|
-
}
|
|
35899
|
-
probeGooseSessionId() {
|
|
35900
|
-
const dbPath = path8.join(os9.homedir(), ".local", "share", "goose", "sessions", "sessions.db");
|
|
35901
|
-
if (!fs5.existsSync(dbPath)) return null;
|
|
35902
|
-
const minCreatedAtIso = new Date(Math.max(0, this.startedAt - 6e4)).toISOString().slice(0, 19).replace("T", " ");
|
|
35903
|
-
const directories = this.getProbeDirectories();
|
|
35904
|
-
const query = `select id from sessions where working_dir in (${this.buildSqlPlaceholderList(directories.length)}) and created_at >= ? order by updated_at desc limit 1;`;
|
|
35905
|
-
try {
|
|
35906
|
-
return this.querySqliteText(dbPath, query, [...directories, minCreatedAtIso]);
|
|
35907
|
-
} catch {
|
|
35908
|
-
return null;
|
|
35909
|
-
}
|
|
35910
|
-
}
|
|
35911
36077
|
getProbeDirectories() {
|
|
35912
36078
|
const dirs = /* @__PURE__ */ new Set();
|
|
35913
36079
|
const addDir = (value) => {
|
|
@@ -36373,13 +36539,13 @@ ${data.message || ""}`.trim();
|
|
|
36373
36539
|
}
|
|
36374
36540
|
this.currentStatus = "waiting_approval";
|
|
36375
36541
|
this.detectStatusTransition();
|
|
36376
|
-
const approved = await new Promise((
|
|
36377
|
-
this.permissionResolvers.push(
|
|
36542
|
+
const approved = await new Promise((resolve9) => {
|
|
36543
|
+
this.permissionResolvers.push(resolve9);
|
|
36378
36544
|
setTimeout(() => {
|
|
36379
|
-
const idx = this.permissionResolvers.indexOf(
|
|
36545
|
+
const idx = this.permissionResolvers.indexOf(resolve9);
|
|
36380
36546
|
if (idx >= 0) {
|
|
36381
36547
|
this.permissionResolvers.splice(idx, 1);
|
|
36382
|
-
|
|
36548
|
+
resolve9(false);
|
|
36383
36549
|
}
|
|
36384
36550
|
}, 3e5);
|
|
36385
36551
|
});
|
|
@@ -37168,7 +37334,19 @@ ${installInfo}`
|
|
|
37168
37334
|
return { runtimeSessionId: sessionId };
|
|
37169
37335
|
}
|
|
37170
37336
|
const cliInfo = await detectCLI(cliType, this.providerLoader);
|
|
37171
|
-
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
|
+
}
|
|
37172
37350
|
console.log(colorize("yellow", ` \u26A1 Starting CLI ${cliType} in ${resolvedDir}...`));
|
|
37173
37351
|
if (provider) {
|
|
37174
37352
|
console.log(colorize("cyan", ` \u{1F4E6} Using provider: ${provider.name} (${provider.type})`));
|
|
@@ -37484,8 +37662,9 @@ ${installInfo}`
|
|
|
37484
37662
|
const dir = rdir.path;
|
|
37485
37663
|
if (!cliType) throw new Error("cliType required");
|
|
37486
37664
|
const found = this.findAdapter(cliType, { instanceKey: args?.targetSessionId, dir });
|
|
37665
|
+
const prevCliArgs = found ? found.adapter.extraArgs : void 0;
|
|
37487
37666
|
if (found) await this.stopSession(found.key);
|
|
37488
|
-
await this.startSession(cliType, dir);
|
|
37667
|
+
await this.startSession(cliType, dir, args?.cliArgs || prevCliArgs, args?.initialModel);
|
|
37489
37668
|
return { success: true, restarted: true };
|
|
37490
37669
|
}
|
|
37491
37670
|
case "agent_command": {
|
|
@@ -38099,7 +38278,7 @@ ${installInfo}`
|
|
|
38099
38278
|
return { updated: false };
|
|
38100
38279
|
}
|
|
38101
38280
|
try {
|
|
38102
|
-
const etag = await new Promise((
|
|
38281
|
+
const etag = await new Promise((resolve9, reject) => {
|
|
38103
38282
|
const options = {
|
|
38104
38283
|
method: "HEAD",
|
|
38105
38284
|
hostname: "github.com",
|
|
@@ -38117,7 +38296,7 @@ ${installInfo}`
|
|
|
38117
38296
|
headers: { "User-Agent": "adhdev-launcher" },
|
|
38118
38297
|
timeout: 1e4
|
|
38119
38298
|
}, (res2) => {
|
|
38120
|
-
|
|
38299
|
+
resolve9(res2.headers.etag || res2.headers["last-modified"] || "");
|
|
38121
38300
|
});
|
|
38122
38301
|
req2.on("error", reject);
|
|
38123
38302
|
req2.on("timeout", () => {
|
|
@@ -38126,7 +38305,7 @@ ${installInfo}`
|
|
|
38126
38305
|
});
|
|
38127
38306
|
req2.end();
|
|
38128
38307
|
} else {
|
|
38129
|
-
|
|
38308
|
+
resolve9(res.headers.etag || res.headers["last-modified"] || "");
|
|
38130
38309
|
}
|
|
38131
38310
|
});
|
|
38132
38311
|
req.on("error", reject);
|
|
@@ -38190,7 +38369,7 @@ ${installInfo}`
|
|
|
38190
38369
|
downloadFile(url2, destPath) {
|
|
38191
38370
|
const https = require("https");
|
|
38192
38371
|
const http3 = require("http");
|
|
38193
|
-
return new Promise((
|
|
38372
|
+
return new Promise((resolve9, reject) => {
|
|
38194
38373
|
const doRequest = (reqUrl, redirectCount = 0) => {
|
|
38195
38374
|
if (redirectCount > 5) {
|
|
38196
38375
|
reject(new Error("Too many redirects"));
|
|
@@ -38210,7 +38389,7 @@ ${installInfo}`
|
|
|
38210
38389
|
res.pipe(ws2);
|
|
38211
38390
|
ws2.on("finish", () => {
|
|
38212
38391
|
ws2.close();
|
|
38213
|
-
|
|
38392
|
+
resolve9();
|
|
38214
38393
|
});
|
|
38215
38394
|
ws2.on("error", reject);
|
|
38216
38395
|
});
|
|
@@ -38530,9 +38709,9 @@ ${installInfo}`
|
|
|
38530
38709
|
}
|
|
38531
38710
|
}
|
|
38532
38711
|
compareVersions(a, b2) {
|
|
38533
|
-
const
|
|
38534
|
-
const pa2 =
|
|
38535
|
-
const pb =
|
|
38712
|
+
const normalize3 = (v2) => v2.split(/[-_+]/)[0].split(".").map((x) => parseInt(x, 10) || 0);
|
|
38713
|
+
const pa2 = normalize3(a);
|
|
38714
|
+
const pb = normalize3(b2);
|
|
38536
38715
|
for (let i = 0; i < Math.max(pa2.length, pb.length); i++) {
|
|
38537
38716
|
const va2 = pa2[i] || 0;
|
|
38538
38717
|
const vb = pb[i] || 0;
|
|
@@ -38573,17 +38752,17 @@ ${installInfo}`
|
|
|
38573
38752
|
throw new Error("No free port found");
|
|
38574
38753
|
}
|
|
38575
38754
|
function checkPortFree(port) {
|
|
38576
|
-
return new Promise((
|
|
38755
|
+
return new Promise((resolve9) => {
|
|
38577
38756
|
const server = net3.createServer();
|
|
38578
38757
|
server.unref();
|
|
38579
|
-
server.on("error", () =>
|
|
38758
|
+
server.on("error", () => resolve9(false));
|
|
38580
38759
|
server.listen(port, "127.0.0.1", () => {
|
|
38581
|
-
server.close(() =>
|
|
38760
|
+
server.close(() => resolve9(true));
|
|
38582
38761
|
});
|
|
38583
38762
|
});
|
|
38584
38763
|
}
|
|
38585
38764
|
async function isCdpActive(port) {
|
|
38586
|
-
return new Promise((
|
|
38765
|
+
return new Promise((resolve9) => {
|
|
38587
38766
|
const req = require("http").get(`http://127.0.0.1:${port}/json/version`, {
|
|
38588
38767
|
timeout: 2e3
|
|
38589
38768
|
}, (res) => {
|
|
@@ -38592,16 +38771,16 @@ ${installInfo}`
|
|
|
38592
38771
|
res.on("end", () => {
|
|
38593
38772
|
try {
|
|
38594
38773
|
const info = JSON.parse(data);
|
|
38595
|
-
|
|
38774
|
+
resolve9(!!info["WebKit-Version"] || !!info["Browser"]);
|
|
38596
38775
|
} catch {
|
|
38597
|
-
|
|
38776
|
+
resolve9(false);
|
|
38598
38777
|
}
|
|
38599
38778
|
});
|
|
38600
38779
|
});
|
|
38601
|
-
req.on("error", () =>
|
|
38780
|
+
req.on("error", () => resolve9(false));
|
|
38602
38781
|
req.on("timeout", () => {
|
|
38603
38782
|
req.destroy();
|
|
38604
|
-
|
|
38783
|
+
resolve9(false);
|
|
38605
38784
|
});
|
|
38606
38785
|
});
|
|
38607
38786
|
}
|
|
@@ -38743,7 +38922,7 @@ ${installInfo}`
|
|
|
38743
38922
|
return void 0;
|
|
38744
38923
|
}
|
|
38745
38924
|
async function launchWithCdp(options = {}) {
|
|
38746
|
-
const
|
|
38925
|
+
const platform9 = os12.platform();
|
|
38747
38926
|
let targetIde;
|
|
38748
38927
|
const ides = await detectIDEs();
|
|
38749
38928
|
if (options.ideId) {
|
|
@@ -38812,9 +38991,9 @@ ${installInfo}`
|
|
|
38812
38991
|
}
|
|
38813
38992
|
const port = await findFreePort(portPair);
|
|
38814
38993
|
try {
|
|
38815
|
-
if (
|
|
38994
|
+
if (platform9 === "darwin") {
|
|
38816
38995
|
await launchMacOS(targetIde, port, workspace, options.newWindow);
|
|
38817
|
-
} else if (
|
|
38996
|
+
} else if (platform9 === "win32") {
|
|
38818
38997
|
await launchWindows(targetIde, port, workspace, options.newWindow);
|
|
38819
38998
|
} else {
|
|
38820
38999
|
await launchLinux(targetIde, port, workspace, options.newWindow);
|
|
@@ -39203,7 +39382,7 @@ ${installInfo}`
|
|
|
39203
39382
|
while (Date.now() - start < timeoutMs) {
|
|
39204
39383
|
try {
|
|
39205
39384
|
process.kill(pid, 0);
|
|
39206
|
-
await new Promise((
|
|
39385
|
+
await new Promise((resolve9) => setTimeout(resolve9, 250));
|
|
39207
39386
|
} catch {
|
|
39208
39387
|
return;
|
|
39209
39388
|
}
|
|
@@ -42406,7 +42585,7 @@ async (params) => {
|
|
|
42406
42585
|
return { target, instance, adapter };
|
|
42407
42586
|
}
|
|
42408
42587
|
function sleep(ms2) {
|
|
42409
|
-
return new Promise((
|
|
42588
|
+
return new Promise((resolve9) => setTimeout(resolve9, ms2));
|
|
42410
42589
|
}
|
|
42411
42590
|
async function waitForCliReady(ctx, type, instanceId, timeoutMs) {
|
|
42412
42591
|
const startedAt = Date.now();
|
|
@@ -44572,15 +44751,15 @@ data: ${JSON.stringify(msg.data)}
|
|
|
44572
44751
|
this.json(res, 500, { error: e.message });
|
|
44573
44752
|
}
|
|
44574
44753
|
});
|
|
44575
|
-
return new Promise((
|
|
44754
|
+
return new Promise((resolve9, reject) => {
|
|
44576
44755
|
this.server.listen(port, "127.0.0.1", () => {
|
|
44577
44756
|
this.log(`Dev server listening on http://127.0.0.1:${port}`);
|
|
44578
|
-
|
|
44757
|
+
resolve9();
|
|
44579
44758
|
});
|
|
44580
44759
|
this.server.on("error", (e) => {
|
|
44581
44760
|
if (e.code === "EADDRINUSE") {
|
|
44582
44761
|
this.log(`Port ${port} in use, skipping dev server`);
|
|
44583
|
-
|
|
44762
|
+
resolve9();
|
|
44584
44763
|
} else {
|
|
44585
44764
|
reject(e);
|
|
44586
44765
|
}
|
|
@@ -44663,20 +44842,20 @@ data: ${JSON.stringify(msg.data)}
|
|
|
44663
44842
|
child.stderr?.on("data", (d) => {
|
|
44664
44843
|
stderr += d.toString().slice(0, 2e3);
|
|
44665
44844
|
});
|
|
44666
|
-
await new Promise((
|
|
44845
|
+
await new Promise((resolve9) => {
|
|
44667
44846
|
const timer = setTimeout(() => {
|
|
44668
44847
|
child.kill();
|
|
44669
|
-
|
|
44848
|
+
resolve9();
|
|
44670
44849
|
}, 3e3);
|
|
44671
44850
|
child.on("exit", () => {
|
|
44672
44851
|
clearTimeout(timer);
|
|
44673
|
-
|
|
44852
|
+
resolve9();
|
|
44674
44853
|
});
|
|
44675
44854
|
child.stdout?.once("data", () => {
|
|
44676
44855
|
setTimeout(() => {
|
|
44677
44856
|
child.kill();
|
|
44678
44857
|
clearTimeout(timer);
|
|
44679
|
-
|
|
44858
|
+
resolve9();
|
|
44680
44859
|
}, 500);
|
|
44681
44860
|
});
|
|
44682
44861
|
});
|
|
@@ -45185,14 +45364,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
45185
45364
|
child.stderr?.on("data", (d) => {
|
|
45186
45365
|
stderr += d.toString();
|
|
45187
45366
|
});
|
|
45188
|
-
await new Promise((
|
|
45367
|
+
await new Promise((resolve9) => {
|
|
45189
45368
|
const timer = setTimeout(() => {
|
|
45190
45369
|
child.kill();
|
|
45191
|
-
|
|
45370
|
+
resolve9();
|
|
45192
45371
|
}, timeout);
|
|
45193
45372
|
child.on("exit", () => {
|
|
45194
45373
|
clearTimeout(timer);
|
|
45195
|
-
|
|
45374
|
+
resolve9();
|
|
45196
45375
|
});
|
|
45197
45376
|
});
|
|
45198
45377
|
const elapsed = Date.now() - start;
|
|
@@ -45867,14 +46046,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
45867
46046
|
res.end(JSON.stringify(data, null, 2));
|
|
45868
46047
|
}
|
|
45869
46048
|
async readBody(req) {
|
|
45870
|
-
return new Promise((
|
|
46049
|
+
return new Promise((resolve9) => {
|
|
45871
46050
|
let body = "";
|
|
45872
46051
|
req.on("data", (chunk) => body += chunk);
|
|
45873
46052
|
req.on("end", () => {
|
|
45874
46053
|
try {
|
|
45875
|
-
|
|
46054
|
+
resolve9(JSON.parse(body));
|
|
45876
46055
|
} catch {
|
|
45877
|
-
|
|
46056
|
+
resolve9({});
|
|
45878
46057
|
}
|
|
45879
46058
|
});
|
|
45880
46059
|
});
|
|
@@ -45943,12 +46122,12 @@ data: ${JSON.stringify(msg.data)}
|
|
|
45943
46122
|
};
|
|
45944
46123
|
init_provider_cli_adapter();
|
|
45945
46124
|
init_pty_transport();
|
|
45946
|
-
var
|
|
46125
|
+
var import_session_host_core22 = require_dist();
|
|
45947
46126
|
init_logger();
|
|
45948
46127
|
var SessionHostRuntimeTransport = class {
|
|
45949
46128
|
constructor(options) {
|
|
45950
46129
|
this.options = options;
|
|
45951
|
-
this.client = new
|
|
46130
|
+
this.client = new import_session_host_core22.SessionHostClient({
|
|
45952
46131
|
endpoint: options.endpoint,
|
|
45953
46132
|
appName: options.appName
|
|
45954
46133
|
});
|
|
@@ -46315,11 +46494,11 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46315
46494
|
});
|
|
46316
46495
|
}
|
|
46317
46496
|
};
|
|
46318
|
-
var
|
|
46497
|
+
var import_session_host_core3 = require_dist();
|
|
46319
46498
|
var STARTUP_TIMEOUT_MS = 8e3;
|
|
46320
46499
|
var STARTUP_POLL_MS = 200;
|
|
46321
46500
|
async function canConnect(endpoint) {
|
|
46322
|
-
const client = new
|
|
46501
|
+
const client = new import_session_host_core3.SessionHostClient({ endpoint });
|
|
46323
46502
|
try {
|
|
46324
46503
|
await client.connect();
|
|
46325
46504
|
await client.close();
|
|
@@ -46332,19 +46511,19 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46332
46511
|
const deadline = Date.now() + timeoutMs;
|
|
46333
46512
|
while (Date.now() < deadline) {
|
|
46334
46513
|
if (await canConnect(endpoint)) return;
|
|
46335
|
-
await new Promise((
|
|
46514
|
+
await new Promise((resolve9) => setTimeout(resolve9, STARTUP_POLL_MS));
|
|
46336
46515
|
}
|
|
46337
46516
|
throw new Error(`Session host did not become ready within ${timeoutMs}ms`);
|
|
46338
46517
|
}
|
|
46339
46518
|
async function ensureSessionHostReady2(options) {
|
|
46340
|
-
const endpoint = (0,
|
|
46519
|
+
const endpoint = (0, import_session_host_core3.getDefaultSessionHostEndpoint)(options.appName || "adhdev");
|
|
46341
46520
|
if (await canConnect(endpoint)) return endpoint;
|
|
46342
46521
|
options.spawnHost();
|
|
46343
46522
|
await waitForReady(endpoint, options.timeoutMs);
|
|
46344
46523
|
return endpoint;
|
|
46345
46524
|
}
|
|
46346
46525
|
async function listHostedCliRuntimes2(endpoint) {
|
|
46347
|
-
const client = new
|
|
46526
|
+
const client = new import_session_host_core3.SessionHostClient({ endpoint });
|
|
46348
46527
|
try {
|
|
46349
46528
|
const response = await client.request({
|
|
46350
46529
|
type: "list_sessions",
|
|
@@ -46486,10 +46665,10 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46486
46665
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
46487
46666
|
const fs15 = await import("fs");
|
|
46488
46667
|
fs15.writeFileSync(vsixPath, buffer);
|
|
46489
|
-
return new Promise((
|
|
46668
|
+
return new Promise((resolve9) => {
|
|
46490
46669
|
const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
|
|
46491
46670
|
(0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error48, _stdout, stderr) => {
|
|
46492
|
-
|
|
46671
|
+
resolve9({
|
|
46493
46672
|
extensionId: extension.id,
|
|
46494
46673
|
marketplaceId: extension.marketplaceId,
|
|
46495
46674
|
success: !error48,
|
|
@@ -46502,11 +46681,11 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46502
46681
|
} catch (e) {
|
|
46503
46682
|
}
|
|
46504
46683
|
}
|
|
46505
|
-
return new Promise((
|
|
46684
|
+
return new Promise((resolve9) => {
|
|
46506
46685
|
const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
|
|
46507
46686
|
(0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error48, stdout, stderr) => {
|
|
46508
46687
|
if (error48) {
|
|
46509
|
-
|
|
46688
|
+
resolve9({
|
|
46510
46689
|
extensionId: extension.id,
|
|
46511
46690
|
marketplaceId: extension.marketplaceId,
|
|
46512
46691
|
success: false,
|
|
@@ -46514,7 +46693,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46514
46693
|
error: stderr || error48.message
|
|
46515
46694
|
});
|
|
46516
46695
|
} else {
|
|
46517
|
-
|
|
46696
|
+
resolve9({
|
|
46518
46697
|
extensionId: extension.id,
|
|
46519
46698
|
marketplaceId: extension.marketplaceId,
|
|
46520
46699
|
success: true,
|
|
@@ -46817,10 +46996,18 @@ function buildSessionHostEnv(baseEnv) {
|
|
|
46817
46996
|
env[key] = value;
|
|
46818
46997
|
}
|
|
46819
46998
|
for (const key of Object.keys(env)) {
|
|
46820
|
-
if (key === "INIT_CWD" || key === "
|
|
46999
|
+
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_")) {
|
|
46821
47000
|
delete env[key];
|
|
46822
47001
|
}
|
|
46823
47002
|
}
|
|
47003
|
+
if (!env.NO_COLOR) {
|
|
47004
|
+
if (!env.TERM || env.TERM === "xterm-color") env.TERM = "xterm-256color";
|
|
47005
|
+
if (!env.COLORTERM) env.COLORTERM = "truecolor";
|
|
47006
|
+
if (process.platform === "win32") {
|
|
47007
|
+
if (!env.FORCE_COLOR) env.FORCE_COLOR = "1";
|
|
47008
|
+
if (!env.CLICOLOR) env.CLICOLOR = "1";
|
|
47009
|
+
}
|
|
47010
|
+
}
|
|
46824
47011
|
env.ADHDEV_SESSION_HOST_NAME = SESSION_HOST_APP_NAME;
|
|
46825
47012
|
return env;
|
|
46826
47013
|
}
|
|
@@ -46984,6 +47171,13 @@ var SessionHostClient = class {
|
|
|
46984
47171
|
}
|
|
46985
47172
|
async connect() {
|
|
46986
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
|
+
}
|
|
46987
47181
|
const socket = net.createConnection(this.endpoint.path);
|
|
46988
47182
|
this.socket = socket;
|
|
46989
47183
|
socket.on("data", createLineParser((envelope) => {
|
|
@@ -47004,9 +47198,16 @@ var SessionHostClient = class {
|
|
|
47004
47198
|
waiter.reject(error48);
|
|
47005
47199
|
}
|
|
47006
47200
|
this.requestWaiters.clear();
|
|
47201
|
+
if (this.socket === socket) {
|
|
47202
|
+
this.socket = null;
|
|
47203
|
+
}
|
|
47204
|
+
try {
|
|
47205
|
+
socket.destroy();
|
|
47206
|
+
} catch {
|
|
47207
|
+
}
|
|
47007
47208
|
});
|
|
47008
|
-
await new Promise((
|
|
47009
|
-
socket.once("connect", () =>
|
|
47209
|
+
await new Promise((resolve22, reject) => {
|
|
47210
|
+
socket.once("connect", () => resolve22());
|
|
47010
47211
|
socket.once("error", reject);
|
|
47011
47212
|
});
|
|
47012
47213
|
}
|
|
@@ -47025,7 +47226,7 @@ var SessionHostClient = class {
|
|
|
47025
47226
|
requestId,
|
|
47026
47227
|
request
|
|
47027
47228
|
};
|
|
47028
|
-
const response = await new Promise((
|
|
47229
|
+
const response = await new Promise((resolve22, reject) => {
|
|
47029
47230
|
const timeout = setTimeout(() => {
|
|
47030
47231
|
this.requestWaiters.delete(requestId);
|
|
47031
47232
|
reject(new Error(`Session host request timed out after 30s (${request.type})`));
|
|
@@ -47033,7 +47234,7 @@ var SessionHostClient = class {
|
|
|
47033
47234
|
this.requestWaiters.set(requestId, {
|
|
47034
47235
|
resolve: (value) => {
|
|
47035
47236
|
clearTimeout(timeout);
|
|
47036
|
-
|
|
47237
|
+
resolve22(value);
|
|
47037
47238
|
},
|
|
47038
47239
|
reject: (error48) => {
|
|
47039
47240
|
clearTimeout(timeout);
|
|
@@ -47052,12 +47253,12 @@ var SessionHostClient = class {
|
|
|
47052
47253
|
waiter.reject(new Error("Session host client closed"));
|
|
47053
47254
|
}
|
|
47054
47255
|
this.requestWaiters.clear();
|
|
47055
|
-
await new Promise((
|
|
47256
|
+
await new Promise((resolve22) => {
|
|
47056
47257
|
let settled = false;
|
|
47057
47258
|
const done = () => {
|
|
47058
47259
|
if (settled) return;
|
|
47059
47260
|
settled = true;
|
|
47060
|
-
|
|
47261
|
+
resolve22();
|
|
47061
47262
|
};
|
|
47062
47263
|
socket.once("close", done);
|
|
47063
47264
|
socket.end();
|