@adhdev/daemon-standalone 0.9.82-rc.167 → 0.9.82-rc.169
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 +394 -22
- 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",
|
|
@@ -44755,6 +44756,10 @@ ${lastSnapshot}`;
|
|
|
44755
44756
|
"type": "integer",
|
|
44756
44757
|
"minimum": 1,
|
|
44757
44758
|
"default": 2
|
|
44759
|
+
},
|
|
44760
|
+
"continuation_lines": {
|
|
44761
|
+
"type": "boolean",
|
|
44762
|
+
"default": false
|
|
44758
44763
|
}
|
|
44759
44764
|
}
|
|
44760
44765
|
}
|
|
@@ -46907,6 +46912,7 @@ ${lastSnapshot}`;
|
|
|
46907
46912
|
ProviderCliAdapter: () => ProviderCliAdapter,
|
|
46908
46913
|
ProviderInstanceManager: () => ProviderInstanceManager,
|
|
46909
46914
|
ProviderLoader: () => ProviderLoader,
|
|
46915
|
+
RawTerminalAttachment: () => RawTerminalAttachment,
|
|
46910
46916
|
STANDALONE_CDP_SCAN_INTERVAL_MS: () => STANDALONE_CDP_SCAN_INTERVAL_MS2,
|
|
46911
46917
|
SessionHostPtyTransportFactory: () => SessionHostPtyTransportFactory2,
|
|
46912
46918
|
SpecDriver: () => SpecDriver,
|
|
@@ -47057,6 +47063,8 @@ ${lastSnapshot}`;
|
|
|
47057
47063
|
markSetupComplete: () => markSetupComplete,
|
|
47058
47064
|
markStaleDirectDispatches: () => markStaleDirectDispatches,
|
|
47059
47065
|
maybeRunDaemonUpgradeHelperFromEnv: () => maybeRunDaemonUpgradeHelperFromEnv2,
|
|
47066
|
+
namedKeyToAnsi: () => namedKeyToAnsi,
|
|
47067
|
+
namedKeysToAnsi: () => namedKeysToAnsi,
|
|
47060
47068
|
normalizeActiveChatData: () => normalizeActiveChatData,
|
|
47061
47069
|
normalizeChatMessage: () => normalizeChatMessage,
|
|
47062
47070
|
normalizeChatMessageKind: () => normalizeChatMessageKind,
|
|
@@ -47137,7 +47145,8 @@ ${lastSnapshot}`;
|
|
|
47137
47145
|
validateCliProviderManifest: () => validateCliProviderManifest,
|
|
47138
47146
|
validateMeshRefineConfig: () => validateMeshRefineConfig,
|
|
47139
47147
|
validateMeshTaskModeRequest: () => validateMeshTaskModeRequest,
|
|
47140
|
-
validateMeshWorktreeBootstrapConfig: () => validateMeshWorktreeBootstrapConfig
|
|
47148
|
+
validateMeshWorktreeBootstrapConfig: () => validateMeshWorktreeBootstrapConfig,
|
|
47149
|
+
withRawTerminalAttachment: () => withRawTerminalAttachment2
|
|
47141
47150
|
});
|
|
47142
47151
|
module2.exports = __toCommonJS2(index_exports);
|
|
47143
47152
|
init_repo_mesh_types();
|
|
@@ -54850,6 +54859,11 @@ ${effect.notification.body || ""}`.trim();
|
|
|
54850
54859
|
}
|
|
54851
54860
|
return { index: -1, label: "" };
|
|
54852
54861
|
}
|
|
54862
|
+
function pickAutoApprovalButton(buttons) {
|
|
54863
|
+
const labels = (buttons || []).map((button) => String(button || "").trim());
|
|
54864
|
+
const index = labels.findIndex(Boolean);
|
|
54865
|
+
return index >= 0 ? { index, label: labels[index] } : { index: -1, label: "" };
|
|
54866
|
+
}
|
|
54853
54867
|
function formatAutoApprovalMessage(modalMessage, buttonLabel) {
|
|
54854
54868
|
const lines = [`Auto-approved${buttonLabel ? `: ${buttonLabel}` : ""}`];
|
|
54855
54869
|
const cleanMessage = String(modalMessage || "").trim();
|
|
@@ -55422,7 +55436,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
55422
55436
|
}
|
|
55423
55437
|
this.autoApproveBusy = true;
|
|
55424
55438
|
try {
|
|
55425
|
-
const { label: targetButton } =
|
|
55439
|
+
const { label: targetButton } = pickAutoApprovalButton(_chatData?.activeModal?.buttons);
|
|
55426
55440
|
const script = scriptFn({ action: "approve", button: targetButton, buttonText: targetButton });
|
|
55427
55441
|
if (!script) return;
|
|
55428
55442
|
const now = Date.now();
|
|
@@ -61826,6 +61840,10 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
61826
61840
|
const flags = ref.flags ?? "gm";
|
|
61827
61841
|
return new RegExp(ref.pattern, flags.includes("g") ? flags : flags + "g");
|
|
61828
61842
|
}
|
|
61843
|
+
function compileLinePattern(ref) {
|
|
61844
|
+
const flags = (ref.flags ?? "m").replace(/g/g, "");
|
|
61845
|
+
return new RegExp(ref.pattern, flags);
|
|
61846
|
+
}
|
|
61829
61847
|
function matchState(state, sections, fullScreen, trace) {
|
|
61830
61848
|
const haystack = sectionText(sections, state.when.section, fullScreen);
|
|
61831
61849
|
const re = compileRegex(state.when);
|
|
@@ -61846,16 +61864,41 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
61846
61864
|
function extractModal(state, sections, fullScreen, title, trace) {
|
|
61847
61865
|
if (!state.modal_buttons) return null;
|
|
61848
61866
|
const hay = sectionText(sections, state.modal_buttons.section, fullScreen);
|
|
61849
|
-
const re = compilePattern(state.modal_buttons);
|
|
61850
61867
|
const buttons = [];
|
|
61851
|
-
|
|
61852
|
-
|
|
61853
|
-
const
|
|
61854
|
-
|
|
61855
|
-
|
|
61856
|
-
|
|
61857
|
-
|
|
61858
|
-
|
|
61868
|
+
if (state.modal_buttons.continuation_lines) {
|
|
61869
|
+
const re = compileLinePattern(state.modal_buttons);
|
|
61870
|
+
const lines = hay.split("\n");
|
|
61871
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
61872
|
+
const m = re.exec(lines[i]);
|
|
61873
|
+
if (!m) continue;
|
|
61874
|
+
const idx = Number(m[1]);
|
|
61875
|
+
let label = String(m[2] ?? "").trim();
|
|
61876
|
+
if (!Number.isFinite(idx) || idx <= 0 || !label) continue;
|
|
61877
|
+
let j = i + 1;
|
|
61878
|
+
while (j < lines.length) {
|
|
61879
|
+
const next = lines[j];
|
|
61880
|
+
if (!next.trim()) break;
|
|
61881
|
+
if (re.test(next)) break;
|
|
61882
|
+
if (!/^\s+/.test(next)) break;
|
|
61883
|
+
label += " " + next.trim();
|
|
61884
|
+
j += 1;
|
|
61885
|
+
}
|
|
61886
|
+
if (buttons.some((b) => b.index === idx)) continue;
|
|
61887
|
+
const key = state.modal_buttons.key_for_index.replace(/\{index\}/g, String(idx));
|
|
61888
|
+
buttons.push({ index: idx, label, key });
|
|
61889
|
+
i = j - 1;
|
|
61890
|
+
}
|
|
61891
|
+
} else {
|
|
61892
|
+
const re = compilePattern(state.modal_buttons);
|
|
61893
|
+
let m;
|
|
61894
|
+
while ((m = re.exec(hay)) !== null) {
|
|
61895
|
+
const idx = Number(m[1]);
|
|
61896
|
+
const label = String(m[2] ?? "").trim();
|
|
61897
|
+
if (!Number.isFinite(idx) || idx <= 0 || !label) continue;
|
|
61898
|
+
if (buttons.some((b) => b.index === idx)) continue;
|
|
61899
|
+
const key = state.modal_buttons.key_for_index.replace(/\{index\}/g, String(idx));
|
|
61900
|
+
buttons.push({ index: idx, label, key });
|
|
61901
|
+
}
|
|
61859
61902
|
}
|
|
61860
61903
|
buttons.sort((a, b) => a.index - b.index);
|
|
61861
61904
|
const minCount = state.modal_buttons.min_count ?? 2;
|
|
@@ -63351,7 +63394,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
63351
63394
|
if (!modal || buttons.length === 0) {
|
|
63352
63395
|
return autoApproveActive;
|
|
63353
63396
|
}
|
|
63354
|
-
const { index: buttonIndex, label: buttonLabel } =
|
|
63397
|
+
const { index: buttonIndex, label: buttonLabel } = pickAutoApprovalButton(buttons);
|
|
63355
63398
|
if (buttonIndex < 0) {
|
|
63356
63399
|
return autoApproveActive;
|
|
63357
63400
|
}
|
|
@@ -73995,9 +74038,9 @@ ${e?.stderr || ""}`
|
|
|
73995
74038
|
});
|
|
73996
74039
|
let node;
|
|
73997
74040
|
if (meshRecord.inline) {
|
|
73998
|
-
const { randomUUID:
|
|
74041
|
+
const { randomUUID: randomUUID11 } = await import("crypto");
|
|
73999
74042
|
node = {
|
|
74000
|
-
id: `node_${
|
|
74043
|
+
id: `node_${randomUUID11().replace(/-/g, "")}`,
|
|
74001
74044
|
workspace: result.worktreePath,
|
|
74002
74045
|
repoRoot: result.worktreePath,
|
|
74003
74046
|
daemonId: sourceNode.daemonId,
|
|
@@ -76217,8 +76260,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
76217
76260
|
if (stream?.status === "waiting_approval") {
|
|
76218
76261
|
const autoApprove = providerLoader.getSettings(stream.agentType).autoApprove !== false;
|
|
76219
76262
|
if (autoApprove && resolvedActiveSessionId) {
|
|
76220
|
-
const
|
|
76221
|
-
const { label: buttonLabel } = pickApprovalButton(stream.activeModal?.buttons, provider);
|
|
76263
|
+
const { label: buttonLabel } = pickAutoApprovalButton(stream.activeModal?.buttons);
|
|
76222
76264
|
const approved = await agentStreamManager.resolveSessionAction(cdp, resolvedActiveSessionId, "approve", buttonLabel);
|
|
76223
76265
|
if (approved) {
|
|
76224
76266
|
const effectId = [
|
|
@@ -82310,6 +82352,199 @@ data: ${JSON.stringify(msg.data)}
|
|
|
82310
82352
|
});
|
|
82311
82353
|
}
|
|
82312
82354
|
};
|
|
82355
|
+
var import_crypto6 = require("crypto");
|
|
82356
|
+
var import_session_host_core4 = require_dist2();
|
|
82357
|
+
var BASE_KEY_SEQUENCES = {
|
|
82358
|
+
enter: "\r",
|
|
82359
|
+
escape: "\x1B",
|
|
82360
|
+
tab: " ",
|
|
82361
|
+
backspace: "\x7F",
|
|
82362
|
+
up: "\x1B[A",
|
|
82363
|
+
down: "\x1B[B",
|
|
82364
|
+
right: "\x1B[C",
|
|
82365
|
+
left: "\x1B[D",
|
|
82366
|
+
home: "\x1B[H",
|
|
82367
|
+
end: "\x1B[F",
|
|
82368
|
+
pageup: "\x1B[5~",
|
|
82369
|
+
pagedown: "\x1B[6~",
|
|
82370
|
+
space: " ",
|
|
82371
|
+
f1: "\x1BOP",
|
|
82372
|
+
f2: "\x1BOQ",
|
|
82373
|
+
f3: "\x1BOR",
|
|
82374
|
+
f4: "\x1BOS",
|
|
82375
|
+
f5: "\x1B[15~",
|
|
82376
|
+
f6: "\x1B[17~",
|
|
82377
|
+
f7: "\x1B[18~",
|
|
82378
|
+
f8: "\x1B[19~",
|
|
82379
|
+
f9: "\x1B[20~",
|
|
82380
|
+
f10: "\x1B[21~",
|
|
82381
|
+
f11: "\x1B[23~",
|
|
82382
|
+
f12: "\x1B[24~"
|
|
82383
|
+
};
|
|
82384
|
+
var SHIFTED_CSI_KEYS = {
|
|
82385
|
+
up: "\x1B[1;2A",
|
|
82386
|
+
down: "\x1B[1;2B",
|
|
82387
|
+
right: "\x1B[1;2C",
|
|
82388
|
+
left: "\x1B[1;2D",
|
|
82389
|
+
home: "\x1B[1;2H",
|
|
82390
|
+
end: "\x1B[1;2F",
|
|
82391
|
+
pageup: "\x1B[5;2~",
|
|
82392
|
+
pagedown: "\x1B[6;2~",
|
|
82393
|
+
f1: "\x1B[1;2P",
|
|
82394
|
+
f2: "\x1B[1;2Q",
|
|
82395
|
+
f3: "\x1B[1;2R",
|
|
82396
|
+
f4: "\x1B[1;2S",
|
|
82397
|
+
f5: "\x1B[15;2~",
|
|
82398
|
+
f6: "\x1B[17;2~",
|
|
82399
|
+
f7: "\x1B[18;2~",
|
|
82400
|
+
f8: "\x1B[19;2~",
|
|
82401
|
+
f9: "\x1B[20;2~",
|
|
82402
|
+
f10: "\x1B[21;2~",
|
|
82403
|
+
f11: "\x1B[23;2~",
|
|
82404
|
+
f12: "\x1B[24;2~"
|
|
82405
|
+
};
|
|
82406
|
+
function isLowercaseLetter(value) {
|
|
82407
|
+
return /^[a-z]$/.test(value);
|
|
82408
|
+
}
|
|
82409
|
+
function encodeControlLetter(letter) {
|
|
82410
|
+
return String.fromCharCode(letter.charCodeAt(0) - 96);
|
|
82411
|
+
}
|
|
82412
|
+
function encodeShiftedKey(key) {
|
|
82413
|
+
if (isLowercaseLetter(key)) return key.toUpperCase();
|
|
82414
|
+
if (key.startsWith("ctrl+") && isLowercaseLetter(key.slice(5))) {
|
|
82415
|
+
return encodeControlLetter(key.slice(5));
|
|
82416
|
+
}
|
|
82417
|
+
if (key.startsWith("alt+") && isLowercaseLetter(key.slice(4))) {
|
|
82418
|
+
return `\x1B${key.slice(4).toUpperCase()}`;
|
|
82419
|
+
}
|
|
82420
|
+
if (key === "tab") return "\x1B[Z";
|
|
82421
|
+
if (key in SHIFTED_CSI_KEYS) return SHIFTED_CSI_KEYS[key];
|
|
82422
|
+
if (key in BASE_KEY_SEQUENCES) return BASE_KEY_SEQUENCES[key];
|
|
82423
|
+
throw new Error(`Unsupported named key: shift+${key}`);
|
|
82424
|
+
}
|
|
82425
|
+
function namedKeyToAnsi(key) {
|
|
82426
|
+
const normalized = String(key || "").trim().toLowerCase();
|
|
82427
|
+
if (normalized in BASE_KEY_SEQUENCES) return BASE_KEY_SEQUENCES[normalized];
|
|
82428
|
+
if (normalized.startsWith("ctrl+") && isLowercaseLetter(normalized.slice(5))) {
|
|
82429
|
+
return encodeControlLetter(normalized.slice(5));
|
|
82430
|
+
}
|
|
82431
|
+
if (normalized.startsWith("alt+") && isLowercaseLetter(normalized.slice(4))) {
|
|
82432
|
+
return `\x1B${normalized.slice(4)}`;
|
|
82433
|
+
}
|
|
82434
|
+
if (normalized.startsWith("shift+")) return encodeShiftedKey(normalized.slice(6));
|
|
82435
|
+
throw new Error(`Unsupported named key: ${key}`);
|
|
82436
|
+
}
|
|
82437
|
+
function namedKeysToAnsi(keys) {
|
|
82438
|
+
if (!Array.isArray(keys)) throw new Error("keys must be an array");
|
|
82439
|
+
return keys.map(namedKeyToAnsi).join("");
|
|
82440
|
+
}
|
|
82441
|
+
var RawTerminalAttachment = class _RawTerminalAttachment {
|
|
82442
|
+
constructor(sessionId, clientId, mode, client) {
|
|
82443
|
+
this.sessionId = sessionId;
|
|
82444
|
+
this.clientId = clientId;
|
|
82445
|
+
this.mode = mode;
|
|
82446
|
+
this.client = client;
|
|
82447
|
+
}
|
|
82448
|
+
closed = false;
|
|
82449
|
+
static async attach(options) {
|
|
82450
|
+
const sessionId = String(options.sessionId || "").trim();
|
|
82451
|
+
if (!sessionId) throw new Error("sessionId is required");
|
|
82452
|
+
const mode = options.mode || "read";
|
|
82453
|
+
const clientId = options.clientId || `raw-terminal-${process.pid}-${(0, import_crypto6.randomUUID)().slice(0, 8)}`;
|
|
82454
|
+
const client = options.client || new import_session_host_core4.SessionHostClient({ endpoint: options.endpoint });
|
|
82455
|
+
await client.connect();
|
|
82456
|
+
const attachResponse = await client.request({
|
|
82457
|
+
type: "attach_session",
|
|
82458
|
+
payload: {
|
|
82459
|
+
sessionId,
|
|
82460
|
+
clientId,
|
|
82461
|
+
clientType: "web",
|
|
82462
|
+
readOnly: mode === "read"
|
|
82463
|
+
}
|
|
82464
|
+
});
|
|
82465
|
+
if (!attachResponse.success) {
|
|
82466
|
+
await client.close().catch(() => {
|
|
82467
|
+
});
|
|
82468
|
+
throw new Error(attachResponse.error || `Failed to attach terminal session ${sessionId}`);
|
|
82469
|
+
}
|
|
82470
|
+
if (mode === "write") {
|
|
82471
|
+
const ownerResponse = await client.request({
|
|
82472
|
+
type: "acquire_write",
|
|
82473
|
+
payload: {
|
|
82474
|
+
sessionId,
|
|
82475
|
+
clientId,
|
|
82476
|
+
ownerType: "user",
|
|
82477
|
+
force: true
|
|
82478
|
+
}
|
|
82479
|
+
});
|
|
82480
|
+
if (!ownerResponse.success) {
|
|
82481
|
+
await client.request({
|
|
82482
|
+
type: "detach_session",
|
|
82483
|
+
payload: { sessionId, clientId }
|
|
82484
|
+
}).catch(() => ({ success: false }));
|
|
82485
|
+
await client.close().catch(() => {
|
|
82486
|
+
});
|
|
82487
|
+
throw new Error(ownerResponse.error || `Failed to acquire terminal session ${sessionId}`);
|
|
82488
|
+
}
|
|
82489
|
+
}
|
|
82490
|
+
return new _RawTerminalAttachment(sessionId, clientId, mode, client);
|
|
82491
|
+
}
|
|
82492
|
+
async readSnapshot() {
|
|
82493
|
+
const response = await this.client.request({
|
|
82494
|
+
type: "get_terminal_snapshot",
|
|
82495
|
+
payload: { sessionId: this.sessionId }
|
|
82496
|
+
});
|
|
82497
|
+
if (!response.success || !response.result) {
|
|
82498
|
+
throw new Error(response.error || `Terminal screen unavailable for ${this.sessionId}`);
|
|
82499
|
+
}
|
|
82500
|
+
return response.result;
|
|
82501
|
+
}
|
|
82502
|
+
async readScreenText() {
|
|
82503
|
+
return (await this.readSnapshot()).text;
|
|
82504
|
+
}
|
|
82505
|
+
async readState() {
|
|
82506
|
+
return (await this.readSnapshot()).state;
|
|
82507
|
+
}
|
|
82508
|
+
async writeInput(text) {
|
|
82509
|
+
if (this.mode !== "write") throw new Error("Raw terminal attachment is read-only");
|
|
82510
|
+
const response = await this.client.request({
|
|
82511
|
+
type: "send_input",
|
|
82512
|
+
payload: {
|
|
82513
|
+
sessionId: this.sessionId,
|
|
82514
|
+
clientId: this.clientId,
|
|
82515
|
+
data: text
|
|
82516
|
+
}
|
|
82517
|
+
});
|
|
82518
|
+
if (!response.success) throw new Error(response.error || `Failed to write terminal input to ${this.sessionId}`);
|
|
82519
|
+
}
|
|
82520
|
+
async writeKeys(keys) {
|
|
82521
|
+
await this.writeInput(namedKeysToAnsi(keys));
|
|
82522
|
+
}
|
|
82523
|
+
async close() {
|
|
82524
|
+
if (this.closed) return;
|
|
82525
|
+
this.closed = true;
|
|
82526
|
+
if (this.mode === "write") {
|
|
82527
|
+
await this.client.request({
|
|
82528
|
+
type: "release_write",
|
|
82529
|
+
payload: { sessionId: this.sessionId, clientId: this.clientId }
|
|
82530
|
+
}).catch(() => ({ success: false }));
|
|
82531
|
+
}
|
|
82532
|
+
await this.client.request({
|
|
82533
|
+
type: "detach_session",
|
|
82534
|
+
payload: { sessionId: this.sessionId, clientId: this.clientId }
|
|
82535
|
+
}).catch(() => ({ success: false }));
|
|
82536
|
+
await this.client.close().catch(() => {
|
|
82537
|
+
});
|
|
82538
|
+
}
|
|
82539
|
+
};
|
|
82540
|
+
async function withRawTerminalAttachment2(options, operation) {
|
|
82541
|
+
const attachment = await RawTerminalAttachment.attach(options);
|
|
82542
|
+
try {
|
|
82543
|
+
return await operation(attachment);
|
|
82544
|
+
} finally {
|
|
82545
|
+
await attachment.close();
|
|
82546
|
+
}
|
|
82547
|
+
}
|
|
82313
82548
|
var DEFAULT_SESSION_HOST_APP_NAME = "adhdev";
|
|
82314
82549
|
var DEFAULT_STANDALONE_SESSION_HOST_APP_NAME = "adhdev-standalone";
|
|
82315
82550
|
function getReservedStandaloneNamespaceWarning() {
|
|
@@ -82339,7 +82574,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
82339
82574
|
function resolveSessionHostAppName(options = {}) {
|
|
82340
82575
|
return resolveSessionHostAppNameResolution2(options).appName;
|
|
82341
82576
|
}
|
|
82342
|
-
var
|
|
82577
|
+
var import_session_host_core5 = require_dist2();
|
|
82343
82578
|
var STARTUP_TIMEOUT_MS = DEFAULT_SESSION_HOST_READY_TIMEOUT_MS2;
|
|
82344
82579
|
var STARTUP_POLL_MS = 200;
|
|
82345
82580
|
var SessionHostCompatibilityError = class extends Error {
|
|
@@ -82367,7 +82602,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
82367
82602
|
}
|
|
82368
82603
|
}
|
|
82369
82604
|
async function canConnect(endpoint, requiredRequestTypes = []) {
|
|
82370
|
-
const client = new
|
|
82605
|
+
const client = new import_session_host_core5.SessionHostClient({ endpoint });
|
|
82371
82606
|
try {
|
|
82372
82607
|
await client.connect();
|
|
82373
82608
|
await assertRequiredRequestTypes(client, requiredRequestTypes);
|
|
@@ -82389,7 +82624,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
82389
82624
|
throw new Error(`Session host did not become ready within ${timeoutMs}ms`);
|
|
82390
82625
|
}
|
|
82391
82626
|
async function ensureSessionHostReady2(options) {
|
|
82392
|
-
const endpoint = (0,
|
|
82627
|
+
const endpoint = (0, import_session_host_core5.getDefaultSessionHostEndpoint)(options.appName || "adhdev");
|
|
82393
82628
|
const requiredRequestTypes = options.requiredRequestTypes || [];
|
|
82394
82629
|
if (await canConnect(endpoint, requiredRequestTypes)) return endpoint;
|
|
82395
82630
|
options.spawnHost();
|
|
@@ -82397,7 +82632,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
82397
82632
|
return endpoint;
|
|
82398
82633
|
}
|
|
82399
82634
|
async function listHostedCliRuntimes2(endpoint) {
|
|
82400
|
-
const client = new
|
|
82635
|
+
const client = new import_session_host_core5.SessionHostClient({ endpoint });
|
|
82401
82636
|
try {
|
|
82402
82637
|
const response = await client.request({
|
|
82403
82638
|
type: "list_sessions",
|
|
@@ -83396,7 +83631,7 @@ async function ensureSessionHostReady() {
|
|
|
83396
83631
|
appName: SESSION_HOST_APP_NAME,
|
|
83397
83632
|
spawnHost,
|
|
83398
83633
|
timeoutMs: SESSION_HOST_START_TIMEOUT_MS,
|
|
83399
|
-
requiredRequestTypes: ["delete_session"]
|
|
83634
|
+
requiredRequestTypes: ["delete_session", "get_terminal_snapshot"]
|
|
83400
83635
|
});
|
|
83401
83636
|
} catch (error48) {
|
|
83402
83637
|
stopSessionHost();
|
|
@@ -83404,7 +83639,7 @@ async function ensureSessionHostReady() {
|
|
|
83404
83639
|
appName: SESSION_HOST_APP_NAME,
|
|
83405
83640
|
spawnHost,
|
|
83406
83641
|
timeoutMs: SESSION_HOST_START_TIMEOUT_MS,
|
|
83407
|
-
requiredRequestTypes: ["delete_session"]
|
|
83642
|
+
requiredRequestTypes: ["delete_session", "get_terminal_snapshot"]
|
|
83408
83643
|
}).catch((retryError) => {
|
|
83409
83644
|
const initialMessage = error48 instanceof Error ? error48.message : String(error48);
|
|
83410
83645
|
const retryMessage = retryError instanceof Error ? retryError.message : String(retryError);
|
|
@@ -83805,6 +84040,109 @@ async function getWorkspaceSocketInfo(workspaceName) {
|
|
|
83805
84040
|
|
|
83806
84041
|
// src/index.ts
|
|
83807
84042
|
var import_daemon_core4 = __toESM(require_dist3());
|
|
84043
|
+
|
|
84044
|
+
// src/raw-terminal-http.ts
|
|
84045
|
+
function parseRawTerminalPath(pathname) {
|
|
84046
|
+
const match = /^\/api\/v1\/sessions\/([^/]+)\/(screen|state|input|keys)$/.exec(pathname);
|
|
84047
|
+
if (!match) return null;
|
|
84048
|
+
try {
|
|
84049
|
+
const sessionId = decodeURIComponent(match[1]).trim();
|
|
84050
|
+
return sessionId ? { sessionId, action: match[2] } : null;
|
|
84051
|
+
} catch {
|
|
84052
|
+
return null;
|
|
84053
|
+
}
|
|
84054
|
+
}
|
|
84055
|
+
function isRawTerminalApiPath(pathname) {
|
|
84056
|
+
return parseRawTerminalPath(pathname) !== null;
|
|
84057
|
+
}
|
|
84058
|
+
function isLoopbackAddress(address) {
|
|
84059
|
+
if (!address) return false;
|
|
84060
|
+
const normalized = address.toLowerCase().split("%", 1)[0];
|
|
84061
|
+
return normalized === "127.0.0.1" || normalized.startsWith("127.") || normalized === "::1" || normalized === "::ffff:127.0.0.1" || normalized.startsWith("::ffff:127.");
|
|
84062
|
+
}
|
|
84063
|
+
function isLoopbackRequest(req) {
|
|
84064
|
+
return isLoopbackAddress(req.socket.remoteAddress);
|
|
84065
|
+
}
|
|
84066
|
+
async function readJsonBody(req) {
|
|
84067
|
+
return await new Promise((resolve2, reject) => {
|
|
84068
|
+
let body = "";
|
|
84069
|
+
req.setEncoding("utf8");
|
|
84070
|
+
req.on("data", (chunk) => {
|
|
84071
|
+
body += chunk;
|
|
84072
|
+
if (body.length > 64 * 1024) reject(new Error("Request body too large"));
|
|
84073
|
+
});
|
|
84074
|
+
req.on("end", () => {
|
|
84075
|
+
try {
|
|
84076
|
+
resolve2(body ? JSON.parse(body) : {});
|
|
84077
|
+
} catch (error48) {
|
|
84078
|
+
reject(error48);
|
|
84079
|
+
}
|
|
84080
|
+
});
|
|
84081
|
+
req.on("error", reject);
|
|
84082
|
+
});
|
|
84083
|
+
}
|
|
84084
|
+
function writeJson(res, statusCode, value) {
|
|
84085
|
+
res.writeHead(statusCode, { "Content-Type": "application/json" });
|
|
84086
|
+
res.end(JSON.stringify(value));
|
|
84087
|
+
}
|
|
84088
|
+
function errorStatus(error48) {
|
|
84089
|
+
const message = error48 instanceof Error ? error48.message : String(error48);
|
|
84090
|
+
if (/Unknown session/i.test(message)) return 404;
|
|
84091
|
+
if (/not running|unavailable/i.test(message)) return 409;
|
|
84092
|
+
if (/Unsupported named key|keys must|text must|JSON|body too large/i.test(message)) return 400;
|
|
84093
|
+
return 500;
|
|
84094
|
+
}
|
|
84095
|
+
async function handleRawTerminalHttpRequest(options) {
|
|
84096
|
+
const { req, res, parsedUrl, service } = options;
|
|
84097
|
+
const route = parseRawTerminalPath(parsedUrl.pathname);
|
|
84098
|
+
if (!route) return false;
|
|
84099
|
+
if (!isLoopbackRequest(req)) {
|
|
84100
|
+
writeJson(res, 403, { error: "Raw terminal API is available only from localhost." });
|
|
84101
|
+
return true;
|
|
84102
|
+
}
|
|
84103
|
+
const method = req.method || "GET";
|
|
84104
|
+
try {
|
|
84105
|
+
if (route.action === "screen" && method === "GET") {
|
|
84106
|
+
const format = parsedUrl.searchParams.get("format") || "text";
|
|
84107
|
+
if (format !== "text") {
|
|
84108
|
+
writeJson(res, 400, { error: "Phase 2 supports only format=text." });
|
|
84109
|
+
return true;
|
|
84110
|
+
}
|
|
84111
|
+
const text = await service.readScreen(route.sessionId);
|
|
84112
|
+
res.writeHead(200, { "Content-Type": "text/plain; charset=utf-8" });
|
|
84113
|
+
res.end(text);
|
|
84114
|
+
return true;
|
|
84115
|
+
}
|
|
84116
|
+
if (route.action === "state" && method === "GET") {
|
|
84117
|
+
writeJson(res, 200, await service.readState(route.sessionId));
|
|
84118
|
+
return true;
|
|
84119
|
+
}
|
|
84120
|
+
if (route.action === "input" && method === "POST") {
|
|
84121
|
+
const body = await readJsonBody(req);
|
|
84122
|
+
if (typeof body.text !== "string") throw new Error("text must be a string");
|
|
84123
|
+
await service.writeInput(route.sessionId, body.text);
|
|
84124
|
+
writeJson(res, 200, { success: true });
|
|
84125
|
+
return true;
|
|
84126
|
+
}
|
|
84127
|
+
if (route.action === "keys" && method === "POST") {
|
|
84128
|
+
const body = await readJsonBody(req);
|
|
84129
|
+
if (!Array.isArray(body.keys) || !body.keys.every((key) => typeof key === "string")) {
|
|
84130
|
+
throw new Error("keys must be an array of named key strings");
|
|
84131
|
+
}
|
|
84132
|
+
await service.writeKeys(route.sessionId, body.keys);
|
|
84133
|
+
writeJson(res, 200, { success: true });
|
|
84134
|
+
return true;
|
|
84135
|
+
}
|
|
84136
|
+
writeJson(res, 405, { error: "Method not allowed" });
|
|
84137
|
+
return true;
|
|
84138
|
+
} catch (error48) {
|
|
84139
|
+
const message = error48 instanceof Error ? error48.message : String(error48);
|
|
84140
|
+
writeJson(res, errorStatus(error48), { error: message });
|
|
84141
|
+
return true;
|
|
84142
|
+
}
|
|
84143
|
+
}
|
|
84144
|
+
|
|
84145
|
+
// src/index.ts
|
|
83808
84146
|
var DEFAULT_PORT = 3847;
|
|
83809
84147
|
var STATUS_INTERVAL = 2e3;
|
|
83810
84148
|
var CHAT_OUTPUT_ACTIVITY_HOT_MS = import_daemon_core4.DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS;
|
|
@@ -84027,6 +84365,27 @@ var StandaloneServer = class {
|
|
|
84027
84365
|
devServer = null;
|
|
84028
84366
|
sessionHostEndpoint = null;
|
|
84029
84367
|
sessionHostControl = null;
|
|
84368
|
+
rawTerminalService() {
|
|
84369
|
+
const endpoint = this.sessionHostEndpoint || void 0;
|
|
84370
|
+
return {
|
|
84371
|
+
readScreen: (sessionId) => (0, import_daemon_core2.withRawTerminalAttachment)(
|
|
84372
|
+
{ endpoint, sessionId, mode: "read" },
|
|
84373
|
+
(attachment) => attachment.readScreenText()
|
|
84374
|
+
),
|
|
84375
|
+
readState: (sessionId) => (0, import_daemon_core2.withRawTerminalAttachment)(
|
|
84376
|
+
{ endpoint, sessionId, mode: "read" },
|
|
84377
|
+
(attachment) => attachment.readState()
|
|
84378
|
+
),
|
|
84379
|
+
writeInput: (sessionId, text) => (0, import_daemon_core2.withRawTerminalAttachment)(
|
|
84380
|
+
{ endpoint, sessionId, mode: "write" },
|
|
84381
|
+
(attachment) => attachment.writeInput(text)
|
|
84382
|
+
),
|
|
84383
|
+
writeKeys: (sessionId, keys) => (0, import_daemon_core2.withRawTerminalAttachment)(
|
|
84384
|
+
{ endpoint, sessionId, mode: "write" },
|
|
84385
|
+
(attachment) => attachment.writeKeys(keys)
|
|
84386
|
+
)
|
|
84387
|
+
};
|
|
84388
|
+
}
|
|
84030
84389
|
isRecoverableSessionHostError(error48) {
|
|
84031
84390
|
const message = error48 instanceof Error ? error48.message : String(error48);
|
|
84032
84391
|
return message.includes("ECONNREFUSED") || message.includes("ENOENT") || message.includes("Session host socket unavailable");
|
|
@@ -84589,6 +84948,19 @@ var StandaloneServer = class {
|
|
|
84589
84948
|
return;
|
|
84590
84949
|
}
|
|
84591
84950
|
const apiPath = url2.startsWith("/api/v1/") ? url2.slice(7) : null;
|
|
84951
|
+
if (isRawTerminalApiPath(parsedUrl.pathname)) {
|
|
84952
|
+
void handleRawTerminalHttpRequest({
|
|
84953
|
+
req,
|
|
84954
|
+
res,
|
|
84955
|
+
parsedUrl,
|
|
84956
|
+
service: this.rawTerminalService()
|
|
84957
|
+
}).catch((error48) => {
|
|
84958
|
+
if (res.headersSent) return;
|
|
84959
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
84960
|
+
res.end(JSON.stringify({ error: error48?.message || String(error48) }));
|
|
84961
|
+
});
|
|
84962
|
+
return;
|
|
84963
|
+
}
|
|
84592
84964
|
if (apiPath === "/status" && method === "GET") {
|
|
84593
84965
|
const status = this.getStatus(getSharedSnapshot());
|
|
84594
84966
|
res.writeHead(200, { "Content-Type": "application/json" });
|