@adhdev/daemon-core 0.7.38 → 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/agent-stream/forward.d.ts +8 -0
- package/dist/agent-stream/index.d.ts +6 -0
- package/dist/agent-stream/manager.d.ts +59 -0
- package/dist/agent-stream/poller.d.ts +41 -0
- package/dist/agent-stream/provider-adapter.d.ts +29 -0
- package/dist/agent-stream/types.d.ts +62 -0
- package/dist/boot/daemon-lifecycle.d.ts +97 -0
- package/dist/cdp/devtools.d.ts +51 -0
- package/dist/cdp/initializer.d.ts +50 -0
- package/dist/cdp/manager.d.ts +145 -0
- package/dist/cdp/scanner.d.ts +58 -0
- package/dist/cdp/setup.d.ts +58 -0
- package/dist/cli-adapter-types.d.ts +25 -0
- package/dist/cli-adapters/provider-cli-adapter.d.ts +229 -0
- package/dist/cli-adapters/pty-transport.d.ts +43 -0
- package/dist/cli-adapters/session-host-transport.d.ts +19 -0
- package/dist/cli-adapters/terminal-backends/ghostty-vt-backend.d.ts +12 -0
- package/dist/cli-adapters/terminal-backends/types.d.ts +14 -0
- package/dist/cli-adapters/terminal-backends/xterm-backend.d.ts +13 -0
- package/dist/cli-adapters/terminal-screen.d.ts +27 -0
- package/dist/commands/cdp-commands.d.ts +15 -0
- package/dist/commands/chat-commands.d.ts +15 -0
- package/dist/commands/cli-manager.d.ts +82 -0
- package/dist/commands/handler.d.ts +101 -0
- package/dist/commands/router.d.ts +69 -0
- package/dist/commands/stream-commands.d.ts +13 -0
- package/dist/commands/workspace-commands.d.ts +11 -0
- package/dist/config/chat-history.d.ts +60 -0
- package/dist/config/config.d.ts +103 -0
- package/dist/config/recent-activity.d.ts +27 -0
- package/dist/config/workspaces.d.ts +82 -0
- package/dist/daemon/dev-auto-implement.d.ts +26 -0
- package/dist/daemon/dev-cdp-handlers.d.ts +22 -0
- package/dist/daemon/dev-cli-debug.d.ts +24 -0
- package/dist/daemon/dev-server-types.d.ts +43 -0
- package/dist/daemon/dev-server.d.ts +133 -0
- package/dist/daemon/scaffold-template.d.ts +32 -0
- package/dist/daemon-core.d.ts +36 -0
- package/dist/detection/cli-detector.d.ts +27 -0
- package/dist/detection/ide-detector.d.ts +34 -0
- package/dist/index.d.ts +72 -2499
- package/dist/index.js +673 -879
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +680 -884
- package/dist/index.mjs.map +1 -1
- package/dist/installer.d.ts +50 -0
- package/dist/ipc-protocol.d.ts +111 -0
- package/dist/launch.d.ts +46 -0
- package/dist/logging/command-log.d.ts +31 -0
- package/dist/logging/logger.d.ts +87 -0
- package/dist/providers/acp-provider-instance.d.ts +101 -0
- package/dist/providers/cli-provider-instance.d.ts +43 -0
- package/dist/providers/contracts.d.ts +483 -0
- package/dist/providers/extension-provider-instance.d.ts +44 -0
- package/dist/providers/ide-provider-instance.d.ts +61 -0
- package/dist/providers/index.d.ts +5 -0
- package/dist/providers/provider-instance-manager.d.ts +84 -0
- package/dist/providers/provider-instance.d.ts +148 -0
- package/dist/providers/provider-loader.d.ts +270 -0
- package/dist/providers/status-monitor.d.ts +48 -0
- package/dist/providers/version-archive.d.ts +52 -0
- package/dist/session-host/runtime-support.d.ts +8 -0
- package/dist/sessions/registry.d.ts +24 -0
- package/dist/shared-types-extra.d.ts +29 -0
- package/dist/shared-types.d.ts +205 -0
- package/dist/status/builders.d.ts +33 -0
- package/dist/status/normalize.d.ts +14 -1
- package/dist/status/reporter.d.ts +69 -0
- package/dist/status/snapshot.d.ts +51 -0
- package/dist/system/host-memory.d.ts +19 -0
- package/dist/types.d.ts +123 -0
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +3 -2
- package/src/commands/cli-manager.ts +1 -26
- package/src/commands/handler.ts +0 -31
- package/src/commands/router.ts +27 -34
- package/src/commands/stream-commands.ts +2 -4
- package/src/commands/workspace-commands.ts +9 -23
- package/src/config/config.ts +7 -81
- package/src/config/recent-activity.ts +24 -12
- package/src/config/workspaces.ts +0 -24
- package/src/index.ts +16 -15
- package/src/providers/provider-loader.ts +13 -5
- package/src/shared-types-extra.ts +34 -0
- package/src/shared-types.d.ts +4 -6
- package/src/shared-types.ts +17 -38
- package/src/status/builders.ts +12 -0
- package/src/status/reporter.ts +2 -1
- package/src/status/snapshot.ts +70 -87
- package/src/types.ts +3 -8
- package/dist/index.d.mts +0 -2504
- package/dist/normalize-DVI4Lo5I.d.mts +0 -947
- package/dist/normalize-DVI4Lo5I.d.ts +0 -947
- package/dist/status/normalize.d.mts +0 -1
- package/src/config/workspace-activity.ts +0 -65
package/src/commands/router.ts
CHANGED
|
@@ -18,14 +18,14 @@ import type { ProviderInstanceManager } from '../providers/provider-instance-man
|
|
|
18
18
|
import { launchWithCdp, killIdeProcess, isIdeRunning } from '../launch.js';
|
|
19
19
|
import { loadConfig, saveConfig, updateConfig } from '../config/config.js';
|
|
20
20
|
import { resolveIdeLaunchWorkspace } from '../config/workspaces.js';
|
|
21
|
-
import {
|
|
22
|
-
import { addCliHistory } from '../config/config.js';
|
|
23
|
-
import { appendRecentActivity, buildRecentActivityKey, markRecentSessionSeen } from '../config/recent-activity.js';
|
|
21
|
+
import { appendRecentActivity, markSessionSeen } from '../config/recent-activity.js';
|
|
24
22
|
import { detectIDEs } from '../detection/ide-detector.js';
|
|
25
23
|
import { SessionRegistry } from '../sessions/registry.js';
|
|
26
24
|
import { LOG } from '../logging/logger.js';
|
|
27
25
|
import { logCommand } from '../logging/command-log.js';
|
|
28
26
|
import { getRecentLogs, LOG_PATH } from '../logging/logger.js';
|
|
27
|
+
import { buildSessionEntries } from '../status/builders.js';
|
|
28
|
+
import { getSessionCompletionMarker } from '../status/snapshot.js';
|
|
29
29
|
import * as fs from 'fs';
|
|
30
30
|
|
|
31
31
|
// ─── Types ───
|
|
@@ -63,6 +63,7 @@ const CHAT_COMMANDS = [
|
|
|
63
63
|
'send_chat', 'new_chat', 'switch_chat', 'set_mode',
|
|
64
64
|
'change_model',
|
|
65
65
|
];
|
|
66
|
+
const READ_DEBUG_ENABLED = process.argv.includes('--dev') || process.env.ADHDEV_READ_DEBUG === '1';
|
|
66
67
|
|
|
67
68
|
export class DaemonCommandRouter {
|
|
68
69
|
private deps: CommandRouterDeps;
|
|
@@ -208,17 +209,6 @@ export class DaemonCommandRouter {
|
|
|
208
209
|
};
|
|
209
210
|
LOG.info('LaunchIDE', `target=${ideKey || 'auto'}`);
|
|
210
211
|
const result = await launchWithCdp(launchArgs);
|
|
211
|
-
if (result.success && (result.ideId || ideKey)) {
|
|
212
|
-
try {
|
|
213
|
-
addCliHistory({
|
|
214
|
-
category: 'ide',
|
|
215
|
-
cliType: result.ideId || ideKey,
|
|
216
|
-
dir: resolvedWorkspace || '',
|
|
217
|
-
workspace: resolvedWorkspace || '',
|
|
218
|
-
newWindow: args?.newWindow === true,
|
|
219
|
-
});
|
|
220
|
-
} catch { /* ignore history failure */ }
|
|
221
|
-
}
|
|
222
212
|
|
|
223
213
|
if (result.success && result.port && result.ideId && !this.deps.cdpManagers.has(result.ideId)) {
|
|
224
214
|
const logFn = this.deps.getCdpLogFn
|
|
@@ -241,11 +231,7 @@ export class DaemonCommandRouter {
|
|
|
241
231
|
this.deps.onIdeConnected?.();
|
|
242
232
|
if (result.success && resolvedWorkspace) {
|
|
243
233
|
try {
|
|
244
|
-
|
|
245
|
-
kind: 'ide',
|
|
246
|
-
agentType: result.ideId,
|
|
247
|
-
});
|
|
248
|
-
next = appendRecentActivity(next, {
|
|
234
|
+
const next = appendRecentActivity(loadConfig(), {
|
|
249
235
|
kind: 'ide',
|
|
250
236
|
providerType: result.ideId || ideKey,
|
|
251
237
|
providerName: result.ideId || ideKey,
|
|
@@ -282,28 +268,35 @@ export class DaemonCommandRouter {
|
|
|
282
268
|
return { success: true, userName: name };
|
|
283
269
|
}
|
|
284
270
|
|
|
285
|
-
case '
|
|
286
|
-
const
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
return { success: false, error: 'kind and providerType are required' };
|
|
271
|
+
case 'mark_session_seen': {
|
|
272
|
+
const sessionId = args?.sessionId;
|
|
273
|
+
if (!sessionId || typeof sessionId !== 'string') {
|
|
274
|
+
return { success: false, error: 'sessionId is required' };
|
|
290
275
|
}
|
|
291
|
-
const
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
276
|
+
const currentConfig = loadConfig();
|
|
277
|
+
const prevSeenAt = currentConfig.sessionReads?.[sessionId] || 0;
|
|
278
|
+
const sessionEntries = buildSessionEntries(
|
|
279
|
+
this.deps.instanceManager.collectAllStates(),
|
|
280
|
+
this.deps.cdpManagers as Map<string, any>,
|
|
281
|
+
);
|
|
282
|
+
const targetSession = sessionEntries.find((entry) => entry.id === sessionId);
|
|
283
|
+
const completionMarker = targetSession ? getSessionCompletionMarker(targetSession) : '';
|
|
284
|
+
const next = markSessionSeen(
|
|
285
|
+
currentConfig,
|
|
286
|
+
sessionId,
|
|
299
287
|
typeof args?.seenAt === 'number' ? args.seenAt : Date.now(),
|
|
288
|
+
completionMarker,
|
|
300
289
|
);
|
|
290
|
+
if (READ_DEBUG_ENABLED) {
|
|
291
|
+
LOG.info('RecentRead', `mark_session_seen sessionId=${sessionId} seenAt=${String(args?.seenAt || '')} prevSeenAt=${String(prevSeenAt)} nextSeenAt=${String(next.sessionReads?.[sessionId] || 0)} marker=${completionMarker || '-'}`);
|
|
292
|
+
}
|
|
301
293
|
saveConfig(next);
|
|
302
294
|
this.deps.onStatusChange?.();
|
|
303
295
|
return {
|
|
304
296
|
success: true,
|
|
305
|
-
|
|
306
|
-
seenAt: next.
|
|
297
|
+
sessionId,
|
|
298
|
+
seenAt: next.sessionReads?.[sessionId] || Date.now(),
|
|
299
|
+
completionMarker,
|
|
307
300
|
};
|
|
308
301
|
}
|
|
309
302
|
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
|
|
6
6
|
import type { CommandResult, CommandHelpers } from './handler.js';
|
|
7
7
|
import type { ProviderLoader } from '../providers/provider-loader.js';
|
|
8
|
-
import { loadConfig } from '../config/config.js';
|
|
9
8
|
import { LOG } from '../logging/logger.js';
|
|
10
9
|
|
|
11
10
|
export async function handleFocusSession(h: CommandHelpers, args: any): Promise<CommandResult> {
|
|
@@ -193,14 +192,13 @@ export function handleGetIdeExtensions(h: CommandHelpers, args: any): CommandRes
|
|
|
193
192
|
if (!loader) return { success: false, error: 'ProviderLoader not initialized' };
|
|
194
193
|
|
|
195
194
|
const allExtProviders = loader.getByCategory?.('extension') || [];
|
|
196
|
-
const config = loadConfig();
|
|
197
195
|
|
|
198
196
|
if (ideType) {
|
|
199
197
|
const extensions = allExtProviders.map(p => ({
|
|
200
198
|
type: p.type,
|
|
201
199
|
name: p.name,
|
|
202
200
|
extensionId: p.extensionId,
|
|
203
|
-
enabled:
|
|
201
|
+
enabled: loader.getIdeExtensionEnabledState?.(ideType, p.type) === true,
|
|
204
202
|
}));
|
|
205
203
|
return { success: true, ideType, extensions };
|
|
206
204
|
}
|
|
@@ -212,7 +210,7 @@ export function handleGetIdeExtensions(h: CommandHelpers, args: any): CommandRes
|
|
|
212
210
|
type: p.type,
|
|
213
211
|
name: p.name,
|
|
214
212
|
extensionId: p.extensionId,
|
|
215
|
-
enabled:
|
|
213
|
+
enabled: loader.getIdeExtensionEnabledState?.(ide, p.type) === true,
|
|
216
214
|
}));
|
|
217
215
|
}
|
|
218
216
|
return { success: true, ideExtensions: result };
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
import { loadConfig, saveConfig } from '../config/config.js';
|
|
6
6
|
import * as W from '../config/workspaces.js';
|
|
7
|
-
import { appendWorkspaceActivity, getWorkspaceActivity, removeActivityForPath } from '../config/workspace-activity.js';
|
|
8
7
|
|
|
9
8
|
export type WorkspaceCommandResult = { success: boolean;[key: string]: unknown };
|
|
10
9
|
|
|
@@ -16,8 +15,6 @@ export function handleWorkspaceList(): WorkspaceCommandResult {
|
|
|
16
15
|
workspaces: state.workspaces,
|
|
17
16
|
defaultWorkspaceId: state.defaultWorkspaceId,
|
|
18
17
|
defaultWorkspacePath: state.defaultWorkspacePath,
|
|
19
|
-
legacyRecentPaths: config.recentCliWorkspaces || [],
|
|
20
|
-
activity: getWorkspaceActivity(config, 25),
|
|
21
18
|
};
|
|
22
19
|
}
|
|
23
20
|
|
|
@@ -31,10 +28,9 @@ export function handleWorkspaceAdd(args: any): WorkspaceCommandResult {
|
|
|
31
28
|
const result = W.addWorkspaceEntry(config, rawPath, label, { createIfMissing });
|
|
32
29
|
if ('error' in result) return { success: false, error: result.error };
|
|
33
30
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return { success: true, entry: result.entry, ...state, activity: getWorkspaceActivity(cfg, 25) };
|
|
31
|
+
saveConfig(result.config);
|
|
32
|
+
const state = W.getWorkspaceState(result.config);
|
|
33
|
+
return { success: true, entry: result.entry, ...state };
|
|
38
34
|
}
|
|
39
35
|
|
|
40
36
|
export function handleWorkspaceRemove(args: any): WorkspaceCommandResult {
|
|
@@ -46,13 +42,9 @@ export function handleWorkspaceRemove(args: any): WorkspaceCommandResult {
|
|
|
46
42
|
const result = W.removeWorkspaceEntry(config, id);
|
|
47
43
|
if ('error' in result) return { success: false, error: result.error };
|
|
48
44
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
saveConfig(cfg);
|
|
54
|
-
const state = W.getWorkspaceState(cfg);
|
|
55
|
-
return { success: true, removedId: id, ...state, activity: getWorkspaceActivity(cfg, 25) };
|
|
45
|
+
saveConfig(result.config);
|
|
46
|
+
const state = W.getWorkspaceState(result.config);
|
|
47
|
+
return { success: true, removedId: id, ...state };
|
|
56
48
|
}
|
|
57
49
|
|
|
58
50
|
export function handleWorkspaceSetDefault(args: any): WorkspaceCommandResult {
|
|
@@ -66,7 +58,6 @@ export function handleWorkspaceSetDefault(args: any): WorkspaceCommandResult {
|
|
|
66
58
|
return {
|
|
67
59
|
success: true,
|
|
68
60
|
...state,
|
|
69
|
-
activity: getWorkspaceActivity(result.config, 25),
|
|
70
61
|
};
|
|
71
62
|
}
|
|
72
63
|
|
|
@@ -98,12 +89,7 @@ export function handleWorkspaceSetDefault(args: any): WorkspaceCommandResult {
|
|
|
98
89
|
const result = W.setDefaultWorkspaceId(config, nextId);
|
|
99
90
|
if ('error' in result) return { success: false, error: result.error };
|
|
100
91
|
|
|
101
|
-
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
out = appendWorkspaceActivity(out, ap, { kind: 'default' });
|
|
105
|
-
}
|
|
106
|
-
saveConfig(out);
|
|
107
|
-
const state = W.getWorkspaceState(out);
|
|
108
|
-
return { success: true, ...state, activity: getWorkspaceActivity(out, 25) };
|
|
92
|
+
saveConfig(result.config);
|
|
93
|
+
const state = W.getWorkspaceState(result.config);
|
|
94
|
+
return { success: true, ...state };
|
|
109
95
|
}
|
package/src/config/config.ts
CHANGED
|
@@ -8,12 +8,9 @@ import { homedir } from 'os';
|
|
|
8
8
|
import { join } from 'path';
|
|
9
9
|
import { existsSync, mkdirSync, readFileSync, writeFileSync, chmodSync } from 'fs';
|
|
10
10
|
import { randomUUID } from 'crypto';
|
|
11
|
-
import { migrateWorkspacesFromRecent } from './workspaces.js';
|
|
12
11
|
import type { WorkspaceEntry } from './workspaces.js';
|
|
13
|
-
import type { WorkspaceActivityEntry } from './workspace-activity.js';
|
|
14
12
|
import type { RecentActivityEntry } from './recent-activity.js';
|
|
15
13
|
export type { WorkspaceEntry } from './workspaces.js';
|
|
16
|
-
export type { WorkspaceActivityEntry } from './workspace-activity.js';
|
|
17
14
|
export type { RecentActivityEntry } from './recent-activity.js';
|
|
18
15
|
|
|
19
16
|
export interface ADHDevConfig {
|
|
@@ -54,19 +51,18 @@ export interface ADHDevConfig {
|
|
|
54
51
|
|
|
55
52
|
// Daemon: which IDEs to connect (empty = all)
|
|
56
53
|
enabledIdes: string[];
|
|
57
|
-
recentCliWorkspaces: string[];
|
|
58
54
|
|
|
59
55
|
/** Saved workspaces for IDE/CLI/ACP launch (daemon-local) */
|
|
60
56
|
workspaces?: WorkspaceEntry[];
|
|
61
57
|
/** Default workspace id (from workspaces[]) — never used implicitly for launch */
|
|
62
58
|
defaultWorkspaceId?: string | null;
|
|
63
59
|
|
|
64
|
-
/** Recently used workspaces (IDE / CLI / ACP / default) for quick resume */
|
|
65
|
-
recentWorkspaceActivity?: WorkspaceActivityEntry[];
|
|
66
60
|
/** Unified recent activity across IDE / CLI / ACP launch flows */
|
|
67
61
|
recentActivity?: RecentActivityEntry[];
|
|
68
|
-
/** Last seen timestamps for
|
|
69
|
-
|
|
62
|
+
/** Last seen timestamps for live sessions, keyed by sessionId */
|
|
63
|
+
sessionReads?: Record<string, number>;
|
|
64
|
+
/** Last seen completion marker for live sessions, keyed by sessionId */
|
|
65
|
+
sessionReadMarkers?: Record<string, string>;
|
|
70
66
|
|
|
71
67
|
// Machine nickname (user-customizable label for this machine)
|
|
72
68
|
machineNickname: string | null;
|
|
@@ -94,9 +90,6 @@ export interface ADHDevConfig {
|
|
|
94
90
|
*/
|
|
95
91
|
registeredMachineId?: string;
|
|
96
92
|
|
|
97
|
-
// CLI launch history
|
|
98
|
-
cliHistory: CliHistoryEntry[];
|
|
99
|
-
|
|
100
93
|
// Per-provider user config (public setting values)
|
|
101
94
|
providerSettings: Record<string, Record<string, any>>;
|
|
102
95
|
|
|
@@ -113,18 +106,6 @@ export interface ADHDevConfig {
|
|
|
113
106
|
providerDir?: string;
|
|
114
107
|
}
|
|
115
108
|
|
|
116
|
-
export interface CliHistoryEntry {
|
|
117
|
-
category?: 'ide' | 'cli' | 'acp';
|
|
118
|
-
cliType: string;
|
|
119
|
-
dir: string;
|
|
120
|
-
cliArgs?: string[];
|
|
121
|
-
workspace?: string;
|
|
122
|
-
newWindow?: boolean;
|
|
123
|
-
model?: string;
|
|
124
|
-
timestamp: number;
|
|
125
|
-
label?: string;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
109
|
const DEFAULT_CONFIG: ADHDevConfig = {
|
|
129
110
|
serverUrl: 'https://api.adhf.dev',
|
|
130
111
|
apiToken: null,
|
|
@@ -140,17 +121,15 @@ const DEFAULT_CONFIG: ADHDevConfig = {
|
|
|
140
121
|
setupDate: null,
|
|
141
122
|
configuredCLIs: [],
|
|
142
123
|
enabledIdes: [],
|
|
143
|
-
recentCliWorkspaces: [],
|
|
144
124
|
workspaces: [],
|
|
145
125
|
defaultWorkspaceId: null,
|
|
146
|
-
recentWorkspaceActivity: [],
|
|
147
126
|
recentActivity: [],
|
|
148
|
-
|
|
127
|
+
sessionReads: {},
|
|
128
|
+
sessionReadMarkers: {},
|
|
149
129
|
machineNickname: null,
|
|
150
130
|
machineId: undefined,
|
|
151
131
|
machineSecret: null,
|
|
152
132
|
registeredMachineId: undefined,
|
|
153
|
-
cliHistory: [],
|
|
154
133
|
providerSettings: {},
|
|
155
134
|
ideSettings: {},
|
|
156
135
|
disableUpstream: false,
|
|
@@ -227,18 +206,9 @@ export function loadConfig(): ADHDevConfig {
|
|
|
227
206
|
(merged as ADHDevConfig).defaultWorkspaceId = merged.activeWorkspaceId;
|
|
228
207
|
}
|
|
229
208
|
delete (merged as any).activeWorkspaceId;
|
|
230
|
-
const hadStoredWorkspaces = Array.isArray(parsed.workspaces) && parsed.workspaces.length > 0;
|
|
231
209
|
const ensured = ensureMachineId(merged);
|
|
232
210
|
const normalized = ensured.config as ADHDevConfig & { activeWorkspaceId?: string | null };
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
let configChanged = ensured.changed;
|
|
236
|
-
|
|
237
|
-
if (!hadStoredWorkspaces && (normalized.workspaces?.length || 0) > 0) {
|
|
238
|
-
configChanged = true;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
if (configChanged) {
|
|
211
|
+
if (ensured.changed) {
|
|
242
212
|
try {
|
|
243
213
|
saveConfig(normalized);
|
|
244
214
|
} catch { /* ignore */ }
|
|
@@ -318,47 +288,3 @@ export function generateConnectionToken(): string {
|
|
|
318
288
|
}
|
|
319
289
|
return token;
|
|
320
290
|
}
|
|
321
|
-
/**
|
|
322
|
-
* Add launch to history (max 20, dedup by category+type+dir+args+workspace+model)
|
|
323
|
-
*/
|
|
324
|
-
export function addCliHistory(entry: Omit<CliHistoryEntry, 'timestamp'>): void {
|
|
325
|
-
const config = loadConfig();
|
|
326
|
-
const history = config.cliHistory || [];
|
|
327
|
-
const argsKey = (entry.cliArgs || []).join(' ');
|
|
328
|
-
const category = entry.category || 'cli';
|
|
329
|
-
const workspaceKey = entry.workspace || '';
|
|
330
|
-
const modelKey = entry.model || '';
|
|
331
|
-
|
|
332
|
-
// Remove duplicate (same category + type + dir + args + workspace + model)
|
|
333
|
-
const filtered = history.filter(h => {
|
|
334
|
-
const hArgsKey = (h.cliArgs || []).join(' ');
|
|
335
|
-
return !(
|
|
336
|
-
(h.category || 'cli') === category &&
|
|
337
|
-
h.cliType === entry.cliType &&
|
|
338
|
-
h.dir === entry.dir &&
|
|
339
|
-
hArgsKey === argsKey &&
|
|
340
|
-
(h.workspace || '') === workspaceKey &&
|
|
341
|
-
(h.model || '') === modelKey
|
|
342
|
-
);
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
// Add to front
|
|
346
|
-
filtered.unshift({
|
|
347
|
-
...entry,
|
|
348
|
-
category,
|
|
349
|
-
timestamp: Date.now(),
|
|
350
|
-
label: entry.label || (() => {
|
|
351
|
-
const base = `${entry.cliType} · ${entry.dir.split('/').filter(Boolean).pop() || 'root'}`;
|
|
352
|
-
const suffix: string[] = [];
|
|
353
|
-
if (entry.workspace && entry.workspace !== entry.dir) suffix.push(entry.workspace.split('/').filter(Boolean).pop() || entry.workspace);
|
|
354
|
-
if (entry.model) suffix.push(`model=${entry.model}`);
|
|
355
|
-
if (argsKey) suffix.push(argsKey);
|
|
356
|
-
if (entry.newWindow) suffix.push('new window');
|
|
357
|
-
return suffix.length > 0 ? `${base} (${suffix.join(' · ')})` : base;
|
|
358
|
-
})(),
|
|
359
|
-
});
|
|
360
|
-
|
|
361
|
-
// Keep max 20
|
|
362
|
-
config.cliHistory = filtered.slice(0, 20);
|
|
363
|
-
saveConfig(config);
|
|
364
|
-
}
|
|
@@ -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
|
|
|
10
10
|
import * as path from 'path';
|
|
@@ -18,7 +18,6 @@ export interface RecentActivityEntry {
|
|
|
18
18
|
providerName: string;
|
|
19
19
|
workspace?: string | null;
|
|
20
20
|
currentModel?: string;
|
|
21
|
-
sessionId?: string | null;
|
|
22
21
|
title?: string;
|
|
23
22
|
lastUsedAt: number;
|
|
24
23
|
}
|
|
@@ -62,22 +61,35 @@ export function getRecentActivity(config: ADHDevConfig, limit = 20): RecentActiv
|
|
|
62
61
|
.slice(0, limit);
|
|
63
62
|
}
|
|
64
63
|
|
|
65
|
-
export function
|
|
66
|
-
return config.
|
|
64
|
+
export function getSessionSeenAt(config: ADHDevConfig, sessionId: string): number {
|
|
65
|
+
return config.sessionReads?.[sessionId] || 0;
|
|
67
66
|
}
|
|
68
67
|
|
|
69
|
-
export function
|
|
68
|
+
export function getSessionSeenMarker(config: ADHDevConfig, sessionId: string): string {
|
|
69
|
+
return config.sessionReadMarkers?.[sessionId] || '';
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function markSessionSeen(
|
|
70
73
|
config: ADHDevConfig,
|
|
71
|
-
|
|
74
|
+
sessionId: string,
|
|
72
75
|
seenAt = Date.now(),
|
|
76
|
+
completionMarker?: string | null,
|
|
73
77
|
): ADHDevConfig {
|
|
74
|
-
const prev = config.
|
|
75
|
-
const nextSeenAt = Math.max(prev[
|
|
78
|
+
const prev = config.sessionReads || {};
|
|
79
|
+
const nextSeenAt = Math.max(prev[sessionId] || 0, seenAt);
|
|
80
|
+
const prevMarkers = config.sessionReadMarkers || {};
|
|
81
|
+
const nextMarker = typeof completionMarker === 'string' ? completionMarker : '';
|
|
76
82
|
return {
|
|
77
83
|
...config,
|
|
78
|
-
|
|
84
|
+
sessionReads: {
|
|
79
85
|
...prev,
|
|
80
|
-
[
|
|
86
|
+
[sessionId]: nextSeenAt,
|
|
81
87
|
},
|
|
88
|
+
sessionReadMarkers: nextMarker
|
|
89
|
+
? {
|
|
90
|
+
...prevMarkers,
|
|
91
|
+
[sessionId]: nextMarker,
|
|
92
|
+
}
|
|
93
|
+
: prevMarkers,
|
|
82
94
|
};
|
|
83
95
|
}
|
package/src/config/workspaces.ts
CHANGED
|
@@ -42,30 +42,6 @@ export function defaultWorkspaceLabel(absPath: string): string {
|
|
|
42
42
|
return base;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
/**
|
|
46
|
-
* Ensure config.workspaces exists; seed from recentCliWorkspaces once (same paths).
|
|
47
|
-
*/
|
|
48
|
-
export function migrateWorkspacesFromRecent(config: ADHDevConfig): ADHDevConfig {
|
|
49
|
-
if (!config.workspaces) config.workspaces = [];
|
|
50
|
-
if (config.workspaces.length > 0) return config;
|
|
51
|
-
|
|
52
|
-
const recent = config.recentCliWorkspaces || [];
|
|
53
|
-
const now = Date.now();
|
|
54
|
-
for (const raw of recent) {
|
|
55
|
-
const abs = expandPath(raw);
|
|
56
|
-
if (!abs || validateWorkspacePath(abs).ok !== true) continue;
|
|
57
|
-
if (config.workspaces.some(w => path.resolve(w.path) === abs)) continue;
|
|
58
|
-
config.workspaces.push({
|
|
59
|
-
id: randomUUID(),
|
|
60
|
-
path: abs,
|
|
61
|
-
label: defaultWorkspaceLabel(abs),
|
|
62
|
-
addedAt: now,
|
|
63
|
-
});
|
|
64
|
-
if (config.workspaces.length >= MAX_WORKSPACES) break;
|
|
65
|
-
}
|
|
66
|
-
return config;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
45
|
export function getDefaultWorkspacePath(config: ADHDevConfig): string | null {
|
|
70
46
|
const id = config.defaultWorkspaceId;
|
|
71
47
|
if (!id) return null;
|
package/src/index.ts
CHANGED
|
@@ -33,7 +33,6 @@ export type {
|
|
|
33
33
|
MachineInfo,
|
|
34
34
|
DetectedIdeInfo,
|
|
35
35
|
WorkspaceEntry,
|
|
36
|
-
WorkspaceActivity,
|
|
37
36
|
ProviderStatus,
|
|
38
37
|
ProviderErrorReason,
|
|
39
38
|
ActiveChatData,
|
|
@@ -43,26 +42,28 @@ export type {
|
|
|
43
42
|
ExtensionProviderState,
|
|
44
43
|
} from './shared-types.js';
|
|
45
44
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
45
|
+
// These types live in shared-types-extra.ts — imported directly because
|
|
46
|
+
// rollup-dts cannot resolve re-exports from shared-types.ts for them.
|
|
47
|
+
import type { RuntimeWriteOwner as _RuntimeWriteOwner } from './shared-types-extra.js';
|
|
48
|
+
import type { RuntimeAttachedClient as _RuntimeAttachedClient } from './shared-types-extra.js';
|
|
49
|
+
import type { RecentLaunchEntry as _RecentLaunchEntry } from './shared-types.js';
|
|
50
|
+
import type { TerminalBackendStatus as _TerminalBackendStatus } from './shared-types-extra.js';
|
|
51
|
+
export type RuntimeWriteOwner = _RuntimeWriteOwner;
|
|
52
|
+
export type RuntimeAttachedClient = _RuntimeAttachedClient;
|
|
53
|
+
export type RecentLaunchEntry = _RecentLaunchEntry;
|
|
54
|
+
export type TerminalBackendStatus = _TerminalBackendStatus;
|
|
55
|
+
|
|
56
|
+
// Type aliases — rollup-dts cannot bundle re-exported type aliases at all.
|
|
57
|
+
// Canonical definition lives in shared-types-extra.ts — keep these in sync.
|
|
58
|
+
export type SessionStatus = 'idle' | 'generating' | 'waiting_approval' | 'error' | 'stopped' | 'starting' | 'panel_hidden' | 'not_monitored' | 'disconnected';
|
|
59
|
+
export type RecentSessionBucket = 'needs_attention' | 'working' | 'task_complete' | 'idle';
|
|
58
60
|
|
|
59
61
|
// ── Core Interface ──
|
|
60
62
|
export type { IDaemonCore, DaemonCoreOptions } from './daemon-core.js';
|
|
61
63
|
|
|
62
64
|
// ── Config ──
|
|
63
|
-
export { loadConfig, saveConfig, resetConfig, isSetupComplete,
|
|
65
|
+
export { loadConfig, saveConfig, resetConfig, isSetupComplete, markSetupComplete, updateConfig } from './config/config.js';
|
|
64
66
|
export { getWorkspaceState } from './config/workspaces.js';
|
|
65
|
-
export { getWorkspaceActivity } from './config/workspace-activity.js';
|
|
66
67
|
export { appendRecentActivity, getRecentActivity } from './config/recent-activity.js';
|
|
67
68
|
export type { RecentActivityEntry } from './config/recent-activity.js';
|
|
68
69
|
|
|
@@ -284,16 +284,24 @@ export class ProviderLoader {
|
|
|
284
284
|
isEnabled(type: string, ideType?: string): boolean {
|
|
285
285
|
if (!ideType) return true;
|
|
286
286
|
try {
|
|
287
|
-
|
|
288
|
-
const config = loadConfig();
|
|
289
|
-
const baseIdeType = ideType.split('_')[0];
|
|
290
|
-
const val = config.ideSettings?.[baseIdeType]?.extensions?.[type]?.enabled;
|
|
291
|
-
return val === true; // undefined → false (default inactive)
|
|
287
|
+
return this.getIdeExtensionEnabledState(ideType, type);
|
|
292
288
|
} catch {
|
|
293
289
|
return false;
|
|
294
290
|
}
|
|
295
291
|
}
|
|
296
292
|
|
|
293
|
+
/**
|
|
294
|
+
* Resolve per-IDE extension enabled state using the same normalization
|
|
295
|
+
* that runtime attach/remove uses.
|
|
296
|
+
*/
|
|
297
|
+
getIdeExtensionEnabledState(ideType: string, extensionType: string): boolean {
|
|
298
|
+
const { loadConfig } = require('../config/config.js');
|
|
299
|
+
const config = loadConfig();
|
|
300
|
+
const baseIdeType = ideType.split('_')[0];
|
|
301
|
+
const val = config.ideSettings?.[baseIdeType]?.extensions?.[extensionType]?.enabled;
|
|
302
|
+
return val === true;
|
|
303
|
+
}
|
|
304
|
+
|
|
297
305
|
/**
|
|
298
306
|
* Save IDE extension enabled setting
|
|
299
307
|
*/
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ADHDev Shared Types — Additional cross-package type definitions
|
|
3
|
+
*
|
|
4
|
+
* Extracted common sub-types previously inlined across multiple packages.
|
|
5
|
+
* Separated from shared-types.ts due to rollup-dts bundling constraints.
|
|
6
|
+
*
|
|
7
|
+
* IMPORTANT: This file must remain runtime-free (types only).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** Runtime terminal write-owner descriptor */
|
|
11
|
+
export interface RuntimeWriteOwner {
|
|
12
|
+
clientId: string;
|
|
13
|
+
ownerType: 'agent' | 'user';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Runtime attached client descriptor */
|
|
17
|
+
export interface RuntimeAttachedClient {
|
|
18
|
+
clientId: string;
|
|
19
|
+
type: 'daemon' | 'web' | 'local-terminal';
|
|
20
|
+
readOnly: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Session status union (used by SessionEntry.status, legacy recent-launch metadata, etc.) */
|
|
24
|
+
export type SessionStatus = 'idle' | 'generating' | 'waiting_approval' | 'error' | 'stopped' | 'starting' | 'panel_hidden' | 'not_monitored' | 'disconnected';
|
|
25
|
+
|
|
26
|
+
/** Inbox bucket categories for recent sessions */
|
|
27
|
+
export type RecentSessionBucket = 'needs_attention' | 'working' | 'task_complete' | 'idle';
|
|
28
|
+
|
|
29
|
+
/** Terminal backend status */
|
|
30
|
+
export interface TerminalBackendStatus {
|
|
31
|
+
backend: 'xterm' | 'ghostty-vt';
|
|
32
|
+
preference: 'auto' | 'xterm' | 'ghostty-vt';
|
|
33
|
+
ghosttyAvailable: boolean;
|
|
34
|
+
}
|
package/src/shared-types.d.ts
CHANGED
|
@@ -147,17 +147,15 @@ export interface WorkspaceActivity {
|
|
|
147
147
|
kind?: string;
|
|
148
148
|
agentType?: string;
|
|
149
149
|
}
|
|
150
|
-
export interface
|
|
150
|
+
export interface RecentLaunchEntry {
|
|
151
151
|
id: string;
|
|
152
|
-
sessionId?: string | null;
|
|
153
152
|
providerType: string;
|
|
154
153
|
providerName: string;
|
|
155
154
|
kind: 'ide' | 'cli' | 'acp';
|
|
156
|
-
title
|
|
155
|
+
title?: string;
|
|
157
156
|
workspace?: string | null;
|
|
158
157
|
currentModel?: string;
|
|
159
|
-
|
|
160
|
-
lastUsedAt: number;
|
|
158
|
+
lastLaunchedAt: number;
|
|
161
159
|
}
|
|
162
160
|
export interface StatusReportPayload {
|
|
163
161
|
/** Daemon instance ID */
|
|
@@ -188,5 +186,5 @@ export interface StatusReportPayload {
|
|
|
188
186
|
defaultWorkspaceId?: string | null;
|
|
189
187
|
defaultWorkspacePath?: string | null;
|
|
190
188
|
workspaceActivity?: WorkspaceActivity[];
|
|
191
|
-
|
|
189
|
+
recentLaunches?: RecentLaunchEntry[];
|
|
192
190
|
}
|