@adhdev/daemon-core 0.7.40 → 0.7.42
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-adapters/provider-cli-adapter.d.ts +1 -0
- package/dist/commands/cli-manager.d.ts +3 -0
- package/dist/config/config.d.ts +2 -22
- package/dist/index.js +310 -34
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +310 -34
- package/dist/index.mjs.map +1 -1
- package/dist/providers/cli-provider-instance.d.ts +3 -0
- package/dist/providers/extension-provider-instance.d.ts +1 -0
- package/dist/shared-types.d.ts +2 -0
- package/dist/status/normalize.js +67 -1
- package/dist/status/normalize.js.map +1 -1
- package/dist/status/normalize.mjs +67 -1
- package/dist/status/normalize.mjs.map +1 -1
- package/dist/status/reporter.d.ts +1 -0
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +1 -1
- package/src/agent-stream/forward.ts +21 -1
- package/src/agent-stream/poller.ts +6 -1
- package/src/cli-adapters/provider-cli-adapter.ts +37 -2
- package/src/commands/cli-manager.ts +45 -2
- package/src/commands/router.ts +1 -0
- package/src/commands/stream-commands.ts +14 -0
- package/src/config/config.d.ts +5 -50
- package/src/config/config.ts +71 -49
- package/src/config/workspaces.d.ts +1 -4
- package/src/providers/cli-provider-instance.ts +18 -5
- package/src/providers/contracts.ts +0 -1
- package/src/providers/extension-provider-instance.ts +27 -0
- package/src/providers/ide-provider-instance.ts +12 -0
- package/src/shared-types.ts +2 -0
- package/src/status/builders.ts +8 -1
- package/src/status/normalize.ts +85 -0
- package/src/status/reporter.ts +31 -2
package/dist/index.js
CHANGED
|
@@ -33,7 +33,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
33
33
|
// src/config/config.ts
|
|
34
34
|
var config_exports = {};
|
|
35
35
|
__export(config_exports, {
|
|
36
|
-
generateConnectionToken: () => generateConnectionToken,
|
|
37
36
|
generateMachineId: () => generateMachineId,
|
|
38
37
|
getConfigDir: () => getConfigDir,
|
|
39
38
|
isSetupComplete: () => isSetupComplete,
|
|
@@ -44,6 +43,57 @@ __export(config_exports, {
|
|
|
44
43
|
saveConfig: () => saveConfig,
|
|
45
44
|
updateConfig: () => updateConfig
|
|
46
45
|
});
|
|
46
|
+
function isPlainObject(value) {
|
|
47
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
48
|
+
}
|
|
49
|
+
function asStringArray(value) {
|
|
50
|
+
if (!Array.isArray(value)) return [];
|
|
51
|
+
return value.filter((item) => typeof item === "string");
|
|
52
|
+
}
|
|
53
|
+
function asNullableString(value) {
|
|
54
|
+
return typeof value === "string" ? value : null;
|
|
55
|
+
}
|
|
56
|
+
function asOptionalString(value) {
|
|
57
|
+
return typeof value === "string" && value.trim() ? value : void 0;
|
|
58
|
+
}
|
|
59
|
+
function asBoolean(value, fallback) {
|
|
60
|
+
return typeof value === "boolean" ? value : fallback;
|
|
61
|
+
}
|
|
62
|
+
function normalizeConfig(raw) {
|
|
63
|
+
const parsed = isPlainObject(raw) ? raw : {};
|
|
64
|
+
const legacySessionReads = isPlainObject(parsed.recentSessionReads) ? parsed.recentSessionReads : {};
|
|
65
|
+
const sessionReads = isPlainObject(parsed.sessionReads) ? parsed.sessionReads : {};
|
|
66
|
+
const mergedSessionReads = Object.fromEntries(
|
|
67
|
+
Object.entries({ ...legacySessionReads, ...sessionReads }).filter(([, value]) => typeof value === "number" && Number.isFinite(value))
|
|
68
|
+
);
|
|
69
|
+
const sessionReadMarkers = Object.fromEntries(
|
|
70
|
+
Object.entries(isPlainObject(parsed.sessionReadMarkers) ? parsed.sessionReadMarkers : {}).filter(([, value]) => typeof value === "string")
|
|
71
|
+
);
|
|
72
|
+
return {
|
|
73
|
+
serverUrl: typeof parsed.serverUrl === "string" && parsed.serverUrl.trim() ? parsed.serverUrl : DEFAULT_CONFIG.serverUrl,
|
|
74
|
+
selectedIde: asNullableString(parsed.selectedIde),
|
|
75
|
+
configuredIdes: asStringArray(parsed.configuredIdes),
|
|
76
|
+
installedExtensions: asStringArray(parsed.installedExtensions),
|
|
77
|
+
userEmail: asNullableString(parsed.userEmail),
|
|
78
|
+
userName: asNullableString(parsed.userName),
|
|
79
|
+
setupCompleted: asBoolean(parsed.setupCompleted, DEFAULT_CONFIG.setupCompleted),
|
|
80
|
+
setupDate: asNullableString(parsed.setupDate),
|
|
81
|
+
enabledIdes: asStringArray(parsed.enabledIdes),
|
|
82
|
+
workspaces: Array.isArray(parsed.workspaces) ? parsed.workspaces : [],
|
|
83
|
+
defaultWorkspaceId: asNullableString(parsed.defaultWorkspaceId) ?? asNullableString(parsed.activeWorkspaceId),
|
|
84
|
+
recentActivity: Array.isArray(parsed.recentActivity) ? parsed.recentActivity : [],
|
|
85
|
+
sessionReads: mergedSessionReads,
|
|
86
|
+
sessionReadMarkers,
|
|
87
|
+
machineNickname: asNullableString(parsed.machineNickname),
|
|
88
|
+
machineId: asOptionalString(parsed.machineId),
|
|
89
|
+
machineSecret: parsed.machineSecret === null ? null : asOptionalString(parsed.machineSecret),
|
|
90
|
+
registeredMachineId: asOptionalString(parsed.registeredMachineId),
|
|
91
|
+
providerSettings: isPlainObject(parsed.providerSettings) ? parsed.providerSettings : {},
|
|
92
|
+
ideSettings: isPlainObject(parsed.ideSettings) ? parsed.ideSettings : {},
|
|
93
|
+
disableUpstream: asBoolean(parsed.disableUpstream, DEFAULT_CONFIG.disableUpstream ?? false),
|
|
94
|
+
providerDir: asOptionalString(parsed.providerDir)
|
|
95
|
+
};
|
|
96
|
+
}
|
|
47
97
|
function generateMachineId() {
|
|
48
98
|
return `${MACHINE_ID_PREFIX}${(0, import_crypto.randomUUID)().replace(/-/g, "")}`;
|
|
49
99
|
}
|
|
@@ -87,14 +137,10 @@ function loadConfig() {
|
|
|
87
137
|
try {
|
|
88
138
|
const raw = (0, import_fs.readFileSync)(configPath, "utf-8");
|
|
89
139
|
const parsed = JSON.parse(raw);
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
merged.defaultWorkspaceId = merged.activeWorkspaceId;
|
|
93
|
-
}
|
|
94
|
-
delete merged.activeWorkspaceId;
|
|
95
|
-
const ensured = ensureMachineId(merged);
|
|
140
|
+
const normalizedInput = normalizeConfig(parsed);
|
|
141
|
+
const ensured = ensureMachineId(normalizedInput);
|
|
96
142
|
const normalized = ensured.config;
|
|
97
|
-
if (ensured.changed) {
|
|
143
|
+
if (ensured.changed || JSON.stringify(parsed) !== JSON.stringify(normalized)) {
|
|
98
144
|
try {
|
|
99
145
|
saveConfig(normalized);
|
|
100
146
|
} catch {
|
|
@@ -109,10 +155,11 @@ function loadConfig() {
|
|
|
109
155
|
function saveConfig(config) {
|
|
110
156
|
const configPath = getConfigPath();
|
|
111
157
|
const dir = getConfigDir();
|
|
158
|
+
const normalized = normalizeConfig(config);
|
|
112
159
|
if (!(0, import_fs.existsSync)(dir)) {
|
|
113
160
|
(0, import_fs.mkdirSync)(dir, { recursive: true, mode: 448 });
|
|
114
161
|
}
|
|
115
|
-
(0, import_fs.writeFileSync)(configPath, JSON.stringify(
|
|
162
|
+
(0, import_fs.writeFileSync)(configPath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
|
|
116
163
|
try {
|
|
117
164
|
(0, import_fs.chmodSync)(configPath, 384);
|
|
118
165
|
} catch {
|
|
@@ -141,14 +188,6 @@ function isSetupComplete() {
|
|
|
141
188
|
function resetConfig() {
|
|
142
189
|
saveConfig({ ...DEFAULT_CONFIG });
|
|
143
190
|
}
|
|
144
|
-
function generateConnectionToken() {
|
|
145
|
-
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
146
|
-
let token = "db_";
|
|
147
|
-
for (let i = 0; i < 32; i++) {
|
|
148
|
-
token += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
149
|
-
}
|
|
150
|
-
return token;
|
|
151
|
-
}
|
|
152
191
|
var import_os, import_path, import_fs, import_crypto, DEFAULT_CONFIG, MACHINE_ID_PREFIX;
|
|
153
192
|
var init_config = __esm({
|
|
154
193
|
"src/config/config.ts"() {
|
|
@@ -159,18 +198,13 @@ var init_config = __esm({
|
|
|
159
198
|
import_crypto = require("crypto");
|
|
160
199
|
DEFAULT_CONFIG = {
|
|
161
200
|
serverUrl: "https://api.adhf.dev",
|
|
162
|
-
apiToken: null,
|
|
163
|
-
connectionToken: null,
|
|
164
201
|
selectedIde: null,
|
|
165
202
|
configuredIdes: [],
|
|
166
203
|
installedExtensions: [],
|
|
167
|
-
autoConnect: true,
|
|
168
|
-
notifications: true,
|
|
169
204
|
userEmail: null,
|
|
170
205
|
userName: null,
|
|
171
206
|
setupCompleted: false,
|
|
172
207
|
setupDate: null,
|
|
173
|
-
configuredCLIs: [],
|
|
174
208
|
enabledIdes: [],
|
|
175
209
|
workspaces: [],
|
|
176
210
|
defaultWorkspaceId: null,
|
|
@@ -983,6 +1017,13 @@ var init_provider_cli_adapter = __esm({
|
|
|
983
1017
|
this.messages = [...this.committedMessages];
|
|
984
1018
|
this.structuredMessages = [...this.committedMessages];
|
|
985
1019
|
}
|
|
1020
|
+
normalizeParsedMessages(parsedMessages) {
|
|
1021
|
+
return parsedMessages.filter((message) => message && (message.role === "user" || message.role === "assistant")).map((message) => ({
|
|
1022
|
+
role: message.role,
|
|
1023
|
+
content: typeof message.content === "string" ? message.content : String(message.content || ""),
|
|
1024
|
+
timestamp: typeof message.timestamp === "number" && Number.isFinite(message.timestamp) ? message.timestamp : Date.now()
|
|
1025
|
+
}));
|
|
1026
|
+
}
|
|
986
1027
|
sliceFromOffset(text, start) {
|
|
987
1028
|
if (!text) return "";
|
|
988
1029
|
if (!Number.isFinite(start) || start <= 0) return text;
|
|
@@ -1379,6 +1420,15 @@ var init_provider_cli_adapter = __esm({
|
|
|
1379
1420
|
this.onStatusChange?.();
|
|
1380
1421
|
}
|
|
1381
1422
|
commitCurrentTranscript() {
|
|
1423
|
+
const parsed = this.parseCurrentTranscript(
|
|
1424
|
+
this.committedMessages,
|
|
1425
|
+
this.responseBuffer,
|
|
1426
|
+
this.currentTurnScope
|
|
1427
|
+
);
|
|
1428
|
+
if (parsed && Array.isArray(parsed.messages)) {
|
|
1429
|
+
this.committedMessages = this.normalizeParsedMessages(parsed.messages);
|
|
1430
|
+
this.syncMessageViews();
|
|
1431
|
+
}
|
|
1382
1432
|
}
|
|
1383
1433
|
// ─── Script Execution ──────────────────────────
|
|
1384
1434
|
runDetectStatus(text) {
|
|
@@ -1423,6 +1473,21 @@ var init_provider_cli_adapter = __esm({
|
|
|
1423
1473
|
* Called by command handler / dashboard for rich content rendering.
|
|
1424
1474
|
*/
|
|
1425
1475
|
getScriptParsedStatus() {
|
|
1476
|
+
const parsed = this.parseCurrentTranscript(
|
|
1477
|
+
this.committedMessages,
|
|
1478
|
+
this.responseBuffer,
|
|
1479
|
+
this.currentTurnScope
|
|
1480
|
+
);
|
|
1481
|
+
if (parsed && Array.isArray(parsed.messages)) {
|
|
1482
|
+
return {
|
|
1483
|
+
id: parsed.id || "cli_session",
|
|
1484
|
+
status: parsed.status || this.currentStatus,
|
|
1485
|
+
title: parsed.title || this.cliName,
|
|
1486
|
+
terminalHistory: this.terminalHistory,
|
|
1487
|
+
messages: parsed.messages,
|
|
1488
|
+
activeModal: parsed.activeModal ?? this.activeModal
|
|
1489
|
+
};
|
|
1490
|
+
}
|
|
1426
1491
|
const messages = [...this.committedMessages];
|
|
1427
1492
|
return {
|
|
1428
1493
|
id: "cli_session",
|
|
@@ -3823,6 +3888,8 @@ var ExtensionProviderInstance = class {
|
|
|
3823
3888
|
this.detectTransition(newStatus, data);
|
|
3824
3889
|
this.currentStatus = newStatus;
|
|
3825
3890
|
}
|
|
3891
|
+
} else if (event === "stream_reset") {
|
|
3892
|
+
this.resetStreamState();
|
|
3826
3893
|
} else if (event === "extension_connected") {
|
|
3827
3894
|
this.ideType = data?.ideType || "";
|
|
3828
3895
|
}
|
|
@@ -3902,6 +3969,30 @@ var ExtensionProviderInstance = class {
|
|
|
3902
3969
|
const title = typeof data?.title === "string" && data.title.trim() ? data.title.trim() : this.chatTitle;
|
|
3903
3970
|
return title || this.agentName || this.provider.name;
|
|
3904
3971
|
}
|
|
3972
|
+
resetStreamState() {
|
|
3973
|
+
if (this.currentStatus !== "idle") {
|
|
3974
|
+
this.detectTransition("idle", {
|
|
3975
|
+
title: this.chatTitle,
|
|
3976
|
+
agentName: this.agentName,
|
|
3977
|
+
extensionId: this.extensionId,
|
|
3978
|
+
messages: this.messages
|
|
3979
|
+
});
|
|
3980
|
+
}
|
|
3981
|
+
this.agentStreams = [];
|
|
3982
|
+
this.messages = [];
|
|
3983
|
+
this.activeModal = null;
|
|
3984
|
+
this.currentModel = "";
|
|
3985
|
+
this.currentMode = "";
|
|
3986
|
+
this.controlValues = {};
|
|
3987
|
+
this.currentStatus = "idle";
|
|
3988
|
+
this.chatId = null;
|
|
3989
|
+
this.chatTitle = null;
|
|
3990
|
+
this.agentName = "";
|
|
3991
|
+
this.extensionId = "";
|
|
3992
|
+
this.lastAgentStatus = "idle";
|
|
3993
|
+
this.generatingStartedAt = 0;
|
|
3994
|
+
this.monitor.reset();
|
|
3995
|
+
}
|
|
3905
3996
|
};
|
|
3906
3997
|
|
|
3907
3998
|
// src/config/chat-history.ts
|
|
@@ -4184,11 +4275,23 @@ var IdeProviderInstance = class {
|
|
|
4184
4275
|
} else if (event === "cdp_disconnected") {
|
|
4185
4276
|
this.cachedChat = null;
|
|
4186
4277
|
this.currentStatus = "idle";
|
|
4278
|
+
for (const ext of this.extensions.values()) {
|
|
4279
|
+
ext.onEvent("stream_reset");
|
|
4280
|
+
}
|
|
4187
4281
|
} else if (event === "stream_update") {
|
|
4188
4282
|
const extType = data?.extensionType;
|
|
4189
4283
|
if (extType && this.extensions.has(extType)) {
|
|
4190
4284
|
this.extensions.get(extType).onEvent("stream_update", data);
|
|
4191
4285
|
}
|
|
4286
|
+
} else if (event === "stream_reset") {
|
|
4287
|
+
const extType = data?.extensionType;
|
|
4288
|
+
if (extType && this.extensions.has(extType)) {
|
|
4289
|
+
this.extensions.get(extType).onEvent("stream_reset");
|
|
4290
|
+
}
|
|
4291
|
+
} else if (event === "stream_reset_all") {
|
|
4292
|
+
for (const ext of this.extensions.values()) {
|
|
4293
|
+
ext.onEvent("stream_reset");
|
|
4294
|
+
}
|
|
4192
4295
|
}
|
|
4193
4296
|
}
|
|
4194
4297
|
dispose() {
|
|
@@ -4855,6 +4958,63 @@ var WORKING_STATUSES = /* @__PURE__ */ new Set([
|
|
|
4855
4958
|
"thinking",
|
|
4856
4959
|
"active"
|
|
4857
4960
|
]);
|
|
4961
|
+
var STATUS_ACTIVE_CHAT_MESSAGE_LIMIT = 60;
|
|
4962
|
+
var STATUS_ACTIVE_CHAT_TOTAL_BYTES_LIMIT = 96 * 1024;
|
|
4963
|
+
var STATUS_ACTIVE_CHAT_STRING_LIMIT = 4 * 1024;
|
|
4964
|
+
var STATUS_ACTIVE_CHAT_FALLBACK_STRING_LIMIT = 1024;
|
|
4965
|
+
var STATUS_TERMINAL_HISTORY_LIMIT = 8 * 1024;
|
|
4966
|
+
var STATUS_INPUT_CONTENT_LIMIT = 2 * 1024;
|
|
4967
|
+
var STATUS_MODAL_MESSAGE_LIMIT = 2 * 1024;
|
|
4968
|
+
var STATUS_MODAL_BUTTON_LIMIT = 120;
|
|
4969
|
+
function truncateString(value, maxChars) {
|
|
4970
|
+
if (value.length <= maxChars) return value;
|
|
4971
|
+
if (maxChars <= 12) return value.slice(0, Math.max(0, maxChars));
|
|
4972
|
+
return `${value.slice(0, maxChars - 12)}...[truncated]`;
|
|
4973
|
+
}
|
|
4974
|
+
function truncateStringTail(value, maxChars) {
|
|
4975
|
+
if (value.length <= maxChars) return value;
|
|
4976
|
+
if (maxChars <= 12) return value.slice(value.length - Math.max(0, maxChars));
|
|
4977
|
+
return `...[truncated]${value.slice(value.length - (maxChars - 12))}`;
|
|
4978
|
+
}
|
|
4979
|
+
function trimStructuredStrings(value, maxChars) {
|
|
4980
|
+
if (typeof value === "string") return truncateString(value, maxChars);
|
|
4981
|
+
if (Array.isArray(value)) return value.map((item) => trimStructuredStrings(item, maxChars));
|
|
4982
|
+
if (!value || typeof value !== "object") return value;
|
|
4983
|
+
return Object.fromEntries(
|
|
4984
|
+
Object.entries(value).map(([key, nested]) => [key, trimStructuredStrings(nested, maxChars)])
|
|
4985
|
+
);
|
|
4986
|
+
}
|
|
4987
|
+
function estimateBytes(value) {
|
|
4988
|
+
try {
|
|
4989
|
+
return JSON.stringify(value).length;
|
|
4990
|
+
} catch {
|
|
4991
|
+
return String(value ?? "").length;
|
|
4992
|
+
}
|
|
4993
|
+
}
|
|
4994
|
+
function trimMessageForStatus(message, stringLimit) {
|
|
4995
|
+
if (!message || typeof message !== "object") return message;
|
|
4996
|
+
return trimStructuredStrings(message, stringLimit);
|
|
4997
|
+
}
|
|
4998
|
+
function trimMessagesForStatus(messages) {
|
|
4999
|
+
if (!Array.isArray(messages) || messages.length === 0) return [];
|
|
5000
|
+
const recent = messages.slice(-STATUS_ACTIVE_CHAT_MESSAGE_LIMIT);
|
|
5001
|
+
const kept = [];
|
|
5002
|
+
let totalBytes = 0;
|
|
5003
|
+
for (let i = recent.length - 1; i >= 0; i -= 1) {
|
|
5004
|
+
let normalized = trimMessageForStatus(recent[i], STATUS_ACTIVE_CHAT_STRING_LIMIT);
|
|
5005
|
+
let size = estimateBytes(normalized);
|
|
5006
|
+
if (size > STATUS_ACTIVE_CHAT_TOTAL_BYTES_LIMIT) {
|
|
5007
|
+
normalized = trimMessageForStatus(recent[i], STATUS_ACTIVE_CHAT_FALLBACK_STRING_LIMIT);
|
|
5008
|
+
size = estimateBytes(normalized);
|
|
5009
|
+
}
|
|
5010
|
+
if (kept.length > 0 && totalBytes + size > STATUS_ACTIVE_CHAT_TOTAL_BYTES_LIMIT) {
|
|
5011
|
+
continue;
|
|
5012
|
+
}
|
|
5013
|
+
kept.push(normalized);
|
|
5014
|
+
totalBytes += size;
|
|
5015
|
+
}
|
|
5016
|
+
return kept.reverse();
|
|
5017
|
+
}
|
|
4858
5018
|
function hasApprovalButtons(activeModal) {
|
|
4859
5019
|
return (activeModal?.buttons?.length ?? 0) > 0;
|
|
4860
5020
|
}
|
|
@@ -4881,7 +5041,16 @@ function normalizeActiveChatData(activeChat) {
|
|
|
4881
5041
|
if (!activeChat) return activeChat;
|
|
4882
5042
|
return {
|
|
4883
5043
|
...activeChat,
|
|
4884
|
-
status: normalizeManagedStatus(activeChat.status, { activeModal: activeChat.activeModal })
|
|
5044
|
+
status: normalizeManagedStatus(activeChat.status, { activeModal: activeChat.activeModal }),
|
|
5045
|
+
messages: trimMessagesForStatus(activeChat.messages),
|
|
5046
|
+
activeModal: activeChat.activeModal ? {
|
|
5047
|
+
message: truncateString(activeChat.activeModal.message || "", STATUS_MODAL_MESSAGE_LIMIT),
|
|
5048
|
+
buttons: (activeChat.activeModal.buttons || []).map(
|
|
5049
|
+
(button) => truncateString(String(button || ""), STATUS_MODAL_BUTTON_LIMIT)
|
|
5050
|
+
)
|
|
5051
|
+
} : activeChat.activeModal,
|
|
5052
|
+
terminalHistory: activeChat.terminalHistory ? truncateStringTail(activeChat.terminalHistory, STATUS_TERMINAL_HISTORY_LIMIT) : activeChat.terminalHistory,
|
|
5053
|
+
inputContent: activeChat.inputContent ? truncateString(activeChat.inputContent, STATUS_INPUT_CONTENT_LIMIT) : activeChat.inputContent
|
|
4885
5054
|
};
|
|
4886
5055
|
}
|
|
4887
5056
|
|
|
@@ -4979,6 +5148,11 @@ var PTY_SESSION_CAPABILITIES = [
|
|
|
4979
5148
|
"terminal_io",
|
|
4980
5149
|
"resize_terminal"
|
|
4981
5150
|
];
|
|
5151
|
+
var CLI_CHAT_SESSION_CAPABILITIES = [
|
|
5152
|
+
"read_chat",
|
|
5153
|
+
"send_message",
|
|
5154
|
+
"resolve_action"
|
|
5155
|
+
];
|
|
4982
5156
|
var ACP_SESSION_CAPABILITIES = [
|
|
4983
5157
|
"read_chat",
|
|
4984
5158
|
"send_message",
|
|
@@ -5068,9 +5242,10 @@ function buildCliSession(state) {
|
|
|
5068
5242
|
runtimeWorkspaceLabel: state.runtime?.workspaceLabel,
|
|
5069
5243
|
runtimeWriteOwner: state.runtime?.writeOwner || null,
|
|
5070
5244
|
runtimeAttachedClients: state.runtime?.attachedClients || [],
|
|
5245
|
+
mode: state.mode,
|
|
5071
5246
|
resume: state.resume,
|
|
5072
5247
|
activeChat,
|
|
5073
|
-
capabilities: PTY_SESSION_CAPABILITIES,
|
|
5248
|
+
capabilities: state.mode === "terminal" ? PTY_SESSION_CAPABILITIES : CLI_CHAT_SESSION_CAPABILITIES,
|
|
5074
5249
|
controlValues: state.controlValues,
|
|
5075
5250
|
providerControls: buildFallbackControls(
|
|
5076
5251
|
state.providerControls
|
|
@@ -6244,6 +6419,13 @@ async function handleFileListBrowse(h, args) {
|
|
|
6244
6419
|
|
|
6245
6420
|
// src/commands/stream-commands.ts
|
|
6246
6421
|
init_logger();
|
|
6422
|
+
function getCliPresentationMode(h, targetSessionId) {
|
|
6423
|
+
if (!targetSessionId) return null;
|
|
6424
|
+
const instance = h.ctx.instanceManager?.getInstance(targetSessionId);
|
|
6425
|
+
if (instance?.category !== "cli") return null;
|
|
6426
|
+
const mode = instance.getPresentationMode?.();
|
|
6427
|
+
return mode === "chat" || mode === "terminal" ? mode : null;
|
|
6428
|
+
}
|
|
6247
6429
|
async function handleFocusSession(h, args) {
|
|
6248
6430
|
if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
|
|
6249
6431
|
const sessionId = args?.targetSessionId || h.currentSession?.sessionId;
|
|
@@ -6254,6 +6436,9 @@ async function handleFocusSession(h, args) {
|
|
|
6254
6436
|
function handlePtyInput(h, args) {
|
|
6255
6437
|
const { cliType, data, targetSessionId } = args || {};
|
|
6256
6438
|
if (!data) return { success: false, error: "data required" };
|
|
6439
|
+
if (getCliPresentationMode(h, targetSessionId) === "chat") {
|
|
6440
|
+
return { success: false, error: "CLI session is in chat mode", code: "CLI_VIEW_MODE_NOT_TERMINAL" };
|
|
6441
|
+
}
|
|
6257
6442
|
const adapter = h.getCliAdapter(targetSessionId || cliType);
|
|
6258
6443
|
if (!adapter || typeof adapter.writeRaw !== "function") {
|
|
6259
6444
|
return { success: false, error: `CLI adapter not found: ${targetSessionId || cliType || "unknown"}` };
|
|
@@ -6264,6 +6449,9 @@ function handlePtyInput(h, args) {
|
|
|
6264
6449
|
function handlePtyResize(h, args) {
|
|
6265
6450
|
const { cliType, cols, rows, force, targetSessionId } = args || {};
|
|
6266
6451
|
if (!cols || !rows) return { success: false, error: "cols and rows required" };
|
|
6452
|
+
if (getCliPresentationMode(h, targetSessionId) === "chat") {
|
|
6453
|
+
return { success: false, error: "CLI session is in chat mode", code: "CLI_VIEW_MODE_NOT_TERMINAL" };
|
|
6454
|
+
}
|
|
6267
6455
|
const adapter = h.getCliAdapter(targetSessionId || cliType);
|
|
6268
6456
|
if (!adapter || typeof adapter.resize !== "function") {
|
|
6269
6457
|
return { success: false, error: `CLI adapter not found: ${targetSessionId || cliType || "unknown"}` };
|
|
@@ -8671,6 +8859,7 @@ var DaemonCommandRouter = class {
|
|
|
8671
8859
|
// ─── CLI / ACP commands ───
|
|
8672
8860
|
case "launch_cli":
|
|
8673
8861
|
case "stop_cli":
|
|
8862
|
+
case "set_cli_view_mode":
|
|
8674
8863
|
case "agent_command": {
|
|
8675
8864
|
return this.deps.cliManager.handleCliCommand(cmd, args);
|
|
8676
8865
|
}
|
|
@@ -9015,6 +9204,20 @@ var DaemonStatusReporter = class {
|
|
|
9015
9204
|
ts() {
|
|
9016
9205
|
return (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
9017
9206
|
}
|
|
9207
|
+
summarizeLargePayloadSessions(payload) {
|
|
9208
|
+
const sessions = Array.isArray(payload.sessions) ? payload.sessions : [];
|
|
9209
|
+
return sessions.map((session) => ({
|
|
9210
|
+
id: String(session?.id || ""),
|
|
9211
|
+
providerType: String(session?.providerType || ""),
|
|
9212
|
+
bytes: (() => {
|
|
9213
|
+
try {
|
|
9214
|
+
return JSON.stringify(session).length;
|
|
9215
|
+
} catch {
|
|
9216
|
+
return 0;
|
|
9217
|
+
}
|
|
9218
|
+
})()
|
|
9219
|
+
})).sort((a, b) => b.bytes - a.bytes).slice(0, 3).map((session) => `${session.providerType || "unknown"}:${session.id}=${session.bytes}b`).join(", ");
|
|
9220
|
+
}
|
|
9018
9221
|
async sendUnifiedStatusReport(opts) {
|
|
9019
9222
|
const { serverConn, p2p } = this.deps;
|
|
9020
9223
|
if (!serverConn?.isConnected()) return;
|
|
@@ -9067,9 +9270,16 @@ var DaemonStatusReporter = class {
|
|
|
9067
9270
|
screenshotUsage: this.deps.getScreenshotUsage?.() || null,
|
|
9068
9271
|
connectedExtensions: []
|
|
9069
9272
|
};
|
|
9273
|
+
const payloadBytes = JSON.stringify(payload).length;
|
|
9070
9274
|
const p2pSent = this.sendP2PPayload(payload);
|
|
9071
9275
|
if (p2pSent) {
|
|
9072
|
-
LOG.debug("P2P", `sent (${
|
|
9276
|
+
LOG.debug("P2P", `sent (${payloadBytes} bytes)`);
|
|
9277
|
+
if (payloadBytes > 256 * 1024) {
|
|
9278
|
+
LOG.warn(
|
|
9279
|
+
"P2P",
|
|
9280
|
+
`large status payload (${payloadBytes} bytes) top sessions: ${this.summarizeLargePayloadSessions(payload) || "n/a"}`
|
|
9281
|
+
);
|
|
9282
|
+
}
|
|
9073
9283
|
}
|
|
9074
9284
|
if (opts?.p2pOnly) return;
|
|
9075
9285
|
const wsPayload = {
|
|
@@ -9099,7 +9309,9 @@ var DaemonStatusReporter = class {
|
|
|
9099
9309
|
acpModes: session.acpModes
|
|
9100
9310
|
})),
|
|
9101
9311
|
p2p: payload.p2p,
|
|
9102
|
-
timestamp: now
|
|
9312
|
+
timestamp: now,
|
|
9313
|
+
detectedIdes: payload.detectedIdes,
|
|
9314
|
+
availableProviders: payload.availableProviders
|
|
9103
9315
|
};
|
|
9104
9316
|
serverConn.sendMessage("status_report", wsPayload);
|
|
9105
9317
|
LOG.debug("Server", `sent status_report (${JSON.stringify(wsPayload).length} bytes)`);
|
|
@@ -9151,6 +9363,7 @@ var CliProviderInstance = class {
|
|
|
9151
9363
|
this.cliArgs = cliArgs;
|
|
9152
9364
|
this.type = provider.type;
|
|
9153
9365
|
this.instanceId = instanceId || crypto3.randomUUID();
|
|
9366
|
+
this.presentationMode = "terminal";
|
|
9154
9367
|
this.adapter = new ProviderCliAdapter(provider, workingDir, cliArgs, transportFactory);
|
|
9155
9368
|
this.monitor = new StatusMonitor();
|
|
9156
9369
|
this.historyWriter = new ChatHistoryWriter();
|
|
@@ -9169,6 +9382,7 @@ var CliProviderInstance = class {
|
|
|
9169
9382
|
lastApprovalEventAt = 0;
|
|
9170
9383
|
historyWriter;
|
|
9171
9384
|
instanceId;
|
|
9385
|
+
presentationMode;
|
|
9172
9386
|
// ─── Lifecycle ─────────────────────────────────
|
|
9173
9387
|
async init(context) {
|
|
9174
9388
|
this.context = context;
|
|
@@ -9193,6 +9407,7 @@ var CliProviderInstance = class {
|
|
|
9193
9407
|
}
|
|
9194
9408
|
getState() {
|
|
9195
9409
|
const adapterStatus = this.adapter.getStatus();
|
|
9410
|
+
const parsedStatus = this.adapter.getScriptParsedStatus?.() || null;
|
|
9196
9411
|
const runtime = this.adapter.getRuntimeMetadata();
|
|
9197
9412
|
const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
|
|
9198
9413
|
if (adapterStatus.terminalHistory?.trim()) {
|
|
@@ -9208,13 +9423,13 @@ var CliProviderInstance = class {
|
|
|
9208
9423
|
name: this.provider.name,
|
|
9209
9424
|
category: "cli",
|
|
9210
9425
|
status: adapterStatus.status,
|
|
9211
|
-
mode:
|
|
9426
|
+
mode: this.presentationMode,
|
|
9212
9427
|
activeChat: {
|
|
9213
9428
|
id: `${this.type}_${this.workingDir}`,
|
|
9214
|
-
title: `${this.provider.name} \xB7 ${dirName}`,
|
|
9215
|
-
status: adapterStatus.status,
|
|
9216
|
-
messages: [],
|
|
9217
|
-
activeModal: adapterStatus.activeModal,
|
|
9429
|
+
title: parsedStatus?.title || `${this.provider.name} \xB7 ${dirName}`,
|
|
9430
|
+
status: parsedStatus?.status || adapterStatus.status,
|
|
9431
|
+
messages: Array.isArray(parsedStatus?.messages) ? parsedStatus.messages : [],
|
|
9432
|
+
activeModal: parsedStatus?.activeModal ?? adapterStatus.activeModal,
|
|
9218
9433
|
terminalHistory: adapterStatus.terminalHistory,
|
|
9219
9434
|
inputContent: ""
|
|
9220
9435
|
},
|
|
@@ -9237,6 +9452,13 @@ var CliProviderInstance = class {
|
|
|
9237
9452
|
providerControls: this.provider.controls
|
|
9238
9453
|
};
|
|
9239
9454
|
}
|
|
9455
|
+
setPresentationMode(mode) {
|
|
9456
|
+
if (this.presentationMode === mode) return;
|
|
9457
|
+
this.presentationMode = mode;
|
|
9458
|
+
}
|
|
9459
|
+
getPresentationMode() {
|
|
9460
|
+
return this.presentationMode;
|
|
9461
|
+
}
|
|
9240
9462
|
onEvent(event, data) {
|
|
9241
9463
|
if (event === "send_message" && data?.text) {
|
|
9242
9464
|
void this.adapter.sendMessage(data.text).catch((e) => {
|
|
@@ -10295,6 +10517,15 @@ var DaemonCliManager = class {
|
|
|
10295
10517
|
const hash = require("crypto").createHash("md5").update(require("path").resolve(dir)).digest("hex").slice(0, 8);
|
|
10296
10518
|
return `${cliType}_${hash}`;
|
|
10297
10519
|
}
|
|
10520
|
+
getSessionPresentationMode(sessionId) {
|
|
10521
|
+
if (!sessionId) return null;
|
|
10522
|
+
const instance = this.deps.getInstanceManager()?.getInstance(sessionId);
|
|
10523
|
+
const mode = instance?.category === "cli" ? instance.getPresentationMode?.() : null;
|
|
10524
|
+
return mode === "chat" || mode === "terminal" ? mode : null;
|
|
10525
|
+
}
|
|
10526
|
+
isTerminalSession(sessionId) {
|
|
10527
|
+
return this.getSessionPresentationMode(sessionId) === "terminal";
|
|
10528
|
+
}
|
|
10298
10529
|
persistRecentActivity(entry) {
|
|
10299
10530
|
try {
|
|
10300
10531
|
saveConfig(appendRecentActivity(loadConfig(), entry));
|
|
@@ -10473,6 +10704,7 @@ ${installInfo}`
|
|
|
10473
10704
|
if (provider) {
|
|
10474
10705
|
console.log(colorize("cyan", ` \u{1F4E6} Using provider: ${provider.name} (${provider.type})`));
|
|
10475
10706
|
}
|
|
10707
|
+
const resolvedCliArgs = cliArgs;
|
|
10476
10708
|
const instanceManager = this.deps.getInstanceManager();
|
|
10477
10709
|
if (provider && instanceManager) {
|
|
10478
10710
|
const resolvedProvider = this.providerLoader.resolve(cliType, { version: cliInfo.version }) || provider;
|
|
@@ -10481,14 +10713,14 @@ ${installInfo}`
|
|
|
10481
10713
|
normalizedType,
|
|
10482
10714
|
cliType,
|
|
10483
10715
|
resolvedDir,
|
|
10484
|
-
|
|
10716
|
+
resolvedCliArgs,
|
|
10485
10717
|
resolvedProvider,
|
|
10486
10718
|
{},
|
|
10487
10719
|
false
|
|
10488
10720
|
);
|
|
10489
10721
|
console.log(colorize("green", ` \u2713 CLI started: ${cliInfo.displayName} v${cliInfo.version || "unknown"} in ${resolvedDir}`));
|
|
10490
10722
|
} else {
|
|
10491
|
-
const adapter = this.createAdapter(cliType, resolvedDir,
|
|
10723
|
+
const adapter = this.createAdapter(cliType, resolvedDir, resolvedCliArgs, key, false);
|
|
10492
10724
|
try {
|
|
10493
10725
|
await adapter.spawn();
|
|
10494
10726
|
} catch (spawnErr) {
|
|
@@ -10638,6 +10870,14 @@ ${installInfo}`
|
|
|
10638
10870
|
}
|
|
10639
10871
|
return null;
|
|
10640
10872
|
}
|
|
10873
|
+
findAdapterBySessionId(instanceKey) {
|
|
10874
|
+
if (!instanceKey) return null;
|
|
10875
|
+
let ik = instanceKey;
|
|
10876
|
+
const colonIdx = ik.lastIndexOf(":");
|
|
10877
|
+
if (colonIdx >= 0) ik = ik.substring(colonIdx + 1);
|
|
10878
|
+
const adapter = this.adapters.get(ik);
|
|
10879
|
+
return adapter ? { adapter, key: ik } : null;
|
|
10880
|
+
}
|
|
10641
10881
|
// ─── CLI command handling ────────────────────────────
|
|
10642
10882
|
async handleCliCommand(cmd, args) {
|
|
10643
10883
|
switch (cmd) {
|
|
@@ -10688,6 +10928,23 @@ ${installInfo}`
|
|
|
10688
10928
|
}
|
|
10689
10929
|
return { success: true, cliType, dir, stopped: true, mode };
|
|
10690
10930
|
}
|
|
10931
|
+
case "set_cli_view_mode": {
|
|
10932
|
+
const mode = args?.mode === "chat" ? "chat" : "terminal";
|
|
10933
|
+
const targetSessionId = typeof args?.targetSessionId === "string" ? args.targetSessionId : "";
|
|
10934
|
+
const cliType = args?.cliType || args?.agentType || "";
|
|
10935
|
+
const dir = args?.dir || "";
|
|
10936
|
+
const found = this.findAdapterBySessionId(targetSessionId) || (cliType ? this.findAdapter(cliType, { instanceKey: targetSessionId, dir }) : null);
|
|
10937
|
+
if (!found) {
|
|
10938
|
+
return { success: false, error: "CLI session not found", code: "CLI_SESSION_NOT_FOUND" };
|
|
10939
|
+
}
|
|
10940
|
+
const instance = this.deps.getInstanceManager()?.getInstance(found.key);
|
|
10941
|
+
if (!(instance instanceof CliProviderInstance)) {
|
|
10942
|
+
return { success: false, error: "CLI instance not found", code: "CLI_INSTANCE_NOT_FOUND" };
|
|
10943
|
+
}
|
|
10944
|
+
instance.setPresentationMode(mode);
|
|
10945
|
+
this.deps.onStatusChange();
|
|
10946
|
+
return { success: true, id: found.key, mode };
|
|
10947
|
+
}
|
|
10691
10948
|
case "restart_session": {
|
|
10692
10949
|
const cliType = args?.cliType || args?.agentType || args?.ideType;
|
|
10693
10950
|
const cfg = loadConfig();
|
|
@@ -11306,7 +11563,12 @@ var AgentStreamPoller = class {
|
|
|
11306
11563
|
} catch {
|
|
11307
11564
|
}
|
|
11308
11565
|
}
|
|
11309
|
-
if (!resolvedActiveSessionId || !parentSessionId)
|
|
11566
|
+
if (!resolvedActiveSessionId || !parentSessionId) {
|
|
11567
|
+
if (parentSessionId) {
|
|
11568
|
+
this.deps.onStreamsUpdated?.(ideType, []);
|
|
11569
|
+
}
|
|
11570
|
+
continue;
|
|
11571
|
+
}
|
|
11310
11572
|
try {
|
|
11311
11573
|
await agentStreamManager.syncActiveSession(cdp, parentSessionId);
|
|
11312
11574
|
const stream = await agentStreamManager.collectActiveSession(cdp, parentSessionId);
|
|
@@ -11321,7 +11583,11 @@ var AgentStreamPoller = class {
|
|
|
11321
11583
|
function forwardAgentStreamsToIdeInstance(instanceManager, ideType, streams) {
|
|
11322
11584
|
const ideInstance = instanceManager.getInstance(`ide:${ideType}`);
|
|
11323
11585
|
if (!ideInstance?.onEvent) return;
|
|
11586
|
+
const seenExtensionTypes = /* @__PURE__ */ new Set();
|
|
11324
11587
|
for (const stream of streams) {
|
|
11588
|
+
if (typeof stream.agentType === "string" && stream.agentType) {
|
|
11589
|
+
seenExtensionTypes.add(stream.agentType);
|
|
11590
|
+
}
|
|
11325
11591
|
ideInstance.onEvent("stream_update", {
|
|
11326
11592
|
extensionType: stream.agentType,
|
|
11327
11593
|
streams: [stream],
|
|
@@ -11338,6 +11604,16 @@ function forwardAgentStreamsToIdeInstance(instanceManager, ideType, streams) {
|
|
|
11338
11604
|
inputContent: stream.inputContent || ""
|
|
11339
11605
|
});
|
|
11340
11606
|
}
|
|
11607
|
+
const extensionTypes = ideInstance.getExtensionTypes?.() || [];
|
|
11608
|
+
if (streams.length === 0) {
|
|
11609
|
+
ideInstance.onEvent("stream_reset_all");
|
|
11610
|
+
return;
|
|
11611
|
+
}
|
|
11612
|
+
for (const extensionType of extensionTypes) {
|
|
11613
|
+
if (!seenExtensionTypes.has(extensionType)) {
|
|
11614
|
+
ideInstance.onEvent("stream_reset", { extensionType });
|
|
11615
|
+
}
|
|
11616
|
+
}
|
|
11341
11617
|
}
|
|
11342
11618
|
|
|
11343
11619
|
// src/providers/provider-instance-manager.ts
|