adhdev 0.8.35 → 0.8.36
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 +1084 -186
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +1051 -186
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -67,6 +67,7 @@ function normalizeConfig(raw) {
|
|
|
67
67
|
const parsed = isPlainObject(raw) ? raw : {};
|
|
68
68
|
return {
|
|
69
69
|
serverUrl: typeof parsed.serverUrl === "string" && parsed.serverUrl.trim() ? parsed.serverUrl : DEFAULT_CONFIG.serverUrl,
|
|
70
|
+
allowServerApiProxy: asBoolean(parsed.allowServerApiProxy, DEFAULT_CONFIG.allowServerApiProxy ?? false),
|
|
70
71
|
selectedIde: asNullableString(parsed.selectedIde),
|
|
71
72
|
configuredIdes: asStringArray(parsed.configuredIdes),
|
|
72
73
|
installedExtensions: asStringArray(parsed.installedExtensions),
|
|
@@ -215,6 +216,7 @@ var init_config = __esm({
|
|
|
215
216
|
import_crypto = require("crypto");
|
|
216
217
|
DEFAULT_CONFIG = {
|
|
217
218
|
serverUrl: "https://api.adhf.dev",
|
|
219
|
+
allowServerApiProxy: false,
|
|
218
220
|
selectedIde: null,
|
|
219
221
|
configuredIdes: [],
|
|
220
222
|
installedExtensions: [],
|
|
@@ -4500,19 +4502,20 @@ function normalizeMessageTime(message) {
|
|
|
4500
4502
|
}
|
|
4501
4503
|
return msg;
|
|
4502
4504
|
}
|
|
4503
|
-
function trimMessagesForStatus(messages) {
|
|
4505
|
+
function trimMessagesForStatus(messages, options) {
|
|
4506
|
+
if (!options.includeMessages || options.messageLimit <= 0 || options.totalBytesLimit <= 0) return [];
|
|
4504
4507
|
if (!Array.isArray(messages) || messages.length === 0) return [];
|
|
4505
|
-
const recent = messages.slice(-
|
|
4508
|
+
const recent = messages.slice(-options.messageLimit);
|
|
4506
4509
|
const kept = [];
|
|
4507
4510
|
let totalBytes = 0;
|
|
4508
4511
|
for (let i = recent.length - 1; i >= 0; i -= 1) {
|
|
4509
|
-
let normalized = normalizeMessageTime(trimMessageForStatus(recent[i],
|
|
4512
|
+
let normalized = normalizeMessageTime(trimMessageForStatus(recent[i], options.stringLimit));
|
|
4510
4513
|
let size = estimateBytes(normalized);
|
|
4511
|
-
if (size >
|
|
4512
|
-
normalized = normalizeMessageTime(trimMessageForStatus(recent[i],
|
|
4514
|
+
if (size > options.totalBytesLimit) {
|
|
4515
|
+
normalized = normalizeMessageTime(trimMessageForStatus(recent[i], options.fallbackStringLimit));
|
|
4513
4516
|
size = estimateBytes(normalized);
|
|
4514
4517
|
}
|
|
4515
|
-
if (kept.length > 0 && totalBytes + size >
|
|
4518
|
+
if (kept.length > 0 && totalBytes + size > options.totalBytesLimit) {
|
|
4516
4519
|
continue;
|
|
4517
4520
|
}
|
|
4518
4521
|
kept.push(normalized);
|
|
@@ -4542,22 +4545,26 @@ function isManagedStatusWorking(status) {
|
|
|
4542
4545
|
function isManagedStatusWaiting(status, opts) {
|
|
4543
4546
|
return normalizeManagedStatus(status, opts) === "waiting_approval";
|
|
4544
4547
|
}
|
|
4545
|
-
function normalizeActiveChatData(activeChat) {
|
|
4548
|
+
function normalizeActiveChatData(activeChat, options = FULL_STATUS_ACTIVE_CHAT_OPTIONS) {
|
|
4546
4549
|
if (!activeChat) return activeChat;
|
|
4550
|
+
const resolvedOptions = {
|
|
4551
|
+
...FULL_STATUS_ACTIVE_CHAT_OPTIONS,
|
|
4552
|
+
...options
|
|
4553
|
+
};
|
|
4547
4554
|
return {
|
|
4548
4555
|
...activeChat,
|
|
4549
4556
|
status: normalizeManagedStatus(activeChat.status, { activeModal: activeChat.activeModal }),
|
|
4550
|
-
messages: trimMessagesForStatus(activeChat.messages),
|
|
4551
|
-
activeModal: activeChat.activeModal ? {
|
|
4557
|
+
messages: trimMessagesForStatus(activeChat.messages, resolvedOptions),
|
|
4558
|
+
activeModal: resolvedOptions.includeActiveModal && activeChat.activeModal ? {
|
|
4552
4559
|
message: truncateString(activeChat.activeModal.message || "", STATUS_MODAL_MESSAGE_LIMIT),
|
|
4553
4560
|
buttons: (activeChat.activeModal.buttons || []).map(
|
|
4554
4561
|
(button) => truncateString(String(button || ""), STATUS_MODAL_BUTTON_LIMIT)
|
|
4555
4562
|
)
|
|
4556
|
-
} :
|
|
4557
|
-
inputContent: activeChat.inputContent ? truncateString(activeChat.inputContent,
|
|
4563
|
+
} : null,
|
|
4564
|
+
inputContent: resolvedOptions.includeInputContent && activeChat.inputContent ? truncateString(activeChat.inputContent, 2 * 1024) : void 0
|
|
4558
4565
|
};
|
|
4559
4566
|
}
|
|
4560
|
-
var WORKING_STATUSES,
|
|
4567
|
+
var WORKING_STATUSES, FULL_STATUS_ACTIVE_CHAT_OPTIONS, LIVE_STATUS_ACTIVE_CHAT_OPTIONS, STATUS_MODAL_MESSAGE_LIMIT, STATUS_MODAL_BUTTON_LIMIT;
|
|
4561
4568
|
var init_normalize = __esm({
|
|
4562
4569
|
"../../oss/packages/daemon-core/src/status/normalize.ts"() {
|
|
4563
4570
|
"use strict";
|
|
@@ -4569,17 +4576,43 @@ var init_normalize = __esm({
|
|
|
4569
4576
|
"thinking",
|
|
4570
4577
|
"active"
|
|
4571
4578
|
]);
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4579
|
+
FULL_STATUS_ACTIVE_CHAT_OPTIONS = {
|
|
4580
|
+
includeMessages: true,
|
|
4581
|
+
includeInputContent: true,
|
|
4582
|
+
includeActiveModal: true,
|
|
4583
|
+
messageLimit: 60,
|
|
4584
|
+
totalBytesLimit: 96 * 1024,
|
|
4585
|
+
stringLimit: 4 * 1024,
|
|
4586
|
+
fallbackStringLimit: 1024
|
|
4587
|
+
};
|
|
4588
|
+
LIVE_STATUS_ACTIVE_CHAT_OPTIONS = {
|
|
4589
|
+
includeMessages: false,
|
|
4590
|
+
includeInputContent: false,
|
|
4591
|
+
includeActiveModal: false,
|
|
4592
|
+
messageLimit: 0,
|
|
4593
|
+
totalBytesLimit: 0,
|
|
4594
|
+
stringLimit: 512,
|
|
4595
|
+
fallbackStringLimit: 256
|
|
4596
|
+
};
|
|
4577
4597
|
STATUS_MODAL_MESSAGE_LIMIT = 2 * 1024;
|
|
4578
4598
|
STATUS_MODAL_BUTTON_LIMIT = 120;
|
|
4579
4599
|
}
|
|
4580
4600
|
});
|
|
4581
4601
|
|
|
4582
4602
|
// ../../oss/packages/daemon-core/src/status/builders.ts
|
|
4603
|
+
function getActiveChatOptions(profile) {
|
|
4604
|
+
if (profile === "full") return {};
|
|
4605
|
+
return LIVE_STATUS_ACTIVE_CHAT_OPTIONS;
|
|
4606
|
+
}
|
|
4607
|
+
function shouldIncludeSessionControls(profile) {
|
|
4608
|
+
return profile !== "live";
|
|
4609
|
+
}
|
|
4610
|
+
function shouldIncludeSessionMetadata(profile) {
|
|
4611
|
+
return profile !== "live";
|
|
4612
|
+
}
|
|
4613
|
+
function shouldIncludeRuntimeMetadata(profile) {
|
|
4614
|
+
return profile !== "live";
|
|
4615
|
+
}
|
|
4583
4616
|
function findCdpManager(cdpManagers, key) {
|
|
4584
4617
|
const exact = cdpManagers.get(key);
|
|
4585
4618
|
if (exact) return exact;
|
|
@@ -4645,74 +4678,88 @@ function buildFallbackControls(providerControls, serverModel, serverMode, acpCon
|
|
|
4645
4678
|
}
|
|
4646
4679
|
return controls;
|
|
4647
4680
|
}
|
|
4648
|
-
function buildIdeWorkspaceSession(state, cdpManagers) {
|
|
4649
|
-
const
|
|
4681
|
+
function buildIdeWorkspaceSession(state, cdpManagers, options) {
|
|
4682
|
+
const profile = options.profile || "full";
|
|
4683
|
+
const activeChat = normalizeActiveChatData(state.activeChat, getActiveChatOptions(profile));
|
|
4684
|
+
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
4685
|
+
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
4650
4686
|
const title = activeChat?.title || state.name;
|
|
4651
4687
|
return {
|
|
4652
4688
|
id: state.instanceId || state.type,
|
|
4653
4689
|
parentId: null,
|
|
4654
4690
|
providerType: state.type,
|
|
4655
|
-
providerName: state.name,
|
|
4691
|
+
...includeSessionMetadata && { providerName: state.name },
|
|
4656
4692
|
kind: "workspace",
|
|
4657
4693
|
transport: "cdp-page",
|
|
4658
4694
|
status: normalizeManagedStatus(activeChat?.status || state.status, {
|
|
4659
4695
|
activeModal: activeChat?.activeModal || null
|
|
4660
4696
|
}),
|
|
4661
4697
|
title,
|
|
4662
|
-
workspace: state.workspace || null,
|
|
4698
|
+
...includeSessionMetadata && { workspace: state.workspace || null },
|
|
4663
4699
|
activeChat,
|
|
4664
|
-
capabilities: IDE_SESSION_CAPABILITIES,
|
|
4700
|
+
...includeSessionMetadata && { capabilities: IDE_SESSION_CAPABILITIES },
|
|
4665
4701
|
cdpConnected: state.cdpConnected ?? isCdpConnected(cdpManagers, state.type),
|
|
4666
4702
|
currentModel: state.currentModel,
|
|
4667
4703
|
currentPlan: state.currentPlan,
|
|
4668
4704
|
currentAutoApprove: state.currentAutoApprove,
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4673
|
-
|
|
4674
|
-
|
|
4705
|
+
...includeSessionControls && {
|
|
4706
|
+
controlValues: state.controlValues,
|
|
4707
|
+
providerControls: buildFallbackControls(
|
|
4708
|
+
state.providerControls,
|
|
4709
|
+
state.currentModel,
|
|
4710
|
+
state.currentPlan
|
|
4711
|
+
)
|
|
4712
|
+
},
|
|
4675
4713
|
errorMessage: state.errorMessage,
|
|
4676
4714
|
errorReason: state.errorReason,
|
|
4677
4715
|
lastUpdated: state.lastUpdated
|
|
4678
4716
|
};
|
|
4679
4717
|
}
|
|
4680
|
-
function buildExtensionAgentSession(parent, ext) {
|
|
4681
|
-
const
|
|
4718
|
+
function buildExtensionAgentSession(parent, ext, options) {
|
|
4719
|
+
const profile = options.profile || "full";
|
|
4720
|
+
const activeChat = normalizeActiveChatData(ext.activeChat, getActiveChatOptions(profile));
|
|
4721
|
+
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
4722
|
+
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
4682
4723
|
return {
|
|
4683
4724
|
id: ext.instanceId || `${parent.instanceId}:${ext.type}`,
|
|
4684
4725
|
parentId: parent.instanceId || parent.type,
|
|
4685
4726
|
providerType: ext.type,
|
|
4686
|
-
providerName: ext.name,
|
|
4727
|
+
...includeSessionMetadata && { providerName: ext.name },
|
|
4687
4728
|
kind: "agent",
|
|
4688
4729
|
transport: "cdp-webview",
|
|
4689
4730
|
status: normalizeManagedStatus(activeChat?.status || ext.status, {
|
|
4690
4731
|
activeModal: activeChat?.activeModal || null
|
|
4691
4732
|
}),
|
|
4692
4733
|
title: activeChat?.title || ext.name,
|
|
4693
|
-
workspace: parent.workspace || null,
|
|
4734
|
+
...includeSessionMetadata && { workspace: parent.workspace || null },
|
|
4694
4735
|
activeChat,
|
|
4695
|
-
capabilities: EXTENSION_SESSION_CAPABILITIES,
|
|
4736
|
+
...includeSessionMetadata && { capabilities: EXTENSION_SESSION_CAPABILITIES },
|
|
4696
4737
|
currentModel: ext.currentModel,
|
|
4697
4738
|
currentPlan: ext.currentPlan,
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
4739
|
+
...includeSessionControls && {
|
|
4740
|
+
controlValues: ext.controlValues,
|
|
4741
|
+
providerControls: buildFallbackControls(
|
|
4742
|
+
ext.providerControls,
|
|
4743
|
+
ext.currentModel,
|
|
4744
|
+
ext.currentPlan
|
|
4745
|
+
)
|
|
4746
|
+
},
|
|
4704
4747
|
errorMessage: ext.errorMessage,
|
|
4705
4748
|
errorReason: ext.errorReason,
|
|
4706
4749
|
lastUpdated: ext.lastUpdated
|
|
4707
4750
|
};
|
|
4708
4751
|
}
|
|
4709
|
-
function buildCliSession(state) {
|
|
4710
|
-
const
|
|
4752
|
+
function buildCliSession(state, options) {
|
|
4753
|
+
const profile = options.profile || "full";
|
|
4754
|
+
const activeChat = normalizeActiveChatData(state.activeChat, getActiveChatOptions(profile));
|
|
4755
|
+
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
4756
|
+
const includeRuntimeMetadata = shouldIncludeRuntimeMetadata(profile);
|
|
4757
|
+
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
4711
4758
|
return {
|
|
4712
4759
|
id: state.instanceId,
|
|
4713
4760
|
parentId: null,
|
|
4714
4761
|
providerType: state.type,
|
|
4715
|
-
providerName: state.name,
|
|
4762
|
+
...includeSessionMetadata && { providerName: state.name },
|
|
4716
4763
|
providerSessionId: state.providerSessionId,
|
|
4717
4764
|
kind: "agent",
|
|
4718
4765
|
transport: "pty",
|
|
@@ -4720,74 +4767,85 @@ function buildCliSession(state) {
|
|
|
4720
4767
|
activeModal: activeChat?.activeModal || null
|
|
4721
4768
|
}),
|
|
4722
4769
|
title: activeChat?.title || state.name,
|
|
4723
|
-
workspace: state.workspace || null,
|
|
4724
|
-
|
|
4725
|
-
|
|
4726
|
-
|
|
4727
|
-
|
|
4728
|
-
|
|
4770
|
+
...includeSessionMetadata && { workspace: state.workspace || null },
|
|
4771
|
+
...includeRuntimeMetadata && {
|
|
4772
|
+
runtimeKey: state.runtime?.runtimeKey,
|
|
4773
|
+
runtimeDisplayName: state.runtime?.displayName,
|
|
4774
|
+
runtimeWorkspaceLabel: state.runtime?.workspaceLabel,
|
|
4775
|
+
runtimeWriteOwner: state.runtime?.writeOwner || null,
|
|
4776
|
+
runtimeAttachedClients: state.runtime?.attachedClients || []
|
|
4777
|
+
},
|
|
4729
4778
|
mode: state.mode,
|
|
4730
4779
|
resume: state.resume,
|
|
4731
4780
|
activeChat,
|
|
4732
|
-
|
|
4733
|
-
|
|
4734
|
-
|
|
4735
|
-
|
|
4736
|
-
|
|
4781
|
+
...includeSessionMetadata && {
|
|
4782
|
+
capabilities: state.mode === "terminal" ? PTY_SESSION_CAPABILITIES : CLI_CHAT_SESSION_CAPABILITIES
|
|
4783
|
+
},
|
|
4784
|
+
...includeSessionControls && {
|
|
4785
|
+
controlValues: state.controlValues,
|
|
4786
|
+
providerControls: buildFallbackControls(
|
|
4787
|
+
state.providerControls
|
|
4788
|
+
)
|
|
4789
|
+
},
|
|
4737
4790
|
errorMessage: state.errorMessage,
|
|
4738
4791
|
errorReason: state.errorReason,
|
|
4739
4792
|
lastUpdated: state.lastUpdated
|
|
4740
4793
|
};
|
|
4741
4794
|
}
|
|
4742
|
-
function buildAcpSession(state) {
|
|
4743
|
-
const
|
|
4795
|
+
function buildAcpSession(state, options) {
|
|
4796
|
+
const profile = options.profile || "full";
|
|
4797
|
+
const activeChat = normalizeActiveChatData(state.activeChat, getActiveChatOptions(profile));
|
|
4798
|
+
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
4799
|
+
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
4744
4800
|
return {
|
|
4745
4801
|
id: state.instanceId,
|
|
4746
4802
|
parentId: null,
|
|
4747
4803
|
providerType: state.type,
|
|
4748
|
-
providerName: state.name,
|
|
4804
|
+
...includeSessionMetadata && { providerName: state.name },
|
|
4749
4805
|
kind: "agent",
|
|
4750
4806
|
transport: "acp",
|
|
4751
4807
|
status: normalizeManagedStatus(activeChat?.status || state.status, {
|
|
4752
4808
|
activeModal: activeChat?.activeModal || null
|
|
4753
4809
|
}),
|
|
4754
4810
|
title: activeChat?.title || state.name,
|
|
4755
|
-
workspace: state.workspace || null,
|
|
4811
|
+
...includeSessionMetadata && { workspace: state.workspace || null },
|
|
4756
4812
|
activeChat,
|
|
4757
|
-
capabilities: ACP_SESSION_CAPABILITIES,
|
|
4813
|
+
...includeSessionMetadata && { capabilities: ACP_SESSION_CAPABILITIES },
|
|
4758
4814
|
currentModel: state.currentModel,
|
|
4759
4815
|
currentPlan: state.currentPlan,
|
|
4760
|
-
|
|
4761
|
-
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4816
|
+
...includeSessionControls && {
|
|
4817
|
+
acpConfigOptions: state.acpConfigOptions,
|
|
4818
|
+
acpModes: state.acpModes,
|
|
4819
|
+
controlValues: state.controlValues,
|
|
4820
|
+
providerControls: buildFallbackControls(
|
|
4821
|
+
state.providerControls,
|
|
4822
|
+
state.currentModel,
|
|
4823
|
+
state.currentPlan,
|
|
4824
|
+
state.acpConfigOptions,
|
|
4825
|
+
state.acpModes
|
|
4826
|
+
)
|
|
4827
|
+
},
|
|
4770
4828
|
errorMessage: state.errorMessage,
|
|
4771
4829
|
errorReason: state.errorReason,
|
|
4772
4830
|
lastUpdated: state.lastUpdated
|
|
4773
4831
|
};
|
|
4774
4832
|
}
|
|
4775
|
-
function buildSessionEntries(allStates, cdpManagers) {
|
|
4833
|
+
function buildSessionEntries(allStates, cdpManagers, options = {}) {
|
|
4776
4834
|
const sessions = [];
|
|
4777
4835
|
const ideStates = allStates.filter((s) => s.category === "ide");
|
|
4778
4836
|
const cliStates = allStates.filter((s) => s.category === "cli");
|
|
4779
4837
|
const acpStates = allStates.filter((s) => s.category === "acp");
|
|
4780
4838
|
for (const state of ideStates) {
|
|
4781
|
-
sessions.push(buildIdeWorkspaceSession(state, cdpManagers));
|
|
4839
|
+
sessions.push(buildIdeWorkspaceSession(state, cdpManagers, options));
|
|
4782
4840
|
for (const ext of state.extensions) {
|
|
4783
|
-
sessions.push(buildExtensionAgentSession(state, ext));
|
|
4841
|
+
sessions.push(buildExtensionAgentSession(state, ext, options));
|
|
4784
4842
|
}
|
|
4785
4843
|
}
|
|
4786
4844
|
for (const state of cliStates) {
|
|
4787
|
-
sessions.push(buildCliSession(state));
|
|
4845
|
+
sessions.push(buildCliSession(state, options));
|
|
4788
4846
|
}
|
|
4789
4847
|
for (const state of acpStates) {
|
|
4790
|
-
sessions.push(buildAcpSession(state));
|
|
4848
|
+
sessions.push(buildAcpSession(state, options));
|
|
4791
4849
|
}
|
|
4792
4850
|
const extensionParentIds = new Set(
|
|
4793
4851
|
sessions.filter((session) => session.transport === "cdp-webview" && !!session.parentId).map((session) => session.parentId)
|
|
@@ -4899,7 +4957,31 @@ var init_reconcile = __esm({
|
|
|
4899
4957
|
}
|
|
4900
4958
|
});
|
|
4901
4959
|
|
|
4960
|
+
// ../../oss/packages/daemon-core/src/providers/contracts.ts
|
|
4961
|
+
function flattenContent(content) {
|
|
4962
|
+
if (typeof content === "string") return content;
|
|
4963
|
+
return content.filter((b) => b.type === "text").map((b) => b.text).join("\n");
|
|
4964
|
+
}
|
|
4965
|
+
var init_contracts = __esm({
|
|
4966
|
+
"../../oss/packages/daemon-core/src/providers/contracts.ts"() {
|
|
4967
|
+
"use strict";
|
|
4968
|
+
}
|
|
4969
|
+
});
|
|
4970
|
+
|
|
4902
4971
|
// ../../oss/packages/daemon-core/src/commands/chat-commands.ts
|
|
4972
|
+
function hashSignatureParts(parts) {
|
|
4973
|
+
let hash2 = 2166136261;
|
|
4974
|
+
for (const part of parts) {
|
|
4975
|
+
const text = String(part || "");
|
|
4976
|
+
for (let i = 0; i < text.length; i += 1) {
|
|
4977
|
+
hash2 ^= text.charCodeAt(i);
|
|
4978
|
+
hash2 = Math.imul(hash2, 16777619) >>> 0;
|
|
4979
|
+
}
|
|
4980
|
+
hash2 ^= 255;
|
|
4981
|
+
hash2 = Math.imul(hash2, 16777619) >>> 0;
|
|
4982
|
+
}
|
|
4983
|
+
return hash2.toString(16).padStart(8, "0");
|
|
4984
|
+
}
|
|
4903
4985
|
function getCurrentProviderType(h, fallback = "") {
|
|
4904
4986
|
return h.currentSession?.providerType || h.currentProviderType || fallback;
|
|
4905
4987
|
}
|
|
@@ -4973,6 +5055,134 @@ function parseMaybeJson(value) {
|
|
|
4973
5055
|
return value;
|
|
4974
5056
|
}
|
|
4975
5057
|
}
|
|
5058
|
+
function getChatMessageSignature(message) {
|
|
5059
|
+
if (!message) return "";
|
|
5060
|
+
let content = "";
|
|
5061
|
+
try {
|
|
5062
|
+
content = JSON.stringify(message.content ?? "");
|
|
5063
|
+
} catch {
|
|
5064
|
+
content = String(message.content ?? "");
|
|
5065
|
+
}
|
|
5066
|
+
return hashSignatureParts([
|
|
5067
|
+
String(message.id || ""),
|
|
5068
|
+
String(message.index ?? ""),
|
|
5069
|
+
String(message.role || ""),
|
|
5070
|
+
String(message.receivedAt ?? message.timestamp ?? ""),
|
|
5071
|
+
content
|
|
5072
|
+
]);
|
|
5073
|
+
}
|
|
5074
|
+
function normalizeReadChatCursor(args) {
|
|
5075
|
+
const knownMessageCount = Math.max(0, Number(args?.knownMessageCount || 0));
|
|
5076
|
+
const lastMessageSignature = typeof args?.lastMessageSignature === "string" ? args.lastMessageSignature : "";
|
|
5077
|
+
const tailLimit = Math.max(0, Number(args?.tailLimit || 0));
|
|
5078
|
+
return { knownMessageCount, lastMessageSignature, tailLimit };
|
|
5079
|
+
}
|
|
5080
|
+
function normalizeReadChatMessages(payload) {
|
|
5081
|
+
const messages = Array.isArray(payload.messages) ? payload.messages : [];
|
|
5082
|
+
return messages;
|
|
5083
|
+
}
|
|
5084
|
+
function deriveHistoryDedupKey(message) {
|
|
5085
|
+
const unitKey = typeof message._unitKey === "string" ? message._unitKey.trim() : "";
|
|
5086
|
+
if (unitKey) return `read_chat:${unitKey}`;
|
|
5087
|
+
const turnKey = typeof message._turnKey === "string" ? message._turnKey.trim() : "";
|
|
5088
|
+
if (!turnKey) return void 0;
|
|
5089
|
+
let content = "";
|
|
5090
|
+
try {
|
|
5091
|
+
content = JSON.stringify(message.content ?? "");
|
|
5092
|
+
} catch {
|
|
5093
|
+
content = String(message.content ?? "");
|
|
5094
|
+
}
|
|
5095
|
+
return `read_chat:${turnKey}:${String(message.role || "").toLowerCase()}:${content}`;
|
|
5096
|
+
}
|
|
5097
|
+
function toHistoryPersistedMessages(messages) {
|
|
5098
|
+
return messages.map((message) => ({
|
|
5099
|
+
role: message.role,
|
|
5100
|
+
content: flattenContent(message.content),
|
|
5101
|
+
receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : void 0,
|
|
5102
|
+
kind: typeof message.kind === "string" ? message.kind : void 0,
|
|
5103
|
+
senderName: typeof message.senderName === "string" ? message.senderName : void 0,
|
|
5104
|
+
historyDedupKey: deriveHistoryDedupKey(message)
|
|
5105
|
+
}));
|
|
5106
|
+
}
|
|
5107
|
+
function computeReadChatSync(messages, cursor) {
|
|
5108
|
+
const totalMessages = messages.length;
|
|
5109
|
+
const lastMessageSignature = getChatMessageSignature(messages[totalMessages - 1]);
|
|
5110
|
+
const { knownMessageCount, lastMessageSignature: knownSignature } = cursor;
|
|
5111
|
+
if (!knownMessageCount || !knownSignature) {
|
|
5112
|
+
return {
|
|
5113
|
+
syncMode: "full",
|
|
5114
|
+
replaceFrom: 0,
|
|
5115
|
+
messages,
|
|
5116
|
+
totalMessages,
|
|
5117
|
+
lastMessageSignature
|
|
5118
|
+
};
|
|
5119
|
+
}
|
|
5120
|
+
if (knownMessageCount > totalMessages) {
|
|
5121
|
+
return {
|
|
5122
|
+
syncMode: "full",
|
|
5123
|
+
replaceFrom: 0,
|
|
5124
|
+
messages,
|
|
5125
|
+
totalMessages,
|
|
5126
|
+
lastMessageSignature
|
|
5127
|
+
};
|
|
5128
|
+
}
|
|
5129
|
+
if (knownMessageCount === totalMessages && knownSignature === lastMessageSignature) {
|
|
5130
|
+
return {
|
|
5131
|
+
syncMode: "noop",
|
|
5132
|
+
replaceFrom: totalMessages,
|
|
5133
|
+
messages: [],
|
|
5134
|
+
totalMessages,
|
|
5135
|
+
lastMessageSignature
|
|
5136
|
+
};
|
|
5137
|
+
}
|
|
5138
|
+
if (knownMessageCount < totalMessages) {
|
|
5139
|
+
const anchorSignature = getChatMessageSignature(messages[knownMessageCount - 1]);
|
|
5140
|
+
if (anchorSignature === knownSignature) {
|
|
5141
|
+
return {
|
|
5142
|
+
syncMode: "append",
|
|
5143
|
+
replaceFrom: knownMessageCount,
|
|
5144
|
+
messages: messages.slice(knownMessageCount),
|
|
5145
|
+
totalMessages,
|
|
5146
|
+
lastMessageSignature
|
|
5147
|
+
};
|
|
5148
|
+
}
|
|
5149
|
+
}
|
|
5150
|
+
const replaceFrom = Math.max(0, Math.min(knownMessageCount - 1, totalMessages));
|
|
5151
|
+
return {
|
|
5152
|
+
syncMode: replaceFrom === 0 ? "full" : "replace_tail",
|
|
5153
|
+
replaceFrom,
|
|
5154
|
+
messages: replaceFrom === 0 ? messages : messages.slice(replaceFrom),
|
|
5155
|
+
totalMessages,
|
|
5156
|
+
lastMessageSignature
|
|
5157
|
+
};
|
|
5158
|
+
}
|
|
5159
|
+
function buildReadChatCommandResult(payload, args) {
|
|
5160
|
+
const messages = normalizeReadChatMessages(payload);
|
|
5161
|
+
const cursor = normalizeReadChatCursor(args);
|
|
5162
|
+
if (!cursor.knownMessageCount && !cursor.lastMessageSignature && cursor.tailLimit > 0 && messages.length > cursor.tailLimit) {
|
|
5163
|
+
const tailMessages = messages.slice(-cursor.tailLimit);
|
|
5164
|
+
const lastMessageSignature = getChatMessageSignature(tailMessages[tailMessages.length - 1]);
|
|
5165
|
+
return {
|
|
5166
|
+
success: true,
|
|
5167
|
+
...payload,
|
|
5168
|
+
messages: tailMessages,
|
|
5169
|
+
syncMode: "full",
|
|
5170
|
+
replaceFrom: 0,
|
|
5171
|
+
totalMessages: messages.length,
|
|
5172
|
+
lastMessageSignature
|
|
5173
|
+
};
|
|
5174
|
+
}
|
|
5175
|
+
const sync = computeReadChatSync(messages, cursor);
|
|
5176
|
+
return {
|
|
5177
|
+
success: true,
|
|
5178
|
+
...payload,
|
|
5179
|
+
messages: sync.messages,
|
|
5180
|
+
syncMode: sync.syncMode,
|
|
5181
|
+
replaceFrom: sync.replaceFrom,
|
|
5182
|
+
totalMessages: sync.totalMessages,
|
|
5183
|
+
lastMessageSignature: sync.lastMessageSignature
|
|
5184
|
+
};
|
|
5185
|
+
}
|
|
4976
5186
|
function didProviderConfirmSend(result) {
|
|
4977
5187
|
const parsed = parseMaybeJson(result);
|
|
4978
5188
|
if (parsed === true) return true;
|
|
@@ -5046,12 +5256,11 @@ async function handleReadChat(h, args) {
|
|
|
5046
5256
|
_log(`${transport} adapter: ${adapter.cliType}`);
|
|
5047
5257
|
const status = adapter.getStatus();
|
|
5048
5258
|
if (status) {
|
|
5049
|
-
return {
|
|
5050
|
-
success: true,
|
|
5259
|
+
return buildReadChatCommandResult({
|
|
5051
5260
|
messages: status.messages || [],
|
|
5052
5261
|
status: status.status,
|
|
5053
5262
|
activeModal: status.activeModal
|
|
5054
|
-
};
|
|
5263
|
+
}, args);
|
|
5055
5264
|
}
|
|
5056
5265
|
}
|
|
5057
5266
|
return { success: false, error: `${transport} adapter not found` };
|
|
@@ -5071,12 +5280,12 @@ async function handleReadChat(h, args) {
|
|
|
5071
5280
|
_log(`Extension OK: ${parsed.messages?.length || 0} msgs`);
|
|
5072
5281
|
h.historyWriter.appendNewMessages(
|
|
5073
5282
|
provider?.type || "unknown_extension",
|
|
5074
|
-
parsed
|
|
5283
|
+
toHistoryPersistedMessages(normalizeReadChatMessages(parsed)),
|
|
5075
5284
|
parsed.title,
|
|
5076
5285
|
args?.targetSessionId,
|
|
5077
5286
|
historySessionId
|
|
5078
5287
|
);
|
|
5079
|
-
return
|
|
5288
|
+
return buildReadChatCommandResult(parsed, args);
|
|
5080
5289
|
}
|
|
5081
5290
|
}
|
|
5082
5291
|
} catch (e) {
|
|
@@ -5088,21 +5297,25 @@ async function handleReadChat(h, args) {
|
|
|
5088
5297
|
if (cdp2 && parentSessionId) {
|
|
5089
5298
|
const stream = await h.agentStream.collectActiveSession(cdp2, parentSessionId);
|
|
5090
5299
|
if (stream?.agentType !== provider?.type) {
|
|
5091
|
-
return {
|
|
5300
|
+
return buildReadChatCommandResult({ messages: [], status: "idle" }, args);
|
|
5092
5301
|
}
|
|
5093
5302
|
if (stream) {
|
|
5094
5303
|
h.historyWriter.appendNewMessages(
|
|
5095
5304
|
stream.agentType,
|
|
5096
|
-
stream.messages || [],
|
|
5305
|
+
toHistoryPersistedMessages(stream.messages || []),
|
|
5097
5306
|
void 0,
|
|
5098
5307
|
args?.targetSessionId,
|
|
5099
5308
|
historySessionId
|
|
5100
5309
|
);
|
|
5101
|
-
return {
|
|
5310
|
+
return buildReadChatCommandResult({
|
|
5311
|
+
messages: stream.messages || [],
|
|
5312
|
+
status: stream.status,
|
|
5313
|
+
agentType: stream.agentType
|
|
5314
|
+
}, args);
|
|
5102
5315
|
}
|
|
5103
5316
|
}
|
|
5104
5317
|
}
|
|
5105
|
-
return {
|
|
5318
|
+
return buildReadChatCommandResult({ messages: [], status: "idle" }, args);
|
|
5106
5319
|
}
|
|
5107
5320
|
const cdp = h.getCdp();
|
|
5108
5321
|
if (!cdp?.isConnected) return { success: false, error: "CDP not connected" };
|
|
@@ -5124,18 +5337,18 @@ async function handleReadChat(h, args) {
|
|
|
5124
5337
|
_log(`Webview OK: ${parsed.messages?.length || 0} msgs`);
|
|
5125
5338
|
h.historyWriter.appendNewMessages(
|
|
5126
5339
|
provider?.type || getCurrentProviderType(h, "unknown_webview"),
|
|
5127
|
-
parsed
|
|
5340
|
+
toHistoryPersistedMessages(normalizeReadChatMessages(parsed)),
|
|
5128
5341
|
parsed.title,
|
|
5129
5342
|
args?.targetSessionId,
|
|
5130
5343
|
historySessionId
|
|
5131
5344
|
);
|
|
5132
|
-
return
|
|
5345
|
+
return buildReadChatCommandResult(parsed, args);
|
|
5133
5346
|
}
|
|
5134
5347
|
}
|
|
5135
5348
|
} catch (e) {
|
|
5136
5349
|
_log(`Webview readChat error: ${e.message}`);
|
|
5137
5350
|
}
|
|
5138
|
-
return {
|
|
5351
|
+
return buildReadChatCommandResult({ messages: [], status: "idle" }, args);
|
|
5139
5352
|
}
|
|
5140
5353
|
const script = h.getProviderScript("readChat") || h.getProviderScript("read_chat");
|
|
5141
5354
|
if (script) {
|
|
@@ -5152,18 +5365,18 @@ async function handleReadChat(h, args) {
|
|
|
5152
5365
|
_log(`OK: ${parsed.messages?.length} msgs`);
|
|
5153
5366
|
h.historyWriter.appendNewMessages(
|
|
5154
5367
|
provider?.type || getCurrentProviderType(h, "unknown_ide"),
|
|
5155
|
-
parsed
|
|
5368
|
+
toHistoryPersistedMessages(normalizeReadChatMessages(parsed)),
|
|
5156
5369
|
parsed.title,
|
|
5157
5370
|
args?.targetSessionId,
|
|
5158
5371
|
historySessionId
|
|
5159
5372
|
);
|
|
5160
|
-
return
|
|
5373
|
+
return buildReadChatCommandResult(parsed, args);
|
|
5161
5374
|
}
|
|
5162
5375
|
} catch (e) {
|
|
5163
5376
|
LOG.info("Command", `[read_chat] Script error: ${e.message}`);
|
|
5164
5377
|
}
|
|
5165
5378
|
}
|
|
5166
|
-
return {
|
|
5379
|
+
return buildReadChatCommandResult({ messages: [], status: "idle" }, args);
|
|
5167
5380
|
}
|
|
5168
5381
|
async function handleSendChat(h, args) {
|
|
5169
5382
|
const text = args?.text || args?.message;
|
|
@@ -5814,6 +6027,7 @@ var RECENT_SEND_WINDOW_MS, recentSendByTarget;
|
|
|
5814
6027
|
var init_chat_commands = __esm({
|
|
5815
6028
|
"../../oss/packages/daemon-core/src/commands/chat-commands.ts"() {
|
|
5816
6029
|
"use strict";
|
|
6030
|
+
init_contracts();
|
|
5817
6031
|
init_chat_history();
|
|
5818
6032
|
init_logger();
|
|
5819
6033
|
RECENT_SEND_WINDOW_MS = 1200;
|
|
@@ -6299,21 +6513,21 @@ function applyProviderPatch(h, args, payload) {
|
|
|
6299
6513
|
});
|
|
6300
6514
|
}
|
|
6301
6515
|
async function executeProviderScript(h, args, scriptName) {
|
|
6302
|
-
const
|
|
6303
|
-
if (!
|
|
6516
|
+
const resolvedProviderType = h.currentSession?.providerType || h.currentProviderType || args?.agentType || args?.providerType;
|
|
6517
|
+
if (!resolvedProviderType) return { success: false, error: "targetSessionId or providerType is required" };
|
|
6304
6518
|
const loader = h.ctx.providerLoader;
|
|
6305
6519
|
if (!loader) return { success: false, error: "ProviderLoader not initialized" };
|
|
6306
|
-
const provider = loader.resolve(
|
|
6307
|
-
if (!provider) return { success: false, error: `Provider not found: ${
|
|
6520
|
+
const provider = loader.resolve(resolvedProviderType);
|
|
6521
|
+
if (!provider) return { success: false, error: `Provider not found: ${resolvedProviderType}` };
|
|
6308
6522
|
const webviewScriptName = `webview${scriptName.charAt(0).toUpperCase() + scriptName.slice(1)}`;
|
|
6309
6523
|
const hasWebviewScript = provider.category === "ide" && !!provider.scripts?.[webviewScriptName];
|
|
6310
6524
|
const actualScriptName = hasWebviewScript ? webviewScriptName : scriptName;
|
|
6311
6525
|
if (!provider.scripts?.[actualScriptName]) {
|
|
6312
|
-
return { success: false, error: `Script '${actualScriptName}' not available for ${
|
|
6526
|
+
return { success: false, error: `Script '${actualScriptName}' not available for ${resolvedProviderType}` };
|
|
6313
6527
|
}
|
|
6314
6528
|
const normalizedArgs = normalizeProviderScriptArgs(args);
|
|
6315
6529
|
if (provider.category === "cli") {
|
|
6316
|
-
const adapter = h.getCliAdapter(args?.targetSessionId ||
|
|
6530
|
+
const adapter = h.getCliAdapter(args?.targetSessionId || resolvedProviderType);
|
|
6317
6531
|
if (!adapter?.invokeScript) {
|
|
6318
6532
|
return { success: false, error: `CLI adapter does not support script '${actualScriptName}'` };
|
|
6319
6533
|
}
|
|
@@ -6338,7 +6552,7 @@ async function executeProviderScript(h, args, scriptName) {
|
|
|
6338
6552
|
const scriptFn = provider.scripts[actualScriptName];
|
|
6339
6553
|
const scriptCode = scriptFn(normalizedArgs);
|
|
6340
6554
|
if (!scriptCode) return { success: false, error: `Script '${actualScriptName}' returned null` };
|
|
6341
|
-
const cdpKey = provider.category === "ide" ? h.currentSession?.cdpManagerKey || h.currentManagerKey ||
|
|
6555
|
+
const cdpKey = provider.category === "ide" ? h.currentSession?.cdpManagerKey || h.currentManagerKey || resolvedProviderType : h.currentSession?.cdpManagerKey || h.currentManagerKey;
|
|
6342
6556
|
LOG.info("Command", `[ExtScript] provider=${provider.type} category=${provider.category} cdpKey=${cdpKey}`);
|
|
6343
6557
|
const cdp = h.getCdp(cdpKey);
|
|
6344
6558
|
if (!cdp?.isConnected) return { success: false, error: `No CDP connection for ${cdpKey || "any"}` };
|
|
@@ -6346,7 +6560,7 @@ async function executeProviderScript(h, args, scriptName) {
|
|
|
6346
6560
|
let result;
|
|
6347
6561
|
if (provider.category === "extension") {
|
|
6348
6562
|
const runtimeSessionId = h.currentSession?.sessionId || args?.targetSessionId;
|
|
6349
|
-
if (!runtimeSessionId) return { success: false, error: `No target session found for ${
|
|
6563
|
+
if (!runtimeSessionId) return { success: false, error: `No target session found for ${resolvedProviderType}` };
|
|
6350
6564
|
const parentSessionId = h.currentSession?.parentSessionId;
|
|
6351
6565
|
if (parentSessionId) {
|
|
6352
6566
|
await h.agentStream?.setActiveSession(cdp, parentSessionId, runtimeSessionId);
|
|
@@ -6375,7 +6589,7 @@ async function executeProviderScript(h, args, scriptName) {
|
|
|
6375
6589
|
}
|
|
6376
6590
|
} else {
|
|
6377
6591
|
if (!targetSessionId) {
|
|
6378
|
-
return { success: false, error: `No active session found for ${
|
|
6592
|
+
return { success: false, error: `No active session found for ${resolvedProviderType}` };
|
|
6379
6593
|
}
|
|
6380
6594
|
result = await cdp.evaluateInSessionFrame(targetSessionId, scriptCode);
|
|
6381
6595
|
}
|
|
@@ -26834,17 +27048,6 @@ var init_acp = __esm({
|
|
|
26834
27048
|
}
|
|
26835
27049
|
});
|
|
26836
27050
|
|
|
26837
|
-
// ../../oss/packages/daemon-core/src/providers/contracts.ts
|
|
26838
|
-
function flattenContent(content) {
|
|
26839
|
-
if (typeof content === "string") return content;
|
|
26840
|
-
return content.filter((b) => b.type === "text").map((b) => b.text).join("\n");
|
|
26841
|
-
}
|
|
26842
|
-
var init_contracts = __esm({
|
|
26843
|
-
"../../oss/packages/daemon-core/src/providers/contracts.ts"() {
|
|
26844
|
-
"use strict";
|
|
26845
|
-
}
|
|
26846
|
-
});
|
|
26847
|
-
|
|
26848
27051
|
// ../../oss/packages/daemon-core/src/providers/acp-provider-instance.ts
|
|
26849
27052
|
var import_stream, import_child_process5, AcpProviderInstance;
|
|
26850
27053
|
var init_acp_provider_instance = __esm({
|
|
@@ -31997,6 +32200,37 @@ function buildAvailableProviders(providerLoader) {
|
|
|
31997
32200
|
...provider.detectedPath !== void 0 ? { detectedPath: provider.detectedPath } : {}
|
|
31998
32201
|
}));
|
|
31999
32202
|
}
|
|
32203
|
+
function buildMachineInfo(profile = "full") {
|
|
32204
|
+
const base = {
|
|
32205
|
+
hostname: os17.hostname(),
|
|
32206
|
+
platform: os17.platform()
|
|
32207
|
+
};
|
|
32208
|
+
if (profile === "live") {
|
|
32209
|
+
return base;
|
|
32210
|
+
}
|
|
32211
|
+
if (profile === "metadata") {
|
|
32212
|
+
const memSnap2 = getHostMemorySnapshot();
|
|
32213
|
+
return {
|
|
32214
|
+
...base,
|
|
32215
|
+
arch: os17.arch(),
|
|
32216
|
+
cpus: os17.cpus().length,
|
|
32217
|
+
totalMem: memSnap2.totalMem,
|
|
32218
|
+
release: os17.release()
|
|
32219
|
+
};
|
|
32220
|
+
}
|
|
32221
|
+
const memSnap = getHostMemorySnapshot();
|
|
32222
|
+
return {
|
|
32223
|
+
...base,
|
|
32224
|
+
arch: os17.arch(),
|
|
32225
|
+
cpus: os17.cpus().length,
|
|
32226
|
+
totalMem: memSnap.totalMem,
|
|
32227
|
+
freeMem: memSnap.freeMem,
|
|
32228
|
+
availableMem: memSnap.availableMem,
|
|
32229
|
+
loadavg: os17.loadavg(),
|
|
32230
|
+
uptime: os17.uptime(),
|
|
32231
|
+
release: os17.release()
|
|
32232
|
+
};
|
|
32233
|
+
}
|
|
32000
32234
|
function parseMessageTime(value) {
|
|
32001
32235
|
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
32002
32236
|
if (typeof value === "string") {
|
|
@@ -32052,26 +32286,35 @@ function buildRecentLaunches(recentActivity) {
|
|
|
32052
32286
|
})).sort((a, b) => b.lastLaunchedAt - a.lastLaunchedAt).slice(0, 12);
|
|
32053
32287
|
}
|
|
32054
32288
|
function buildStatusSnapshot(options) {
|
|
32289
|
+
const profile = options.profile || "full";
|
|
32055
32290
|
const cfg = loadConfig();
|
|
32056
32291
|
const state = loadState();
|
|
32057
32292
|
const wsState = getWorkspaceState(cfg);
|
|
32058
|
-
const memSnap = getHostMemorySnapshot();
|
|
32059
32293
|
const recentActivity = getRecentActivity(state, 20);
|
|
32060
|
-
const
|
|
32294
|
+
const unreadSourceSessions = buildSessionEntries(
|
|
32061
32295
|
options.allStates,
|
|
32062
|
-
options.cdpManagers
|
|
32296
|
+
options.cdpManagers,
|
|
32297
|
+
{ profile: "full" }
|
|
32063
32298
|
);
|
|
32064
|
-
|
|
32065
|
-
|
|
32066
|
-
|
|
32067
|
-
|
|
32068
|
-
|
|
32069
|
-
|
|
32070
|
-
|
|
32071
|
-
|
|
32299
|
+
const sessions = profile === "full" ? unreadSourceSessions : buildSessionEntries(
|
|
32300
|
+
options.allStates,
|
|
32301
|
+
options.cdpManagers,
|
|
32302
|
+
{ profile }
|
|
32303
|
+
);
|
|
32304
|
+
const sessionsById = new Map(sessions.map((session) => [session.id, session]));
|
|
32305
|
+
for (const sourceSession of unreadSourceSessions) {
|
|
32306
|
+
const session = sessionsById.get(sourceSession.id);
|
|
32307
|
+
if (!session) continue;
|
|
32308
|
+
const lastSeenAt = getSessionSeenAt(state, sourceSession.id);
|
|
32309
|
+
const seenCompletionMarker = getSessionSeenMarker(state, sourceSession.id);
|
|
32310
|
+
const lastUsedAt = getSessionLastUsedAt(sourceSession);
|
|
32311
|
+
const completionMarker = getSessionCompletionMarker(sourceSession);
|
|
32312
|
+
const { unread, inboxBucket } = sourceSession.surfaceHidden ? { unread: false, inboxBucket: "idle" } : getUnreadState(
|
|
32313
|
+
getSessionMessageUpdatedAt(sourceSession) > 0,
|
|
32314
|
+
sourceSession.status,
|
|
32072
32315
|
lastUsedAt,
|
|
32073
32316
|
lastSeenAt,
|
|
32074
|
-
getLastMessageRole(
|
|
32317
|
+
getLastMessageRole(sourceSession),
|
|
32075
32318
|
completionMarker,
|
|
32076
32319
|
seenCompletionMarker
|
|
32077
32320
|
);
|
|
@@ -32081,39 +32324,30 @@ function buildStatusSnapshot(options) {
|
|
|
32081
32324
|
if (READ_DEBUG_ENABLED && (session.unread || session.inboxBucket !== "idle" || session.providerType.includes("codex"))) {
|
|
32082
32325
|
LOG.info(
|
|
32083
32326
|
"RecentRead",
|
|
32084
|
-
`snapshot session id=${session.id} provider=${session.providerType} status=${String(session.status || "")} bucket=${inboxBucket} unread=${String(unread)} lastSeenAt=${lastSeenAt} completionMarker=${completionMarker || "-"} seenMarker=${seenCompletionMarker || "-"} lastUpdated=${String(session.lastUpdated || 0)} lastUsedAt=${lastUsedAt} lastRole=${getLastMessageRole(
|
|
32327
|
+
`snapshot session id=${session.id} provider=${session.providerType} status=${String(session.status || "")} bucket=${inboxBucket} unread=${String(unread)} lastSeenAt=${lastSeenAt} completionMarker=${completionMarker || "-"} seenMarker=${seenCompletionMarker || "-"} lastUpdated=${String(session.lastUpdated || 0)} lastUsedAt=${lastUsedAt} lastRole=${getLastMessageRole(sourceSession)} msgUpdatedAt=${getSessionMessageUpdatedAt(sourceSession)}`
|
|
32085
32328
|
);
|
|
32086
32329
|
}
|
|
32087
32330
|
}
|
|
32088
|
-
const
|
|
32331
|
+
const includeMachineMetadata = profile !== "live";
|
|
32332
|
+
const terminalBackend = includeMachineMetadata ? getTerminalBackendRuntimeStatus() : void 0;
|
|
32089
32333
|
return {
|
|
32090
32334
|
instanceId: options.instanceId,
|
|
32091
|
-
version: options.version,
|
|
32092
|
-
|
|
32093
|
-
|
|
32094
|
-
hostname: os17.hostname(),
|
|
32095
|
-
platform: os17.platform(),
|
|
32096
|
-
arch: os17.arch(),
|
|
32097
|
-
cpus: os17.cpus().length,
|
|
32098
|
-
totalMem: memSnap.totalMem,
|
|
32099
|
-
freeMem: memSnap.freeMem,
|
|
32100
|
-
availableMem: memSnap.availableMem,
|
|
32101
|
-
loadavg: os17.loadavg(),
|
|
32102
|
-
uptime: os17.uptime(),
|
|
32103
|
-
release: os17.release()
|
|
32104
|
-
},
|
|
32105
|
-
machineNickname: options.machineNickname ?? cfg.machineNickname ?? null,
|
|
32335
|
+
...includeMachineMetadata ? { version: options.version } : {},
|
|
32336
|
+
machine: buildMachineInfo(profile),
|
|
32337
|
+
...includeMachineMetadata ? { machineNickname: options.machineNickname ?? cfg.machineNickname ?? null } : {},
|
|
32106
32338
|
timestamp: options.timestamp ?? Date.now(),
|
|
32107
|
-
detectedIdes: buildDetectedIdeInfos(options.detectedIdes, options.cdpManagers),
|
|
32108
32339
|
...options.p2p ? { p2p: options.p2p } : {},
|
|
32109
32340
|
sessions,
|
|
32110
|
-
|
|
32111
|
-
|
|
32112
|
-
|
|
32113
|
-
|
|
32114
|
-
|
|
32115
|
-
|
|
32116
|
-
|
|
32341
|
+
...terminalBackend ? { terminalBackend } : {},
|
|
32342
|
+
...includeMachineMetadata && {
|
|
32343
|
+
detectedIdes: buildDetectedIdeInfos(options.detectedIdes, options.cdpManagers),
|
|
32344
|
+
workspaces: wsState.workspaces,
|
|
32345
|
+
defaultWorkspaceId: wsState.defaultWorkspaceId,
|
|
32346
|
+
defaultWorkspacePath: wsState.defaultWorkspacePath,
|
|
32347
|
+
terminalSizingMode: cfg.terminalSizingMode || "measured",
|
|
32348
|
+
recentLaunches: buildRecentLaunches(recentActivity),
|
|
32349
|
+
availableProviders: buildAvailableProviders(options.providerLoader)
|
|
32350
|
+
}
|
|
32117
32351
|
};
|
|
32118
32352
|
}
|
|
32119
32353
|
var os17, READ_DEBUG_ENABLED;
|
|
@@ -32384,6 +32618,7 @@ var init_router = __esm({
|
|
|
32384
32618
|
init_logger();
|
|
32385
32619
|
init_builders();
|
|
32386
32620
|
init_snapshot();
|
|
32621
|
+
init_snapshot();
|
|
32387
32622
|
init_upgrade_helper();
|
|
32388
32623
|
fs9 = __toESM(require("fs"));
|
|
32389
32624
|
CHAT_COMMANDS = [
|
|
@@ -32712,6 +32947,25 @@ var init_router = __esm({
|
|
|
32712
32947
|
updateConfig({ userName: name });
|
|
32713
32948
|
return { success: true, userName: name };
|
|
32714
32949
|
}
|
|
32950
|
+
case "get_status_metadata": {
|
|
32951
|
+
const snapshot = buildStatusSnapshot({
|
|
32952
|
+
allStates: this.deps.instanceManager.collectAllStates(),
|
|
32953
|
+
cdpManagers: this.deps.cdpManagers,
|
|
32954
|
+
providerLoader: this.deps.providerLoader,
|
|
32955
|
+
detectedIdes: this.deps.detectedIdes.value,
|
|
32956
|
+
instanceId: this.deps.statusInstanceId || loadConfig().machineId || "daemon",
|
|
32957
|
+
version: this.deps.statusVersion || "unknown",
|
|
32958
|
+
profile: "metadata"
|
|
32959
|
+
});
|
|
32960
|
+
return { success: true, status: snapshot };
|
|
32961
|
+
}
|
|
32962
|
+
case "get_machine_runtime_stats": {
|
|
32963
|
+
return {
|
|
32964
|
+
success: true,
|
|
32965
|
+
machine: buildMachineInfo("full"),
|
|
32966
|
+
timestamp: Date.now()
|
|
32967
|
+
};
|
|
32968
|
+
}
|
|
32715
32969
|
case "mark_session_seen": {
|
|
32716
32970
|
const sessionId = args?.sessionId;
|
|
32717
32971
|
if (!sessionId || typeof sessionId !== "string") {
|
|
@@ -32925,9 +33179,58 @@ var init_reporter = __esm({
|
|
|
32925
33179
|
}, 5e3 - elapsed);
|
|
32926
33180
|
}
|
|
32927
33181
|
}
|
|
33182
|
+
toDaemonStatusEventName(value) {
|
|
33183
|
+
switch (value) {
|
|
33184
|
+
case "agent:generating_started":
|
|
33185
|
+
case "agent:waiting_approval":
|
|
33186
|
+
case "agent:generating_completed":
|
|
33187
|
+
case "agent:stopped":
|
|
33188
|
+
case "monitor:long_generating":
|
|
33189
|
+
return value;
|
|
33190
|
+
default:
|
|
33191
|
+
return null;
|
|
33192
|
+
}
|
|
33193
|
+
}
|
|
33194
|
+
buildServerStatusEvent(event) {
|
|
33195
|
+
const eventName = this.toDaemonStatusEventName(event.event);
|
|
33196
|
+
if (!eventName) return null;
|
|
33197
|
+
if (eventName.startsWith("provider:")) {
|
|
33198
|
+
return null;
|
|
33199
|
+
}
|
|
33200
|
+
const payload = {
|
|
33201
|
+
event: eventName,
|
|
33202
|
+
timestamp: typeof event.timestamp === "number" && Number.isFinite(event.timestamp) ? event.timestamp : Date.now()
|
|
33203
|
+
};
|
|
33204
|
+
if (typeof event.targetSessionId === "string" && event.targetSessionId.trim()) {
|
|
33205
|
+
payload.targetSessionId = event.targetSessionId.trim();
|
|
33206
|
+
}
|
|
33207
|
+
const providerType = typeof event.providerType === "string" && event.providerType.trim() ? event.providerType.trim() : typeof event.ideType === "string" && event.ideType.trim() ? event.ideType.trim() : "";
|
|
33208
|
+
if (providerType) {
|
|
33209
|
+
payload.providerType = providerType;
|
|
33210
|
+
}
|
|
33211
|
+
if (typeof event.duration === "number" && Number.isFinite(event.duration)) {
|
|
33212
|
+
payload.duration = event.duration;
|
|
33213
|
+
}
|
|
33214
|
+
if (typeof event.elapsedSec === "number" && Number.isFinite(event.elapsedSec)) {
|
|
33215
|
+
payload.elapsedSec = event.elapsedSec;
|
|
33216
|
+
}
|
|
33217
|
+
if (typeof event.modalMessage === "string" && event.modalMessage.trim()) {
|
|
33218
|
+
payload.modalMessage = event.modalMessage;
|
|
33219
|
+
}
|
|
33220
|
+
if (Array.isArray(event.modalButtons)) {
|
|
33221
|
+
const modalButtons = event.modalButtons.filter((button) => typeof button === "string" && button.trim().length > 0);
|
|
33222
|
+
if (modalButtons.length > 0) {
|
|
33223
|
+
payload.modalButtons = modalButtons;
|
|
33224
|
+
}
|
|
33225
|
+
}
|
|
33226
|
+
return payload;
|
|
33227
|
+
}
|
|
32928
33228
|
emitStatusEvent(event) {
|
|
32929
33229
|
LOG.info("StatusEvent", `${event.event} (${event.providerType || event.ideType || ""})`);
|
|
32930
|
-
this.
|
|
33230
|
+
const serverEvent = this.buildServerStatusEvent(event);
|
|
33231
|
+
if (!serverEvent) return;
|
|
33232
|
+
this.deps.p2p?.sendStatusEvent(serverEvent);
|
|
33233
|
+
this.deps.serverConn?.sendMessage("status_event", serverEvent);
|
|
32931
33234
|
}
|
|
32932
33235
|
removeAgentTracking(_key) {
|
|
32933
33236
|
}
|
|
@@ -32996,17 +33299,16 @@ var init_reporter = __esm({
|
|
|
32996
33299
|
detectedIdes: this.deps.detectedIdes || [],
|
|
32997
33300
|
instanceId: this.deps.instanceId,
|
|
32998
33301
|
version: this.deps.daemonVersion || "unknown",
|
|
32999
|
-
daemonMode: true,
|
|
33000
33302
|
timestamp: now,
|
|
33001
33303
|
p2p: {
|
|
33002
33304
|
available: p2p?.isAvailable || false,
|
|
33003
33305
|
state: p2p?.connectionState || "unavailable",
|
|
33004
33306
|
peers: p2p?.connectedPeerCount || 0,
|
|
33005
33307
|
screenshotActive: p2p?.screenshotActive || false
|
|
33006
|
-
}
|
|
33308
|
+
},
|
|
33309
|
+
profile: "live"
|
|
33007
33310
|
}),
|
|
33008
|
-
screenshotUsage: this.deps.getScreenshotUsage?.() || null
|
|
33009
|
-
connectedExtensions: []
|
|
33311
|
+
screenshotUsage: this.deps.getScreenshotUsage?.() || null
|
|
33010
33312
|
};
|
|
33011
33313
|
const payloadBytes = JSON.stringify(payload).length;
|
|
33012
33314
|
const p2pSent = this.sendP2PPayload(payload);
|
|
@@ -33021,16 +33323,15 @@ var init_reporter = __esm({
|
|
|
33021
33323
|
}
|
|
33022
33324
|
if (opts?.p2pOnly) return;
|
|
33023
33325
|
const wsPayload = {
|
|
33024
|
-
daemonMode: true,
|
|
33025
33326
|
sessions: sessions.map((session) => ({
|
|
33026
33327
|
id: session.id,
|
|
33027
33328
|
parentId: session.parentId,
|
|
33028
33329
|
providerType: session.providerType,
|
|
33029
|
-
providerName: session.providerName,
|
|
33330
|
+
providerName: session.providerName || session.providerType,
|
|
33030
33331
|
kind: session.kind,
|
|
33031
33332
|
transport: session.transport,
|
|
33032
33333
|
status: session.status,
|
|
33033
|
-
workspace: session.workspace,
|
|
33334
|
+
workspace: session.workspace ?? null,
|
|
33034
33335
|
title: session.title,
|
|
33035
33336
|
cdpConnected: session.cdpConnected,
|
|
33036
33337
|
currentModel: session.currentModel,
|
|
@@ -33038,9 +33339,7 @@ var init_reporter = __esm({
|
|
|
33038
33339
|
currentAutoApprove: session.currentAutoApprove
|
|
33039
33340
|
})),
|
|
33040
33341
|
p2p: payload.p2p,
|
|
33041
|
-
timestamp: now
|
|
33042
|
-
detectedIdes: payload.detectedIdes,
|
|
33043
|
-
availableProviders: payload.availableProviders
|
|
33342
|
+
timestamp: now
|
|
33044
33343
|
};
|
|
33045
33344
|
const wsHash = this.simpleHash(JSON.stringify({
|
|
33046
33345
|
...wsPayload,
|
|
@@ -33057,10 +33356,15 @@ var init_reporter = __esm({
|
|
|
33057
33356
|
// ─── P2P ─────────────────────────────────────────
|
|
33058
33357
|
sendP2PPayload(payload) {
|
|
33059
33358
|
const { timestamp: _ts, system: _sys, ...hashTarget } = payload;
|
|
33359
|
+
const sessions = Array.isArray(hashTarget.sessions) ? hashTarget.sessions.map((session) => {
|
|
33360
|
+
if (!session || typeof session !== "object") return session;
|
|
33361
|
+
const { lastUpdated: _lu, ...stableSession } = session;
|
|
33362
|
+
return stableSession;
|
|
33363
|
+
}) : hashTarget.sessions;
|
|
33060
33364
|
const hashPayload = hashTarget.machine ? (() => {
|
|
33061
33365
|
const { freeMem: _f, availableMem: _a2, loadavg: _l, uptime: _u, ...stableMachine } = hashTarget.machine;
|
|
33062
|
-
return { ...hashTarget, machine: stableMachine };
|
|
33063
|
-
})() : hashTarget;
|
|
33366
|
+
return { ...hashTarget, sessions, machine: stableMachine };
|
|
33367
|
+
})() : { ...hashTarget, sessions };
|
|
33064
33368
|
const h = this.simpleHash(JSON.stringify(hashPayload));
|
|
33065
33369
|
if (h !== this.lastP2PStatusHash) {
|
|
33066
33370
|
this.lastP2PStatusHash = h;
|
|
@@ -40271,6 +40575,8 @@ async function initDaemonComponents(config2) {
|
|
|
40271
40575
|
onStatusChange: config2.onStatusChange,
|
|
40272
40576
|
onPostChatCommand: config2.onPostChatCommand,
|
|
40273
40577
|
sessionHostControl: config2.sessionHostControl,
|
|
40578
|
+
statusInstanceId: config2.statusInstanceId,
|
|
40579
|
+
statusVersion: config2.statusVersion,
|
|
40274
40580
|
getCdpLogFn: config2.getCdpLogFn || ((ideType) => LOG.forComponent(`CDP:${ideType}`).asLogFn())
|
|
40275
40581
|
});
|
|
40276
40582
|
poller = new AgentStreamPoller({
|
|
@@ -40396,6 +40702,7 @@ __export(src_exports, {
|
|
|
40396
40702
|
SessionHostPtyTransportFactory: () => SessionHostPtyTransportFactory,
|
|
40397
40703
|
VersionArchive: () => VersionArchive,
|
|
40398
40704
|
appendRecentActivity: () => appendRecentActivity,
|
|
40705
|
+
buildMachineInfo: () => buildMachineInfo,
|
|
40399
40706
|
buildSessionEntries: () => buildSessionEntries,
|
|
40400
40707
|
buildStatusSnapshot: () => buildStatusSnapshot,
|
|
40401
40708
|
connectCdpManager: () => connectCdpManager,
|
|
@@ -40539,6 +40846,7 @@ var init_server_connection = __esm({
|
|
|
40539
40846
|
this.ws = new import_ws2.default(fullUrl, {
|
|
40540
40847
|
headers: {
|
|
40541
40848
|
"X-ADHDev-Token": this.options.token,
|
|
40849
|
+
"X-ADHDev-Daemon": JSON.stringify(this.options.cliInfo),
|
|
40542
40850
|
"X-ADHDev-IDE": JSON.stringify(this.options.cliInfo),
|
|
40543
40851
|
"X-ADHDev-Version": this.options.daemonVersion || "unknown"
|
|
40544
40852
|
}
|
|
@@ -40623,7 +40931,7 @@ var init_server_connection = __esm({
|
|
|
40623
40931
|
type: "auth",
|
|
40624
40932
|
payload: {
|
|
40625
40933
|
token: this.options.token,
|
|
40626
|
-
|
|
40934
|
+
daemon: this.options.cliInfo
|
|
40627
40935
|
},
|
|
40628
40936
|
timestamp: Date.now()
|
|
40629
40937
|
});
|
|
@@ -40863,11 +41171,19 @@ function routeDataChannelMessage(peerId, msg, peers, handlers) {
|
|
|
40863
41171
|
if (peer) peer.lastPongAt = Date.now();
|
|
40864
41172
|
return;
|
|
40865
41173
|
}
|
|
41174
|
+
if (parsed.type === "subscribe") {
|
|
41175
|
+
handleSubscribe(peerId, parsed, peers, handlers);
|
|
41176
|
+
return;
|
|
41177
|
+
}
|
|
41178
|
+
if (parsed.type === "unsubscribe") {
|
|
41179
|
+
handleUnsubscribe(peerId, parsed, peers);
|
|
41180
|
+
return;
|
|
41181
|
+
}
|
|
40866
41182
|
if (parsed.type === "screenshot_start") {
|
|
40867
41183
|
const peer = peers.get(peerId);
|
|
40868
41184
|
const permission = peer?.sharePermission;
|
|
40869
|
-
if (!parsed.
|
|
40870
|
-
log(`screenshot_start: REJECTED \u2014 no
|
|
41185
|
+
if (!parsed.targetSessionId) {
|
|
41186
|
+
log(`screenshot_start: REJECTED \u2014 no targetSessionId from peer ${peerId}`);
|
|
40871
41187
|
return;
|
|
40872
41188
|
}
|
|
40873
41189
|
if (!canPeerStartScreenshots(permission)) {
|
|
@@ -40876,9 +41192,9 @@ function routeDataChannelMessage(peerId, msg, peers, handlers) {
|
|
|
40876
41192
|
}
|
|
40877
41193
|
if (peer) {
|
|
40878
41194
|
peer.screenshotActive = true;
|
|
40879
|
-
peer.
|
|
41195
|
+
peer.screenshotTargetSessionId = parsed.targetSessionId;
|
|
40880
41196
|
peer.needsFirstFrame = true;
|
|
40881
|
-
log(`screenshot_start: peer=${peerId},
|
|
41197
|
+
log(`screenshot_start: peer=${peerId}, targetSessionId=${parsed.targetSessionId}, channelOpen=${!!peer.dataChannel}, state=${peer.state}`);
|
|
40882
41198
|
handlers.screenshotStartHandler?.();
|
|
40883
41199
|
} else {
|
|
40884
41200
|
log(`screenshot_start: peer ${peerId} NOT FOUND in peers map!`);
|
|
@@ -40930,6 +41246,87 @@ function routeDataChannelMessage(peerId, msg, peers, handlers) {
|
|
|
40930
41246
|
log(`Parse error from peer ${peerId}: ${e?.message}`);
|
|
40931
41247
|
}
|
|
40932
41248
|
}
|
|
41249
|
+
function handleSubscribe(peerId, msg, peers, handlers) {
|
|
41250
|
+
const peer = peers.get(peerId);
|
|
41251
|
+
if (!peer) return;
|
|
41252
|
+
if (msg.topic === "session.chat_tail") {
|
|
41253
|
+
const targetSessionId = typeof msg.params?.targetSessionId === "string" ? msg.params.targetSessionId.trim() : "";
|
|
41254
|
+
if (!targetSessionId) return;
|
|
41255
|
+
if (!peer.chatSubscriptions) peer.chatSubscriptions = /* @__PURE__ */ new Map();
|
|
41256
|
+
peer.chatSubscriptions.set(msg.key, {
|
|
41257
|
+
key: msg.key,
|
|
41258
|
+
params: msg.params,
|
|
41259
|
+
seq: 0,
|
|
41260
|
+
cursor: {
|
|
41261
|
+
knownMessageCount: Math.max(0, Number(msg.params.knownMessageCount || 0)),
|
|
41262
|
+
lastMessageSignature: typeof msg.params.lastMessageSignature === "string" ? msg.params.lastMessageSignature : "",
|
|
41263
|
+
tailLimit: Math.max(0, Number(msg.params.tailLimit || 0))
|
|
41264
|
+
},
|
|
41265
|
+
lastDeliveredSignature: ""
|
|
41266
|
+
});
|
|
41267
|
+
} else if (msg.topic === "machine.runtime") {
|
|
41268
|
+
if (!peer.machineRuntimeSubscriptions) peer.machineRuntimeSubscriptions = /* @__PURE__ */ new Map();
|
|
41269
|
+
peer.machineRuntimeSubscriptions.set(msg.key, {
|
|
41270
|
+
key: msg.key,
|
|
41271
|
+
params: msg.params,
|
|
41272
|
+
seq: 0,
|
|
41273
|
+
lastSentAt: 0
|
|
41274
|
+
});
|
|
41275
|
+
} else if (msg.topic === "session_host.diagnostics") {
|
|
41276
|
+
if (!peer.sessionHostDiagnosticsSubscriptions) peer.sessionHostDiagnosticsSubscriptions = /* @__PURE__ */ new Map();
|
|
41277
|
+
peer.sessionHostDiagnosticsSubscriptions.set(msg.key, {
|
|
41278
|
+
key: msg.key,
|
|
41279
|
+
params: msg.params,
|
|
41280
|
+
seq: 0,
|
|
41281
|
+
lastSentAt: 0
|
|
41282
|
+
});
|
|
41283
|
+
} else if (msg.topic === "session.modal") {
|
|
41284
|
+
const targetSessionId = typeof msg.params?.targetSessionId === "string" ? msg.params.targetSessionId.trim() : "";
|
|
41285
|
+
if (!targetSessionId) return;
|
|
41286
|
+
if (!peer.sessionModalSubscriptions) peer.sessionModalSubscriptions = /* @__PURE__ */ new Map();
|
|
41287
|
+
peer.sessionModalSubscriptions.set(msg.key, {
|
|
41288
|
+
key: msg.key,
|
|
41289
|
+
params: msg.params,
|
|
41290
|
+
seq: 0,
|
|
41291
|
+
lastSentAt: 0,
|
|
41292
|
+
lastDeliveredSignature: ""
|
|
41293
|
+
});
|
|
41294
|
+
} else if (msg.topic === "daemon.metadata") {
|
|
41295
|
+
if (!peer.daemonMetadataSubscriptions) peer.daemonMetadataSubscriptions = /* @__PURE__ */ new Map();
|
|
41296
|
+
peer.daemonMetadataSubscriptions.set(msg.key, {
|
|
41297
|
+
key: msg.key,
|
|
41298
|
+
params: msg.params,
|
|
41299
|
+
seq: 0,
|
|
41300
|
+
lastSentAt: 0
|
|
41301
|
+
});
|
|
41302
|
+
} else {
|
|
41303
|
+
return;
|
|
41304
|
+
}
|
|
41305
|
+
handlers.subscriptionChangeHandler?.();
|
|
41306
|
+
}
|
|
41307
|
+
function handleUnsubscribe(peerId, msg, peers) {
|
|
41308
|
+
const peer = peers.get(peerId);
|
|
41309
|
+
if (!peer) return;
|
|
41310
|
+
if (msg.topic === "session.chat_tail") {
|
|
41311
|
+
peer.chatSubscriptions?.delete(msg.key);
|
|
41312
|
+
return;
|
|
41313
|
+
}
|
|
41314
|
+
if (msg.topic === "machine.runtime") {
|
|
41315
|
+
peer.machineRuntimeSubscriptions?.delete(msg.key);
|
|
41316
|
+
return;
|
|
41317
|
+
}
|
|
41318
|
+
if (msg.topic === "session_host.diagnostics") {
|
|
41319
|
+
peer.sessionHostDiagnosticsSubscriptions?.delete(msg.key);
|
|
41320
|
+
return;
|
|
41321
|
+
}
|
|
41322
|
+
if (msg.topic === "session.modal") {
|
|
41323
|
+
peer.sessionModalSubscriptions?.delete(msg.key);
|
|
41324
|
+
return;
|
|
41325
|
+
}
|
|
41326
|
+
if (msg.topic === "daemon.metadata") {
|
|
41327
|
+
peer.daemonMetadataSubscriptions?.delete(msg.key);
|
|
41328
|
+
}
|
|
41329
|
+
}
|
|
40933
41330
|
async function handleP2PCommand(peerId, msg, peers, handlers) {
|
|
40934
41331
|
const { id, commandType, data } = msg;
|
|
40935
41332
|
const peer = peers.get(peerId);
|
|
@@ -40950,7 +41347,7 @@ async function handleP2PCommand(peerId, msg, peers, handlers) {
|
|
|
40950
41347
|
}
|
|
40951
41348
|
}
|
|
40952
41349
|
async function handleInputEvent(peerId, msg, peers, handlers) {
|
|
40953
|
-
const { id, action, params,
|
|
41350
|
+
const { id, action, params, targetSessionId: explicitTargetSessionId } = msg;
|
|
40954
41351
|
const peer = peers.get(peerId);
|
|
40955
41352
|
const permission = peer?.sharePermission;
|
|
40956
41353
|
if (!canPeerUseRemoteInput(permission)) {
|
|
@@ -40962,11 +41359,11 @@ async function handleInputEvent(peerId, msg, peers, handlers) {
|
|
|
40962
41359
|
return;
|
|
40963
41360
|
}
|
|
40964
41361
|
try {
|
|
40965
|
-
const
|
|
40966
|
-
if (!
|
|
40967
|
-
log(`[Input] WARNING: No
|
|
41362
|
+
const targetSessionId = explicitTargetSessionId || peer?.screenshotTargetSessionId;
|
|
41363
|
+
if (!targetSessionId) {
|
|
41364
|
+
log(`[Input] WARNING: No targetSessionId for peer ${peerId}`);
|
|
40968
41365
|
}
|
|
40969
|
-
const result = await handlers.inputHandler({ action, params,
|
|
41366
|
+
const result = await handlers.inputHandler({ action, params, targetSessionId });
|
|
40970
41367
|
sendToPeer(peer, { id, type: "response", success: true, result });
|
|
40971
41368
|
} catch (e) {
|
|
40972
41369
|
sendToPeer(peer, { id, type: "response", success: false, error: e?.message });
|
|
@@ -41025,6 +41422,35 @@ var init_screenshot_sender = __esm({
|
|
|
41025
41422
|
}
|
|
41026
41423
|
return sentAny;
|
|
41027
41424
|
}
|
|
41425
|
+
sendStatusEvent(peers, event) {
|
|
41426
|
+
const payload = JSON.stringify({
|
|
41427
|
+
type: "status_event",
|
|
41428
|
+
payload: event,
|
|
41429
|
+
timestamp: Date.now()
|
|
41430
|
+
});
|
|
41431
|
+
let sentAny = false;
|
|
41432
|
+
for (const peer of peers.values()) {
|
|
41433
|
+
if (peer.state !== "connected" || !peer.dataChannel) continue;
|
|
41434
|
+
try {
|
|
41435
|
+
peer.dataChannel.sendMessage(payload);
|
|
41436
|
+
sentAny = true;
|
|
41437
|
+
} catch {
|
|
41438
|
+
}
|
|
41439
|
+
}
|
|
41440
|
+
return sentAny;
|
|
41441
|
+
}
|
|
41442
|
+
sendTopicUpdateToPeer(peer, update) {
|
|
41443
|
+
if (!peer?.dataChannel || peer.state !== "connected") return false;
|
|
41444
|
+
try {
|
|
41445
|
+
peer.dataChannel.sendMessage(JSON.stringify({
|
|
41446
|
+
type: "topic_update",
|
|
41447
|
+
update
|
|
41448
|
+
}));
|
|
41449
|
+
return true;
|
|
41450
|
+
} catch {
|
|
41451
|
+
return false;
|
|
41452
|
+
}
|
|
41453
|
+
}
|
|
41028
41454
|
/** Broadcast runtime session output to all connected peers */
|
|
41029
41455
|
broadcastSessionOutput(peers, sessionId, data) {
|
|
41030
41456
|
const msg = JSON.stringify({ type: "session_output", sessionId, data });
|
|
@@ -41186,7 +41612,12 @@ async function initiateConnection(deps, peerId, sharePermission) {
|
|
|
41186
41612
|
pendingCandidates: [],
|
|
41187
41613
|
remoteDescriptionSet: false,
|
|
41188
41614
|
isRelay: false,
|
|
41189
|
-
lastPongAt: Date.now()
|
|
41615
|
+
lastPongAt: Date.now(),
|
|
41616
|
+
chatSubscriptions: /* @__PURE__ */ new Map(),
|
|
41617
|
+
machineRuntimeSubscriptions: /* @__PURE__ */ new Map(),
|
|
41618
|
+
sessionHostDiagnosticsSubscriptions: /* @__PURE__ */ new Map(),
|
|
41619
|
+
sessionModalSubscriptions: /* @__PURE__ */ new Map(),
|
|
41620
|
+
daemonMetadataSubscriptions: /* @__PURE__ */ new Map()
|
|
41190
41621
|
};
|
|
41191
41622
|
deps.peers.set(pid, entry);
|
|
41192
41623
|
deps.notifyStateChange();
|
|
@@ -41433,7 +41864,8 @@ var init_daemon_p2p = __esm({
|
|
|
41433
41864
|
commandHandler: null,
|
|
41434
41865
|
ptyInputHandler: null,
|
|
41435
41866
|
ptyResizeHandler: null,
|
|
41436
|
-
screenshotStartHandler: null
|
|
41867
|
+
screenshotStartHandler: null,
|
|
41868
|
+
subscriptionChangeHandler: null
|
|
41437
41869
|
};
|
|
41438
41870
|
get screenshotActive() {
|
|
41439
41871
|
for (const peer of this.peers.values()) {
|
|
@@ -41441,11 +41873,11 @@ var init_daemon_p2p = __esm({
|
|
|
41441
41873
|
}
|
|
41442
41874
|
return false;
|
|
41443
41875
|
}
|
|
41444
|
-
/** Get the
|
|
41445
|
-
get
|
|
41876
|
+
/** Get the target session for the currently active screenshot request */
|
|
41877
|
+
get screenshotTargetSessionId() {
|
|
41446
41878
|
for (const peer of this.peers.values()) {
|
|
41447
|
-
if (peer.screenshotActive && peer.state === "connected" && peer.
|
|
41448
|
-
return peer.
|
|
41879
|
+
if (peer.screenshotActive && peer.state === "connected" && peer.screenshotTargetSessionId) {
|
|
41880
|
+
return peer.screenshotTargetSessionId;
|
|
41449
41881
|
}
|
|
41450
41882
|
}
|
|
41451
41883
|
return void 0;
|
|
@@ -41597,6 +42029,9 @@ ${e?.stack || ""}`);
|
|
|
41597
42029
|
sendStatus(status) {
|
|
41598
42030
|
return this.screenshotSender.sendStatus(this.peers, status);
|
|
41599
42031
|
}
|
|
42032
|
+
sendStatusEvent(event) {
|
|
42033
|
+
return this.screenshotSender.sendStatusEvent(this.peers, event);
|
|
42034
|
+
}
|
|
41600
42035
|
broadcastSessionOutput(sessionId, data) {
|
|
41601
42036
|
return this.screenshotSender.broadcastSessionOutput(this.peers, sessionId, data);
|
|
41602
42037
|
}
|
|
@@ -41625,6 +42060,89 @@ ${e?.stack || ""}`);
|
|
|
41625
42060
|
onScreenshotStart(handler) {
|
|
41626
42061
|
this.handlers.screenshotStartHandler = handler;
|
|
41627
42062
|
}
|
|
42063
|
+
onSubscriptionChange(handler) {
|
|
42064
|
+
this.handlers.subscriptionChangeHandler = handler;
|
|
42065
|
+
}
|
|
42066
|
+
hasChatSubscriptions() {
|
|
42067
|
+
for (const peer of this.peers.values()) {
|
|
42068
|
+
if (peer.chatSubscriptions && peer.chatSubscriptions.size > 0) return true;
|
|
42069
|
+
}
|
|
42070
|
+
return false;
|
|
42071
|
+
}
|
|
42072
|
+
hasMachineRuntimeSubscriptions() {
|
|
42073
|
+
for (const peer of this.peers.values()) {
|
|
42074
|
+
if (peer.machineRuntimeSubscriptions && peer.machineRuntimeSubscriptions.size > 0) return true;
|
|
42075
|
+
}
|
|
42076
|
+
return false;
|
|
42077
|
+
}
|
|
42078
|
+
hasSessionHostDiagnosticsSubscriptions() {
|
|
42079
|
+
for (const peer of this.peers.values()) {
|
|
42080
|
+
if (peer.sessionHostDiagnosticsSubscriptions && peer.sessionHostDiagnosticsSubscriptions.size > 0) return true;
|
|
42081
|
+
}
|
|
42082
|
+
return false;
|
|
42083
|
+
}
|
|
42084
|
+
hasSessionModalSubscriptions() {
|
|
42085
|
+
for (const peer of this.peers.values()) {
|
|
42086
|
+
if (peer.sessionModalSubscriptions && peer.sessionModalSubscriptions.size > 0) return true;
|
|
42087
|
+
}
|
|
42088
|
+
return false;
|
|
42089
|
+
}
|
|
42090
|
+
hasDaemonMetadataSubscriptions() {
|
|
42091
|
+
for (const peer of this.peers.values()) {
|
|
42092
|
+
if (peer.daemonMetadataSubscriptions && peer.daemonMetadataSubscriptions.size > 0) return true;
|
|
42093
|
+
}
|
|
42094
|
+
return false;
|
|
42095
|
+
}
|
|
42096
|
+
async flushChatSubscriptions(builder) {
|
|
42097
|
+
for (const peer of this.peers.values()) {
|
|
42098
|
+
if (peer.state !== "connected" || !peer.chatSubscriptions || peer.chatSubscriptions.size === 0) continue;
|
|
42099
|
+
for (const subscription of peer.chatSubscriptions.values()) {
|
|
42100
|
+
const update = await builder(subscription);
|
|
42101
|
+
if (!update) continue;
|
|
42102
|
+
this.screenshotSender.sendTopicUpdateToPeer(peer, update);
|
|
42103
|
+
}
|
|
42104
|
+
}
|
|
42105
|
+
}
|
|
42106
|
+
async flushMachineRuntimeSubscriptions(builder) {
|
|
42107
|
+
for (const peer of this.peers.values()) {
|
|
42108
|
+
if (peer.state !== "connected" || !peer.machineRuntimeSubscriptions || peer.machineRuntimeSubscriptions.size === 0) continue;
|
|
42109
|
+
for (const subscription of peer.machineRuntimeSubscriptions.values()) {
|
|
42110
|
+
const update = await builder(subscription);
|
|
42111
|
+
if (!update) continue;
|
|
42112
|
+
this.screenshotSender.sendTopicUpdateToPeer(peer, update);
|
|
42113
|
+
}
|
|
42114
|
+
}
|
|
42115
|
+
}
|
|
42116
|
+
async flushSessionHostDiagnosticsSubscriptions(builder) {
|
|
42117
|
+
for (const peer of this.peers.values()) {
|
|
42118
|
+
if (peer.state !== "connected" || !peer.sessionHostDiagnosticsSubscriptions || peer.sessionHostDiagnosticsSubscriptions.size === 0) continue;
|
|
42119
|
+
for (const subscription of peer.sessionHostDiagnosticsSubscriptions.values()) {
|
|
42120
|
+
const update = await builder(subscription);
|
|
42121
|
+
if (!update) continue;
|
|
42122
|
+
this.screenshotSender.sendTopicUpdateToPeer(peer, update);
|
|
42123
|
+
}
|
|
42124
|
+
}
|
|
42125
|
+
}
|
|
42126
|
+
async flushSessionModalSubscriptions(builder) {
|
|
42127
|
+
for (const peer of this.peers.values()) {
|
|
42128
|
+
if (peer.state !== "connected" || !peer.sessionModalSubscriptions || peer.sessionModalSubscriptions.size === 0) continue;
|
|
42129
|
+
for (const subscription of peer.sessionModalSubscriptions.values()) {
|
|
42130
|
+
const update = await builder(subscription);
|
|
42131
|
+
if (!update) continue;
|
|
42132
|
+
this.screenshotSender.sendTopicUpdateToPeer(peer, update);
|
|
42133
|
+
}
|
|
42134
|
+
}
|
|
42135
|
+
}
|
|
42136
|
+
async flushDaemonMetadataSubscriptions(builder) {
|
|
42137
|
+
for (const peer of this.peers.values()) {
|
|
42138
|
+
if (peer.state !== "connected" || !peer.daemonMetadataSubscriptions || peer.daemonMetadataSubscriptions.size === 0) continue;
|
|
42139
|
+
for (const subscription of peer.daemonMetadataSubscriptions.values()) {
|
|
42140
|
+
const update = await builder(subscription);
|
|
42141
|
+
if (!update) continue;
|
|
42142
|
+
this.screenshotSender.sendTopicUpdateToPeer(peer, update);
|
|
42143
|
+
}
|
|
42144
|
+
}
|
|
42145
|
+
}
|
|
41628
42146
|
};
|
|
41629
42147
|
}
|
|
41630
42148
|
});
|
|
@@ -48285,12 +48803,12 @@ var init_screenshot_controller = __esm({
|
|
|
48285
48803
|
async tick() {
|
|
48286
48804
|
if (!this.deps.isRunning()) return;
|
|
48287
48805
|
const active = this.deps.isScreenshotActive();
|
|
48288
|
-
const
|
|
48289
|
-
if (active && !
|
|
48806
|
+
const targetSessionId = this.deps.getScreenshotTargetSessionId();
|
|
48807
|
+
if (active && !targetSessionId) {
|
|
48290
48808
|
this.timer = setTimeout(() => this.tick(), 500);
|
|
48291
48809
|
return;
|
|
48292
48810
|
}
|
|
48293
|
-
const cdp =
|
|
48811
|
+
const cdp = targetSessionId ? this.deps.getCdp(targetSessionId) : null;
|
|
48294
48812
|
const isRelay = this.deps.isUsingRelay();
|
|
48295
48813
|
const profile = isRelay ? this.profileRelay : this.profileDirect;
|
|
48296
48814
|
this.checkBudgetReset();
|
|
@@ -48769,6 +49287,48 @@ __export(adhdev_daemon_exports, {
|
|
|
48769
49287
|
isDaemonRunning: () => isDaemonRunning,
|
|
48770
49288
|
stopDaemon: () => stopDaemon
|
|
48771
49289
|
});
|
|
49290
|
+
function hashSignatureParts2(parts) {
|
|
49291
|
+
let hash2 = 2166136261;
|
|
49292
|
+
for (const part of parts) {
|
|
49293
|
+
const text = String(part || "");
|
|
49294
|
+
for (let i = 0; i < text.length; i += 1) {
|
|
49295
|
+
hash2 ^= text.charCodeAt(i);
|
|
49296
|
+
hash2 = Math.imul(hash2, 16777619) >>> 0;
|
|
49297
|
+
}
|
|
49298
|
+
hash2 ^= 255;
|
|
49299
|
+
hash2 = Math.imul(hash2, 16777619) >>> 0;
|
|
49300
|
+
}
|
|
49301
|
+
return hash2.toString(16).padStart(8, "0");
|
|
49302
|
+
}
|
|
49303
|
+
function buildChatTailDeliverySignature(payload) {
|
|
49304
|
+
let messages = "";
|
|
49305
|
+
try {
|
|
49306
|
+
messages = JSON.stringify(payload.messages);
|
|
49307
|
+
} catch {
|
|
49308
|
+
messages = String(payload.messages.length);
|
|
49309
|
+
}
|
|
49310
|
+
return hashSignatureParts2([
|
|
49311
|
+
payload.sessionId,
|
|
49312
|
+
payload.historySessionId || "",
|
|
49313
|
+
payload.status,
|
|
49314
|
+
payload.title || "",
|
|
49315
|
+
payload.syncMode,
|
|
49316
|
+
String(payload.replaceFrom),
|
|
49317
|
+
String(payload.totalMessages),
|
|
49318
|
+
payload.lastMessageSignature,
|
|
49319
|
+
payload.activeModal ? `${payload.activeModal.message}|${payload.activeModal.buttons.join("")}` : "",
|
|
49320
|
+
messages
|
|
49321
|
+
]);
|
|
49322
|
+
}
|
|
49323
|
+
function buildSessionModalDeliverySignature(payload) {
|
|
49324
|
+
return hashSignatureParts2([
|
|
49325
|
+
payload.sessionId,
|
|
49326
|
+
payload.status,
|
|
49327
|
+
payload.title || "",
|
|
49328
|
+
payload.modalMessage || "",
|
|
49329
|
+
Array.isArray(payload.modalButtons) ? payload.modalButtons.join("") : ""
|
|
49330
|
+
]);
|
|
49331
|
+
}
|
|
48772
49332
|
function getDaemonPidFile() {
|
|
48773
49333
|
const dir = path25.join(os23.homedir(), ".adhdev");
|
|
48774
49334
|
if (!fs17.existsSync(dir)) fs17.mkdirSync(dir, { recursive: true });
|
|
@@ -48832,7 +49392,7 @@ function stopDaemon() {
|
|
|
48832
49392
|
return false;
|
|
48833
49393
|
}
|
|
48834
49394
|
}
|
|
48835
|
-
var os23, fs17, path25, import_http, import_ws3, import_chalk2, pkgVersion, AdhdevDaemon;
|
|
49395
|
+
var os23, fs17, path25, import_http, import_ws3, import_chalk2, pkgVersion, ACTIVE_CHAT_POLL_STATUSES, AdhdevDaemon;
|
|
48836
49396
|
var init_adhdev_daemon = __esm({
|
|
48837
49397
|
"src/adhdev-daemon.ts"() {
|
|
48838
49398
|
"use strict";
|
|
@@ -48850,7 +49410,12 @@ var init_adhdev_daemon = __esm({
|
|
|
48850
49410
|
import_ws3 = require("ws");
|
|
48851
49411
|
import_chalk2 = __toESM(require("chalk"));
|
|
48852
49412
|
init_version();
|
|
48853
|
-
pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.
|
|
49413
|
+
pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.36" });
|
|
49414
|
+
ACTIVE_CHAT_POLL_STATUSES = /* @__PURE__ */ new Set([
|
|
49415
|
+
"generating",
|
|
49416
|
+
"waiting_approval",
|
|
49417
|
+
"starting"
|
|
49418
|
+
]);
|
|
48854
49419
|
AdhdevDaemon = class {
|
|
48855
49420
|
localHttpServer = null;
|
|
48856
49421
|
localWss = null;
|
|
@@ -48859,6 +49424,11 @@ var init_adhdev_daemon = __esm({
|
|
|
48859
49424
|
p2p = null;
|
|
48860
49425
|
screenshotController = null;
|
|
48861
49426
|
statusReporter = null;
|
|
49427
|
+
topicSubscriptionTimer = null;
|
|
49428
|
+
p2pChatFlushInFlight = false;
|
|
49429
|
+
pendingP2PChatFlush = false;
|
|
49430
|
+
pendingP2PChatFlushOnlyActive = true;
|
|
49431
|
+
hotP2PChatSessionIds = /* @__PURE__ */ new Set();
|
|
48862
49432
|
components = null;
|
|
48863
49433
|
sessionHostEndpoint = null;
|
|
48864
49434
|
sessionHostController = null;
|
|
@@ -48882,6 +49452,252 @@ var init_adhdev_daemon = __esm({
|
|
|
48882
49452
|
const mode = this.getCliPresentationMode(sessionId);
|
|
48883
49453
|
return mode === "chat" || mode === "terminal";
|
|
48884
49454
|
}
|
|
49455
|
+
async buildChatTailUpdateForSubscription(subscription) {
|
|
49456
|
+
const result = await this.components.router.execute("read_chat", {
|
|
49457
|
+
targetSessionId: subscription.params.targetSessionId,
|
|
49458
|
+
...subscription.params.historySessionId ? { historySessionId: subscription.params.historySessionId } : {},
|
|
49459
|
+
knownMessageCount: subscription.cursor.knownMessageCount,
|
|
49460
|
+
lastMessageSignature: subscription.cursor.lastMessageSignature,
|
|
49461
|
+
...subscription.cursor.tailLimit > 0 ? { tailLimit: subscription.cursor.tailLimit } : {}
|
|
49462
|
+
}, "p2p");
|
|
49463
|
+
if (!result?.success || result.syncMode === "noop") {
|
|
49464
|
+
if (result?.success) {
|
|
49465
|
+
subscription.cursor = {
|
|
49466
|
+
knownMessageCount: Math.max(0, Number(result.totalMessages || subscription.cursor.knownMessageCount)),
|
|
49467
|
+
lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : subscription.cursor.lastMessageSignature,
|
|
49468
|
+
tailLimit: subscription.cursor.tailLimit
|
|
49469
|
+
};
|
|
49470
|
+
}
|
|
49471
|
+
return null;
|
|
49472
|
+
}
|
|
49473
|
+
subscription.seq += 1;
|
|
49474
|
+
const syncMode = result.syncMode === "append" || result.syncMode === "replace_tail" || result.syncMode === "noop" || result.syncMode === "full" ? result.syncMode : "full";
|
|
49475
|
+
subscription.cursor = {
|
|
49476
|
+
knownMessageCount: Math.max(0, Number(result.totalMessages || 0)),
|
|
49477
|
+
lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : "",
|
|
49478
|
+
tailLimit: subscription.cursor.tailLimit
|
|
49479
|
+
};
|
|
49480
|
+
const activeModal = result.activeModal && typeof result.activeModal === "object" && typeof result.activeModal.message === "string" && Array.isArray(result.activeModal.buttons) ? {
|
|
49481
|
+
message: result.activeModal.message,
|
|
49482
|
+
buttons: result.activeModal.buttons.filter((button) => typeof button === "string")
|
|
49483
|
+
} : null;
|
|
49484
|
+
const deliverySignature = buildChatTailDeliverySignature({
|
|
49485
|
+
sessionId: subscription.params.targetSessionId,
|
|
49486
|
+
...subscription.params.historySessionId ? { historySessionId: subscription.params.historySessionId } : {},
|
|
49487
|
+
messages: Array.isArray(result.messages) ? result.messages : [],
|
|
49488
|
+
status: typeof result.status === "string" ? result.status : "idle",
|
|
49489
|
+
...typeof result.title === "string" ? { title: result.title } : {},
|
|
49490
|
+
...activeModal ? { activeModal } : {},
|
|
49491
|
+
syncMode,
|
|
49492
|
+
replaceFrom: Number(result.replaceFrom || 0),
|
|
49493
|
+
totalMessages: Number(result.totalMessages || 0),
|
|
49494
|
+
lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : ""
|
|
49495
|
+
});
|
|
49496
|
+
if (deliverySignature === subscription.lastDeliveredSignature) {
|
|
49497
|
+
return null;
|
|
49498
|
+
}
|
|
49499
|
+
subscription.lastDeliveredSignature = deliverySignature;
|
|
49500
|
+
return {
|
|
49501
|
+
topic: "session.chat_tail",
|
|
49502
|
+
key: subscription.key,
|
|
49503
|
+
sessionId: subscription.params.targetSessionId,
|
|
49504
|
+
...subscription.params.historySessionId ? { historySessionId: subscription.params.historySessionId } : {},
|
|
49505
|
+
seq: subscription.seq,
|
|
49506
|
+
timestamp: Date.now(),
|
|
49507
|
+
messages: Array.isArray(result.messages) ? result.messages : [],
|
|
49508
|
+
status: typeof result.status === "string" ? result.status : "idle",
|
|
49509
|
+
...typeof result.title === "string" ? { title: result.title } : {},
|
|
49510
|
+
...activeModal ? { activeModal } : {},
|
|
49511
|
+
syncMode,
|
|
49512
|
+
replaceFrom: Number(result.replaceFrom || 0),
|
|
49513
|
+
totalMessages: Number(result.totalMessages || 0),
|
|
49514
|
+
lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : ""
|
|
49515
|
+
};
|
|
49516
|
+
}
|
|
49517
|
+
buildLiveStatusSnapshot() {
|
|
49518
|
+
return buildStatusSnapshot({
|
|
49519
|
+
allStates: this.components.instanceManager.collectAllStates(),
|
|
49520
|
+
cdpManagers: this.components.cdpManagers,
|
|
49521
|
+
providerLoader: this.components.providerLoader,
|
|
49522
|
+
detectedIdes: this.components.detectedIdes.value.map((ide) => ({
|
|
49523
|
+
...ide,
|
|
49524
|
+
path: ide.path ?? void 0
|
|
49525
|
+
})),
|
|
49526
|
+
instanceId: `daemon_${loadConfig().machineId || "daemon"}`,
|
|
49527
|
+
version: pkgVersion,
|
|
49528
|
+
profile: "live"
|
|
49529
|
+
});
|
|
49530
|
+
}
|
|
49531
|
+
getHotChatSessionIdsForP2PFlush() {
|
|
49532
|
+
const snapshot = this.buildLiveStatusSnapshot();
|
|
49533
|
+
const active = new Set(
|
|
49534
|
+
snapshot.sessions.filter((session) => ACTIVE_CHAT_POLL_STATUSES.has(String(session.status || "").toLowerCase())).map((session) => session.id)
|
|
49535
|
+
);
|
|
49536
|
+
const finalizing = new Set(
|
|
49537
|
+
Array.from(this.hotP2PChatSessionIds).filter((sessionId) => !active.has(sessionId))
|
|
49538
|
+
);
|
|
49539
|
+
this.hotP2PChatSessionIds = active;
|
|
49540
|
+
return { active, finalizing };
|
|
49541
|
+
}
|
|
49542
|
+
async flushP2PChatSubscriptions(options = {}) {
|
|
49543
|
+
if (!this.p2p?.isConnected || !this.p2p.hasChatSubscriptions()) return;
|
|
49544
|
+
const onlyActive = options.onlyActive === true;
|
|
49545
|
+
if (this.p2pChatFlushInFlight) {
|
|
49546
|
+
this.pendingP2PChatFlush = true;
|
|
49547
|
+
this.pendingP2PChatFlushOnlyActive = this.pendingP2PChatFlushOnlyActive && onlyActive;
|
|
49548
|
+
return;
|
|
49549
|
+
}
|
|
49550
|
+
this.p2pChatFlushInFlight = true;
|
|
49551
|
+
try {
|
|
49552
|
+
const hotSessionIds = onlyActive ? this.getHotChatSessionIdsForP2PFlush() : null;
|
|
49553
|
+
await this.p2p.flushChatSubscriptions(async (subscription) => {
|
|
49554
|
+
if (hotSessionIds && !hotSessionIds.active.has(subscription.params.targetSessionId) && !hotSessionIds.finalizing.has(subscription.params.targetSessionId)) {
|
|
49555
|
+
return null;
|
|
49556
|
+
}
|
|
49557
|
+
return this.buildChatTailUpdateForSubscription(subscription);
|
|
49558
|
+
});
|
|
49559
|
+
} finally {
|
|
49560
|
+
this.p2pChatFlushInFlight = false;
|
|
49561
|
+
if (this.pendingP2PChatFlush) {
|
|
49562
|
+
const pendingOnlyActive = this.pendingP2PChatFlushOnlyActive;
|
|
49563
|
+
this.pendingP2PChatFlush = false;
|
|
49564
|
+
this.pendingP2PChatFlushOnlyActive = true;
|
|
49565
|
+
void this.flushP2PChatSubscriptions({ onlyActive: pendingOnlyActive });
|
|
49566
|
+
}
|
|
49567
|
+
}
|
|
49568
|
+
}
|
|
49569
|
+
buildMachineRuntimeUpdateForSubscription(subscription) {
|
|
49570
|
+
const intervalMs = Math.max(5e3, Number(subscription.params.intervalMs || 15e3));
|
|
49571
|
+
const now = Date.now();
|
|
49572
|
+
if (subscription.lastSentAt > 0 && now - subscription.lastSentAt < intervalMs) {
|
|
49573
|
+
return null;
|
|
49574
|
+
}
|
|
49575
|
+
subscription.seq += 1;
|
|
49576
|
+
subscription.lastSentAt = now;
|
|
49577
|
+
return {
|
|
49578
|
+
topic: "machine.runtime",
|
|
49579
|
+
key: subscription.key,
|
|
49580
|
+
machine: buildMachineInfo("full"),
|
|
49581
|
+
seq: subscription.seq,
|
|
49582
|
+
timestamp: now
|
|
49583
|
+
};
|
|
49584
|
+
}
|
|
49585
|
+
async flushP2PMachineRuntimeSubscriptions() {
|
|
49586
|
+
if (!this.p2p?.isConnected || !this.p2p.hasMachineRuntimeSubscriptions()) return;
|
|
49587
|
+
await this.p2p.flushMachineRuntimeSubscriptions(async (subscription) => this.buildMachineRuntimeUpdateForSubscription(subscription));
|
|
49588
|
+
}
|
|
49589
|
+
async buildSessionHostDiagnosticsUpdateForSubscription(subscription) {
|
|
49590
|
+
if (!this.sessionHostController) return null;
|
|
49591
|
+
const intervalMs = Math.max(5e3, Number(subscription.params.intervalMs || 1e4));
|
|
49592
|
+
const now = Date.now();
|
|
49593
|
+
if (subscription.lastSentAt > 0 && now - subscription.lastSentAt < intervalMs) {
|
|
49594
|
+
return null;
|
|
49595
|
+
}
|
|
49596
|
+
const diagnostics = await this.sessionHostController.getDiagnostics({
|
|
49597
|
+
includeSessions: subscription.params.includeSessions !== false,
|
|
49598
|
+
limit: Number(subscription.params.limit) || void 0
|
|
49599
|
+
});
|
|
49600
|
+
subscription.seq += 1;
|
|
49601
|
+
subscription.lastSentAt = now;
|
|
49602
|
+
return {
|
|
49603
|
+
topic: "session_host.diagnostics",
|
|
49604
|
+
key: subscription.key,
|
|
49605
|
+
diagnostics,
|
|
49606
|
+
seq: subscription.seq,
|
|
49607
|
+
timestamp: now
|
|
49608
|
+
};
|
|
49609
|
+
}
|
|
49610
|
+
async flushP2PSessionHostDiagnosticsSubscriptions() {
|
|
49611
|
+
if (!this.p2p?.isConnected || !this.p2p.hasSessionHostDiagnosticsSubscriptions()) return;
|
|
49612
|
+
await this.p2p.flushSessionHostDiagnosticsSubscriptions(
|
|
49613
|
+
async (subscription) => this.buildSessionHostDiagnosticsUpdateForSubscription(subscription)
|
|
49614
|
+
);
|
|
49615
|
+
}
|
|
49616
|
+
findProviderStateBySessionId(sessionId) {
|
|
49617
|
+
if (!this.components || !sessionId) return null;
|
|
49618
|
+
const states = this.components.instanceManager.collectAllStates();
|
|
49619
|
+
for (const state of states) {
|
|
49620
|
+
if (state.instanceId === sessionId) return state;
|
|
49621
|
+
if (state.category === "ide") {
|
|
49622
|
+
const child = state.extensions.find((entry) => entry.instanceId === sessionId);
|
|
49623
|
+
if (child) return child;
|
|
49624
|
+
}
|
|
49625
|
+
}
|
|
49626
|
+
return null;
|
|
49627
|
+
}
|
|
49628
|
+
buildSessionModalUpdateForSubscription(subscription) {
|
|
49629
|
+
const state = this.findProviderStateBySessionId(subscription.params.targetSessionId);
|
|
49630
|
+
if (!state) return null;
|
|
49631
|
+
const now = Date.now();
|
|
49632
|
+
const activeModal = state.activeChat?.activeModal;
|
|
49633
|
+
const modalButtons = Array.isArray(activeModal?.buttons) ? activeModal.buttons.filter((button) => typeof button === "string") : [];
|
|
49634
|
+
const status = String(state.activeChat?.status || state.status || "idle");
|
|
49635
|
+
const title = typeof state.activeChat?.title === "string" ? state.activeChat.title : void 0;
|
|
49636
|
+
const modalMessage = typeof activeModal?.message === "string" ? activeModal.message : void 0;
|
|
49637
|
+
const deliverySignature = buildSessionModalDeliverySignature({
|
|
49638
|
+
sessionId: subscription.params.targetSessionId,
|
|
49639
|
+
status,
|
|
49640
|
+
...title ? { title } : {},
|
|
49641
|
+
...modalMessage ? { modalMessage } : {},
|
|
49642
|
+
...modalButtons.length > 0 ? { modalButtons } : {}
|
|
49643
|
+
});
|
|
49644
|
+
if (deliverySignature === subscription.lastDeliveredSignature) {
|
|
49645
|
+
return null;
|
|
49646
|
+
}
|
|
49647
|
+
subscription.lastDeliveredSignature = deliverySignature;
|
|
49648
|
+
subscription.seq += 1;
|
|
49649
|
+
subscription.lastSentAt = now;
|
|
49650
|
+
return {
|
|
49651
|
+
topic: "session.modal",
|
|
49652
|
+
key: subscription.key,
|
|
49653
|
+
sessionId: subscription.params.targetSessionId,
|
|
49654
|
+
status,
|
|
49655
|
+
...title ? { title } : {},
|
|
49656
|
+
...modalMessage ? { modalMessage } : {},
|
|
49657
|
+
...modalButtons.length > 0 ? { modalButtons } : {},
|
|
49658
|
+
seq: subscription.seq,
|
|
49659
|
+
timestamp: now
|
|
49660
|
+
};
|
|
49661
|
+
}
|
|
49662
|
+
async flushP2PSessionModalSubscriptions() {
|
|
49663
|
+
if (!this.p2p?.isConnected || !this.p2p.hasSessionModalSubscriptions()) return;
|
|
49664
|
+
await this.p2p.flushSessionModalSubscriptions(
|
|
49665
|
+
async (subscription) => this.buildSessionModalUpdateForSubscription(subscription)
|
|
49666
|
+
);
|
|
49667
|
+
}
|
|
49668
|
+
buildDaemonMetadataSnapshot() {
|
|
49669
|
+
return buildStatusSnapshot({
|
|
49670
|
+
allStates: this.components.instanceManager.collectAllStates(),
|
|
49671
|
+
cdpManagers: this.components.cdpManagers,
|
|
49672
|
+
providerLoader: this.components.providerLoader,
|
|
49673
|
+
detectedIdes: this.components.detectedIdes.value.map((ide) => ({
|
|
49674
|
+
...ide,
|
|
49675
|
+
path: ide.path ?? void 0
|
|
49676
|
+
})),
|
|
49677
|
+
instanceId: `daemon_${loadConfig().machineId || "daemon"}`,
|
|
49678
|
+
version: pkgVersion,
|
|
49679
|
+
profile: "metadata"
|
|
49680
|
+
});
|
|
49681
|
+
}
|
|
49682
|
+
buildDaemonMetadataUpdateForSubscription(subscription) {
|
|
49683
|
+
const now = Date.now();
|
|
49684
|
+
subscription.seq += 1;
|
|
49685
|
+
subscription.lastSentAt = now;
|
|
49686
|
+
return {
|
|
49687
|
+
topic: "daemon.metadata",
|
|
49688
|
+
key: subscription.key,
|
|
49689
|
+
daemonId: `daemon_${loadConfig().machineId || "daemon"}`,
|
|
49690
|
+
status: this.buildDaemonMetadataSnapshot(),
|
|
49691
|
+
seq: subscription.seq,
|
|
49692
|
+
timestamp: now
|
|
49693
|
+
};
|
|
49694
|
+
}
|
|
49695
|
+
async flushP2PDaemonMetadataSubscriptions() {
|
|
49696
|
+
if (!this.p2p?.isConnected || !this.p2p.hasDaemonMetadataSubscriptions()) return;
|
|
49697
|
+
await this.p2p.flushDaemonMetadataSubscriptions(
|
|
49698
|
+
async (subscription) => this.buildDaemonMetadataUpdateForSubscription(subscription)
|
|
49699
|
+
);
|
|
49700
|
+
}
|
|
48885
49701
|
async start(options = {}) {
|
|
48886
49702
|
installGlobalInterceptor();
|
|
48887
49703
|
process.on("uncaughtException", (err) => {
|
|
@@ -48914,9 +49730,14 @@ ${err?.stack || ""}`);
|
|
|
48914
49730
|
this.sessionHostEndpoint = sessionHostEndpoint;
|
|
48915
49731
|
this.sessionHostController = new SessionHostController(
|
|
48916
49732
|
sessionHostEndpoint,
|
|
48917
|
-
(event) =>
|
|
49733
|
+
(event) => {
|
|
49734
|
+
this.broadcastLocalIpcMessage("daemon:session_host_event", event);
|
|
49735
|
+
void this.flushP2PSessionHostDiagnosticsSubscriptions();
|
|
49736
|
+
void this.flushP2PSessionModalSubscriptions();
|
|
49737
|
+
}
|
|
48918
49738
|
);
|
|
48919
49739
|
await this.sessionHostController.start();
|
|
49740
|
+
const instanceId = `daemon_${config2.machineId}`;
|
|
48920
49741
|
this.components = await initDaemonComponents({
|
|
48921
49742
|
providerLogFn: LOG.forComponent("Provider").asLogFn(),
|
|
48922
49743
|
cliManagerDeps: {
|
|
@@ -48949,6 +49770,8 @@ ${err?.stack || ""}`);
|
|
|
48949
49770
|
listHostedCliRuntimes: async () => listHostedCliRuntimes2(sessionHostEndpoint)
|
|
48950
49771
|
},
|
|
48951
49772
|
enabledIdes: config2.enabledIdes,
|
|
49773
|
+
statusInstanceId: instanceId,
|
|
49774
|
+
statusVersion: pkgVersion,
|
|
48952
49775
|
onStatusChange: () => this.statusReporter?.onStatusChange(),
|
|
48953
49776
|
onPostChatCommand: () => {
|
|
48954
49777
|
setTimeout(() => this.statusReporter?.throttledReport(), 1e3);
|
|
@@ -48974,7 +49797,6 @@ ${err?.stack || ""}`);
|
|
|
48974
49797
|
}
|
|
48975
49798
|
}).catch(() => {
|
|
48976
49799
|
});
|
|
48977
|
-
const instanceId = `daemon_${config2.machineId}`;
|
|
48978
49800
|
this.serverConn = new ServerConnection({
|
|
48979
49801
|
serverUrl: options.serverUrl || config2.serverUrl,
|
|
48980
49802
|
token: authToken,
|
|
@@ -49024,6 +49846,13 @@ ${err?.stack || ""}`);
|
|
|
49024
49846
|
found.adapter.resize(cols, rows);
|
|
49025
49847
|
}
|
|
49026
49848
|
});
|
|
49849
|
+
this.p2p.onSubscriptionChange(() => {
|
|
49850
|
+
void this.flushP2PChatSubscriptions();
|
|
49851
|
+
void this.flushP2PMachineRuntimeSubscriptions();
|
|
49852
|
+
void this.flushP2PSessionHostDiagnosticsSubscriptions();
|
|
49853
|
+
void this.flushP2PSessionModalSubscriptions();
|
|
49854
|
+
void this.flushP2PDaemonMetadataSubscriptions();
|
|
49855
|
+
});
|
|
49027
49856
|
this.p2p.onStateChange((state) => {
|
|
49028
49857
|
if (state === "connected") {
|
|
49029
49858
|
LOG.info("P2P", "Peer connected \u2192 sending immediate full status report");
|
|
@@ -49040,18 +49869,24 @@ ${err?.stack || ""}`);
|
|
|
49040
49869
|
this.screenshotController = new ScreenshotController({
|
|
49041
49870
|
isRunning: () => this.running,
|
|
49042
49871
|
isScreenshotActive: () => this.p2p?.screenshotActive ?? false,
|
|
49043
|
-
|
|
49872
|
+
getScreenshotTargetSessionId: () => this.p2p?.screenshotTargetSessionId,
|
|
49044
49873
|
isUsingRelay: () => this.p2p?.isUsingRelay ?? false,
|
|
49045
49874
|
hasAnyNeedingFirstFrame: () => this.p2p?.hasAnyNeedingFirstFrame() ?? false,
|
|
49046
|
-
getCdp: (
|
|
49047
|
-
if (
|
|
49048
|
-
LOG.warn("P2P", "Screenshot requested without
|
|
49875
|
+
getCdp: (targetSessionId) => {
|
|
49876
|
+
if (targetSessionId) return this.getCdpFor(targetSessionId);
|
|
49877
|
+
LOG.warn("P2P", "Screenshot requested without targetSessionId \u2014 cannot determine target session. Skipping frame.");
|
|
49049
49878
|
return null;
|
|
49050
49879
|
},
|
|
49051
49880
|
sendScreenshotBuffer: (buf) => this.p2p.sendScreenshotBuffer(buf)
|
|
49052
49881
|
}, planLimits ?? void 0);
|
|
49053
49882
|
this.screenshotController.start();
|
|
49054
49883
|
this.p2p.onScreenshotStart(() => this.screenshotController?.triggerImmediate());
|
|
49884
|
+
this.topicSubscriptionTimer = setInterval(() => {
|
|
49885
|
+
void this.flushP2PChatSubscriptions({ onlyActive: true });
|
|
49886
|
+
void this.flushP2PMachineRuntimeSubscriptions();
|
|
49887
|
+
void this.flushP2PSessionHostDiagnosticsSubscriptions();
|
|
49888
|
+
void this.flushP2PSessionModalSubscriptions();
|
|
49889
|
+
}, 2500);
|
|
49055
49890
|
} else {
|
|
49056
49891
|
console.log(import_chalk2.default.gray(" \u26A0 P2P unavailable \u2014 using server relay"));
|
|
49057
49892
|
}
|
|
@@ -49156,10 +49991,26 @@ ${err?.stack || ""}`);
|
|
|
49156
49991
|
async handleCommand(msg, cmd, args) {
|
|
49157
49992
|
LOG.info("Command", `${cmd}${args?.targetSessionId ? ` \u2192 session:${String(args.targetSessionId).split("_")[0]}` : ""}`);
|
|
49158
49993
|
const cmdStart = Date.now();
|
|
49159
|
-
const source = msg.ipcWs ? "ext" : "ws";
|
|
49994
|
+
const source = msg.ipcWs ? "ext" : typeof msg.source === "string" && msg.source.trim() ? msg.source : "ws";
|
|
49160
49995
|
try {
|
|
49996
|
+
if (source === "api" && !loadConfig().allowServerApiProxy) {
|
|
49997
|
+
this.sendResult(msg, false, {
|
|
49998
|
+
error: "Server API relay is disabled on this daemon. Enable it explicitly with `adhdev daemon:api enable`.",
|
|
49999
|
+
code: "SERVER_API_DISABLED"
|
|
50000
|
+
});
|
|
50001
|
+
return;
|
|
50002
|
+
}
|
|
49161
50003
|
const result = await this.components.router.execute(cmd, args, source);
|
|
49162
50004
|
if (cmd.startsWith("workspace_")) this.statusReporter?.throttledReport();
|
|
50005
|
+
if (cmd === "get_status_metadata" || cmd.startsWith("workspace_") || cmd.startsWith("session_host_")) {
|
|
50006
|
+
void this.flushP2PDaemonMetadataSubscriptions();
|
|
50007
|
+
}
|
|
50008
|
+
if (cmd.startsWith("session_host_")) {
|
|
50009
|
+
void this.flushP2PSessionHostDiagnosticsSubscriptions();
|
|
50010
|
+
}
|
|
50011
|
+
if (cmd === "resolve_action" || cmd === "send_chat" || cmd === "read_chat") {
|
|
50012
|
+
void this.flushP2PSessionModalSubscriptions();
|
|
50013
|
+
}
|
|
49163
50014
|
this.sendResult(msg, result.success, result);
|
|
49164
50015
|
} catch (e) {
|
|
49165
50016
|
console.error(import_chalk2.default.red(` \u2717 Command failed: ${e.message}`));
|
|
@@ -49199,6 +50050,7 @@ ${err?.stack || ""}`);
|
|
|
49199
50050
|
const config2 = loadConfig();
|
|
49200
50051
|
config2.machineNickname = nickname;
|
|
49201
50052
|
saveConfig(config2);
|
|
50053
|
+
void this.flushP2PDaemonMetadataSubscriptions();
|
|
49202
50054
|
logCommand({ ts: (/* @__PURE__ */ new Date()).toISOString(), cmd: cmdType, source: "p2p", args: { nickname }, success: true, durationMs: Date.now() - cmdStart });
|
|
49203
50055
|
return { success: true, nickname };
|
|
49204
50056
|
}
|
|
@@ -49211,6 +50063,15 @@ ${err?.stack || ""}`);
|
|
|
49211
50063
|
}
|
|
49212
50064
|
const routed = await this.components.router.execute(cmdType, data, "p2p");
|
|
49213
50065
|
if (cmdType.startsWith("workspace_")) this.statusReporter?.throttledReport();
|
|
50066
|
+
if (cmdType === "get_status_metadata" || cmdType.startsWith("workspace_") || cmdType.startsWith("session_host_")) {
|
|
50067
|
+
void this.flushP2PDaemonMetadataSubscriptions();
|
|
50068
|
+
}
|
|
50069
|
+
if (cmdType.startsWith("session_host_")) {
|
|
50070
|
+
void this.flushP2PSessionHostDiagnosticsSubscriptions();
|
|
50071
|
+
}
|
|
50072
|
+
if (cmdType === "resolve_action" || cmdType === "send_chat" || cmdType === "read_chat") {
|
|
50073
|
+
void this.flushP2PSessionModalSubscriptions();
|
|
50074
|
+
}
|
|
49214
50075
|
return routed;
|
|
49215
50076
|
} catch (e) {
|
|
49216
50077
|
logCommand({ ts: (/* @__PURE__ */ new Date()).toISOString(), cmd: cmdType, source: "p2p", success: false, error: e.message, durationMs: Date.now() - cmdStart });
|
|
@@ -49383,6 +50244,10 @@ ${err?.stack || ""}`);
|
|
|
49383
50244
|
this.statusReporter.stopReporting();
|
|
49384
50245
|
this.statusReporter = null;
|
|
49385
50246
|
}
|
|
50247
|
+
if (this.topicSubscriptionTimer) {
|
|
50248
|
+
clearInterval(this.topicSubscriptionTimer);
|
|
50249
|
+
this.topicSubscriptionTimer = null;
|
|
50250
|
+
}
|
|
49386
50251
|
if (this.components) {
|
|
49387
50252
|
await shutdownDaemonComponents(this.components);
|
|
49388
50253
|
}
|