@adhdev/daemon-standalone 0.9.82-rc.167 → 0.9.82-rc.168
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 +344 -9
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
- package/vendor/session-host-daemon/index.js +72 -1
- package/vendor/session-host-daemon/index.js.map +1 -1
- package/vendor/session-host-daemon/index.mjs +72 -1
- package/vendor/session-host-daemon/index.mjs.map +1 -1
package/dist/index.js
CHANGED
|
@@ -7700,6 +7700,7 @@ var require_dist2 = __commonJS({
|
|
|
7700
7700
|
"acquire_write",
|
|
7701
7701
|
"release_write",
|
|
7702
7702
|
"get_snapshot",
|
|
7703
|
+
"get_terminal_snapshot",
|
|
7703
7704
|
"clear_session_buffer",
|
|
7704
7705
|
"update_session_meta",
|
|
7705
7706
|
"get_host_diagnostics",
|
|
@@ -46907,6 +46908,7 @@ ${lastSnapshot}`;
|
|
|
46907
46908
|
ProviderCliAdapter: () => ProviderCliAdapter,
|
|
46908
46909
|
ProviderInstanceManager: () => ProviderInstanceManager,
|
|
46909
46910
|
ProviderLoader: () => ProviderLoader,
|
|
46911
|
+
RawTerminalAttachment: () => RawTerminalAttachment,
|
|
46910
46912
|
STANDALONE_CDP_SCAN_INTERVAL_MS: () => STANDALONE_CDP_SCAN_INTERVAL_MS2,
|
|
46911
46913
|
SessionHostPtyTransportFactory: () => SessionHostPtyTransportFactory2,
|
|
46912
46914
|
SpecDriver: () => SpecDriver,
|
|
@@ -47057,6 +47059,8 @@ ${lastSnapshot}`;
|
|
|
47057
47059
|
markSetupComplete: () => markSetupComplete,
|
|
47058
47060
|
markStaleDirectDispatches: () => markStaleDirectDispatches,
|
|
47059
47061
|
maybeRunDaemonUpgradeHelperFromEnv: () => maybeRunDaemonUpgradeHelperFromEnv2,
|
|
47062
|
+
namedKeyToAnsi: () => namedKeyToAnsi,
|
|
47063
|
+
namedKeysToAnsi: () => namedKeysToAnsi,
|
|
47060
47064
|
normalizeActiveChatData: () => normalizeActiveChatData,
|
|
47061
47065
|
normalizeChatMessage: () => normalizeChatMessage,
|
|
47062
47066
|
normalizeChatMessageKind: () => normalizeChatMessageKind,
|
|
@@ -47137,7 +47141,8 @@ ${lastSnapshot}`;
|
|
|
47137
47141
|
validateCliProviderManifest: () => validateCliProviderManifest,
|
|
47138
47142
|
validateMeshRefineConfig: () => validateMeshRefineConfig,
|
|
47139
47143
|
validateMeshTaskModeRequest: () => validateMeshTaskModeRequest,
|
|
47140
|
-
validateMeshWorktreeBootstrapConfig: () => validateMeshWorktreeBootstrapConfig
|
|
47144
|
+
validateMeshWorktreeBootstrapConfig: () => validateMeshWorktreeBootstrapConfig,
|
|
47145
|
+
withRawTerminalAttachment: () => withRawTerminalAttachment2
|
|
47141
47146
|
});
|
|
47142
47147
|
module2.exports = __toCommonJS2(index_exports);
|
|
47143
47148
|
init_repo_mesh_types();
|
|
@@ -73995,9 +74000,9 @@ ${e?.stderr || ""}`
|
|
|
73995
74000
|
});
|
|
73996
74001
|
let node;
|
|
73997
74002
|
if (meshRecord.inline) {
|
|
73998
|
-
const { randomUUID:
|
|
74003
|
+
const { randomUUID: randomUUID11 } = await import("crypto");
|
|
73999
74004
|
node = {
|
|
74000
|
-
id: `node_${
|
|
74005
|
+
id: `node_${randomUUID11().replace(/-/g, "")}`,
|
|
74001
74006
|
workspace: result.worktreePath,
|
|
74002
74007
|
repoRoot: result.worktreePath,
|
|
74003
74008
|
daemonId: sourceNode.daemonId,
|
|
@@ -82310,6 +82315,199 @@ data: ${JSON.stringify(msg.data)}
|
|
|
82310
82315
|
});
|
|
82311
82316
|
}
|
|
82312
82317
|
};
|
|
82318
|
+
var import_crypto6 = require("crypto");
|
|
82319
|
+
var import_session_host_core4 = require_dist2();
|
|
82320
|
+
var BASE_KEY_SEQUENCES = {
|
|
82321
|
+
enter: "\r",
|
|
82322
|
+
escape: "\x1B",
|
|
82323
|
+
tab: " ",
|
|
82324
|
+
backspace: "\x7F",
|
|
82325
|
+
up: "\x1B[A",
|
|
82326
|
+
down: "\x1B[B",
|
|
82327
|
+
right: "\x1B[C",
|
|
82328
|
+
left: "\x1B[D",
|
|
82329
|
+
home: "\x1B[H",
|
|
82330
|
+
end: "\x1B[F",
|
|
82331
|
+
pageup: "\x1B[5~",
|
|
82332
|
+
pagedown: "\x1B[6~",
|
|
82333
|
+
space: " ",
|
|
82334
|
+
f1: "\x1BOP",
|
|
82335
|
+
f2: "\x1BOQ",
|
|
82336
|
+
f3: "\x1BOR",
|
|
82337
|
+
f4: "\x1BOS",
|
|
82338
|
+
f5: "\x1B[15~",
|
|
82339
|
+
f6: "\x1B[17~",
|
|
82340
|
+
f7: "\x1B[18~",
|
|
82341
|
+
f8: "\x1B[19~",
|
|
82342
|
+
f9: "\x1B[20~",
|
|
82343
|
+
f10: "\x1B[21~",
|
|
82344
|
+
f11: "\x1B[23~",
|
|
82345
|
+
f12: "\x1B[24~"
|
|
82346
|
+
};
|
|
82347
|
+
var SHIFTED_CSI_KEYS = {
|
|
82348
|
+
up: "\x1B[1;2A",
|
|
82349
|
+
down: "\x1B[1;2B",
|
|
82350
|
+
right: "\x1B[1;2C",
|
|
82351
|
+
left: "\x1B[1;2D",
|
|
82352
|
+
home: "\x1B[1;2H",
|
|
82353
|
+
end: "\x1B[1;2F",
|
|
82354
|
+
pageup: "\x1B[5;2~",
|
|
82355
|
+
pagedown: "\x1B[6;2~",
|
|
82356
|
+
f1: "\x1B[1;2P",
|
|
82357
|
+
f2: "\x1B[1;2Q",
|
|
82358
|
+
f3: "\x1B[1;2R",
|
|
82359
|
+
f4: "\x1B[1;2S",
|
|
82360
|
+
f5: "\x1B[15;2~",
|
|
82361
|
+
f6: "\x1B[17;2~",
|
|
82362
|
+
f7: "\x1B[18;2~",
|
|
82363
|
+
f8: "\x1B[19;2~",
|
|
82364
|
+
f9: "\x1B[20;2~",
|
|
82365
|
+
f10: "\x1B[21;2~",
|
|
82366
|
+
f11: "\x1B[23;2~",
|
|
82367
|
+
f12: "\x1B[24;2~"
|
|
82368
|
+
};
|
|
82369
|
+
function isLowercaseLetter(value) {
|
|
82370
|
+
return /^[a-z]$/.test(value);
|
|
82371
|
+
}
|
|
82372
|
+
function encodeControlLetter(letter) {
|
|
82373
|
+
return String.fromCharCode(letter.charCodeAt(0) - 96);
|
|
82374
|
+
}
|
|
82375
|
+
function encodeShiftedKey(key) {
|
|
82376
|
+
if (isLowercaseLetter(key)) return key.toUpperCase();
|
|
82377
|
+
if (key.startsWith("ctrl+") && isLowercaseLetter(key.slice(5))) {
|
|
82378
|
+
return encodeControlLetter(key.slice(5));
|
|
82379
|
+
}
|
|
82380
|
+
if (key.startsWith("alt+") && isLowercaseLetter(key.slice(4))) {
|
|
82381
|
+
return `\x1B${key.slice(4).toUpperCase()}`;
|
|
82382
|
+
}
|
|
82383
|
+
if (key === "tab") return "\x1B[Z";
|
|
82384
|
+
if (key in SHIFTED_CSI_KEYS) return SHIFTED_CSI_KEYS[key];
|
|
82385
|
+
if (key in BASE_KEY_SEQUENCES) return BASE_KEY_SEQUENCES[key];
|
|
82386
|
+
throw new Error(`Unsupported named key: shift+${key}`);
|
|
82387
|
+
}
|
|
82388
|
+
function namedKeyToAnsi(key) {
|
|
82389
|
+
const normalized = String(key || "").trim().toLowerCase();
|
|
82390
|
+
if (normalized in BASE_KEY_SEQUENCES) return BASE_KEY_SEQUENCES[normalized];
|
|
82391
|
+
if (normalized.startsWith("ctrl+") && isLowercaseLetter(normalized.slice(5))) {
|
|
82392
|
+
return encodeControlLetter(normalized.slice(5));
|
|
82393
|
+
}
|
|
82394
|
+
if (normalized.startsWith("alt+") && isLowercaseLetter(normalized.slice(4))) {
|
|
82395
|
+
return `\x1B${normalized.slice(4)}`;
|
|
82396
|
+
}
|
|
82397
|
+
if (normalized.startsWith("shift+")) return encodeShiftedKey(normalized.slice(6));
|
|
82398
|
+
throw new Error(`Unsupported named key: ${key}`);
|
|
82399
|
+
}
|
|
82400
|
+
function namedKeysToAnsi(keys) {
|
|
82401
|
+
if (!Array.isArray(keys)) throw new Error("keys must be an array");
|
|
82402
|
+
return keys.map(namedKeyToAnsi).join("");
|
|
82403
|
+
}
|
|
82404
|
+
var RawTerminalAttachment = class _RawTerminalAttachment {
|
|
82405
|
+
constructor(sessionId, clientId, mode, client) {
|
|
82406
|
+
this.sessionId = sessionId;
|
|
82407
|
+
this.clientId = clientId;
|
|
82408
|
+
this.mode = mode;
|
|
82409
|
+
this.client = client;
|
|
82410
|
+
}
|
|
82411
|
+
closed = false;
|
|
82412
|
+
static async attach(options) {
|
|
82413
|
+
const sessionId = String(options.sessionId || "").trim();
|
|
82414
|
+
if (!sessionId) throw new Error("sessionId is required");
|
|
82415
|
+
const mode = options.mode || "read";
|
|
82416
|
+
const clientId = options.clientId || `raw-terminal-${process.pid}-${(0, import_crypto6.randomUUID)().slice(0, 8)}`;
|
|
82417
|
+
const client = options.client || new import_session_host_core4.SessionHostClient({ endpoint: options.endpoint });
|
|
82418
|
+
await client.connect();
|
|
82419
|
+
const attachResponse = await client.request({
|
|
82420
|
+
type: "attach_session",
|
|
82421
|
+
payload: {
|
|
82422
|
+
sessionId,
|
|
82423
|
+
clientId,
|
|
82424
|
+
clientType: "web",
|
|
82425
|
+
readOnly: mode === "read"
|
|
82426
|
+
}
|
|
82427
|
+
});
|
|
82428
|
+
if (!attachResponse.success) {
|
|
82429
|
+
await client.close().catch(() => {
|
|
82430
|
+
});
|
|
82431
|
+
throw new Error(attachResponse.error || `Failed to attach terminal session ${sessionId}`);
|
|
82432
|
+
}
|
|
82433
|
+
if (mode === "write") {
|
|
82434
|
+
const ownerResponse = await client.request({
|
|
82435
|
+
type: "acquire_write",
|
|
82436
|
+
payload: {
|
|
82437
|
+
sessionId,
|
|
82438
|
+
clientId,
|
|
82439
|
+
ownerType: "user",
|
|
82440
|
+
force: true
|
|
82441
|
+
}
|
|
82442
|
+
});
|
|
82443
|
+
if (!ownerResponse.success) {
|
|
82444
|
+
await client.request({
|
|
82445
|
+
type: "detach_session",
|
|
82446
|
+
payload: { sessionId, clientId }
|
|
82447
|
+
}).catch(() => ({ success: false }));
|
|
82448
|
+
await client.close().catch(() => {
|
|
82449
|
+
});
|
|
82450
|
+
throw new Error(ownerResponse.error || `Failed to acquire terminal session ${sessionId}`);
|
|
82451
|
+
}
|
|
82452
|
+
}
|
|
82453
|
+
return new _RawTerminalAttachment(sessionId, clientId, mode, client);
|
|
82454
|
+
}
|
|
82455
|
+
async readSnapshot() {
|
|
82456
|
+
const response = await this.client.request({
|
|
82457
|
+
type: "get_terminal_snapshot",
|
|
82458
|
+
payload: { sessionId: this.sessionId }
|
|
82459
|
+
});
|
|
82460
|
+
if (!response.success || !response.result) {
|
|
82461
|
+
throw new Error(response.error || `Terminal screen unavailable for ${this.sessionId}`);
|
|
82462
|
+
}
|
|
82463
|
+
return response.result;
|
|
82464
|
+
}
|
|
82465
|
+
async readScreenText() {
|
|
82466
|
+
return (await this.readSnapshot()).text;
|
|
82467
|
+
}
|
|
82468
|
+
async readState() {
|
|
82469
|
+
return (await this.readSnapshot()).state;
|
|
82470
|
+
}
|
|
82471
|
+
async writeInput(text) {
|
|
82472
|
+
if (this.mode !== "write") throw new Error("Raw terminal attachment is read-only");
|
|
82473
|
+
const response = await this.client.request({
|
|
82474
|
+
type: "send_input",
|
|
82475
|
+
payload: {
|
|
82476
|
+
sessionId: this.sessionId,
|
|
82477
|
+
clientId: this.clientId,
|
|
82478
|
+
data: text
|
|
82479
|
+
}
|
|
82480
|
+
});
|
|
82481
|
+
if (!response.success) throw new Error(response.error || `Failed to write terminal input to ${this.sessionId}`);
|
|
82482
|
+
}
|
|
82483
|
+
async writeKeys(keys) {
|
|
82484
|
+
await this.writeInput(namedKeysToAnsi(keys));
|
|
82485
|
+
}
|
|
82486
|
+
async close() {
|
|
82487
|
+
if (this.closed) return;
|
|
82488
|
+
this.closed = true;
|
|
82489
|
+
if (this.mode === "write") {
|
|
82490
|
+
await this.client.request({
|
|
82491
|
+
type: "release_write",
|
|
82492
|
+
payload: { sessionId: this.sessionId, clientId: this.clientId }
|
|
82493
|
+
}).catch(() => ({ success: false }));
|
|
82494
|
+
}
|
|
82495
|
+
await this.client.request({
|
|
82496
|
+
type: "detach_session",
|
|
82497
|
+
payload: { sessionId: this.sessionId, clientId: this.clientId }
|
|
82498
|
+
}).catch(() => ({ success: false }));
|
|
82499
|
+
await this.client.close().catch(() => {
|
|
82500
|
+
});
|
|
82501
|
+
}
|
|
82502
|
+
};
|
|
82503
|
+
async function withRawTerminalAttachment2(options, operation) {
|
|
82504
|
+
const attachment = await RawTerminalAttachment.attach(options);
|
|
82505
|
+
try {
|
|
82506
|
+
return await operation(attachment);
|
|
82507
|
+
} finally {
|
|
82508
|
+
await attachment.close();
|
|
82509
|
+
}
|
|
82510
|
+
}
|
|
82313
82511
|
var DEFAULT_SESSION_HOST_APP_NAME = "adhdev";
|
|
82314
82512
|
var DEFAULT_STANDALONE_SESSION_HOST_APP_NAME = "adhdev-standalone";
|
|
82315
82513
|
function getReservedStandaloneNamespaceWarning() {
|
|
@@ -82339,7 +82537,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
82339
82537
|
function resolveSessionHostAppName(options = {}) {
|
|
82340
82538
|
return resolveSessionHostAppNameResolution2(options).appName;
|
|
82341
82539
|
}
|
|
82342
|
-
var
|
|
82540
|
+
var import_session_host_core5 = require_dist2();
|
|
82343
82541
|
var STARTUP_TIMEOUT_MS = DEFAULT_SESSION_HOST_READY_TIMEOUT_MS2;
|
|
82344
82542
|
var STARTUP_POLL_MS = 200;
|
|
82345
82543
|
var SessionHostCompatibilityError = class extends Error {
|
|
@@ -82367,7 +82565,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
82367
82565
|
}
|
|
82368
82566
|
}
|
|
82369
82567
|
async function canConnect(endpoint, requiredRequestTypes = []) {
|
|
82370
|
-
const client = new
|
|
82568
|
+
const client = new import_session_host_core5.SessionHostClient({ endpoint });
|
|
82371
82569
|
try {
|
|
82372
82570
|
await client.connect();
|
|
82373
82571
|
await assertRequiredRequestTypes(client, requiredRequestTypes);
|
|
@@ -82389,7 +82587,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
82389
82587
|
throw new Error(`Session host did not become ready within ${timeoutMs}ms`);
|
|
82390
82588
|
}
|
|
82391
82589
|
async function ensureSessionHostReady2(options) {
|
|
82392
|
-
const endpoint = (0,
|
|
82590
|
+
const endpoint = (0, import_session_host_core5.getDefaultSessionHostEndpoint)(options.appName || "adhdev");
|
|
82393
82591
|
const requiredRequestTypes = options.requiredRequestTypes || [];
|
|
82394
82592
|
if (await canConnect(endpoint, requiredRequestTypes)) return endpoint;
|
|
82395
82593
|
options.spawnHost();
|
|
@@ -82397,7 +82595,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
82397
82595
|
return endpoint;
|
|
82398
82596
|
}
|
|
82399
82597
|
async function listHostedCliRuntimes2(endpoint) {
|
|
82400
|
-
const client = new
|
|
82598
|
+
const client = new import_session_host_core5.SessionHostClient({ endpoint });
|
|
82401
82599
|
try {
|
|
82402
82600
|
const response = await client.request({
|
|
82403
82601
|
type: "list_sessions",
|
|
@@ -83396,7 +83594,7 @@ async function ensureSessionHostReady() {
|
|
|
83396
83594
|
appName: SESSION_HOST_APP_NAME,
|
|
83397
83595
|
spawnHost,
|
|
83398
83596
|
timeoutMs: SESSION_HOST_START_TIMEOUT_MS,
|
|
83399
|
-
requiredRequestTypes: ["delete_session"]
|
|
83597
|
+
requiredRequestTypes: ["delete_session", "get_terminal_snapshot"]
|
|
83400
83598
|
});
|
|
83401
83599
|
} catch (error48) {
|
|
83402
83600
|
stopSessionHost();
|
|
@@ -83404,7 +83602,7 @@ async function ensureSessionHostReady() {
|
|
|
83404
83602
|
appName: SESSION_HOST_APP_NAME,
|
|
83405
83603
|
spawnHost,
|
|
83406
83604
|
timeoutMs: SESSION_HOST_START_TIMEOUT_MS,
|
|
83407
|
-
requiredRequestTypes: ["delete_session"]
|
|
83605
|
+
requiredRequestTypes: ["delete_session", "get_terminal_snapshot"]
|
|
83408
83606
|
}).catch((retryError) => {
|
|
83409
83607
|
const initialMessage = error48 instanceof Error ? error48.message : String(error48);
|
|
83410
83608
|
const retryMessage = retryError instanceof Error ? retryError.message : String(retryError);
|
|
@@ -83805,6 +84003,109 @@ async function getWorkspaceSocketInfo(workspaceName) {
|
|
|
83805
84003
|
|
|
83806
84004
|
// src/index.ts
|
|
83807
84005
|
var import_daemon_core4 = __toESM(require_dist3());
|
|
84006
|
+
|
|
84007
|
+
// src/raw-terminal-http.ts
|
|
84008
|
+
function parseRawTerminalPath(pathname) {
|
|
84009
|
+
const match = /^\/api\/v1\/sessions\/([^/]+)\/(screen|state|input|keys)$/.exec(pathname);
|
|
84010
|
+
if (!match) return null;
|
|
84011
|
+
try {
|
|
84012
|
+
const sessionId = decodeURIComponent(match[1]).trim();
|
|
84013
|
+
return sessionId ? { sessionId, action: match[2] } : null;
|
|
84014
|
+
} catch {
|
|
84015
|
+
return null;
|
|
84016
|
+
}
|
|
84017
|
+
}
|
|
84018
|
+
function isRawTerminalApiPath(pathname) {
|
|
84019
|
+
return parseRawTerminalPath(pathname) !== null;
|
|
84020
|
+
}
|
|
84021
|
+
function isLoopbackAddress(address) {
|
|
84022
|
+
if (!address) return false;
|
|
84023
|
+
const normalized = address.toLowerCase().split("%", 1)[0];
|
|
84024
|
+
return normalized === "127.0.0.1" || normalized.startsWith("127.") || normalized === "::1" || normalized === "::ffff:127.0.0.1" || normalized.startsWith("::ffff:127.");
|
|
84025
|
+
}
|
|
84026
|
+
function isLoopbackRequest(req) {
|
|
84027
|
+
return isLoopbackAddress(req.socket.remoteAddress);
|
|
84028
|
+
}
|
|
84029
|
+
async function readJsonBody(req) {
|
|
84030
|
+
return await new Promise((resolve2, reject) => {
|
|
84031
|
+
let body = "";
|
|
84032
|
+
req.setEncoding("utf8");
|
|
84033
|
+
req.on("data", (chunk) => {
|
|
84034
|
+
body += chunk;
|
|
84035
|
+
if (body.length > 64 * 1024) reject(new Error("Request body too large"));
|
|
84036
|
+
});
|
|
84037
|
+
req.on("end", () => {
|
|
84038
|
+
try {
|
|
84039
|
+
resolve2(body ? JSON.parse(body) : {});
|
|
84040
|
+
} catch (error48) {
|
|
84041
|
+
reject(error48);
|
|
84042
|
+
}
|
|
84043
|
+
});
|
|
84044
|
+
req.on("error", reject);
|
|
84045
|
+
});
|
|
84046
|
+
}
|
|
84047
|
+
function writeJson(res, statusCode, value) {
|
|
84048
|
+
res.writeHead(statusCode, { "Content-Type": "application/json" });
|
|
84049
|
+
res.end(JSON.stringify(value));
|
|
84050
|
+
}
|
|
84051
|
+
function errorStatus(error48) {
|
|
84052
|
+
const message = error48 instanceof Error ? error48.message : String(error48);
|
|
84053
|
+
if (/Unknown session/i.test(message)) return 404;
|
|
84054
|
+
if (/not running|unavailable/i.test(message)) return 409;
|
|
84055
|
+
if (/Unsupported named key|keys must|text must|JSON|body too large/i.test(message)) return 400;
|
|
84056
|
+
return 500;
|
|
84057
|
+
}
|
|
84058
|
+
async function handleRawTerminalHttpRequest(options) {
|
|
84059
|
+
const { req, res, parsedUrl, service } = options;
|
|
84060
|
+
const route = parseRawTerminalPath(parsedUrl.pathname);
|
|
84061
|
+
if (!route) return false;
|
|
84062
|
+
if (!isLoopbackRequest(req)) {
|
|
84063
|
+
writeJson(res, 403, { error: "Raw terminal API is available only from localhost." });
|
|
84064
|
+
return true;
|
|
84065
|
+
}
|
|
84066
|
+
const method = req.method || "GET";
|
|
84067
|
+
try {
|
|
84068
|
+
if (route.action === "screen" && method === "GET") {
|
|
84069
|
+
const format = parsedUrl.searchParams.get("format") || "text";
|
|
84070
|
+
if (format !== "text") {
|
|
84071
|
+
writeJson(res, 400, { error: "Phase 2 supports only format=text." });
|
|
84072
|
+
return true;
|
|
84073
|
+
}
|
|
84074
|
+
const text = await service.readScreen(route.sessionId);
|
|
84075
|
+
res.writeHead(200, { "Content-Type": "text/plain; charset=utf-8" });
|
|
84076
|
+
res.end(text);
|
|
84077
|
+
return true;
|
|
84078
|
+
}
|
|
84079
|
+
if (route.action === "state" && method === "GET") {
|
|
84080
|
+
writeJson(res, 200, await service.readState(route.sessionId));
|
|
84081
|
+
return true;
|
|
84082
|
+
}
|
|
84083
|
+
if (route.action === "input" && method === "POST") {
|
|
84084
|
+
const body = await readJsonBody(req);
|
|
84085
|
+
if (typeof body.text !== "string") throw new Error("text must be a string");
|
|
84086
|
+
await service.writeInput(route.sessionId, body.text);
|
|
84087
|
+
writeJson(res, 200, { success: true });
|
|
84088
|
+
return true;
|
|
84089
|
+
}
|
|
84090
|
+
if (route.action === "keys" && method === "POST") {
|
|
84091
|
+
const body = await readJsonBody(req);
|
|
84092
|
+
if (!Array.isArray(body.keys) || !body.keys.every((key) => typeof key === "string")) {
|
|
84093
|
+
throw new Error("keys must be an array of named key strings");
|
|
84094
|
+
}
|
|
84095
|
+
await service.writeKeys(route.sessionId, body.keys);
|
|
84096
|
+
writeJson(res, 200, { success: true });
|
|
84097
|
+
return true;
|
|
84098
|
+
}
|
|
84099
|
+
writeJson(res, 405, { error: "Method not allowed" });
|
|
84100
|
+
return true;
|
|
84101
|
+
} catch (error48) {
|
|
84102
|
+
const message = error48 instanceof Error ? error48.message : String(error48);
|
|
84103
|
+
writeJson(res, errorStatus(error48), { error: message });
|
|
84104
|
+
return true;
|
|
84105
|
+
}
|
|
84106
|
+
}
|
|
84107
|
+
|
|
84108
|
+
// src/index.ts
|
|
83808
84109
|
var DEFAULT_PORT = 3847;
|
|
83809
84110
|
var STATUS_INTERVAL = 2e3;
|
|
83810
84111
|
var CHAT_OUTPUT_ACTIVITY_HOT_MS = import_daemon_core4.DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS;
|
|
@@ -84027,6 +84328,27 @@ var StandaloneServer = class {
|
|
|
84027
84328
|
devServer = null;
|
|
84028
84329
|
sessionHostEndpoint = null;
|
|
84029
84330
|
sessionHostControl = null;
|
|
84331
|
+
rawTerminalService() {
|
|
84332
|
+
const endpoint = this.sessionHostEndpoint || void 0;
|
|
84333
|
+
return {
|
|
84334
|
+
readScreen: (sessionId) => (0, import_daemon_core2.withRawTerminalAttachment)(
|
|
84335
|
+
{ endpoint, sessionId, mode: "read" },
|
|
84336
|
+
(attachment) => attachment.readScreenText()
|
|
84337
|
+
),
|
|
84338
|
+
readState: (sessionId) => (0, import_daemon_core2.withRawTerminalAttachment)(
|
|
84339
|
+
{ endpoint, sessionId, mode: "read" },
|
|
84340
|
+
(attachment) => attachment.readState()
|
|
84341
|
+
),
|
|
84342
|
+
writeInput: (sessionId, text) => (0, import_daemon_core2.withRawTerminalAttachment)(
|
|
84343
|
+
{ endpoint, sessionId, mode: "write" },
|
|
84344
|
+
(attachment) => attachment.writeInput(text)
|
|
84345
|
+
),
|
|
84346
|
+
writeKeys: (sessionId, keys) => (0, import_daemon_core2.withRawTerminalAttachment)(
|
|
84347
|
+
{ endpoint, sessionId, mode: "write" },
|
|
84348
|
+
(attachment) => attachment.writeKeys(keys)
|
|
84349
|
+
)
|
|
84350
|
+
};
|
|
84351
|
+
}
|
|
84030
84352
|
isRecoverableSessionHostError(error48) {
|
|
84031
84353
|
const message = error48 instanceof Error ? error48.message : String(error48);
|
|
84032
84354
|
return message.includes("ECONNREFUSED") || message.includes("ENOENT") || message.includes("Session host socket unavailable");
|
|
@@ -84589,6 +84911,19 @@ var StandaloneServer = class {
|
|
|
84589
84911
|
return;
|
|
84590
84912
|
}
|
|
84591
84913
|
const apiPath = url2.startsWith("/api/v1/") ? url2.slice(7) : null;
|
|
84914
|
+
if (isRawTerminalApiPath(parsedUrl.pathname)) {
|
|
84915
|
+
void handleRawTerminalHttpRequest({
|
|
84916
|
+
req,
|
|
84917
|
+
res,
|
|
84918
|
+
parsedUrl,
|
|
84919
|
+
service: this.rawTerminalService()
|
|
84920
|
+
}).catch((error48) => {
|
|
84921
|
+
if (res.headersSent) return;
|
|
84922
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
84923
|
+
res.end(JSON.stringify({ error: error48?.message || String(error48) }));
|
|
84924
|
+
});
|
|
84925
|
+
return;
|
|
84926
|
+
}
|
|
84592
84927
|
if (apiPath === "/status" && method === "GET") {
|
|
84593
84928
|
const status = this.getStatus(getSharedSnapshot());
|
|
84594
84929
|
res.writeHead(200, { "Content-Type": "application/json" });
|