adhdev 0.9.55 → 0.9.57
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/cli/index.js +391 -61
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +295 -25
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -13748,6 +13748,12 @@ var init_provider_cli_adapter = __esm({
|
|
|
13748
13748
|
accumulatedRawBuffer = "";
|
|
13749
13749
|
/** Current visible terminal screen snapshot */
|
|
13750
13750
|
terminalScreen = new TerminalScreen(24, 80);
|
|
13751
|
+
static MAX_RESPONSE_BUFFER = 8e3;
|
|
13752
|
+
static MAX_RECENT_OUTPUT_BUFFER = 1e3;
|
|
13753
|
+
responseBufferDroppedChars = 0;
|
|
13754
|
+
recentOutputDroppedChars = 0;
|
|
13755
|
+
accumulatedBufferDroppedChars = 0;
|
|
13756
|
+
accumulatedRawBufferDroppedChars = 0;
|
|
13751
13757
|
/** Max accumulated buffer size. Sized to comfortably hold a single long
|
|
13752
13758
|
* Hermes turn (tool calls + reasoning + final bubble) without the
|
|
13753
13759
|
* rolling window pushing the turn's ╭─ opening line out of view. */
|
|
@@ -13765,6 +13771,23 @@ var init_provider_cli_adapter = __esm({
|
|
|
13765
13771
|
providerResolutionMeta;
|
|
13766
13772
|
static FINISH_RETRY_DELAY_MS = 300;
|
|
13767
13773
|
static MAX_FINISH_RETRIES = 2;
|
|
13774
|
+
getBufferState() {
|
|
13775
|
+
const build = (droppedChars, maxChars) => droppedChars > 0 ? { truncated: true, droppedChars, maxChars } : void 0;
|
|
13776
|
+
const responseBuffer = build(this.responseBufferDroppedChars, _ProviderCliAdapter.MAX_RESPONSE_BUFFER);
|
|
13777
|
+
const recentOutputBuffer = build(this.recentOutputDroppedChars, _ProviderCliAdapter.MAX_RECENT_OUTPUT_BUFFER);
|
|
13778
|
+
const accumulatedBuffer = build(this.accumulatedBufferDroppedChars, _ProviderCliAdapter.MAX_ACCUMULATED_BUFFER);
|
|
13779
|
+
const accumulatedRawBuffer = build(this.accumulatedRawBufferDroppedChars, _ProviderCliAdapter.MAX_ACCUMULATED_BUFFER);
|
|
13780
|
+
if (!responseBuffer && !recentOutputBuffer && !accumulatedBuffer && !accumulatedRawBuffer) return void 0;
|
|
13781
|
+
return {
|
|
13782
|
+
...responseBuffer ? { responseBuffer } : {},
|
|
13783
|
+
...recentOutputBuffer ? { recentOutputBuffer } : {},
|
|
13784
|
+
...accumulatedBuffer ? { accumulatedBuffer } : {},
|
|
13785
|
+
...accumulatedRawBuffer ? { accumulatedRawBuffer } : {}
|
|
13786
|
+
};
|
|
13787
|
+
}
|
|
13788
|
+
recordBoundedAppendDrop(previousLength, appendedLength, nextLength) {
|
|
13789
|
+
return Math.max(0, previousLength + appendedLength - nextLength);
|
|
13790
|
+
}
|
|
13768
13791
|
buildCommittedMessagesActivitySignature() {
|
|
13769
13792
|
const last = this.committedMessages[this.committedMessages.length - 1];
|
|
13770
13793
|
return [
|
|
@@ -14130,7 +14153,9 @@ var init_provider_cli_adapter = __esm({
|
|
|
14130
14153
|
this.scheduleStartupSettleCheck();
|
|
14131
14154
|
}
|
|
14132
14155
|
if (this.isWaitingForResponse && cleanData) {
|
|
14133
|
-
|
|
14156
|
+
const previousResponseLen = this.responseBuffer.length;
|
|
14157
|
+
this.responseBuffer = appendBoundedText(this.responseBuffer, cleanData, _ProviderCliAdapter.MAX_RESPONSE_BUFFER);
|
|
14158
|
+
this.responseBufferDroppedChars += this.recordBoundedAppendDrop(previousResponseLen, cleanData.length, this.responseBuffer.length);
|
|
14134
14159
|
}
|
|
14135
14160
|
if (cleanData.trim()) {
|
|
14136
14161
|
if (this.serverConn) {
|
|
@@ -14139,14 +14164,19 @@ var init_provider_cli_adapter = __esm({
|
|
|
14139
14164
|
this.logBuffer.push({ message: cleanData.trim(), level: "info" });
|
|
14140
14165
|
}
|
|
14141
14166
|
}
|
|
14167
|
+
const prevRecentLen = this.recentOutputBuffer.length;
|
|
14142
14168
|
const prevAccumulatedLen = this.accumulatedBuffer.length;
|
|
14143
14169
|
const prevAccumulatedRawLen = this.accumulatedRawBuffer.length;
|
|
14144
|
-
this.recentOutputBuffer = appendBoundedText(this.recentOutputBuffer, cleanData,
|
|
14170
|
+
this.recentOutputBuffer = appendBoundedText(this.recentOutputBuffer, cleanData, _ProviderCliAdapter.MAX_RECENT_OUTPUT_BUFFER);
|
|
14145
14171
|
this.accumulatedBuffer = appendBoundedText(this.accumulatedBuffer, cleanData, _ProviderCliAdapter.MAX_ACCUMULATED_BUFFER);
|
|
14146
14172
|
this.accumulatedRawBuffer = appendBoundedText(this.accumulatedRawBuffer, rawData, _ProviderCliAdapter.MAX_ACCUMULATED_BUFFER);
|
|
14173
|
+
const droppedRecent = this.recordBoundedAppendDrop(prevRecentLen, cleanData.length, this.recentOutputBuffer.length);
|
|
14174
|
+
const droppedClean = this.recordBoundedAppendDrop(prevAccumulatedLen, cleanData.length, this.accumulatedBuffer.length);
|
|
14175
|
+
const droppedRaw = this.recordBoundedAppendDrop(prevAccumulatedRawLen, rawData.length, this.accumulatedRawBuffer.length);
|
|
14176
|
+
this.recentOutputDroppedChars += droppedRecent;
|
|
14177
|
+
this.accumulatedBufferDroppedChars += droppedClean;
|
|
14178
|
+
this.accumulatedRawBufferDroppedChars += droppedRaw;
|
|
14147
14179
|
if (this.currentTurnScope) {
|
|
14148
|
-
const droppedClean = prevAccumulatedLen + cleanData.length - this.accumulatedBuffer.length;
|
|
14149
|
-
const droppedRaw = prevAccumulatedRawLen + rawData.length - this.accumulatedRawBuffer.length;
|
|
14150
14180
|
if (droppedClean > 0) {
|
|
14151
14181
|
this.currentTurnScope.bufferStart = Math.max(0, this.currentTurnScope.bufferStart - droppedClean);
|
|
14152
14182
|
}
|
|
@@ -14976,13 +15006,15 @@ var init_provider_cli_adapter = __esm({
|
|
|
14976
15006
|
effectiveModal = parsedModal;
|
|
14977
15007
|
}
|
|
14978
15008
|
}
|
|
15009
|
+
const bufferState = this.getBufferState();
|
|
14979
15010
|
return {
|
|
14980
15011
|
status: effectiveStatus,
|
|
14981
15012
|
messages: [...this.committedMessages],
|
|
14982
15013
|
workingDir: this.workingDir,
|
|
14983
15014
|
activeModal: effectiveModal,
|
|
14984
15015
|
errorMessage: this.parseErrorMessage || void 0,
|
|
14985
|
-
errorReason: this.parseErrorMessage ? "parse_error" : void 0
|
|
15016
|
+
errorReason: this.parseErrorMessage ? "parse_error" : void 0,
|
|
15017
|
+
...bufferState ? { bufferState } : {}
|
|
14986
15018
|
};
|
|
14987
15019
|
}
|
|
14988
15020
|
seedCommittedMessages(messages) {
|
|
@@ -15164,10 +15196,12 @@ var init_provider_cli_adapter = __esm({
|
|
|
15164
15196
|
messages: hydratedMessages,
|
|
15165
15197
|
activeModal: parsed.activeModal ?? this.activeModal,
|
|
15166
15198
|
providerSessionId: typeof parsed.providerSessionId === "string" ? parsed.providerSessionId : void 0,
|
|
15199
|
+
...this.getBufferState() ? { bufferState: this.getBufferState() } : {},
|
|
15167
15200
|
...this.providerOwnsTranscript() ? { transcriptAuthority: "provider", coverage: this.shouldUseFullProviderTranscriptContext() ? "full" : "tail" } : {}
|
|
15168
15201
|
};
|
|
15169
15202
|
} else {
|
|
15170
15203
|
const messages = [...this.committedMessages];
|
|
15204
|
+
const bufferState = this.getBufferState();
|
|
15171
15205
|
result = {
|
|
15172
15206
|
id: "cli_session",
|
|
15173
15207
|
status: this.currentStatus,
|
|
@@ -15178,7 +15212,8 @@ var init_provider_cli_adapter = __esm({
|
|
|
15178
15212
|
index: typeof message.index === "number" ? message.index : index,
|
|
15179
15213
|
receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
|
|
15180
15214
|
})),
|
|
15181
|
-
activeModal: this.activeModal
|
|
15215
|
+
activeModal: this.activeModal,
|
|
15216
|
+
...bufferState ? { bufferState } : {}
|
|
15182
15217
|
};
|
|
15183
15218
|
}
|
|
15184
15219
|
const hasVisibleAssistantMessage = Array.isArray(result?.messages) && result.messages.some((message) => message?.role === "assistant" && typeof message?.content === "string" && message.content.trim());
|
|
@@ -34899,7 +34934,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
34899
34934
|
resolvedDir,
|
|
34900
34935
|
resolvedCliArgs,
|
|
34901
34936
|
resolvedProvider,
|
|
34902
|
-
|
|
34937
|
+
this.providerLoader.getSettings(normalizedType),
|
|
34903
34938
|
false,
|
|
34904
34939
|
{
|
|
34905
34940
|
providerSessionId: sessionBinding.providerSessionId,
|
|
@@ -49308,6 +49343,58 @@ var init_server_connection = __esm({
|
|
|
49308
49343
|
onStateChange(callback) {
|
|
49309
49344
|
this.stateChangeCallbacks.push(callback);
|
|
49310
49345
|
}
|
|
49346
|
+
/**
|
|
49347
|
+
* Send a command to another daemon owned by the same user, via server relay.
|
|
49348
|
+
* The server validates ownership before forwarding to the target daemon.
|
|
49349
|
+
*
|
|
49350
|
+
* Returns the command result or throws on timeout / auth failure.
|
|
49351
|
+
*/
|
|
49352
|
+
sendMeshCommand(targetDaemonId, command, args = {}, timeoutMs = 3e4) {
|
|
49353
|
+
return new Promise((resolve19, reject) => {
|
|
49354
|
+
const requestId = `mesh_${Date.now()}_${Math.random().toString(36).substring(2, 8)}`;
|
|
49355
|
+
const timer = setTimeout(() => {
|
|
49356
|
+
this.off("daemon_mesh_result", handler);
|
|
49357
|
+
reject(new Error(`Mesh command timed out after ${timeoutMs}ms`));
|
|
49358
|
+
}, timeoutMs);
|
|
49359
|
+
const handler = (msg) => {
|
|
49360
|
+
if (msg.payload?.requestId !== requestId) return;
|
|
49361
|
+
this.off("daemon_mesh_result", handler);
|
|
49362
|
+
clearTimeout(timer);
|
|
49363
|
+
if (msg.payload?.success === false) {
|
|
49364
|
+
reject(new Error(msg.payload?.error ?? "Mesh command failed"));
|
|
49365
|
+
} else {
|
|
49366
|
+
resolve19(msg.payload?.result);
|
|
49367
|
+
}
|
|
49368
|
+
};
|
|
49369
|
+
this.on("daemon_mesh_result", handler);
|
|
49370
|
+
const sent = this.ws?.readyState === 1 && (() => {
|
|
49371
|
+
try {
|
|
49372
|
+
this.ws.send(JSON.stringify({
|
|
49373
|
+
type: "daemon_mesh_command",
|
|
49374
|
+
requestId,
|
|
49375
|
+
targetDaemonId,
|
|
49376
|
+
command,
|
|
49377
|
+
args,
|
|
49378
|
+
timestamp: Date.now()
|
|
49379
|
+
}));
|
|
49380
|
+
return true;
|
|
49381
|
+
} catch {
|
|
49382
|
+
return false;
|
|
49383
|
+
}
|
|
49384
|
+
})();
|
|
49385
|
+
if (!sent) {
|
|
49386
|
+
clearTimeout(timer);
|
|
49387
|
+
this.off("daemon_mesh_result", handler);
|
|
49388
|
+
reject(new Error("Not connected to server"));
|
|
49389
|
+
}
|
|
49390
|
+
});
|
|
49391
|
+
}
|
|
49392
|
+
off(type, handler) {
|
|
49393
|
+
const handlers = this.messageHandlers.get(type);
|
|
49394
|
+
if (!handlers) return;
|
|
49395
|
+
const idx = handlers.indexOf(handler);
|
|
49396
|
+
if (idx !== -1) handlers.splice(idx, 1);
|
|
49397
|
+
}
|
|
49311
49398
|
getState() {
|
|
49312
49399
|
return this.state;
|
|
49313
49400
|
}
|
|
@@ -49617,7 +49704,7 @@ function sendToPeer(peer, data) {
|
|
|
49617
49704
|
return false;
|
|
49618
49705
|
}
|
|
49619
49706
|
const json2 = JSON.stringify(data);
|
|
49620
|
-
if (messageType === "command_result" && json2
|
|
49707
|
+
if (messageType === "command_result" && Buffer.byteLength(json2, "utf8") > MAX_INLINE_JSON_MESSAGE_CHARS) {
|
|
49621
49708
|
return sendChunkedCommandResult(peer, peerId, requestId, json2);
|
|
49622
49709
|
}
|
|
49623
49710
|
try {
|
|
@@ -49630,21 +49717,51 @@ function sendToPeer(peer, data) {
|
|
|
49630
49717
|
return false;
|
|
49631
49718
|
}
|
|
49632
49719
|
}
|
|
49720
|
+
function buildCommandResultChunkEnvelope(requestId, chunkId, index, total, data) {
|
|
49721
|
+
return JSON.stringify({
|
|
49722
|
+
type: "command_result_chunk",
|
|
49723
|
+
id: requestId,
|
|
49724
|
+
chunkId,
|
|
49725
|
+
index,
|
|
49726
|
+
total,
|
|
49727
|
+
data
|
|
49728
|
+
});
|
|
49729
|
+
}
|
|
49730
|
+
function splitJsonIntoCommandResultChunks(json2, requestId, chunkId) {
|
|
49731
|
+
const chunks = [];
|
|
49732
|
+
let offset = 0;
|
|
49733
|
+
while (offset < json2.length) {
|
|
49734
|
+
let end = Math.min(json2.length, offset + JSON_CHUNK_PAYLOAD_CHARS);
|
|
49735
|
+
while (end > offset) {
|
|
49736
|
+
const candidate = json2.slice(offset, end);
|
|
49737
|
+
const envelope = buildCommandResultChunkEnvelope(requestId, chunkId, chunks.length, MAX_JSON_CHUNKS, candidate);
|
|
49738
|
+
if (Buffer.byteLength(envelope, "utf8") <= MAX_INLINE_JSON_MESSAGE_BYTES) break;
|
|
49739
|
+
end = offset + Math.max(1, Math.floor((end - offset) * 0.8));
|
|
49740
|
+
}
|
|
49741
|
+
chunks.push(json2.slice(offset, end));
|
|
49742
|
+
if (chunks.length > MAX_JSON_CHUNKS) return [];
|
|
49743
|
+
offset = end;
|
|
49744
|
+
}
|
|
49745
|
+
return chunks;
|
|
49746
|
+
}
|
|
49633
49747
|
function sendChunkedCommandResult(peer, peerId, requestId, json2) {
|
|
49634
49748
|
const chunkId = requestId || `command_result_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
49635
|
-
const
|
|
49749
|
+
const chunks = splitJsonIntoCommandResultChunks(json2, requestId, chunkId);
|
|
49750
|
+
const total = chunks.length;
|
|
49751
|
+
if (total === 0 || total > MAX_JSON_CHUNKS) {
|
|
49752
|
+
log(`command_result send failed: peer=${peerId} id=${requestId || "-"} reason=too_many_chunks chunks=${total || "unknown"}`);
|
|
49753
|
+
return false;
|
|
49754
|
+
}
|
|
49636
49755
|
logDebug(`command_result chunked: peer=${peerId} id=${requestId || "-"} chars=${json2.length} chunks=${total}`);
|
|
49637
49756
|
for (let index = 0; index < total; index += 1) {
|
|
49638
|
-
const chunk =
|
|
49757
|
+
const chunk = chunks[index] || "";
|
|
49639
49758
|
try {
|
|
49640
|
-
|
|
49641
|
-
|
|
49642
|
-
|
|
49643
|
-
|
|
49644
|
-
|
|
49645
|
-
|
|
49646
|
-
data: chunk
|
|
49647
|
-
}));
|
|
49759
|
+
const envelope = buildCommandResultChunkEnvelope(requestId, chunkId, index, total, chunk);
|
|
49760
|
+
if (Buffer.byteLength(envelope, "utf8") > MAX_INLINE_JSON_MESSAGE_BYTES) {
|
|
49761
|
+
log(`command_result send failed: peer=${peerId} id=${requestId || "-"} chunk=${index + 1}/${total} reason=chunk_too_large`);
|
|
49762
|
+
return false;
|
|
49763
|
+
}
|
|
49764
|
+
peer.dataChannel?.sendMessage(envelope);
|
|
49648
49765
|
} catch (error48) {
|
|
49649
49766
|
log(`command_result send failed: peer=${peerId} id=${requestId || "-"} chunk=${index + 1}/${total} error=${error48?.message || error48}`);
|
|
49650
49767
|
return false;
|
|
@@ -49652,10 +49769,58 @@ function sendChunkedCommandResult(peer, peerId, requestId, json2) {
|
|
|
49652
49769
|
}
|
|
49653
49770
|
return true;
|
|
49654
49771
|
}
|
|
49772
|
+
function parseChunkedJsonMessage(peerId, parsed) {
|
|
49773
|
+
const chunkType = typeof parsed?.type === "string" ? parsed.type : "";
|
|
49774
|
+
if (!chunkType.endsWith("_chunk")) return parsed;
|
|
49775
|
+
const chunkId = typeof parsed?.chunkId === "string" ? parsed.chunkId : "";
|
|
49776
|
+
const id = typeof parsed?.id === "string" ? parsed.id : "";
|
|
49777
|
+
const index = Number(parsed?.index);
|
|
49778
|
+
const total = Number(parsed?.total);
|
|
49779
|
+
const data = typeof parsed?.data === "string" ? parsed.data : "";
|
|
49780
|
+
if (!chunkId || !Number.isInteger(index) || !Number.isInteger(total) || index < 0 || total <= 0 || total > MAX_JSON_CHUNKS || index >= total || !data) {
|
|
49781
|
+
log(`chunked JSON ignored: peer=${peerId} type=${chunkType || "unknown"} reason=malformed`);
|
|
49782
|
+
return null;
|
|
49783
|
+
}
|
|
49784
|
+
const now = Date.now();
|
|
49785
|
+
incomingJsonChunks.forEach((entry2, key2) => {
|
|
49786
|
+
if (now - entry2.createdAt > JSON_CHUNK_TTL_MS) incomingJsonChunks.delete(key2);
|
|
49787
|
+
});
|
|
49788
|
+
const key = `${peerId}:${chunkId}`;
|
|
49789
|
+
let entry = incomingJsonChunks.get(key);
|
|
49790
|
+
if (!entry || entry.total !== total || entry.type !== chunkType) {
|
|
49791
|
+
entry = { total, chunks: new Array(total).fill(""), received: 0, createdAt: now, type: chunkType, id };
|
|
49792
|
+
incomingJsonChunks.set(key, entry);
|
|
49793
|
+
}
|
|
49794
|
+
if (!entry.chunks[index]) {
|
|
49795
|
+
entry.chunks[index] = data;
|
|
49796
|
+
entry.received += 1;
|
|
49797
|
+
}
|
|
49798
|
+
if (entry.received < entry.total) return null;
|
|
49799
|
+
incomingJsonChunks.delete(key);
|
|
49800
|
+
try {
|
|
49801
|
+
return JSON.parse(entry.chunks.join(""));
|
|
49802
|
+
} catch (error48) {
|
|
49803
|
+
log(`chunked JSON parse failed: peer=${peerId} type=${chunkType} id=${entry.id || "-"} error=${error48?.message || error48}`);
|
|
49804
|
+
return CHUNK_PARSE_FAILED;
|
|
49805
|
+
}
|
|
49806
|
+
}
|
|
49655
49807
|
function routeDataChannelMessage(peerId, msg, peers, handlers) {
|
|
49656
49808
|
const text = typeof msg === "string" ? msg : msg.toString("utf-8");
|
|
49657
49809
|
try {
|
|
49658
|
-
|
|
49810
|
+
let parsed = JSON.parse(text);
|
|
49811
|
+
const chunked = parseChunkedJsonMessage(peerId, parsed);
|
|
49812
|
+
if (chunked === null) return;
|
|
49813
|
+
if (chunked === CHUNK_PARSE_FAILED) {
|
|
49814
|
+
const peer = peers.get(peerId);
|
|
49815
|
+
const id = typeof parsed?.id === "string" ? parsed.id : "";
|
|
49816
|
+
if (parsed?.type === "command_chunk") {
|
|
49817
|
+
sendToPeer(peer, { type: "command_result", id, success: false, error: "Failed to reassemble chunked command" });
|
|
49818
|
+
} else if (id) {
|
|
49819
|
+
sendToPeer(peer, { id, type: "response", success: false, error: "Failed to reassemble chunked request" });
|
|
49820
|
+
}
|
|
49821
|
+
return;
|
|
49822
|
+
}
|
|
49823
|
+
parsed = chunked;
|
|
49659
49824
|
if (parsed.type !== "command" && parsed.type !== "pty_input" && parsed.type !== "pty_resize" && parsed.type !== "ping" && parsed.type !== "pong") {
|
|
49660
49825
|
logDebug(`Files message from peer ${peerId}: type=${parsed.type}`);
|
|
49661
49826
|
}
|
|
@@ -49951,7 +50116,7 @@ async function handleFileRequest(peerId, req, peers, handlers) {
|
|
|
49951
50116
|
}
|
|
49952
50117
|
sendToPeer(peer, response);
|
|
49953
50118
|
}
|
|
49954
|
-
var MAX_INLINE_JSON_MESSAGE_CHARS, JSON_CHUNK_PAYLOAD_CHARS;
|
|
50119
|
+
var MAX_INLINE_JSON_MESSAGE_CHARS, MAX_INLINE_JSON_MESSAGE_BYTES, JSON_CHUNK_PAYLOAD_CHARS, JSON_CHUNK_TTL_MS, MAX_JSON_CHUNKS, CHUNK_PARSE_FAILED, incomingJsonChunks;
|
|
49955
50120
|
var init_data_channel_router = __esm({
|
|
49956
50121
|
"src/daemon-p2p/data-channel-router.ts"() {
|
|
49957
50122
|
"use strict";
|
|
@@ -49959,18 +50124,23 @@ var init_data_channel_router = __esm({
|
|
|
49959
50124
|
init_permission();
|
|
49960
50125
|
init_log();
|
|
49961
50126
|
MAX_INLINE_JSON_MESSAGE_CHARS = 6e4;
|
|
49962
|
-
|
|
50127
|
+
MAX_INLINE_JSON_MESSAGE_BYTES = 6e4;
|
|
50128
|
+
JSON_CHUNK_PAYLOAD_CHARS = 16e3;
|
|
50129
|
+
JSON_CHUNK_TTL_MS = 6e4;
|
|
50130
|
+
MAX_JSON_CHUNKS = 1024;
|
|
50131
|
+
CHUNK_PARSE_FAILED = /* @__PURE__ */ Symbol("chunk_parse_failed");
|
|
50132
|
+
incomingJsonChunks = /* @__PURE__ */ new Map();
|
|
49963
50133
|
}
|
|
49964
50134
|
});
|
|
49965
50135
|
|
|
49966
50136
|
// src/daemon-p2p/screenshot-sender.ts
|
|
49967
|
-
var CHUNK_SIZE,
|
|
50137
|
+
var CHUNK_SIZE, MAX_INLINE_JSON_MESSAGE_BYTES2, JSON_CHUNK_PAYLOAD_CHARS2, ScreenshotSender;
|
|
49968
50138
|
var init_screenshot_sender = __esm({
|
|
49969
50139
|
"src/daemon-p2p/screenshot-sender.ts"() {
|
|
49970
50140
|
"use strict";
|
|
49971
50141
|
init_log();
|
|
49972
50142
|
CHUNK_SIZE = 6e4;
|
|
49973
|
-
|
|
50143
|
+
MAX_INLINE_JSON_MESSAGE_BYTES2 = 6e4;
|
|
49974
50144
|
JSON_CHUNK_PAYLOAD_CHARS2 = 16e3;
|
|
49975
50145
|
ScreenshotSender = class {
|
|
49976
50146
|
_ssDebugDone = false;
|
|
@@ -50014,7 +50184,7 @@ var init_screenshot_sender = __esm({
|
|
|
50014
50184
|
type: "topic_update",
|
|
50015
50185
|
update
|
|
50016
50186
|
});
|
|
50017
|
-
if (Buffer.byteLength(json2, "utf8") >
|
|
50187
|
+
if (Buffer.byteLength(json2, "utf8") > MAX_INLINE_JSON_MESSAGE_BYTES2) {
|
|
50018
50188
|
return this.sendChunkedTopicUpdate(peer, update, json2);
|
|
50019
50189
|
}
|
|
50020
50190
|
try {
|
|
@@ -50053,6 +50223,10 @@ var init_screenshot_sender = __esm({
|
|
|
50053
50223
|
let sentAny = false;
|
|
50054
50224
|
for (const peer of peers.values()) {
|
|
50055
50225
|
if (peer.state !== "connected" || !peer.dataChannel?.isOpen()) continue;
|
|
50226
|
+
if (Buffer.byteLength(msg, "utf8") > MAX_INLINE_JSON_MESSAGE_BYTES2) {
|
|
50227
|
+
if (this.sendChunkedSessionOutput(peer, sessionId, msg)) sentAny = true;
|
|
50228
|
+
continue;
|
|
50229
|
+
}
|
|
50056
50230
|
try {
|
|
50057
50231
|
peer.dataChannel.sendMessage(msg);
|
|
50058
50232
|
sentAny = true;
|
|
@@ -50061,6 +50235,27 @@ var init_screenshot_sender = __esm({
|
|
|
50061
50235
|
}
|
|
50062
50236
|
return sentAny;
|
|
50063
50237
|
}
|
|
50238
|
+
sendChunkedSessionOutput(peer, sessionId, json2) {
|
|
50239
|
+
const chunkId = `session_output:${sessionId}:${Date.now()}:${Math.random().toString(36).slice(2, 8)}`;
|
|
50240
|
+
const total = Math.ceil(json2.length / JSON_CHUNK_PAYLOAD_CHARS2);
|
|
50241
|
+
logDebug(`session_output chunked: peer=${peer.peerId || "unknown"} sessionId=${sessionId || "-"} chars=${json2.length} chunks=${total}`);
|
|
50242
|
+
for (let index = 0; index < total; index += 1) {
|
|
50243
|
+
const chunk = json2.slice(index * JSON_CHUNK_PAYLOAD_CHARS2, (index + 1) * JSON_CHUNK_PAYLOAD_CHARS2);
|
|
50244
|
+
try {
|
|
50245
|
+
peer.dataChannel?.sendMessage(JSON.stringify({
|
|
50246
|
+
type: "session_output_chunk",
|
|
50247
|
+
sessionId,
|
|
50248
|
+
chunkId,
|
|
50249
|
+
index,
|
|
50250
|
+
total,
|
|
50251
|
+
data: chunk
|
|
50252
|
+
}));
|
|
50253
|
+
} catch {
|
|
50254
|
+
return false;
|
|
50255
|
+
}
|
|
50256
|
+
}
|
|
50257
|
+
return true;
|
|
50258
|
+
}
|
|
50064
50259
|
sendScreenshot(peers, base64Data, targetSessionId) {
|
|
50065
50260
|
const buffer = Buffer.from(base64Data, "base64");
|
|
50066
50261
|
return this.sendScreenshotBuffer(peers, buffer, targetSessionId);
|
|
@@ -58650,6 +58845,64 @@ var init_version = __esm({
|
|
|
58650
58845
|
}
|
|
58651
58846
|
});
|
|
58652
58847
|
|
|
58848
|
+
// src/daemon-mesh-manager.ts
|
|
58849
|
+
var daemon_mesh_manager_exports = {};
|
|
58850
|
+
__export(daemon_mesh_manager_exports, {
|
|
58851
|
+
DaemonMeshManager: () => DaemonMeshManager
|
|
58852
|
+
});
|
|
58853
|
+
function interpolateArgs(args, context) {
|
|
58854
|
+
const result = {};
|
|
58855
|
+
for (const [k, v] of Object.entries(args)) {
|
|
58856
|
+
result[k] = typeof v === "string" ? interpolateString(v, context) : v;
|
|
58857
|
+
}
|
|
58858
|
+
return result;
|
|
58859
|
+
}
|
|
58860
|
+
function interpolateString(template, ctx) {
|
|
58861
|
+
return template.replace(/\{\{(\w+)\}\}/g, (_2, key) => {
|
|
58862
|
+
const val = ctx[key];
|
|
58863
|
+
return val !== void 0 ? String(val) : `{{${key}}}`;
|
|
58864
|
+
});
|
|
58865
|
+
}
|
|
58866
|
+
var DaemonMeshManager;
|
|
58867
|
+
var init_daemon_mesh_manager = __esm({
|
|
58868
|
+
"src/daemon-mesh-manager.ts"() {
|
|
58869
|
+
"use strict";
|
|
58870
|
+
init_src();
|
|
58871
|
+
DaemonMeshManager = class {
|
|
58872
|
+
rules = [];
|
|
58873
|
+
serverConn;
|
|
58874
|
+
constructor(serverConn) {
|
|
58875
|
+
this.serverConn = serverConn;
|
|
58876
|
+
}
|
|
58877
|
+
setRules(rules) {
|
|
58878
|
+
this.rules = rules;
|
|
58879
|
+
LOG.info("Mesh", `[Mesh] ${rules.length} rule(s) loaded`);
|
|
58880
|
+
}
|
|
58881
|
+
async emit(event) {
|
|
58882
|
+
const matching = this.rules.filter((r) => r.trigger === event.trigger);
|
|
58883
|
+
if (matching.length === 0) return;
|
|
58884
|
+
await Promise.allSettled(
|
|
58885
|
+
matching.map((rule) => this.executeRule(rule, event.context ?? {}))
|
|
58886
|
+
);
|
|
58887
|
+
}
|
|
58888
|
+
async executeRule(rule, context) {
|
|
58889
|
+
const args = interpolateArgs(rule.args ?? {}, context);
|
|
58890
|
+
try {
|
|
58891
|
+
LOG.info("Mesh", `[Mesh] Relaying '${rule.command}' \u2192 ${rule.targetDaemonId.slice(0, 12)}\u2026`);
|
|
58892
|
+
await this.serverConn.sendMeshCommand(rule.targetDaemonId, rule.command, args);
|
|
58893
|
+
LOG.info("Mesh", `[Mesh] Relay '${rule.command}' complete`);
|
|
58894
|
+
} catch (err) {
|
|
58895
|
+
LOG.warn("Mesh", `[Mesh] Relay '${rule.command}' failed: ${err?.message ?? err}`);
|
|
58896
|
+
}
|
|
58897
|
+
}
|
|
58898
|
+
/** Convenience: send a one-off mesh command without a rule. */
|
|
58899
|
+
async sendCommand(targetDaemonId, command, args = {}) {
|
|
58900
|
+
return this.serverConn.sendMeshCommand(targetDaemonId, command, args);
|
|
58901
|
+
}
|
|
58902
|
+
};
|
|
58903
|
+
}
|
|
58904
|
+
});
|
|
58905
|
+
|
|
58653
58906
|
// src/adhdev-daemon.ts
|
|
58654
58907
|
var adhdev_daemon_exports = {};
|
|
58655
58908
|
__export(adhdev_daemon_exports, {
|
|
@@ -58894,13 +59147,14 @@ var init_adhdev_daemon = __esm({
|
|
|
58894
59147
|
init_version();
|
|
58895
59148
|
init_src();
|
|
58896
59149
|
init_runtime_defaults();
|
|
58897
|
-
pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.
|
|
59150
|
+
pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.57" });
|
|
58898
59151
|
AdhdevDaemon = class _AdhdevDaemon {
|
|
58899
59152
|
localHttpServer = null;
|
|
58900
59153
|
localWss = null;
|
|
58901
59154
|
localClients = /* @__PURE__ */ new Set();
|
|
58902
59155
|
serverConn = null;
|
|
58903
59156
|
p2p = null;
|
|
59157
|
+
meshManager = null;
|
|
58904
59158
|
screenshotController = null;
|
|
58905
59159
|
statusReporter = null;
|
|
58906
59160
|
topicSubscriptionTimer = null;
|
|
@@ -59484,6 +59738,12 @@ ${err?.stack || ""}`);
|
|
|
59484
59738
|
}
|
|
59485
59739
|
});
|
|
59486
59740
|
this.p2p = new DaemonP2PSender(this.serverConn);
|
|
59741
|
+
const { DaemonMeshManager: DaemonMeshManager2 } = await Promise.resolve().then(() => (init_daemon_mesh_manager(), daemon_mesh_manager_exports));
|
|
59742
|
+
this.meshManager = new DaemonMeshManager2(this.serverConn);
|
|
59743
|
+
const meshRules = config2.meshRules;
|
|
59744
|
+
if (Array.isArray(meshRules) && meshRules.length > 0) {
|
|
59745
|
+
this.meshManager.setRules(meshRules);
|
|
59746
|
+
}
|
|
59487
59747
|
if (this.p2p.isAvailable) {
|
|
59488
59748
|
console.log(source_default2.green(" \u{1F517} P2P available (node-datachannel)"));
|
|
59489
59749
|
this.p2p.onInput(async (event) => {
|
|
@@ -59822,6 +60082,16 @@ ${err?.stack || ""}`);
|
|
|
59822
60082
|
if (cmdType.startsWith("git_")) {
|
|
59823
60083
|
void this.flushP2PWorkspaceGitSubscriptions();
|
|
59824
60084
|
}
|
|
60085
|
+
if (cmdType === "git_checkpoint" && routed.success && this.meshManager) {
|
|
60086
|
+
void this.meshManager.emit({
|
|
60087
|
+
trigger: "git_checkpoint_complete",
|
|
60088
|
+
context: {
|
|
60089
|
+
workspace: String(normalizedData.workspace ?? ""),
|
|
60090
|
+
checkpoint_message: routed.checkpoint?.message ?? String(normalizedData.message ?? ""),
|
|
60091
|
+
commit: routed.checkpoint?.commit ?? ""
|
|
60092
|
+
}
|
|
60093
|
+
});
|
|
60094
|
+
}
|
|
59825
60095
|
return { ...routed, interactionId };
|
|
59826
60096
|
} catch (e) {
|
|
59827
60097
|
logCommand({ ts: (/* @__PURE__ */ new Date()).toISOString(), cmd: cmdType, source: "p2p", interactionId, success: false, error: e.message, durationMs: Date.now() - cmdStart });
|