@adhdev/daemon-core 0.8.35 → 0.8.37
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/boot/daemon-lifecycle.d.ts +4 -0
- package/dist/commands/router.d.ts +3 -0
- package/dist/config/config.d.ts +5 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +458 -154
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +457 -154
- package/dist/index.mjs.map +1 -1
- package/dist/shared-types.d.ts +248 -16
- package/dist/status/builders.d.ts +5 -1
- package/dist/status/normalize.d.ts +11 -1
- package/dist/status/normalize.js +36 -16
- package/dist/status/normalize.js.map +1 -1
- package/dist/status/normalize.mjs +35 -16
- package/dist/status/normalize.mjs.map +1 -1
- package/dist/status/reporter.d.ts +4 -0
- package/dist/status/snapshot.d.ts +5 -5
- package/dist/types.d.ts +1 -1
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +1 -1
- package/src/boot/daemon-lifecycle.ts +7 -0
- package/src/commands/chat-commands.ts +192 -17
- package/src/commands/router.ts +25 -0
- package/src/commands/stream-commands.ts +14 -10
- package/src/config/config.ts +8 -0
- package/src/index.d.ts +2 -2
- package/src/index.ts +32 -1
- package/src/shared-types.d.ts +125 -16
- package/src/shared-types.ts +279 -16
- package/src/status/builders.ts +110 -54
- package/src/status/normalize.ts +54 -19
- package/src/status/reporter.ts +88 -13
- package/src/status/snapshot.ts +79 -41
- package/src/types.ts +1 -1
package/dist/index.js
CHANGED
|
@@ -63,6 +63,7 @@ function normalizeConfig(raw) {
|
|
|
63
63
|
const parsed = isPlainObject(raw) ? raw : {};
|
|
64
64
|
return {
|
|
65
65
|
serverUrl: typeof parsed.serverUrl === "string" && parsed.serverUrl.trim() ? parsed.serverUrl : DEFAULT_CONFIG.serverUrl,
|
|
66
|
+
allowServerApiProxy: asBoolean(parsed.allowServerApiProxy, DEFAULT_CONFIG.allowServerApiProxy ?? false),
|
|
66
67
|
selectedIde: asNullableString(parsed.selectedIde),
|
|
67
68
|
configuredIdes: asStringArray(parsed.configuredIdes),
|
|
68
69
|
installedExtensions: asStringArray(parsed.installedExtensions),
|
|
@@ -211,6 +212,7 @@ var init_config = __esm({
|
|
|
211
212
|
import_crypto = require("crypto");
|
|
212
213
|
DEFAULT_CONFIG = {
|
|
213
214
|
serverUrl: "https://api.adhf.dev",
|
|
215
|
+
allowServerApiProxy: false,
|
|
214
216
|
selectedIde: null,
|
|
215
217
|
configuredIdes: [],
|
|
216
218
|
installedExtensions: [],
|
|
@@ -3025,6 +3027,7 @@ __export(index_exports, {
|
|
|
3025
3027
|
SessionHostPtyTransportFactory: () => SessionHostPtyTransportFactory,
|
|
3026
3028
|
VersionArchive: () => VersionArchive,
|
|
3027
3029
|
appendRecentActivity: () => appendRecentActivity,
|
|
3030
|
+
buildMachineInfo: () => buildMachineInfo,
|
|
3028
3031
|
buildSessionEntries: () => buildSessionEntries,
|
|
3029
3032
|
buildStatusSnapshot: () => buildStatusSnapshot,
|
|
3030
3033
|
connectCdpManager: () => connectCdpManager,
|
|
@@ -6984,11 +6987,24 @@ var WORKING_STATUSES = /* @__PURE__ */ new Set([
|
|
|
6984
6987
|
"thinking",
|
|
6985
6988
|
"active"
|
|
6986
6989
|
]);
|
|
6987
|
-
var
|
|
6988
|
-
|
|
6989
|
-
|
|
6990
|
-
|
|
6991
|
-
|
|
6990
|
+
var FULL_STATUS_ACTIVE_CHAT_OPTIONS = {
|
|
6991
|
+
includeMessages: true,
|
|
6992
|
+
includeInputContent: true,
|
|
6993
|
+
includeActiveModal: true,
|
|
6994
|
+
messageLimit: 60,
|
|
6995
|
+
totalBytesLimit: 96 * 1024,
|
|
6996
|
+
stringLimit: 4 * 1024,
|
|
6997
|
+
fallbackStringLimit: 1024
|
|
6998
|
+
};
|
|
6999
|
+
var LIVE_STATUS_ACTIVE_CHAT_OPTIONS = {
|
|
7000
|
+
includeMessages: false,
|
|
7001
|
+
includeInputContent: false,
|
|
7002
|
+
includeActiveModal: false,
|
|
7003
|
+
messageLimit: 0,
|
|
7004
|
+
totalBytesLimit: 0,
|
|
7005
|
+
stringLimit: 512,
|
|
7006
|
+
fallbackStringLimit: 256
|
|
7007
|
+
};
|
|
6992
7008
|
var STATUS_MODAL_MESSAGE_LIMIT = 2 * 1024;
|
|
6993
7009
|
var STATUS_MODAL_BUTTON_LIMIT = 120;
|
|
6994
7010
|
function truncateString(value, maxChars) {
|
|
@@ -7027,19 +7043,20 @@ function normalizeMessageTime(message) {
|
|
|
7027
7043
|
}
|
|
7028
7044
|
return msg;
|
|
7029
7045
|
}
|
|
7030
|
-
function trimMessagesForStatus(messages) {
|
|
7046
|
+
function trimMessagesForStatus(messages, options) {
|
|
7047
|
+
if (!options.includeMessages || options.messageLimit <= 0 || options.totalBytesLimit <= 0) return [];
|
|
7031
7048
|
if (!Array.isArray(messages) || messages.length === 0) return [];
|
|
7032
|
-
const recent = messages.slice(-
|
|
7049
|
+
const recent = messages.slice(-options.messageLimit);
|
|
7033
7050
|
const kept = [];
|
|
7034
7051
|
let totalBytes = 0;
|
|
7035
7052
|
for (let i = recent.length - 1; i >= 0; i -= 1) {
|
|
7036
|
-
let normalized = normalizeMessageTime(trimMessageForStatus(recent[i],
|
|
7053
|
+
let normalized = normalizeMessageTime(trimMessageForStatus(recent[i], options.stringLimit));
|
|
7037
7054
|
let size = estimateBytes(normalized);
|
|
7038
|
-
if (size >
|
|
7039
|
-
normalized = normalizeMessageTime(trimMessageForStatus(recent[i],
|
|
7055
|
+
if (size > options.totalBytesLimit) {
|
|
7056
|
+
normalized = normalizeMessageTime(trimMessageForStatus(recent[i], options.fallbackStringLimit));
|
|
7040
7057
|
size = estimateBytes(normalized);
|
|
7041
7058
|
}
|
|
7042
|
-
if (kept.length > 0 && totalBytes + size >
|
|
7059
|
+
if (kept.length > 0 && totalBytes + size > options.totalBytesLimit) {
|
|
7043
7060
|
continue;
|
|
7044
7061
|
}
|
|
7045
7062
|
kept.push(normalized);
|
|
@@ -7069,23 +7086,40 @@ function isManagedStatusWorking(status) {
|
|
|
7069
7086
|
function isManagedStatusWaiting(status, opts) {
|
|
7070
7087
|
return normalizeManagedStatus(status, opts) === "waiting_approval";
|
|
7071
7088
|
}
|
|
7072
|
-
function normalizeActiveChatData(activeChat) {
|
|
7089
|
+
function normalizeActiveChatData(activeChat, options = FULL_STATUS_ACTIVE_CHAT_OPTIONS) {
|
|
7073
7090
|
if (!activeChat) return activeChat;
|
|
7091
|
+
const resolvedOptions = {
|
|
7092
|
+
...FULL_STATUS_ACTIVE_CHAT_OPTIONS,
|
|
7093
|
+
...options
|
|
7094
|
+
};
|
|
7074
7095
|
return {
|
|
7075
7096
|
...activeChat,
|
|
7076
7097
|
status: normalizeManagedStatus(activeChat.status, { activeModal: activeChat.activeModal }),
|
|
7077
|
-
messages: trimMessagesForStatus(activeChat.messages),
|
|
7078
|
-
activeModal: activeChat.activeModal ? {
|
|
7098
|
+
messages: trimMessagesForStatus(activeChat.messages, resolvedOptions),
|
|
7099
|
+
activeModal: resolvedOptions.includeActiveModal && activeChat.activeModal ? {
|
|
7079
7100
|
message: truncateString(activeChat.activeModal.message || "", STATUS_MODAL_MESSAGE_LIMIT),
|
|
7080
7101
|
buttons: (activeChat.activeModal.buttons || []).map(
|
|
7081
7102
|
(button) => truncateString(String(button || ""), STATUS_MODAL_BUTTON_LIMIT)
|
|
7082
7103
|
)
|
|
7083
|
-
} :
|
|
7084
|
-
inputContent: activeChat.inputContent ? truncateString(activeChat.inputContent,
|
|
7104
|
+
} : null,
|
|
7105
|
+
inputContent: resolvedOptions.includeInputContent && activeChat.inputContent ? truncateString(activeChat.inputContent, 2 * 1024) : void 0
|
|
7085
7106
|
};
|
|
7086
7107
|
}
|
|
7087
7108
|
|
|
7088
7109
|
// src/status/builders.ts
|
|
7110
|
+
function getActiveChatOptions(profile) {
|
|
7111
|
+
if (profile === "full") return {};
|
|
7112
|
+
return LIVE_STATUS_ACTIVE_CHAT_OPTIONS;
|
|
7113
|
+
}
|
|
7114
|
+
function shouldIncludeSessionControls(profile) {
|
|
7115
|
+
return profile !== "live";
|
|
7116
|
+
}
|
|
7117
|
+
function shouldIncludeSessionMetadata(profile) {
|
|
7118
|
+
return profile !== "live";
|
|
7119
|
+
}
|
|
7120
|
+
function shouldIncludeRuntimeMetadata(profile) {
|
|
7121
|
+
return profile !== "live";
|
|
7122
|
+
}
|
|
7089
7123
|
function findCdpManager(cdpManagers, key) {
|
|
7090
7124
|
const exact = cdpManagers.get(key);
|
|
7091
7125
|
if (exact) return exact;
|
|
@@ -7193,74 +7227,88 @@ var ACP_SESSION_CAPABILITIES = [
|
|
|
7193
7227
|
"set_mode",
|
|
7194
7228
|
"set_thought_level"
|
|
7195
7229
|
];
|
|
7196
|
-
function buildIdeWorkspaceSession(state, cdpManagers) {
|
|
7197
|
-
const
|
|
7230
|
+
function buildIdeWorkspaceSession(state, cdpManagers, options) {
|
|
7231
|
+
const profile = options.profile || "full";
|
|
7232
|
+
const activeChat = normalizeActiveChatData(state.activeChat, getActiveChatOptions(profile));
|
|
7233
|
+
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
7234
|
+
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
7198
7235
|
const title = activeChat?.title || state.name;
|
|
7199
7236
|
return {
|
|
7200
7237
|
id: state.instanceId || state.type,
|
|
7201
7238
|
parentId: null,
|
|
7202
7239
|
providerType: state.type,
|
|
7203
|
-
providerName: state.name,
|
|
7240
|
+
...includeSessionMetadata && { providerName: state.name },
|
|
7204
7241
|
kind: "workspace",
|
|
7205
7242
|
transport: "cdp-page",
|
|
7206
7243
|
status: normalizeManagedStatus(activeChat?.status || state.status, {
|
|
7207
7244
|
activeModal: activeChat?.activeModal || null
|
|
7208
7245
|
}),
|
|
7209
7246
|
title,
|
|
7210
|
-
workspace: state.workspace || null,
|
|
7247
|
+
...includeSessionMetadata && { workspace: state.workspace || null },
|
|
7211
7248
|
activeChat,
|
|
7212
|
-
capabilities: IDE_SESSION_CAPABILITIES,
|
|
7249
|
+
...includeSessionMetadata && { capabilities: IDE_SESSION_CAPABILITIES },
|
|
7213
7250
|
cdpConnected: state.cdpConnected ?? isCdpConnected(cdpManagers, state.type),
|
|
7214
7251
|
currentModel: state.currentModel,
|
|
7215
7252
|
currentPlan: state.currentPlan,
|
|
7216
7253
|
currentAutoApprove: state.currentAutoApprove,
|
|
7217
|
-
|
|
7218
|
-
|
|
7219
|
-
|
|
7220
|
-
|
|
7221
|
-
|
|
7222
|
-
|
|
7254
|
+
...includeSessionControls && {
|
|
7255
|
+
controlValues: state.controlValues,
|
|
7256
|
+
providerControls: buildFallbackControls(
|
|
7257
|
+
state.providerControls,
|
|
7258
|
+
state.currentModel,
|
|
7259
|
+
state.currentPlan
|
|
7260
|
+
)
|
|
7261
|
+
},
|
|
7223
7262
|
errorMessage: state.errorMessage,
|
|
7224
7263
|
errorReason: state.errorReason,
|
|
7225
7264
|
lastUpdated: state.lastUpdated
|
|
7226
7265
|
};
|
|
7227
7266
|
}
|
|
7228
|
-
function buildExtensionAgentSession(parent, ext) {
|
|
7229
|
-
const
|
|
7267
|
+
function buildExtensionAgentSession(parent, ext, options) {
|
|
7268
|
+
const profile = options.profile || "full";
|
|
7269
|
+
const activeChat = normalizeActiveChatData(ext.activeChat, getActiveChatOptions(profile));
|
|
7270
|
+
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
7271
|
+
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
7230
7272
|
return {
|
|
7231
7273
|
id: ext.instanceId || `${parent.instanceId}:${ext.type}`,
|
|
7232
7274
|
parentId: parent.instanceId || parent.type,
|
|
7233
7275
|
providerType: ext.type,
|
|
7234
|
-
providerName: ext.name,
|
|
7276
|
+
...includeSessionMetadata && { providerName: ext.name },
|
|
7235
7277
|
kind: "agent",
|
|
7236
7278
|
transport: "cdp-webview",
|
|
7237
7279
|
status: normalizeManagedStatus(activeChat?.status || ext.status, {
|
|
7238
7280
|
activeModal: activeChat?.activeModal || null
|
|
7239
7281
|
}),
|
|
7240
7282
|
title: activeChat?.title || ext.name,
|
|
7241
|
-
workspace: parent.workspace || null,
|
|
7283
|
+
...includeSessionMetadata && { workspace: parent.workspace || null },
|
|
7242
7284
|
activeChat,
|
|
7243
|
-
capabilities: EXTENSION_SESSION_CAPABILITIES,
|
|
7285
|
+
...includeSessionMetadata && { capabilities: EXTENSION_SESSION_CAPABILITIES },
|
|
7244
7286
|
currentModel: ext.currentModel,
|
|
7245
7287
|
currentPlan: ext.currentPlan,
|
|
7246
|
-
|
|
7247
|
-
|
|
7248
|
-
|
|
7249
|
-
|
|
7250
|
-
|
|
7251
|
-
|
|
7288
|
+
...includeSessionControls && {
|
|
7289
|
+
controlValues: ext.controlValues,
|
|
7290
|
+
providerControls: buildFallbackControls(
|
|
7291
|
+
ext.providerControls,
|
|
7292
|
+
ext.currentModel,
|
|
7293
|
+
ext.currentPlan
|
|
7294
|
+
)
|
|
7295
|
+
},
|
|
7252
7296
|
errorMessage: ext.errorMessage,
|
|
7253
7297
|
errorReason: ext.errorReason,
|
|
7254
7298
|
lastUpdated: ext.lastUpdated
|
|
7255
7299
|
};
|
|
7256
7300
|
}
|
|
7257
|
-
function buildCliSession(state) {
|
|
7258
|
-
const
|
|
7301
|
+
function buildCliSession(state, options) {
|
|
7302
|
+
const profile = options.profile || "full";
|
|
7303
|
+
const activeChat = normalizeActiveChatData(state.activeChat, getActiveChatOptions(profile));
|
|
7304
|
+
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
7305
|
+
const includeRuntimeMetadata = shouldIncludeRuntimeMetadata(profile);
|
|
7306
|
+
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
7259
7307
|
return {
|
|
7260
7308
|
id: state.instanceId,
|
|
7261
7309
|
parentId: null,
|
|
7262
7310
|
providerType: state.type,
|
|
7263
|
-
providerName: state.name,
|
|
7311
|
+
...includeSessionMetadata && { providerName: state.name },
|
|
7264
7312
|
providerSessionId: state.providerSessionId,
|
|
7265
7313
|
kind: "agent",
|
|
7266
7314
|
transport: "pty",
|
|
@@ -7268,74 +7316,85 @@ function buildCliSession(state) {
|
|
|
7268
7316
|
activeModal: activeChat?.activeModal || null
|
|
7269
7317
|
}),
|
|
7270
7318
|
title: activeChat?.title || state.name,
|
|
7271
|
-
workspace: state.workspace || null,
|
|
7272
|
-
|
|
7273
|
-
|
|
7274
|
-
|
|
7275
|
-
|
|
7276
|
-
|
|
7319
|
+
...includeSessionMetadata && { workspace: state.workspace || null },
|
|
7320
|
+
...includeRuntimeMetadata && {
|
|
7321
|
+
runtimeKey: state.runtime?.runtimeKey,
|
|
7322
|
+
runtimeDisplayName: state.runtime?.displayName,
|
|
7323
|
+
runtimeWorkspaceLabel: state.runtime?.workspaceLabel,
|
|
7324
|
+
runtimeWriteOwner: state.runtime?.writeOwner || null,
|
|
7325
|
+
runtimeAttachedClients: state.runtime?.attachedClients || []
|
|
7326
|
+
},
|
|
7277
7327
|
mode: state.mode,
|
|
7278
7328
|
resume: state.resume,
|
|
7279
7329
|
activeChat,
|
|
7280
|
-
|
|
7281
|
-
|
|
7282
|
-
|
|
7283
|
-
|
|
7284
|
-
|
|
7330
|
+
...includeSessionMetadata && {
|
|
7331
|
+
capabilities: state.mode === "terminal" ? PTY_SESSION_CAPABILITIES : CLI_CHAT_SESSION_CAPABILITIES
|
|
7332
|
+
},
|
|
7333
|
+
...includeSessionControls && {
|
|
7334
|
+
controlValues: state.controlValues,
|
|
7335
|
+
providerControls: buildFallbackControls(
|
|
7336
|
+
state.providerControls
|
|
7337
|
+
)
|
|
7338
|
+
},
|
|
7285
7339
|
errorMessage: state.errorMessage,
|
|
7286
7340
|
errorReason: state.errorReason,
|
|
7287
7341
|
lastUpdated: state.lastUpdated
|
|
7288
7342
|
};
|
|
7289
7343
|
}
|
|
7290
|
-
function buildAcpSession(state) {
|
|
7291
|
-
const
|
|
7344
|
+
function buildAcpSession(state, options) {
|
|
7345
|
+
const profile = options.profile || "full";
|
|
7346
|
+
const activeChat = normalizeActiveChatData(state.activeChat, getActiveChatOptions(profile));
|
|
7347
|
+
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
7348
|
+
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
7292
7349
|
return {
|
|
7293
7350
|
id: state.instanceId,
|
|
7294
7351
|
parentId: null,
|
|
7295
7352
|
providerType: state.type,
|
|
7296
|
-
providerName: state.name,
|
|
7353
|
+
...includeSessionMetadata && { providerName: state.name },
|
|
7297
7354
|
kind: "agent",
|
|
7298
7355
|
transport: "acp",
|
|
7299
7356
|
status: normalizeManagedStatus(activeChat?.status || state.status, {
|
|
7300
7357
|
activeModal: activeChat?.activeModal || null
|
|
7301
7358
|
}),
|
|
7302
7359
|
title: activeChat?.title || state.name,
|
|
7303
|
-
workspace: state.workspace || null,
|
|
7360
|
+
...includeSessionMetadata && { workspace: state.workspace || null },
|
|
7304
7361
|
activeChat,
|
|
7305
|
-
capabilities: ACP_SESSION_CAPABILITIES,
|
|
7362
|
+
...includeSessionMetadata && { capabilities: ACP_SESSION_CAPABILITIES },
|
|
7306
7363
|
currentModel: state.currentModel,
|
|
7307
7364
|
currentPlan: state.currentPlan,
|
|
7308
|
-
|
|
7309
|
-
|
|
7310
|
-
|
|
7311
|
-
|
|
7312
|
-
|
|
7313
|
-
|
|
7314
|
-
|
|
7315
|
-
|
|
7316
|
-
|
|
7317
|
-
|
|
7365
|
+
...includeSessionControls && {
|
|
7366
|
+
acpConfigOptions: state.acpConfigOptions,
|
|
7367
|
+
acpModes: state.acpModes,
|
|
7368
|
+
controlValues: state.controlValues,
|
|
7369
|
+
providerControls: buildFallbackControls(
|
|
7370
|
+
state.providerControls,
|
|
7371
|
+
state.currentModel,
|
|
7372
|
+
state.currentPlan,
|
|
7373
|
+
state.acpConfigOptions,
|
|
7374
|
+
state.acpModes
|
|
7375
|
+
)
|
|
7376
|
+
},
|
|
7318
7377
|
errorMessage: state.errorMessage,
|
|
7319
7378
|
errorReason: state.errorReason,
|
|
7320
7379
|
lastUpdated: state.lastUpdated
|
|
7321
7380
|
};
|
|
7322
7381
|
}
|
|
7323
|
-
function buildSessionEntries(allStates, cdpManagers) {
|
|
7382
|
+
function buildSessionEntries(allStates, cdpManagers, options = {}) {
|
|
7324
7383
|
const sessions = [];
|
|
7325
7384
|
const ideStates = allStates.filter((s) => s.category === "ide");
|
|
7326
7385
|
const cliStates = allStates.filter((s) => s.category === "cli");
|
|
7327
7386
|
const acpStates = allStates.filter((s) => s.category === "acp");
|
|
7328
7387
|
for (const state of ideStates) {
|
|
7329
|
-
sessions.push(buildIdeWorkspaceSession(state, cdpManagers));
|
|
7388
|
+
sessions.push(buildIdeWorkspaceSession(state, cdpManagers, options));
|
|
7330
7389
|
for (const ext of state.extensions) {
|
|
7331
|
-
sessions.push(buildExtensionAgentSession(state, ext));
|
|
7390
|
+
sessions.push(buildExtensionAgentSession(state, ext, options));
|
|
7332
7391
|
}
|
|
7333
7392
|
}
|
|
7334
7393
|
for (const state of cliStates) {
|
|
7335
|
-
sessions.push(buildCliSession(state));
|
|
7394
|
+
sessions.push(buildCliSession(state, options));
|
|
7336
7395
|
}
|
|
7337
7396
|
for (const state of acpStates) {
|
|
7338
|
-
sessions.push(buildAcpSession(state));
|
|
7397
|
+
sessions.push(buildAcpSession(state, options));
|
|
7339
7398
|
}
|
|
7340
7399
|
const extensionParentIds = new Set(
|
|
7341
7400
|
sessions.filter((session) => session.transport === "cdp-webview" && !!session.parentId).map((session) => session.parentId)
|
|
@@ -7396,10 +7455,29 @@ function reconcileIdeRuntimeSessions(instanceManager, sessionRegistry) {
|
|
|
7396
7455
|
// src/commands/handler.ts
|
|
7397
7456
|
init_logger();
|
|
7398
7457
|
|
|
7458
|
+
// src/providers/contracts.ts
|
|
7459
|
+
function flattenContent(content) {
|
|
7460
|
+
if (typeof content === "string") return content;
|
|
7461
|
+
return content.filter((b) => b.type === "text").map((b) => b.text).join("\n");
|
|
7462
|
+
}
|
|
7463
|
+
|
|
7399
7464
|
// src/commands/chat-commands.ts
|
|
7400
7465
|
init_logger();
|
|
7401
7466
|
var RECENT_SEND_WINDOW_MS = 1200;
|
|
7402
7467
|
var recentSendByTarget = /* @__PURE__ */ new Map();
|
|
7468
|
+
function hashSignatureParts(parts) {
|
|
7469
|
+
let hash = 2166136261;
|
|
7470
|
+
for (const part of parts) {
|
|
7471
|
+
const text = String(part || "");
|
|
7472
|
+
for (let i = 0; i < text.length; i += 1) {
|
|
7473
|
+
hash ^= text.charCodeAt(i);
|
|
7474
|
+
hash = Math.imul(hash, 16777619) >>> 0;
|
|
7475
|
+
}
|
|
7476
|
+
hash ^= 255;
|
|
7477
|
+
hash = Math.imul(hash, 16777619) >>> 0;
|
|
7478
|
+
}
|
|
7479
|
+
return hash.toString(16).padStart(8, "0");
|
|
7480
|
+
}
|
|
7403
7481
|
function getCurrentProviderType(h, fallback = "") {
|
|
7404
7482
|
return h.currentSession?.providerType || h.currentProviderType || fallback;
|
|
7405
7483
|
}
|
|
@@ -7473,6 +7551,134 @@ function parseMaybeJson(value) {
|
|
|
7473
7551
|
return value;
|
|
7474
7552
|
}
|
|
7475
7553
|
}
|
|
7554
|
+
function getChatMessageSignature(message) {
|
|
7555
|
+
if (!message) return "";
|
|
7556
|
+
let content = "";
|
|
7557
|
+
try {
|
|
7558
|
+
content = JSON.stringify(message.content ?? "");
|
|
7559
|
+
} catch {
|
|
7560
|
+
content = String(message.content ?? "");
|
|
7561
|
+
}
|
|
7562
|
+
return hashSignatureParts([
|
|
7563
|
+
String(message.id || ""),
|
|
7564
|
+
String(message.index ?? ""),
|
|
7565
|
+
String(message.role || ""),
|
|
7566
|
+
String(message.receivedAt ?? message.timestamp ?? ""),
|
|
7567
|
+
content
|
|
7568
|
+
]);
|
|
7569
|
+
}
|
|
7570
|
+
function normalizeReadChatCursor(args) {
|
|
7571
|
+
const knownMessageCount = Math.max(0, Number(args?.knownMessageCount || 0));
|
|
7572
|
+
const lastMessageSignature = typeof args?.lastMessageSignature === "string" ? args.lastMessageSignature : "";
|
|
7573
|
+
const tailLimit = Math.max(0, Number(args?.tailLimit || 0));
|
|
7574
|
+
return { knownMessageCount, lastMessageSignature, tailLimit };
|
|
7575
|
+
}
|
|
7576
|
+
function normalizeReadChatMessages(payload) {
|
|
7577
|
+
const messages = Array.isArray(payload.messages) ? payload.messages : [];
|
|
7578
|
+
return messages;
|
|
7579
|
+
}
|
|
7580
|
+
function deriveHistoryDedupKey(message) {
|
|
7581
|
+
const unitKey = typeof message._unitKey === "string" ? message._unitKey.trim() : "";
|
|
7582
|
+
if (unitKey) return `read_chat:${unitKey}`;
|
|
7583
|
+
const turnKey = typeof message._turnKey === "string" ? message._turnKey.trim() : "";
|
|
7584
|
+
if (!turnKey) return void 0;
|
|
7585
|
+
let content = "";
|
|
7586
|
+
try {
|
|
7587
|
+
content = JSON.stringify(message.content ?? "");
|
|
7588
|
+
} catch {
|
|
7589
|
+
content = String(message.content ?? "");
|
|
7590
|
+
}
|
|
7591
|
+
return `read_chat:${turnKey}:${String(message.role || "").toLowerCase()}:${content}`;
|
|
7592
|
+
}
|
|
7593
|
+
function toHistoryPersistedMessages(messages) {
|
|
7594
|
+
return messages.map((message) => ({
|
|
7595
|
+
role: message.role,
|
|
7596
|
+
content: flattenContent(message.content),
|
|
7597
|
+
receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : void 0,
|
|
7598
|
+
kind: typeof message.kind === "string" ? message.kind : void 0,
|
|
7599
|
+
senderName: typeof message.senderName === "string" ? message.senderName : void 0,
|
|
7600
|
+
historyDedupKey: deriveHistoryDedupKey(message)
|
|
7601
|
+
}));
|
|
7602
|
+
}
|
|
7603
|
+
function computeReadChatSync(messages, cursor) {
|
|
7604
|
+
const totalMessages = messages.length;
|
|
7605
|
+
const lastMessageSignature = getChatMessageSignature(messages[totalMessages - 1]);
|
|
7606
|
+
const { knownMessageCount, lastMessageSignature: knownSignature } = cursor;
|
|
7607
|
+
if (!knownMessageCount || !knownSignature) {
|
|
7608
|
+
return {
|
|
7609
|
+
syncMode: "full",
|
|
7610
|
+
replaceFrom: 0,
|
|
7611
|
+
messages,
|
|
7612
|
+
totalMessages,
|
|
7613
|
+
lastMessageSignature
|
|
7614
|
+
};
|
|
7615
|
+
}
|
|
7616
|
+
if (knownMessageCount > totalMessages) {
|
|
7617
|
+
return {
|
|
7618
|
+
syncMode: "full",
|
|
7619
|
+
replaceFrom: 0,
|
|
7620
|
+
messages,
|
|
7621
|
+
totalMessages,
|
|
7622
|
+
lastMessageSignature
|
|
7623
|
+
};
|
|
7624
|
+
}
|
|
7625
|
+
if (knownMessageCount === totalMessages && knownSignature === lastMessageSignature) {
|
|
7626
|
+
return {
|
|
7627
|
+
syncMode: "noop",
|
|
7628
|
+
replaceFrom: totalMessages,
|
|
7629
|
+
messages: [],
|
|
7630
|
+
totalMessages,
|
|
7631
|
+
lastMessageSignature
|
|
7632
|
+
};
|
|
7633
|
+
}
|
|
7634
|
+
if (knownMessageCount < totalMessages) {
|
|
7635
|
+
const anchorSignature = getChatMessageSignature(messages[knownMessageCount - 1]);
|
|
7636
|
+
if (anchorSignature === knownSignature) {
|
|
7637
|
+
return {
|
|
7638
|
+
syncMode: "append",
|
|
7639
|
+
replaceFrom: knownMessageCount,
|
|
7640
|
+
messages: messages.slice(knownMessageCount),
|
|
7641
|
+
totalMessages,
|
|
7642
|
+
lastMessageSignature
|
|
7643
|
+
};
|
|
7644
|
+
}
|
|
7645
|
+
}
|
|
7646
|
+
const replaceFrom = Math.max(0, Math.min(knownMessageCount - 1, totalMessages));
|
|
7647
|
+
return {
|
|
7648
|
+
syncMode: replaceFrom === 0 ? "full" : "replace_tail",
|
|
7649
|
+
replaceFrom,
|
|
7650
|
+
messages: replaceFrom === 0 ? messages : messages.slice(replaceFrom),
|
|
7651
|
+
totalMessages,
|
|
7652
|
+
lastMessageSignature
|
|
7653
|
+
};
|
|
7654
|
+
}
|
|
7655
|
+
function buildReadChatCommandResult(payload, args) {
|
|
7656
|
+
const messages = normalizeReadChatMessages(payload);
|
|
7657
|
+
const cursor = normalizeReadChatCursor(args);
|
|
7658
|
+
if (!cursor.knownMessageCount && !cursor.lastMessageSignature && cursor.tailLimit > 0 && messages.length > cursor.tailLimit) {
|
|
7659
|
+
const tailMessages = messages.slice(-cursor.tailLimit);
|
|
7660
|
+
const lastMessageSignature = getChatMessageSignature(tailMessages[tailMessages.length - 1]);
|
|
7661
|
+
return {
|
|
7662
|
+
success: true,
|
|
7663
|
+
...payload,
|
|
7664
|
+
messages: tailMessages,
|
|
7665
|
+
syncMode: "full",
|
|
7666
|
+
replaceFrom: 0,
|
|
7667
|
+
totalMessages: messages.length,
|
|
7668
|
+
lastMessageSignature
|
|
7669
|
+
};
|
|
7670
|
+
}
|
|
7671
|
+
const sync = computeReadChatSync(messages, cursor);
|
|
7672
|
+
return {
|
|
7673
|
+
success: true,
|
|
7674
|
+
...payload,
|
|
7675
|
+
messages: sync.messages,
|
|
7676
|
+
syncMode: sync.syncMode,
|
|
7677
|
+
replaceFrom: sync.replaceFrom,
|
|
7678
|
+
totalMessages: sync.totalMessages,
|
|
7679
|
+
lastMessageSignature: sync.lastMessageSignature
|
|
7680
|
+
};
|
|
7681
|
+
}
|
|
7476
7682
|
function didProviderConfirmSend(result) {
|
|
7477
7683
|
const parsed = parseMaybeJson(result);
|
|
7478
7684
|
if (parsed === true) return true;
|
|
@@ -7546,12 +7752,11 @@ async function handleReadChat(h, args) {
|
|
|
7546
7752
|
_log(`${transport} adapter: ${adapter.cliType}`);
|
|
7547
7753
|
const status = adapter.getStatus();
|
|
7548
7754
|
if (status) {
|
|
7549
|
-
return {
|
|
7550
|
-
success: true,
|
|
7755
|
+
return buildReadChatCommandResult({
|
|
7551
7756
|
messages: status.messages || [],
|
|
7552
7757
|
status: status.status,
|
|
7553
7758
|
activeModal: status.activeModal
|
|
7554
|
-
};
|
|
7759
|
+
}, args);
|
|
7555
7760
|
}
|
|
7556
7761
|
}
|
|
7557
7762
|
return { success: false, error: `${transport} adapter not found` };
|
|
@@ -7571,12 +7776,12 @@ async function handleReadChat(h, args) {
|
|
|
7571
7776
|
_log(`Extension OK: ${parsed.messages?.length || 0} msgs`);
|
|
7572
7777
|
h.historyWriter.appendNewMessages(
|
|
7573
7778
|
provider?.type || "unknown_extension",
|
|
7574
|
-
parsed
|
|
7779
|
+
toHistoryPersistedMessages(normalizeReadChatMessages(parsed)),
|
|
7575
7780
|
parsed.title,
|
|
7576
7781
|
args?.targetSessionId,
|
|
7577
7782
|
historySessionId
|
|
7578
7783
|
);
|
|
7579
|
-
return
|
|
7784
|
+
return buildReadChatCommandResult(parsed, args);
|
|
7580
7785
|
}
|
|
7581
7786
|
}
|
|
7582
7787
|
} catch (e) {
|
|
@@ -7588,21 +7793,25 @@ async function handleReadChat(h, args) {
|
|
|
7588
7793
|
if (cdp2 && parentSessionId) {
|
|
7589
7794
|
const stream = await h.agentStream.collectActiveSession(cdp2, parentSessionId);
|
|
7590
7795
|
if (stream?.agentType !== provider?.type) {
|
|
7591
|
-
return {
|
|
7796
|
+
return buildReadChatCommandResult({ messages: [], status: "idle" }, args);
|
|
7592
7797
|
}
|
|
7593
7798
|
if (stream) {
|
|
7594
7799
|
h.historyWriter.appendNewMessages(
|
|
7595
7800
|
stream.agentType,
|
|
7596
|
-
stream.messages || [],
|
|
7801
|
+
toHistoryPersistedMessages(stream.messages || []),
|
|
7597
7802
|
void 0,
|
|
7598
7803
|
args?.targetSessionId,
|
|
7599
7804
|
historySessionId
|
|
7600
7805
|
);
|
|
7601
|
-
return {
|
|
7806
|
+
return buildReadChatCommandResult({
|
|
7807
|
+
messages: stream.messages || [],
|
|
7808
|
+
status: stream.status,
|
|
7809
|
+
agentType: stream.agentType
|
|
7810
|
+
}, args);
|
|
7602
7811
|
}
|
|
7603
7812
|
}
|
|
7604
7813
|
}
|
|
7605
|
-
return {
|
|
7814
|
+
return buildReadChatCommandResult({ messages: [], status: "idle" }, args);
|
|
7606
7815
|
}
|
|
7607
7816
|
const cdp = h.getCdp();
|
|
7608
7817
|
if (!cdp?.isConnected) return { success: false, error: "CDP not connected" };
|
|
@@ -7624,18 +7833,18 @@ async function handleReadChat(h, args) {
|
|
|
7624
7833
|
_log(`Webview OK: ${parsed.messages?.length || 0} msgs`);
|
|
7625
7834
|
h.historyWriter.appendNewMessages(
|
|
7626
7835
|
provider?.type || getCurrentProviderType(h, "unknown_webview"),
|
|
7627
|
-
parsed
|
|
7836
|
+
toHistoryPersistedMessages(normalizeReadChatMessages(parsed)),
|
|
7628
7837
|
parsed.title,
|
|
7629
7838
|
args?.targetSessionId,
|
|
7630
7839
|
historySessionId
|
|
7631
7840
|
);
|
|
7632
|
-
return
|
|
7841
|
+
return buildReadChatCommandResult(parsed, args);
|
|
7633
7842
|
}
|
|
7634
7843
|
}
|
|
7635
7844
|
} catch (e) {
|
|
7636
7845
|
_log(`Webview readChat error: ${e.message}`);
|
|
7637
7846
|
}
|
|
7638
|
-
return {
|
|
7847
|
+
return buildReadChatCommandResult({ messages: [], status: "idle" }, args);
|
|
7639
7848
|
}
|
|
7640
7849
|
const script = h.getProviderScript("readChat") || h.getProviderScript("read_chat");
|
|
7641
7850
|
if (script) {
|
|
@@ -7652,18 +7861,18 @@ async function handleReadChat(h, args) {
|
|
|
7652
7861
|
_log(`OK: ${parsed.messages?.length} msgs`);
|
|
7653
7862
|
h.historyWriter.appendNewMessages(
|
|
7654
7863
|
provider?.type || getCurrentProviderType(h, "unknown_ide"),
|
|
7655
|
-
parsed
|
|
7864
|
+
toHistoryPersistedMessages(normalizeReadChatMessages(parsed)),
|
|
7656
7865
|
parsed.title,
|
|
7657
7866
|
args?.targetSessionId,
|
|
7658
7867
|
historySessionId
|
|
7659
7868
|
);
|
|
7660
|
-
return
|
|
7869
|
+
return buildReadChatCommandResult(parsed, args);
|
|
7661
7870
|
}
|
|
7662
7871
|
} catch (e) {
|
|
7663
7872
|
LOG.info("Command", `[read_chat] Script error: ${e.message}`);
|
|
7664
7873
|
}
|
|
7665
7874
|
}
|
|
7666
|
-
return {
|
|
7875
|
+
return buildReadChatCommandResult({ messages: [], status: "idle" }, args);
|
|
7667
7876
|
}
|
|
7668
7877
|
async function handleSendChat(h, args) {
|
|
7669
7878
|
const text = args?.text || args?.message;
|
|
@@ -8784,21 +8993,21 @@ function applyProviderPatch(h, args, payload) {
|
|
|
8784
8993
|
});
|
|
8785
8994
|
}
|
|
8786
8995
|
async function executeProviderScript(h, args, scriptName) {
|
|
8787
|
-
const
|
|
8788
|
-
if (!
|
|
8996
|
+
const resolvedProviderType = h.currentSession?.providerType || h.currentProviderType || args?.agentType || args?.providerType;
|
|
8997
|
+
if (!resolvedProviderType) return { success: false, error: "targetSessionId or providerType is required" };
|
|
8789
8998
|
const loader = h.ctx.providerLoader;
|
|
8790
8999
|
if (!loader) return { success: false, error: "ProviderLoader not initialized" };
|
|
8791
|
-
const provider = loader.resolve(
|
|
8792
|
-
if (!provider) return { success: false, error: `Provider not found: ${
|
|
9000
|
+
const provider = loader.resolve(resolvedProviderType);
|
|
9001
|
+
if (!provider) return { success: false, error: `Provider not found: ${resolvedProviderType}` };
|
|
8793
9002
|
const webviewScriptName = `webview${scriptName.charAt(0).toUpperCase() + scriptName.slice(1)}`;
|
|
8794
9003
|
const hasWebviewScript = provider.category === "ide" && !!provider.scripts?.[webviewScriptName];
|
|
8795
9004
|
const actualScriptName = hasWebviewScript ? webviewScriptName : scriptName;
|
|
8796
9005
|
if (!provider.scripts?.[actualScriptName]) {
|
|
8797
|
-
return { success: false, error: `Script '${actualScriptName}' not available for ${
|
|
9006
|
+
return { success: false, error: `Script '${actualScriptName}' not available for ${resolvedProviderType}` };
|
|
8798
9007
|
}
|
|
8799
9008
|
const normalizedArgs = normalizeProviderScriptArgs(args);
|
|
8800
9009
|
if (provider.category === "cli") {
|
|
8801
|
-
const adapter = h.getCliAdapter(args?.targetSessionId ||
|
|
9010
|
+
const adapter = h.getCliAdapter(args?.targetSessionId || resolvedProviderType);
|
|
8802
9011
|
if (!adapter?.invokeScript) {
|
|
8803
9012
|
return { success: false, error: `CLI adapter does not support script '${actualScriptName}'` };
|
|
8804
9013
|
}
|
|
@@ -8823,7 +9032,7 @@ async function executeProviderScript(h, args, scriptName) {
|
|
|
8823
9032
|
const scriptFn = provider.scripts[actualScriptName];
|
|
8824
9033
|
const scriptCode = scriptFn(normalizedArgs);
|
|
8825
9034
|
if (!scriptCode) return { success: false, error: `Script '${actualScriptName}' returned null` };
|
|
8826
|
-
const cdpKey = provider.category === "ide" ? h.currentSession?.cdpManagerKey || h.currentManagerKey ||
|
|
9035
|
+
const cdpKey = provider.category === "ide" ? h.currentSession?.cdpManagerKey || h.currentManagerKey || resolvedProviderType : h.currentSession?.cdpManagerKey || h.currentManagerKey;
|
|
8827
9036
|
LOG.info("Command", `[ExtScript] provider=${provider.type} category=${provider.category} cdpKey=${cdpKey}`);
|
|
8828
9037
|
const cdp = h.getCdp(cdpKey);
|
|
8829
9038
|
if (!cdp?.isConnected) return { success: false, error: `No CDP connection for ${cdpKey || "any"}` };
|
|
@@ -8831,7 +9040,7 @@ async function executeProviderScript(h, args, scriptName) {
|
|
|
8831
9040
|
let result;
|
|
8832
9041
|
if (provider.category === "extension") {
|
|
8833
9042
|
const runtimeSessionId = h.currentSession?.sessionId || args?.targetSessionId;
|
|
8834
|
-
if (!runtimeSessionId) return { success: false, error: `No target session found for ${
|
|
9043
|
+
if (!runtimeSessionId) return { success: false, error: `No target session found for ${resolvedProviderType}` };
|
|
8835
9044
|
const parentSessionId = h.currentSession?.parentSessionId;
|
|
8836
9045
|
if (parentSessionId) {
|
|
8837
9046
|
await h.agentStream?.setActiveSession(cdp, parentSessionId, runtimeSessionId);
|
|
@@ -8860,7 +9069,7 @@ async function executeProviderScript(h, args, scriptName) {
|
|
|
8860
9069
|
}
|
|
8861
9070
|
} else {
|
|
8862
9071
|
if (!targetSessionId) {
|
|
8863
|
-
return { success: false, error: `No active session found for ${
|
|
9072
|
+
return { success: false, error: `No active session found for ${resolvedProviderType}` };
|
|
8864
9073
|
}
|
|
8865
9074
|
result = await cdp.evaluateInSessionFrame(targetSessionId, scriptCode);
|
|
8866
9075
|
}
|
|
@@ -10243,14 +10452,6 @@ ${effect.notification.body || ""}`.trim();
|
|
|
10243
10452
|
var import_stream = require("stream");
|
|
10244
10453
|
var import_child_process5 = require("child_process");
|
|
10245
10454
|
var import_sdk = require("@agentclientprotocol/sdk");
|
|
10246
|
-
|
|
10247
|
-
// src/providers/contracts.ts
|
|
10248
|
-
function flattenContent(content) {
|
|
10249
|
-
if (typeof content === "string") return content;
|
|
10250
|
-
return content.filter((b) => b.type === "text").map((b) => b.text).join("\n");
|
|
10251
|
-
}
|
|
10252
|
-
|
|
10253
|
-
// src/providers/acp-provider-instance.ts
|
|
10254
10455
|
init_logger();
|
|
10255
10456
|
var AcpProviderInstance = class {
|
|
10256
10457
|
constructor(provider, workingDir, cliArgs = []) {
|
|
@@ -13616,6 +13817,37 @@ function buildAvailableProviders(providerLoader) {
|
|
|
13616
13817
|
...provider.detectedPath !== void 0 ? { detectedPath: provider.detectedPath } : {}
|
|
13617
13818
|
}));
|
|
13618
13819
|
}
|
|
13820
|
+
function buildMachineInfo(profile = "full") {
|
|
13821
|
+
const base = {
|
|
13822
|
+
hostname: os16.hostname(),
|
|
13823
|
+
platform: os16.platform()
|
|
13824
|
+
};
|
|
13825
|
+
if (profile === "live") {
|
|
13826
|
+
return base;
|
|
13827
|
+
}
|
|
13828
|
+
if (profile === "metadata") {
|
|
13829
|
+
const memSnap2 = getHostMemorySnapshot();
|
|
13830
|
+
return {
|
|
13831
|
+
...base,
|
|
13832
|
+
arch: os16.arch(),
|
|
13833
|
+
cpus: os16.cpus().length,
|
|
13834
|
+
totalMem: memSnap2.totalMem,
|
|
13835
|
+
release: os16.release()
|
|
13836
|
+
};
|
|
13837
|
+
}
|
|
13838
|
+
const memSnap = getHostMemorySnapshot();
|
|
13839
|
+
return {
|
|
13840
|
+
...base,
|
|
13841
|
+
arch: os16.arch(),
|
|
13842
|
+
cpus: os16.cpus().length,
|
|
13843
|
+
totalMem: memSnap.totalMem,
|
|
13844
|
+
freeMem: memSnap.freeMem,
|
|
13845
|
+
availableMem: memSnap.availableMem,
|
|
13846
|
+
loadavg: os16.loadavg(),
|
|
13847
|
+
uptime: os16.uptime(),
|
|
13848
|
+
release: os16.release()
|
|
13849
|
+
};
|
|
13850
|
+
}
|
|
13619
13851
|
function parseMessageTime(value) {
|
|
13620
13852
|
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
13621
13853
|
if (typeof value === "string") {
|
|
@@ -13671,26 +13903,35 @@ function buildRecentLaunches(recentActivity) {
|
|
|
13671
13903
|
})).sort((a, b) => b.lastLaunchedAt - a.lastLaunchedAt).slice(0, 12);
|
|
13672
13904
|
}
|
|
13673
13905
|
function buildStatusSnapshot(options) {
|
|
13906
|
+
const profile = options.profile || "full";
|
|
13674
13907
|
const cfg = loadConfig();
|
|
13675
13908
|
const state = loadState();
|
|
13676
13909
|
const wsState = getWorkspaceState(cfg);
|
|
13677
|
-
const memSnap = getHostMemorySnapshot();
|
|
13678
13910
|
const recentActivity = getRecentActivity(state, 20);
|
|
13679
|
-
const
|
|
13911
|
+
const unreadSourceSessions = buildSessionEntries(
|
|
13680
13912
|
options.allStates,
|
|
13681
|
-
options.cdpManagers
|
|
13913
|
+
options.cdpManagers,
|
|
13914
|
+
{ profile: "full" }
|
|
13682
13915
|
);
|
|
13683
|
-
|
|
13684
|
-
|
|
13685
|
-
|
|
13686
|
-
|
|
13687
|
-
|
|
13688
|
-
|
|
13689
|
-
|
|
13690
|
-
|
|
13916
|
+
const sessions = profile === "full" ? unreadSourceSessions : buildSessionEntries(
|
|
13917
|
+
options.allStates,
|
|
13918
|
+
options.cdpManagers,
|
|
13919
|
+
{ profile }
|
|
13920
|
+
);
|
|
13921
|
+
const sessionsById = new Map(sessions.map((session) => [session.id, session]));
|
|
13922
|
+
for (const sourceSession of unreadSourceSessions) {
|
|
13923
|
+
const session = sessionsById.get(sourceSession.id);
|
|
13924
|
+
if (!session) continue;
|
|
13925
|
+
const lastSeenAt = getSessionSeenAt(state, sourceSession.id);
|
|
13926
|
+
const seenCompletionMarker = getSessionSeenMarker(state, sourceSession.id);
|
|
13927
|
+
const lastUsedAt = getSessionLastUsedAt(sourceSession);
|
|
13928
|
+
const completionMarker = getSessionCompletionMarker(sourceSession);
|
|
13929
|
+
const { unread, inboxBucket } = sourceSession.surfaceHidden ? { unread: false, inboxBucket: "idle" } : getUnreadState(
|
|
13930
|
+
getSessionMessageUpdatedAt(sourceSession) > 0,
|
|
13931
|
+
sourceSession.status,
|
|
13691
13932
|
lastUsedAt,
|
|
13692
13933
|
lastSeenAt,
|
|
13693
|
-
getLastMessageRole(
|
|
13934
|
+
getLastMessageRole(sourceSession),
|
|
13694
13935
|
completionMarker,
|
|
13695
13936
|
seenCompletionMarker
|
|
13696
13937
|
);
|
|
@@ -13700,39 +13941,30 @@ function buildStatusSnapshot(options) {
|
|
|
13700
13941
|
if (READ_DEBUG_ENABLED && (session.unread || session.inboxBucket !== "idle" || session.providerType.includes("codex"))) {
|
|
13701
13942
|
LOG.info(
|
|
13702
13943
|
"RecentRead",
|
|
13703
|
-
`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(
|
|
13944
|
+
`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)}`
|
|
13704
13945
|
);
|
|
13705
13946
|
}
|
|
13706
13947
|
}
|
|
13707
|
-
const
|
|
13948
|
+
const includeMachineMetadata = profile !== "live";
|
|
13949
|
+
const terminalBackend = includeMachineMetadata ? getTerminalBackendRuntimeStatus() : void 0;
|
|
13708
13950
|
return {
|
|
13709
13951
|
instanceId: options.instanceId,
|
|
13710
|
-
version: options.version,
|
|
13711
|
-
|
|
13712
|
-
|
|
13713
|
-
hostname: os16.hostname(),
|
|
13714
|
-
platform: os16.platform(),
|
|
13715
|
-
arch: os16.arch(),
|
|
13716
|
-
cpus: os16.cpus().length,
|
|
13717
|
-
totalMem: memSnap.totalMem,
|
|
13718
|
-
freeMem: memSnap.freeMem,
|
|
13719
|
-
availableMem: memSnap.availableMem,
|
|
13720
|
-
loadavg: os16.loadavg(),
|
|
13721
|
-
uptime: os16.uptime(),
|
|
13722
|
-
release: os16.release()
|
|
13723
|
-
},
|
|
13724
|
-
machineNickname: options.machineNickname ?? cfg.machineNickname ?? null,
|
|
13952
|
+
...includeMachineMetadata ? { version: options.version } : {},
|
|
13953
|
+
machine: buildMachineInfo(profile),
|
|
13954
|
+
...includeMachineMetadata ? { machineNickname: options.machineNickname ?? cfg.machineNickname ?? null } : {},
|
|
13725
13955
|
timestamp: options.timestamp ?? Date.now(),
|
|
13726
|
-
detectedIdes: buildDetectedIdeInfos(options.detectedIdes, options.cdpManagers),
|
|
13727
13956
|
...options.p2p ? { p2p: options.p2p } : {},
|
|
13728
13957
|
sessions,
|
|
13729
|
-
|
|
13730
|
-
|
|
13731
|
-
|
|
13732
|
-
|
|
13733
|
-
|
|
13734
|
-
|
|
13735
|
-
|
|
13958
|
+
...terminalBackend ? { terminalBackend } : {},
|
|
13959
|
+
...includeMachineMetadata && {
|
|
13960
|
+
detectedIdes: buildDetectedIdeInfos(options.detectedIdes, options.cdpManagers),
|
|
13961
|
+
workspaces: wsState.workspaces,
|
|
13962
|
+
defaultWorkspaceId: wsState.defaultWorkspaceId,
|
|
13963
|
+
defaultWorkspacePath: wsState.defaultWorkspacePath,
|
|
13964
|
+
terminalSizingMode: cfg.terminalSizingMode || "measured",
|
|
13965
|
+
recentLaunches: buildRecentLaunches(recentActivity),
|
|
13966
|
+
availableProviders: buildAvailableProviders(options.providerLoader)
|
|
13967
|
+
}
|
|
13736
13968
|
};
|
|
13737
13969
|
}
|
|
13738
13970
|
|
|
@@ -14288,6 +14520,25 @@ var DaemonCommandRouter = class {
|
|
|
14288
14520
|
updateConfig({ userName: name });
|
|
14289
14521
|
return { success: true, userName: name };
|
|
14290
14522
|
}
|
|
14523
|
+
case "get_status_metadata": {
|
|
14524
|
+
const snapshot = buildStatusSnapshot({
|
|
14525
|
+
allStates: this.deps.instanceManager.collectAllStates(),
|
|
14526
|
+
cdpManagers: this.deps.cdpManagers,
|
|
14527
|
+
providerLoader: this.deps.providerLoader,
|
|
14528
|
+
detectedIdes: this.deps.detectedIdes.value,
|
|
14529
|
+
instanceId: this.deps.statusInstanceId || loadConfig().machineId || "daemon",
|
|
14530
|
+
version: this.deps.statusVersion || "unknown",
|
|
14531
|
+
profile: "metadata"
|
|
14532
|
+
});
|
|
14533
|
+
return { success: true, status: snapshot };
|
|
14534
|
+
}
|
|
14535
|
+
case "get_machine_runtime_stats": {
|
|
14536
|
+
return {
|
|
14537
|
+
success: true,
|
|
14538
|
+
machine: buildMachineInfo("full"),
|
|
14539
|
+
timestamp: Date.now()
|
|
14540
|
+
};
|
|
14541
|
+
}
|
|
14291
14542
|
case "mark_session_seen": {
|
|
14292
14543
|
const sessionId = args?.sessionId;
|
|
14293
14544
|
if (!sessionId || typeof sessionId !== "string") {
|
|
@@ -14493,9 +14744,58 @@ var DaemonStatusReporter = class {
|
|
|
14493
14744
|
}, 5e3 - elapsed);
|
|
14494
14745
|
}
|
|
14495
14746
|
}
|
|
14747
|
+
toDaemonStatusEventName(value) {
|
|
14748
|
+
switch (value) {
|
|
14749
|
+
case "agent:generating_started":
|
|
14750
|
+
case "agent:waiting_approval":
|
|
14751
|
+
case "agent:generating_completed":
|
|
14752
|
+
case "agent:stopped":
|
|
14753
|
+
case "monitor:long_generating":
|
|
14754
|
+
return value;
|
|
14755
|
+
default:
|
|
14756
|
+
return null;
|
|
14757
|
+
}
|
|
14758
|
+
}
|
|
14759
|
+
buildServerStatusEvent(event) {
|
|
14760
|
+
const eventName = this.toDaemonStatusEventName(event.event);
|
|
14761
|
+
if (!eventName) return null;
|
|
14762
|
+
if (eventName.startsWith("provider:")) {
|
|
14763
|
+
return null;
|
|
14764
|
+
}
|
|
14765
|
+
const payload = {
|
|
14766
|
+
event: eventName,
|
|
14767
|
+
timestamp: typeof event.timestamp === "number" && Number.isFinite(event.timestamp) ? event.timestamp : Date.now()
|
|
14768
|
+
};
|
|
14769
|
+
if (typeof event.targetSessionId === "string" && event.targetSessionId.trim()) {
|
|
14770
|
+
payload.targetSessionId = event.targetSessionId.trim();
|
|
14771
|
+
}
|
|
14772
|
+
const providerType = typeof event.providerType === "string" && event.providerType.trim() ? event.providerType.trim() : typeof event.ideType === "string" && event.ideType.trim() ? event.ideType.trim() : "";
|
|
14773
|
+
if (providerType) {
|
|
14774
|
+
payload.providerType = providerType;
|
|
14775
|
+
}
|
|
14776
|
+
if (typeof event.duration === "number" && Number.isFinite(event.duration)) {
|
|
14777
|
+
payload.duration = event.duration;
|
|
14778
|
+
}
|
|
14779
|
+
if (typeof event.elapsedSec === "number" && Number.isFinite(event.elapsedSec)) {
|
|
14780
|
+
payload.elapsedSec = event.elapsedSec;
|
|
14781
|
+
}
|
|
14782
|
+
if (typeof event.modalMessage === "string" && event.modalMessage.trim()) {
|
|
14783
|
+
payload.modalMessage = event.modalMessage;
|
|
14784
|
+
}
|
|
14785
|
+
if (Array.isArray(event.modalButtons)) {
|
|
14786
|
+
const modalButtons = event.modalButtons.filter((button) => typeof button === "string" && button.trim().length > 0);
|
|
14787
|
+
if (modalButtons.length > 0) {
|
|
14788
|
+
payload.modalButtons = modalButtons;
|
|
14789
|
+
}
|
|
14790
|
+
}
|
|
14791
|
+
return payload;
|
|
14792
|
+
}
|
|
14496
14793
|
emitStatusEvent(event) {
|
|
14497
14794
|
LOG.info("StatusEvent", `${event.event} (${event.providerType || event.ideType || ""})`);
|
|
14498
|
-
this.
|
|
14795
|
+
const serverEvent = this.buildServerStatusEvent(event);
|
|
14796
|
+
if (!serverEvent) return;
|
|
14797
|
+
this.deps.p2p?.sendStatusEvent(serverEvent);
|
|
14798
|
+
this.deps.serverConn?.sendMessage("status_event", serverEvent);
|
|
14499
14799
|
}
|
|
14500
14800
|
removeAgentTracking(_key) {
|
|
14501
14801
|
}
|
|
@@ -14564,17 +14864,16 @@ var DaemonStatusReporter = class {
|
|
|
14564
14864
|
detectedIdes: this.deps.detectedIdes || [],
|
|
14565
14865
|
instanceId: this.deps.instanceId,
|
|
14566
14866
|
version: this.deps.daemonVersion || "unknown",
|
|
14567
|
-
daemonMode: true,
|
|
14568
14867
|
timestamp: now,
|
|
14569
14868
|
p2p: {
|
|
14570
14869
|
available: p2p?.isAvailable || false,
|
|
14571
14870
|
state: p2p?.connectionState || "unavailable",
|
|
14572
14871
|
peers: p2p?.connectedPeerCount || 0,
|
|
14573
14872
|
screenshotActive: p2p?.screenshotActive || false
|
|
14574
|
-
}
|
|
14873
|
+
},
|
|
14874
|
+
profile: "live"
|
|
14575
14875
|
}),
|
|
14576
|
-
screenshotUsage: this.deps.getScreenshotUsage?.() || null
|
|
14577
|
-
connectedExtensions: []
|
|
14876
|
+
screenshotUsage: this.deps.getScreenshotUsage?.() || null
|
|
14578
14877
|
};
|
|
14579
14878
|
const payloadBytes = JSON.stringify(payload).length;
|
|
14580
14879
|
const p2pSent = this.sendP2PPayload(payload);
|
|
@@ -14589,16 +14888,15 @@ var DaemonStatusReporter = class {
|
|
|
14589
14888
|
}
|
|
14590
14889
|
if (opts?.p2pOnly) return;
|
|
14591
14890
|
const wsPayload = {
|
|
14592
|
-
daemonMode: true,
|
|
14593
14891
|
sessions: sessions.map((session) => ({
|
|
14594
14892
|
id: session.id,
|
|
14595
14893
|
parentId: session.parentId,
|
|
14596
14894
|
providerType: session.providerType,
|
|
14597
|
-
providerName: session.providerName,
|
|
14895
|
+
providerName: session.providerName || session.providerType,
|
|
14598
14896
|
kind: session.kind,
|
|
14599
14897
|
transport: session.transport,
|
|
14600
14898
|
status: session.status,
|
|
14601
|
-
workspace: session.workspace,
|
|
14899
|
+
workspace: session.workspace ?? null,
|
|
14602
14900
|
title: session.title,
|
|
14603
14901
|
cdpConnected: session.cdpConnected,
|
|
14604
14902
|
currentModel: session.currentModel,
|
|
@@ -14606,9 +14904,7 @@ var DaemonStatusReporter = class {
|
|
|
14606
14904
|
currentAutoApprove: session.currentAutoApprove
|
|
14607
14905
|
})),
|
|
14608
14906
|
p2p: payload.p2p,
|
|
14609
|
-
timestamp: now
|
|
14610
|
-
detectedIdes: payload.detectedIdes,
|
|
14611
|
-
availableProviders: payload.availableProviders
|
|
14907
|
+
timestamp: now
|
|
14612
14908
|
};
|
|
14613
14909
|
const wsHash = this.simpleHash(JSON.stringify({
|
|
14614
14910
|
...wsPayload,
|
|
@@ -14625,10 +14921,15 @@ var DaemonStatusReporter = class {
|
|
|
14625
14921
|
// ─── P2P ─────────────────────────────────────────
|
|
14626
14922
|
sendP2PPayload(payload) {
|
|
14627
14923
|
const { timestamp: _ts, system: _sys, ...hashTarget } = payload;
|
|
14924
|
+
const sessions = Array.isArray(hashTarget.sessions) ? hashTarget.sessions.map((session) => {
|
|
14925
|
+
if (!session || typeof session !== "object") return session;
|
|
14926
|
+
const { lastUpdated: _lu, ...stableSession } = session;
|
|
14927
|
+
return stableSession;
|
|
14928
|
+
}) : hashTarget.sessions;
|
|
14628
14929
|
const hashPayload = hashTarget.machine ? (() => {
|
|
14629
14930
|
const { freeMem: _f, availableMem: _a, loadavg: _l, uptime: _u, ...stableMachine } = hashTarget.machine;
|
|
14630
|
-
return { ...hashTarget, machine: stableMachine };
|
|
14631
|
-
})() : hashTarget;
|
|
14931
|
+
return { ...hashTarget, sessions, machine: stableMachine };
|
|
14932
|
+
})() : { ...hashTarget, sessions };
|
|
14632
14933
|
const h = this.simpleHash(JSON.stringify(hashPayload));
|
|
14633
14934
|
if (h !== this.lastP2PStatusHash) {
|
|
14634
14935
|
this.lastP2PStatusHash = h;
|
|
@@ -21726,6 +22027,8 @@ async function initDaemonComponents(config) {
|
|
|
21726
22027
|
onStatusChange: config.onStatusChange,
|
|
21727
22028
|
onPostChatCommand: config.onPostChatCommand,
|
|
21728
22029
|
sessionHostControl: config.sessionHostControl,
|
|
22030
|
+
statusInstanceId: config.statusInstanceId,
|
|
22031
|
+
statusVersion: config.statusVersion,
|
|
21729
22032
|
getCdpLogFn: config.getCdpLogFn || ((ideType) => LOG.forComponent(`CDP:${ideType}`).asLogFn())
|
|
21730
22033
|
});
|
|
21731
22034
|
poller = new AgentStreamPoller({
|
|
@@ -21828,6 +22131,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
21828
22131
|
SessionHostPtyTransportFactory,
|
|
21829
22132
|
VersionArchive,
|
|
21830
22133
|
appendRecentActivity,
|
|
22134
|
+
buildMachineInfo,
|
|
21831
22135
|
buildSessionEntries,
|
|
21832
22136
|
buildStatusSnapshot,
|
|
21833
22137
|
connectCdpManager,
|