@adhdev/daemon-core 0.7.39 → 0.7.40
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/config/config.d.ts +4 -2
- package/dist/config/recent-activity.d.ts +6 -6
- package/dist/index.d.ts +2 -2
- package/dist/index.js +187 -214
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +187 -214
- package/dist/index.mjs.map +1 -1
- package/dist/shared-types-extra.d.ts +1 -1
- package/dist/shared-types.d.ts +4 -12
- package/dist/status/snapshot.d.ts +13 -0
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +1 -1
- package/src/commands/router.ts +26 -16
- package/src/config/config.ts +6 -3
- package/src/config/recent-activity.ts +24 -12
- package/src/index.ts +2 -2
- package/src/shared-types-extra.ts +1 -1
- package/src/shared-types.d.ts +4 -6
- package/src/shared-types.ts +4 -12
- package/src/status/reporter.ts +1 -1
- package/src/status/snapshot.ts +61 -91
package/dist/config/config.d.ts
CHANGED
|
@@ -34,8 +34,10 @@ export interface ADHDevConfig {
|
|
|
34
34
|
defaultWorkspaceId?: string | null;
|
|
35
35
|
/** Unified recent activity across IDE / CLI / ACP launch flows */
|
|
36
36
|
recentActivity?: RecentActivityEntry[];
|
|
37
|
-
/** Last seen timestamps for
|
|
38
|
-
|
|
37
|
+
/** Last seen timestamps for live sessions, keyed by sessionId */
|
|
38
|
+
sessionReads?: Record<string, number>;
|
|
39
|
+
/** Last seen completion marker for live sessions, keyed by sessionId */
|
|
40
|
+
sessionReadMarkers?: Record<string, string>;
|
|
39
41
|
machineNickname: string | null;
|
|
40
42
|
/**
|
|
41
43
|
* Stable local machine ID (prefix: `mach_`) — generated locally on first run.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Unified recent activity —
|
|
2
|
+
* Unified recent activity — launcher-facing "pick up where you launched".
|
|
3
3
|
*
|
|
4
|
-
* Unlike
|
|
4
|
+
* Unlike live session state, this is launch oriented:
|
|
5
5
|
* - one normalized row shape for IDE / CLI / ACP
|
|
6
6
|
* - deduped by kind + providerType + workspace
|
|
7
|
-
* -
|
|
7
|
+
* - used only for quick-launch shortcuts
|
|
8
8
|
*/
|
|
9
9
|
import type { ADHDevConfig } from './config.js';
|
|
10
10
|
export interface RecentActivityEntry {
|
|
@@ -14,7 +14,6 @@ export interface RecentActivityEntry {
|
|
|
14
14
|
providerName: string;
|
|
15
15
|
workspace?: string | null;
|
|
16
16
|
currentModel?: string;
|
|
17
|
-
sessionId?: string | null;
|
|
18
17
|
title?: string;
|
|
19
18
|
lastUsedAt: number;
|
|
20
19
|
}
|
|
@@ -23,5 +22,6 @@ export declare function appendRecentActivity(config: ADHDevConfig, entry: Omit<R
|
|
|
23
22
|
lastUsedAt?: number;
|
|
24
23
|
}): ADHDevConfig;
|
|
25
24
|
export declare function getRecentActivity(config: ADHDevConfig, limit?: number): RecentActivityEntry[];
|
|
26
|
-
export declare function
|
|
27
|
-
export declare function
|
|
25
|
+
export declare function getSessionSeenAt(config: ADHDevConfig, sessionId: string): number;
|
|
26
|
+
export declare function getSessionSeenMarker(config: ADHDevConfig, sessionId: string): string;
|
|
27
|
+
export declare function markSessionSeen(config: ADHDevConfig, sessionId: string, seenAt?: number, completionMarker?: string | null): ADHDevConfig;
|
package/dist/index.d.ts
CHANGED
|
@@ -7,11 +7,11 @@ export type { ChatMessage, ExtensionInfo, CommandResult as CoreCommandResult, Pr
|
|
|
7
7
|
export type { SessionEntry, SessionTransport, SessionKind, SessionCapability, AgentSessionStream, AvailableProviderInfo, AcpConfigOption, AcpMode, ProviderControlSchema, StatusReportPayload, MachineInfo, DetectedIdeInfo, WorkspaceEntry, ProviderStatus, ProviderErrorReason, ActiveChatData, IdeProviderState, CliProviderState, AcpProviderState, ExtensionProviderState, } from './shared-types.js';
|
|
8
8
|
import type { RuntimeWriteOwner as _RuntimeWriteOwner } from './shared-types-extra.js';
|
|
9
9
|
import type { RuntimeAttachedClient as _RuntimeAttachedClient } from './shared-types-extra.js';
|
|
10
|
-
import type {
|
|
10
|
+
import type { RecentLaunchEntry as _RecentLaunchEntry } from './shared-types.js';
|
|
11
11
|
import type { TerminalBackendStatus as _TerminalBackendStatus } from './shared-types-extra.js';
|
|
12
12
|
export type RuntimeWriteOwner = _RuntimeWriteOwner;
|
|
13
13
|
export type RuntimeAttachedClient = _RuntimeAttachedClient;
|
|
14
|
-
export type
|
|
14
|
+
export type RecentLaunchEntry = _RecentLaunchEntry;
|
|
15
15
|
export type TerminalBackendStatus = _TerminalBackendStatus;
|
|
16
16
|
export type SessionStatus = 'idle' | 'generating' | 'waiting_approval' | 'error' | 'stopped' | 'starting' | 'panel_hidden' | 'not_monitored' | 'disconnected';
|
|
17
17
|
export type RecentSessionBucket = 'needs_attention' | 'working' | 'task_complete' | 'idle';
|
package/dist/index.js
CHANGED
|
@@ -175,7 +175,8 @@ var init_config = __esm({
|
|
|
175
175
|
workspaces: [],
|
|
176
176
|
defaultWorkspaceId: null,
|
|
177
177
|
recentActivity: [],
|
|
178
|
-
|
|
178
|
+
sessionReads: {},
|
|
179
|
+
sessionReadMarkers: {},
|
|
179
180
|
machineNickname: null,
|
|
180
181
|
machineId: void 0,
|
|
181
182
|
machineSecret: null,
|
|
@@ -2123,18 +2124,27 @@ function appendRecentActivity(config, entry) {
|
|
|
2123
2124
|
function getRecentActivity(config, limit = 20) {
|
|
2124
2125
|
return [...config.recentActivity || []].sort((a, b) => b.lastUsedAt - a.lastUsedAt).slice(0, limit);
|
|
2125
2126
|
}
|
|
2126
|
-
function
|
|
2127
|
-
return config.
|
|
2127
|
+
function getSessionSeenAt(config, sessionId) {
|
|
2128
|
+
return config.sessionReads?.[sessionId] || 0;
|
|
2128
2129
|
}
|
|
2129
|
-
function
|
|
2130
|
-
|
|
2131
|
-
|
|
2130
|
+
function getSessionSeenMarker(config, sessionId) {
|
|
2131
|
+
return config.sessionReadMarkers?.[sessionId] || "";
|
|
2132
|
+
}
|
|
2133
|
+
function markSessionSeen(config, sessionId, seenAt = Date.now(), completionMarker) {
|
|
2134
|
+
const prev = config.sessionReads || {};
|
|
2135
|
+
const nextSeenAt = Math.max(prev[sessionId] || 0, seenAt);
|
|
2136
|
+
const prevMarkers = config.sessionReadMarkers || {};
|
|
2137
|
+
const nextMarker = typeof completionMarker === "string" ? completionMarker : "";
|
|
2132
2138
|
return {
|
|
2133
2139
|
...config,
|
|
2134
|
-
|
|
2140
|
+
sessionReads: {
|
|
2135
2141
|
...prev,
|
|
2136
|
-
[
|
|
2137
|
-
}
|
|
2142
|
+
[sessionId]: nextSeenAt
|
|
2143
|
+
},
|
|
2144
|
+
sessionReadMarkers: nextMarker ? {
|
|
2145
|
+
...prevMarkers,
|
|
2146
|
+
[sessionId]: nextMarker
|
|
2147
|
+
} : prevMarkers
|
|
2138
2148
|
};
|
|
2139
2149
|
}
|
|
2140
2150
|
|
|
@@ -8464,6 +8474,149 @@ cleanOldFiles();
|
|
|
8464
8474
|
|
|
8465
8475
|
// src/commands/router.ts
|
|
8466
8476
|
init_logger();
|
|
8477
|
+
|
|
8478
|
+
// src/status/snapshot.ts
|
|
8479
|
+
var os10 = __toESM(require("os"));
|
|
8480
|
+
init_config();
|
|
8481
|
+
init_terminal_screen();
|
|
8482
|
+
init_logger();
|
|
8483
|
+
var READ_DEBUG_ENABLED = process.argv.includes("--dev") || process.env.ADHDEV_READ_DEBUG === "1";
|
|
8484
|
+
function buildDetectedIdeInfos(detectedIdes, cdpManagers) {
|
|
8485
|
+
return detectedIdes.filter((ide) => ide.installed !== false).map((ide) => ({
|
|
8486
|
+
id: ide.id,
|
|
8487
|
+
type: ide.id,
|
|
8488
|
+
name: ide.displayName || ide.name || ide.id,
|
|
8489
|
+
running: isCdpConnected(cdpManagers, ide.id),
|
|
8490
|
+
...ide.path ? { path: ide.path } : {}
|
|
8491
|
+
}));
|
|
8492
|
+
}
|
|
8493
|
+
function buildAvailableProviders(providerLoader) {
|
|
8494
|
+
return providerLoader.getAll().map((provider) => ({
|
|
8495
|
+
type: provider.type,
|
|
8496
|
+
name: provider.displayName || provider.type,
|
|
8497
|
+
displayName: provider.displayName || provider.type,
|
|
8498
|
+
icon: provider.icon || "\u{1F4BB}",
|
|
8499
|
+
category: provider.category
|
|
8500
|
+
}));
|
|
8501
|
+
}
|
|
8502
|
+
function parseMessageTime(value) {
|
|
8503
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
8504
|
+
if (typeof value === "string") {
|
|
8505
|
+
const parsed = Date.parse(value);
|
|
8506
|
+
if (Number.isFinite(parsed)) return parsed;
|
|
8507
|
+
}
|
|
8508
|
+
return 0;
|
|
8509
|
+
}
|
|
8510
|
+
function getSessionMessageUpdatedAt(session) {
|
|
8511
|
+
const lastMessage = session.activeChat?.messages?.at?.(-1);
|
|
8512
|
+
if (!lastMessage) return 0;
|
|
8513
|
+
return parseMessageTime(lastMessage.timestamp) || parseMessageTime(lastMessage.receivedAt) || parseMessageTime(lastMessage.createdAt) || 0;
|
|
8514
|
+
}
|
|
8515
|
+
function getSessionCompletionMarker(session) {
|
|
8516
|
+
const lastMessage = session.activeChat?.messages?.at?.(-1);
|
|
8517
|
+
if (!lastMessage) return "";
|
|
8518
|
+
const role = typeof lastMessage.role === "string" ? lastMessage.role : "";
|
|
8519
|
+
if (role === "user" || role === "human") return "";
|
|
8520
|
+
if (typeof lastMessage._turnKey === "string" && lastMessage._turnKey) return `turn:${lastMessage._turnKey}`;
|
|
8521
|
+
if (typeof lastMessage.id === "string" && lastMessage.id) return `id:${lastMessage.id}`;
|
|
8522
|
+
if (typeof lastMessage.index === "number" && Number.isFinite(lastMessage.index)) return `idx:${lastMessage.index}`;
|
|
8523
|
+
const timestamp = parseMessageTime(lastMessage.timestamp) || parseMessageTime(lastMessage.receivedAt) || parseMessageTime(lastMessage.createdAt);
|
|
8524
|
+
return timestamp > 0 ? `ts:${timestamp}` : "";
|
|
8525
|
+
}
|
|
8526
|
+
function getSessionLastUsedAt(session) {
|
|
8527
|
+
return getSessionMessageUpdatedAt(session) || session.lastUpdated || Date.now();
|
|
8528
|
+
}
|
|
8529
|
+
function getLastMessageRole(session) {
|
|
8530
|
+
const role = session.activeChat?.messages?.at?.(-1)?.role;
|
|
8531
|
+
return typeof role === "string" ? role : "";
|
|
8532
|
+
}
|
|
8533
|
+
function getUnreadState(hasContentChange, status, lastUsedAt, lastSeenAt, lastRole, completionMarker, seenCompletionMarker) {
|
|
8534
|
+
if (status === "waiting_approval") {
|
|
8535
|
+
return { unread: false, inboxBucket: "needs_attention" };
|
|
8536
|
+
}
|
|
8537
|
+
if (status === "generating" || status === "starting") {
|
|
8538
|
+
return { unread: false, inboxBucket: "working" };
|
|
8539
|
+
}
|
|
8540
|
+
const unread = completionMarker ? completionMarker !== seenCompletionMarker : hasContentChange && lastUsedAt > lastSeenAt && lastRole !== "user" && lastRole !== "human";
|
|
8541
|
+
return { unread, inboxBucket: unread ? "task_complete" : "idle" };
|
|
8542
|
+
}
|
|
8543
|
+
function buildRecentLaunches(recentActivity) {
|
|
8544
|
+
return recentActivity.map((item) => ({
|
|
8545
|
+
id: item.id,
|
|
8546
|
+
providerType: item.providerType,
|
|
8547
|
+
providerName: item.providerName,
|
|
8548
|
+
kind: item.kind,
|
|
8549
|
+
title: item.title || item.providerName,
|
|
8550
|
+
workspace: item.workspace,
|
|
8551
|
+
currentModel: item.currentModel,
|
|
8552
|
+
lastLaunchedAt: item.lastUsedAt
|
|
8553
|
+
})).sort((a, b) => b.lastLaunchedAt - a.lastLaunchedAt).slice(0, 12);
|
|
8554
|
+
}
|
|
8555
|
+
function buildStatusSnapshot(options) {
|
|
8556
|
+
const cfg = loadConfig();
|
|
8557
|
+
const wsState = getWorkspaceState(cfg);
|
|
8558
|
+
const memSnap = getHostMemorySnapshot();
|
|
8559
|
+
const recentActivity = getRecentActivity(cfg, 20);
|
|
8560
|
+
const sessions = buildSessionEntries(
|
|
8561
|
+
options.allStates,
|
|
8562
|
+
options.cdpManagers
|
|
8563
|
+
);
|
|
8564
|
+
for (const session of sessions) {
|
|
8565
|
+
const lastSeenAt = getSessionSeenAt(cfg, session.id);
|
|
8566
|
+
const seenCompletionMarker = getSessionSeenMarker(cfg, session.id);
|
|
8567
|
+
const lastUsedAt = getSessionLastUsedAt(session);
|
|
8568
|
+
const completionMarker = getSessionCompletionMarker(session);
|
|
8569
|
+
const { unread, inboxBucket } = session.surfaceHidden ? { unread: false, inboxBucket: "idle" } : getUnreadState(
|
|
8570
|
+
getSessionMessageUpdatedAt(session) > 0,
|
|
8571
|
+
session.status,
|
|
8572
|
+
lastUsedAt,
|
|
8573
|
+
lastSeenAt,
|
|
8574
|
+
getLastMessageRole(session),
|
|
8575
|
+
completionMarker,
|
|
8576
|
+
seenCompletionMarker
|
|
8577
|
+
);
|
|
8578
|
+
session.lastSeenAt = lastSeenAt;
|
|
8579
|
+
session.unread = unread;
|
|
8580
|
+
session.inboxBucket = inboxBucket;
|
|
8581
|
+
if (READ_DEBUG_ENABLED && (session.unread || session.inboxBucket !== "idle" || session.providerType.includes("codex"))) {
|
|
8582
|
+
LOG.info(
|
|
8583
|
+
"RecentRead",
|
|
8584
|
+
`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(session)} msgUpdatedAt=${getSessionMessageUpdatedAt(session)}`
|
|
8585
|
+
);
|
|
8586
|
+
}
|
|
8587
|
+
}
|
|
8588
|
+
const terminalBackend = getTerminalBackendRuntimeStatus();
|
|
8589
|
+
return {
|
|
8590
|
+
instanceId: options.instanceId,
|
|
8591
|
+
version: options.version,
|
|
8592
|
+
daemonMode: options.daemonMode,
|
|
8593
|
+
machine: {
|
|
8594
|
+
hostname: os10.hostname(),
|
|
8595
|
+
platform: os10.platform(),
|
|
8596
|
+
arch: os10.arch(),
|
|
8597
|
+
cpus: os10.cpus().length,
|
|
8598
|
+
totalMem: memSnap.totalMem,
|
|
8599
|
+
freeMem: memSnap.freeMem,
|
|
8600
|
+
availableMem: memSnap.availableMem,
|
|
8601
|
+
loadavg: os10.loadavg(),
|
|
8602
|
+
uptime: os10.uptime(),
|
|
8603
|
+
release: os10.release()
|
|
8604
|
+
},
|
|
8605
|
+
machineNickname: options.machineNickname ?? cfg.machineNickname ?? null,
|
|
8606
|
+
timestamp: options.timestamp ?? Date.now(),
|
|
8607
|
+
detectedIdes: buildDetectedIdeInfos(options.detectedIdes, options.cdpManagers),
|
|
8608
|
+
...options.p2p ? { p2p: options.p2p } : {},
|
|
8609
|
+
sessions,
|
|
8610
|
+
workspaces: wsState.workspaces,
|
|
8611
|
+
defaultWorkspaceId: wsState.defaultWorkspaceId,
|
|
8612
|
+
defaultWorkspacePath: wsState.defaultWorkspacePath,
|
|
8613
|
+
recentLaunches: buildRecentLaunches(recentActivity),
|
|
8614
|
+
terminalBackend,
|
|
8615
|
+
availableProviders: buildAvailableProviders(options.providerLoader)
|
|
8616
|
+
};
|
|
8617
|
+
}
|
|
8618
|
+
|
|
8619
|
+
// src/commands/router.ts
|
|
8467
8620
|
var fs7 = __toESM(require("fs"));
|
|
8468
8621
|
var CHAT_COMMANDS = [
|
|
8469
8622
|
"send_chat",
|
|
@@ -8472,6 +8625,7 @@ var CHAT_COMMANDS = [
|
|
|
8472
8625
|
"set_mode",
|
|
8473
8626
|
"change_model"
|
|
8474
8627
|
];
|
|
8628
|
+
var READ_DEBUG_ENABLED2 = process.argv.includes("--dev") || process.env.ADHDEV_READ_DEBUG === "1";
|
|
8475
8629
|
var DaemonCommandRouter = class {
|
|
8476
8630
|
deps;
|
|
8477
8631
|
constructor(deps) {
|
|
@@ -8642,28 +8796,35 @@ var DaemonCommandRouter = class {
|
|
|
8642
8796
|
updateConfig({ userName: name });
|
|
8643
8797
|
return { success: true, userName: name };
|
|
8644
8798
|
}
|
|
8645
|
-
case "
|
|
8646
|
-
const
|
|
8647
|
-
|
|
8648
|
-
|
|
8649
|
-
return { success: false, error: "kind and providerType are required" };
|
|
8799
|
+
case "mark_session_seen": {
|
|
8800
|
+
const sessionId = args?.sessionId;
|
|
8801
|
+
if (!sessionId || typeof sessionId !== "string") {
|
|
8802
|
+
return { success: false, error: "sessionId is required" };
|
|
8650
8803
|
}
|
|
8651
|
-
const
|
|
8652
|
-
|
|
8653
|
-
|
|
8654
|
-
|
|
8655
|
-
|
|
8656
|
-
|
|
8657
|
-
|
|
8658
|
-
|
|
8659
|
-
|
|
8804
|
+
const currentConfig = loadConfig();
|
|
8805
|
+
const prevSeenAt = currentConfig.sessionReads?.[sessionId] || 0;
|
|
8806
|
+
const sessionEntries = buildSessionEntries(
|
|
8807
|
+
this.deps.instanceManager.collectAllStates(),
|
|
8808
|
+
this.deps.cdpManagers
|
|
8809
|
+
);
|
|
8810
|
+
const targetSession = sessionEntries.find((entry) => entry.id === sessionId);
|
|
8811
|
+
const completionMarker = targetSession ? getSessionCompletionMarker(targetSession) : "";
|
|
8812
|
+
const next = markSessionSeen(
|
|
8813
|
+
currentConfig,
|
|
8814
|
+
sessionId,
|
|
8815
|
+
typeof args?.seenAt === "number" ? args.seenAt : Date.now(),
|
|
8816
|
+
completionMarker
|
|
8660
8817
|
);
|
|
8818
|
+
if (READ_DEBUG_ENABLED2) {
|
|
8819
|
+
LOG.info("RecentRead", `mark_session_seen sessionId=${sessionId} seenAt=${String(args?.seenAt || "")} prevSeenAt=${String(prevSeenAt)} nextSeenAt=${String(next.sessionReads?.[sessionId] || 0)} marker=${completionMarker || "-"}`);
|
|
8820
|
+
}
|
|
8661
8821
|
saveConfig(next);
|
|
8662
8822
|
this.deps.onStatusChange?.();
|
|
8663
8823
|
return {
|
|
8664
8824
|
success: true,
|
|
8665
|
-
|
|
8666
|
-
seenAt: next.
|
|
8825
|
+
sessionId,
|
|
8826
|
+
seenAt: next.sessionReads?.[sessionId] || Date.now(),
|
|
8827
|
+
completionMarker
|
|
8667
8828
|
};
|
|
8668
8829
|
}
|
|
8669
8830
|
// ─── Daemon Self-Upgrade ───
|
|
@@ -8780,194 +8941,6 @@ var DaemonCommandRouter = class {
|
|
|
8780
8941
|
|
|
8781
8942
|
// src/status/reporter.ts
|
|
8782
8943
|
init_logger();
|
|
8783
|
-
|
|
8784
|
-
// src/status/snapshot.ts
|
|
8785
|
-
var os10 = __toESM(require("os"));
|
|
8786
|
-
init_config();
|
|
8787
|
-
init_terminal_screen();
|
|
8788
|
-
function buildDetectedIdeInfos(detectedIdes, cdpManagers) {
|
|
8789
|
-
return detectedIdes.filter((ide) => ide.installed !== false).map((ide) => ({
|
|
8790
|
-
id: ide.id,
|
|
8791
|
-
type: ide.id,
|
|
8792
|
-
name: ide.displayName || ide.name || ide.id,
|
|
8793
|
-
running: isCdpConnected(cdpManagers, ide.id),
|
|
8794
|
-
...ide.path ? { path: ide.path } : {}
|
|
8795
|
-
}));
|
|
8796
|
-
}
|
|
8797
|
-
function buildAvailableProviders(providerLoader) {
|
|
8798
|
-
return providerLoader.getAll().map((provider) => ({
|
|
8799
|
-
type: provider.type,
|
|
8800
|
-
name: provider.displayName || provider.type,
|
|
8801
|
-
displayName: provider.displayName || provider.type,
|
|
8802
|
-
icon: provider.icon || "\u{1F4BB}",
|
|
8803
|
-
category: provider.category
|
|
8804
|
-
}));
|
|
8805
|
-
}
|
|
8806
|
-
function parseMessageTime(value) {
|
|
8807
|
-
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
8808
|
-
if (typeof value === "string") {
|
|
8809
|
-
const parsed = Date.parse(value);
|
|
8810
|
-
if (Number.isFinite(parsed)) return parsed;
|
|
8811
|
-
}
|
|
8812
|
-
return 0;
|
|
8813
|
-
}
|
|
8814
|
-
function getSessionMessageUpdatedAt(session) {
|
|
8815
|
-
const lastMessage = session.activeChat?.messages?.at?.(-1);
|
|
8816
|
-
if (!lastMessage) return 0;
|
|
8817
|
-
return parseMessageTime(lastMessage.timestamp) || parseMessageTime(lastMessage.receivedAt) || parseMessageTime(lastMessage.createdAt) || 0;
|
|
8818
|
-
}
|
|
8819
|
-
function getSessionLastUsedAt(session) {
|
|
8820
|
-
return getSessionMessageUpdatedAt(session) || session.lastUpdated || Date.now();
|
|
8821
|
-
}
|
|
8822
|
-
function getSessionKind(session) {
|
|
8823
|
-
return session.transport === "cdp-page" || session.transport === "cdp-webview" ? "ide" : session.transport === "acp" ? "acp" : "cli";
|
|
8824
|
-
}
|
|
8825
|
-
function getLastMessageRole(session) {
|
|
8826
|
-
const role = session.activeChat?.messages?.at?.(-1)?.role;
|
|
8827
|
-
return typeof role === "string" ? role : "";
|
|
8828
|
-
}
|
|
8829
|
-
function getUnreadState(hasContentChange, status, lastUsedAt, lastSeenAt, lastRole) {
|
|
8830
|
-
if (status === "waiting_approval") {
|
|
8831
|
-
return { unread: false, inboxBucket: "needs_attention" };
|
|
8832
|
-
}
|
|
8833
|
-
if (status === "generating" || status === "starting") {
|
|
8834
|
-
return { unread: false, inboxBucket: "working" };
|
|
8835
|
-
}
|
|
8836
|
-
const unread = hasContentChange && lastUsedAt > lastSeenAt && lastRole !== "user" && lastRole !== "human";
|
|
8837
|
-
return { unread, inboxBucket: unread ? "task_complete" : "idle" };
|
|
8838
|
-
}
|
|
8839
|
-
function buildRecentSessions(sessions, recentActivity, readState) {
|
|
8840
|
-
const visibleKeys = /* @__PURE__ */ new Set();
|
|
8841
|
-
const hiddenKeys = /* @__PURE__ */ new Set();
|
|
8842
|
-
const live = sessions.filter((session) => !session.surfaceHidden && session.status !== "stopped").map((session) => {
|
|
8843
|
-
const kind = getSessionKind(session);
|
|
8844
|
-
const recentKey = buildRecentActivityKey({
|
|
8845
|
-
kind,
|
|
8846
|
-
providerType: session.providerType,
|
|
8847
|
-
workspace: session.workspace
|
|
8848
|
-
});
|
|
8849
|
-
const lastSeenAt = readState[recentKey] || 0;
|
|
8850
|
-
const lastUsedAt = getSessionLastUsedAt(session);
|
|
8851
|
-
const { unread, inboxBucket } = getUnreadState(
|
|
8852
|
-
getSessionMessageUpdatedAt(session) > 0,
|
|
8853
|
-
session.status,
|
|
8854
|
-
lastUsedAt,
|
|
8855
|
-
lastSeenAt,
|
|
8856
|
-
getLastMessageRole(session)
|
|
8857
|
-
);
|
|
8858
|
-
return {
|
|
8859
|
-
id: session.id,
|
|
8860
|
-
recentKey,
|
|
8861
|
-
sessionId: session.id,
|
|
8862
|
-
providerType: session.providerType,
|
|
8863
|
-
providerName: session.providerName,
|
|
8864
|
-
kind,
|
|
8865
|
-
title: session.activeChat?.title || session.title || session.providerName,
|
|
8866
|
-
workspace: session.workspace,
|
|
8867
|
-
currentModel: session.currentModel,
|
|
8868
|
-
status: session.status,
|
|
8869
|
-
lastUsedAt,
|
|
8870
|
-
unread,
|
|
8871
|
-
lastSeenAt,
|
|
8872
|
-
inboxBucket,
|
|
8873
|
-
surfaceHidden: false
|
|
8874
|
-
};
|
|
8875
|
-
});
|
|
8876
|
-
for (const item of live) {
|
|
8877
|
-
visibleKeys.add(`${item.kind}:${item.providerType}:${item.workspace || ""}`);
|
|
8878
|
-
}
|
|
8879
|
-
for (const session of sessions) {
|
|
8880
|
-
if (!session.surfaceHidden) continue;
|
|
8881
|
-
hiddenKeys.add(`${getSessionKind(session)}:${session.providerType}:${session.workspace || ""}`);
|
|
8882
|
-
}
|
|
8883
|
-
const persisted = recentActivity.filter((item) => {
|
|
8884
|
-
const key = `${item.kind}:${item.providerType}:${item.workspace || ""}`;
|
|
8885
|
-
return !visibleKeys.has(key) && !hiddenKeys.has(key);
|
|
8886
|
-
}).map((item) => {
|
|
8887
|
-
const lastSeenAt = readState[item.id] || 0;
|
|
8888
|
-
const unread = item.lastUsedAt > lastSeenAt;
|
|
8889
|
-
return {
|
|
8890
|
-
id: item.id,
|
|
8891
|
-
recentKey: item.id,
|
|
8892
|
-
sessionId: item.sessionId || null,
|
|
8893
|
-
providerType: item.providerType,
|
|
8894
|
-
providerName: item.providerName,
|
|
8895
|
-
kind: item.kind,
|
|
8896
|
-
title: item.title || item.providerName,
|
|
8897
|
-
workspace: item.workspace,
|
|
8898
|
-
currentModel: item.currentModel,
|
|
8899
|
-
lastUsedAt: item.lastUsedAt,
|
|
8900
|
-
unread,
|
|
8901
|
-
lastSeenAt,
|
|
8902
|
-
inboxBucket: unread ? "task_complete" : "idle",
|
|
8903
|
-
surfaceHidden: false
|
|
8904
|
-
};
|
|
8905
|
-
});
|
|
8906
|
-
return [...live, ...persisted].sort((a, b) => b.lastUsedAt - a.lastUsedAt).slice(0, 12);
|
|
8907
|
-
}
|
|
8908
|
-
function buildStatusSnapshot(options) {
|
|
8909
|
-
const cfg = loadConfig();
|
|
8910
|
-
const wsState = getWorkspaceState(cfg);
|
|
8911
|
-
const memSnap = getHostMemorySnapshot();
|
|
8912
|
-
const recentActivity = getRecentActivity(cfg, 20);
|
|
8913
|
-
const sessions = buildSessionEntries(
|
|
8914
|
-
options.allStates,
|
|
8915
|
-
options.cdpManagers
|
|
8916
|
-
);
|
|
8917
|
-
const readState = cfg.recentSessionReads || {};
|
|
8918
|
-
for (const session of sessions) {
|
|
8919
|
-
const kind = getSessionKind(session);
|
|
8920
|
-
const recentKey = buildRecentActivityKey({
|
|
8921
|
-
kind,
|
|
8922
|
-
providerType: session.providerType,
|
|
8923
|
-
workspace: session.workspace
|
|
8924
|
-
});
|
|
8925
|
-
const lastSeenAt = getRecentSessionSeenAt(cfg, recentKey);
|
|
8926
|
-
const lastUsedAt = getSessionLastUsedAt(session);
|
|
8927
|
-
const { unread, inboxBucket } = session.surfaceHidden ? { unread: false, inboxBucket: "idle" } : getUnreadState(
|
|
8928
|
-
getSessionMessageUpdatedAt(session) > 0,
|
|
8929
|
-
session.status,
|
|
8930
|
-
lastUsedAt,
|
|
8931
|
-
lastSeenAt,
|
|
8932
|
-
getLastMessageRole(session)
|
|
8933
|
-
);
|
|
8934
|
-
session.recentKey = recentKey;
|
|
8935
|
-
session.lastSeenAt = lastSeenAt;
|
|
8936
|
-
session.unread = unread;
|
|
8937
|
-
session.inboxBucket = inboxBucket;
|
|
8938
|
-
}
|
|
8939
|
-
const terminalBackend = getTerminalBackendRuntimeStatus();
|
|
8940
|
-
return {
|
|
8941
|
-
instanceId: options.instanceId,
|
|
8942
|
-
version: options.version,
|
|
8943
|
-
daemonMode: options.daemonMode,
|
|
8944
|
-
machine: {
|
|
8945
|
-
hostname: os10.hostname(),
|
|
8946
|
-
platform: os10.platform(),
|
|
8947
|
-
arch: os10.arch(),
|
|
8948
|
-
cpus: os10.cpus().length,
|
|
8949
|
-
totalMem: memSnap.totalMem,
|
|
8950
|
-
freeMem: memSnap.freeMem,
|
|
8951
|
-
availableMem: memSnap.availableMem,
|
|
8952
|
-
loadavg: os10.loadavg(),
|
|
8953
|
-
uptime: os10.uptime(),
|
|
8954
|
-
release: os10.release()
|
|
8955
|
-
},
|
|
8956
|
-
machineNickname: options.machineNickname ?? cfg.machineNickname ?? null,
|
|
8957
|
-
timestamp: options.timestamp ?? Date.now(),
|
|
8958
|
-
detectedIdes: buildDetectedIdeInfos(options.detectedIdes, options.cdpManagers),
|
|
8959
|
-
...options.p2p ? { p2p: options.p2p } : {},
|
|
8960
|
-
sessions,
|
|
8961
|
-
workspaces: wsState.workspaces,
|
|
8962
|
-
defaultWorkspaceId: wsState.defaultWorkspaceId,
|
|
8963
|
-
defaultWorkspacePath: wsState.defaultWorkspacePath,
|
|
8964
|
-
recentSessions: buildRecentSessions(sessions, recentActivity, readState),
|
|
8965
|
-
terminalBackend,
|
|
8966
|
-
availableProviders: buildAvailableProviders(options.providerLoader)
|
|
8967
|
-
};
|
|
8968
|
-
}
|
|
8969
|
-
|
|
8970
|
-
// src/status/reporter.ts
|
|
8971
8944
|
var DaemonStatusReporter = class {
|
|
8972
8945
|
deps;
|
|
8973
8946
|
log;
|
|
@@ -9115,7 +9088,7 @@ var DaemonStatusReporter = class {
|
|
|
9115
9088
|
currentModel: session.currentModel,
|
|
9116
9089
|
currentPlan: session.currentPlan,
|
|
9117
9090
|
currentAutoApprove: session.currentAutoApprove,
|
|
9118
|
-
|
|
9091
|
+
lastUpdated: session.lastUpdated,
|
|
9119
9092
|
unread: session.unread,
|
|
9120
9093
|
lastSeenAt: session.lastSeenAt,
|
|
9121
9094
|
inboxBucket: session.inboxBucket,
|