@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.
Files changed (95) hide show
  1. package/dist/agent-stream/forward.d.ts +8 -0
  2. package/dist/agent-stream/index.d.ts +6 -0
  3. package/dist/agent-stream/manager.d.ts +59 -0
  4. package/dist/agent-stream/poller.d.ts +41 -0
  5. package/dist/agent-stream/provider-adapter.d.ts +29 -0
  6. package/dist/agent-stream/types.d.ts +62 -0
  7. package/dist/boot/daemon-lifecycle.d.ts +97 -0
  8. package/dist/cdp/devtools.d.ts +51 -0
  9. package/dist/cdp/initializer.d.ts +50 -0
  10. package/dist/cdp/manager.d.ts +145 -0
  11. package/dist/cdp/scanner.d.ts +58 -0
  12. package/dist/cdp/setup.d.ts +58 -0
  13. package/dist/cli-adapter-types.d.ts +25 -0
  14. package/dist/cli-adapters/provider-cli-adapter.d.ts +229 -0
  15. package/dist/cli-adapters/pty-transport.d.ts +43 -0
  16. package/dist/cli-adapters/session-host-transport.d.ts +19 -0
  17. package/dist/cli-adapters/terminal-backends/ghostty-vt-backend.d.ts +12 -0
  18. package/dist/cli-adapters/terminal-backends/types.d.ts +14 -0
  19. package/dist/cli-adapters/terminal-backends/xterm-backend.d.ts +13 -0
  20. package/dist/cli-adapters/terminal-screen.d.ts +27 -0
  21. package/dist/commands/cdp-commands.d.ts +15 -0
  22. package/dist/commands/chat-commands.d.ts +15 -0
  23. package/dist/commands/cli-manager.d.ts +82 -0
  24. package/dist/commands/handler.d.ts +101 -0
  25. package/dist/commands/router.d.ts +69 -0
  26. package/dist/commands/stream-commands.d.ts +13 -0
  27. package/dist/commands/workspace-commands.d.ts +11 -0
  28. package/dist/config/chat-history.d.ts +60 -0
  29. package/dist/config/config.d.ts +103 -0
  30. package/dist/config/recent-activity.d.ts +27 -0
  31. package/dist/config/workspaces.d.ts +82 -0
  32. package/dist/daemon/dev-auto-implement.d.ts +26 -0
  33. package/dist/daemon/dev-cdp-handlers.d.ts +22 -0
  34. package/dist/daemon/dev-cli-debug.d.ts +24 -0
  35. package/dist/daemon/dev-server-types.d.ts +43 -0
  36. package/dist/daemon/dev-server.d.ts +133 -0
  37. package/dist/daemon/scaffold-template.d.ts +32 -0
  38. package/dist/daemon-core.d.ts +36 -0
  39. package/dist/detection/cli-detector.d.ts +27 -0
  40. package/dist/detection/ide-detector.d.ts +34 -0
  41. package/dist/index.d.ts +72 -2499
  42. package/dist/index.js +673 -879
  43. package/dist/index.js.map +1 -1
  44. package/dist/index.mjs +680 -884
  45. package/dist/index.mjs.map +1 -1
  46. package/dist/installer.d.ts +50 -0
  47. package/dist/ipc-protocol.d.ts +111 -0
  48. package/dist/launch.d.ts +46 -0
  49. package/dist/logging/command-log.d.ts +31 -0
  50. package/dist/logging/logger.d.ts +87 -0
  51. package/dist/providers/acp-provider-instance.d.ts +101 -0
  52. package/dist/providers/cli-provider-instance.d.ts +43 -0
  53. package/dist/providers/contracts.d.ts +483 -0
  54. package/dist/providers/extension-provider-instance.d.ts +44 -0
  55. package/dist/providers/ide-provider-instance.d.ts +61 -0
  56. package/dist/providers/index.d.ts +5 -0
  57. package/dist/providers/provider-instance-manager.d.ts +84 -0
  58. package/dist/providers/provider-instance.d.ts +148 -0
  59. package/dist/providers/provider-loader.d.ts +270 -0
  60. package/dist/providers/status-monitor.d.ts +48 -0
  61. package/dist/providers/version-archive.d.ts +52 -0
  62. package/dist/session-host/runtime-support.d.ts +8 -0
  63. package/dist/sessions/registry.d.ts +24 -0
  64. package/dist/shared-types-extra.d.ts +29 -0
  65. package/dist/shared-types.d.ts +205 -0
  66. package/dist/status/builders.d.ts +33 -0
  67. package/dist/status/normalize.d.ts +14 -1
  68. package/dist/status/reporter.d.ts +69 -0
  69. package/dist/status/snapshot.d.ts +51 -0
  70. package/dist/system/host-memory.d.ts +19 -0
  71. package/dist/types.d.ts +123 -0
  72. package/node_modules/@adhdev/session-host-core/package.json +1 -1
  73. package/package.json +3 -2
  74. package/src/commands/cli-manager.ts +1 -26
  75. package/src/commands/handler.ts +0 -31
  76. package/src/commands/router.ts +27 -34
  77. package/src/commands/stream-commands.ts +2 -4
  78. package/src/commands/workspace-commands.ts +9 -23
  79. package/src/config/config.ts +7 -81
  80. package/src/config/recent-activity.ts +24 -12
  81. package/src/config/workspaces.ts +0 -24
  82. package/src/index.ts +16 -15
  83. package/src/providers/provider-loader.ts +13 -5
  84. package/src/shared-types-extra.ts +34 -0
  85. package/src/shared-types.d.ts +4 -6
  86. package/src/shared-types.ts +17 -38
  87. package/src/status/builders.ts +12 -0
  88. package/src/status/reporter.ts +2 -1
  89. package/src/status/snapshot.ts +70 -87
  90. package/src/types.ts +3 -8
  91. package/dist/index.d.mts +0 -2504
  92. package/dist/normalize-DVI4Lo5I.d.mts +0 -947
  93. package/dist/normalize-DVI4Lo5I.d.ts +0 -947
  94. package/dist/status/normalize.d.mts +0 -1
  95. package/src/config/workspace-activity.ts +0 -65
package/dist/index.js CHANGED
@@ -30,201 +30,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
30
  ));
31
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
32
 
33
- // src/config/workspaces.ts
34
- function expandPath(p) {
35
- const t = (p || "").trim();
36
- if (!t) return "";
37
- if (t.startsWith("~")) return path.join(os.homedir(), t.slice(1).replace(/^\//, ""));
38
- return path.resolve(t);
39
- }
40
- function validateWorkspacePath(absPath) {
41
- try {
42
- if (!absPath) return { ok: false, error: "Path required" };
43
- if (!fs.existsSync(absPath)) return { ok: false, error: "Path does not exist" };
44
- const st = fs.statSync(absPath);
45
- if (!st.isDirectory()) return { ok: false, error: "Not a directory" };
46
- return { ok: true };
47
- } catch (e) {
48
- return { ok: false, error: e?.message || "Invalid path" };
49
- }
50
- }
51
- function defaultWorkspaceLabel(absPath) {
52
- const base = path.basename(absPath) || absPath;
53
- return base;
54
- }
55
- function migrateWorkspacesFromRecent(config) {
56
- if (!config.workspaces) config.workspaces = [];
57
- if (config.workspaces.length > 0) return config;
58
- const recent = config.recentCliWorkspaces || [];
59
- const now = Date.now();
60
- for (const raw of recent) {
61
- const abs = expandPath(raw);
62
- if (!abs || validateWorkspacePath(abs).ok !== true) continue;
63
- if (config.workspaces.some((w) => path.resolve(w.path) === abs)) continue;
64
- config.workspaces.push({
65
- id: (0, import_crypto.randomUUID)(),
66
- path: abs,
67
- label: defaultWorkspaceLabel(abs),
68
- addedAt: now
69
- });
70
- if (config.workspaces.length >= MAX_WORKSPACES) break;
71
- }
72
- return config;
73
- }
74
- function getDefaultWorkspacePath(config) {
75
- const id = config.defaultWorkspaceId;
76
- if (!id) return null;
77
- const w = (config.workspaces || []).find((x) => x.id === id);
78
- if (!w) return null;
79
- const abs = expandPath(w.path);
80
- if (validateWorkspacePath(abs).ok !== true) return null;
81
- return abs;
82
- }
83
- function getWorkspaceState(config) {
84
- const workspaces = [...config.workspaces || []].sort((a, b) => b.addedAt - a.addedAt);
85
- const defaultWorkspacePath = getDefaultWorkspacePath(config);
86
- return {
87
- workspaces,
88
- defaultWorkspaceId: config.defaultWorkspaceId ?? null,
89
- defaultWorkspacePath
90
- };
91
- }
92
- function resolveLaunchDirectory(args, config) {
93
- const a = args || {};
94
- if (a.dir != null && String(a.dir).trim()) {
95
- const abs = expandPath(String(a.dir).trim());
96
- if (abs && validateWorkspacePath(abs).ok === true) {
97
- return { ok: true, path: abs, source: "dir" };
98
- }
99
- return {
100
- ok: false,
101
- code: "WORKSPACE_LAUNCH_CONTEXT_REQUIRED",
102
- message: abs ? "Directory path is not valid or does not exist" : "Invalid directory path"
103
- };
104
- }
105
- if (a.workspaceId) {
106
- const w = (config.workspaces || []).find((x) => x.id === a.workspaceId);
107
- if (w) {
108
- const abs = expandPath(w.path);
109
- if (validateWorkspacePath(abs).ok === true) {
110
- return { ok: true, path: abs, source: "workspaceId" };
111
- }
112
- }
113
- return {
114
- ok: false,
115
- code: "WORKSPACE_LAUNCH_CONTEXT_REQUIRED",
116
- message: "Saved workspace not found or path is no longer valid"
117
- };
118
- }
119
- if (a.useDefaultWorkspace === true) {
120
- const d = getDefaultWorkspacePath(config);
121
- if (d) return { ok: true, path: d, source: "defaultWorkspace" };
122
- return {
123
- ok: false,
124
- code: "WORKSPACE_LAUNCH_CONTEXT_REQUIRED",
125
- message: "No default workspace is set"
126
- };
127
- }
128
- if (a.useHome === true) {
129
- return { ok: true, path: os.homedir(), source: "home" };
130
- }
131
- return {
132
- ok: false,
133
- code: "WORKSPACE_LAUNCH_CONTEXT_REQUIRED",
134
- message: "Choose a directory, saved workspace, default workspace, or home before launching."
135
- };
136
- }
137
- function resolveIdeWorkspaceFromArgs(args, config) {
138
- const ar = args || {};
139
- if (ar.workspace) {
140
- const abs = expandPath(ar.workspace);
141
- if (abs && validateWorkspacePath(abs).ok === true) return abs;
142
- }
143
- if (ar.workspaceId) {
144
- const w = (config.workspaces || []).find((x) => x.id === ar.workspaceId);
145
- if (w) {
146
- const abs = expandPath(w.path);
147
- if (validateWorkspacePath(abs).ok === true) return abs;
148
- }
149
- }
150
- if (ar.useDefaultWorkspace === true) {
151
- return getDefaultWorkspacePath(config) || void 0;
152
- }
153
- return void 0;
154
- }
155
- function resolveIdeLaunchWorkspace(args, config) {
156
- const direct = resolveIdeWorkspaceFromArgs(args, config);
157
- if (direct) return direct;
158
- if (args?.useDefaultWorkspace === false) return void 0;
159
- return getDefaultWorkspacePath(config) || void 0;
160
- }
161
- function findWorkspaceByPath(config, rawPath) {
162
- const abs = path.resolve(expandPath(rawPath));
163
- if (!abs) return void 0;
164
- return (config.workspaces || []).find((w) => path.resolve(expandPath(w.path)) === abs);
165
- }
166
- function addWorkspaceEntry(config, rawPath, label, options) {
167
- const abs = expandPath(rawPath);
168
- const createIfMissing = options?.createIfMissing === true;
169
- if (!abs) return { error: "Path required" };
170
- if (!fs.existsSync(abs) && createIfMissing) {
171
- try {
172
- fs.mkdirSync(abs, { recursive: true });
173
- } catch (e) {
174
- return { error: e?.message || "Could not create directory" };
175
- }
176
- }
177
- const v = validateWorkspacePath(abs);
178
- if (!v.ok) return { error: v.error };
179
- const list = [...config.workspaces || []];
180
- if (list.some((w) => path.resolve(w.path) === abs)) {
181
- return { error: "Workspace already in list" };
182
- }
183
- if (list.length >= MAX_WORKSPACES) {
184
- return { error: `Maximum ${MAX_WORKSPACES} workspaces` };
185
- }
186
- const entry = {
187
- id: (0, import_crypto.randomUUID)(),
188
- path: abs,
189
- label: (label || "").trim() || defaultWorkspaceLabel(abs),
190
- addedAt: Date.now()
191
- };
192
- list.push(entry);
193
- return { config: { ...config, workspaces: list }, entry };
194
- }
195
- function removeWorkspaceEntry(config, id) {
196
- const list = (config.workspaces || []).filter((w) => w.id !== id);
197
- if (list.length === (config.workspaces || []).length) return { error: "Workspace not found" };
198
- let defaultWorkspaceId = config.defaultWorkspaceId;
199
- if (defaultWorkspaceId === id) defaultWorkspaceId = null;
200
- return { config: { ...config, workspaces: list, defaultWorkspaceId } };
201
- }
202
- function setDefaultWorkspaceId(config, id) {
203
- if (id === null) {
204
- return { config: { ...config, defaultWorkspaceId: null } };
205
- }
206
- const w = (config.workspaces || []).find((x) => x.id === id);
207
- if (!w) return { error: "Workspace not found" };
208
- const abs = expandPath(w.path);
209
- if (validateWorkspacePath(abs).ok !== true) return { error: "Workspace path is no longer valid" };
210
- return { config: { ...config, defaultWorkspaceId: id } };
211
- }
212
- var fs, os, path, import_crypto, MAX_WORKSPACES;
213
- var init_workspaces = __esm({
214
- "src/config/workspaces.ts"() {
215
- "use strict";
216
- fs = __toESM(require("fs"));
217
- os = __toESM(require("os"));
218
- path = __toESM(require("path"));
219
- import_crypto = require("crypto");
220
- MAX_WORKSPACES = 50;
221
- }
222
- });
223
-
224
33
  // src/config/config.ts
225
34
  var config_exports = {};
226
35
  __export(config_exports, {
227
- addCliHistory: () => addCliHistory,
228
36
  generateConnectionToken: () => generateConnectionToken,
229
37
  generateMachineId: () => generateMachineId,
230
38
  getConfigDir: () => getConfigDir,
@@ -237,7 +45,7 @@ __export(config_exports, {
237
45
  updateConfig: () => updateConfig
238
46
  });
239
47
  function generateMachineId() {
240
- return `${MACHINE_ID_PREFIX}${(0, import_crypto2.randomUUID)().replace(/-/g, "")}`;
48
+ return `${MACHINE_ID_PREFIX}${(0, import_crypto.randomUUID)().replace(/-/g, "")}`;
241
49
  }
242
50
  function isStableMachineId(machineId) {
243
51
  return typeof machineId === "string" && machineId.startsWith(MACHINE_ID_PREFIX);
@@ -284,15 +92,9 @@ function loadConfig() {
284
92
  merged.defaultWorkspaceId = merged.activeWorkspaceId;
285
93
  }
286
94
  delete merged.activeWorkspaceId;
287
- const hadStoredWorkspaces = Array.isArray(parsed.workspaces) && parsed.workspaces.length > 0;
288
95
  const ensured = ensureMachineId(merged);
289
96
  const normalized = ensured.config;
290
- migrateWorkspacesFromRecent(normalized);
291
- let configChanged = ensured.changed;
292
- if (!hadStoredWorkspaces && (normalized.workspaces?.length || 0) > 0) {
293
- configChanged = true;
294
- }
295
- if (configChanged) {
97
+ if (ensured.changed) {
296
98
  try {
297
99
  saveConfig(normalized);
298
100
  } catch {
@@ -347,43 +149,14 @@ function generateConnectionToken() {
347
149
  }
348
150
  return token;
349
151
  }
350
- function addCliHistory(entry) {
351
- const config = loadConfig();
352
- const history = config.cliHistory || [];
353
- const argsKey = (entry.cliArgs || []).join(" ");
354
- const category = entry.category || "cli";
355
- const workspaceKey = entry.workspace || "";
356
- const modelKey = entry.model || "";
357
- const filtered = history.filter((h) => {
358
- const hArgsKey = (h.cliArgs || []).join(" ");
359
- return !((h.category || "cli") === category && h.cliType === entry.cliType && h.dir === entry.dir && hArgsKey === argsKey && (h.workspace || "") === workspaceKey && (h.model || "") === modelKey);
360
- });
361
- filtered.unshift({
362
- ...entry,
363
- category,
364
- timestamp: Date.now(),
365
- label: entry.label || (() => {
366
- const base = `${entry.cliType} \xB7 ${entry.dir.split("/").filter(Boolean).pop() || "root"}`;
367
- const suffix = [];
368
- if (entry.workspace && entry.workspace !== entry.dir) suffix.push(entry.workspace.split("/").filter(Boolean).pop() || entry.workspace);
369
- if (entry.model) suffix.push(`model=${entry.model}`);
370
- if (argsKey) suffix.push(argsKey);
371
- if (entry.newWindow) suffix.push("new window");
372
- return suffix.length > 0 ? `${base} (${suffix.join(" \xB7 ")})` : base;
373
- })()
374
- });
375
- config.cliHistory = filtered.slice(0, 20);
376
- saveConfig(config);
377
- }
378
- var import_os, import_path, import_fs, import_crypto2, DEFAULT_CONFIG, MACHINE_ID_PREFIX;
152
+ var import_os, import_path, import_fs, import_crypto, DEFAULT_CONFIG, MACHINE_ID_PREFIX;
379
153
  var init_config = __esm({
380
154
  "src/config/config.ts"() {
381
155
  "use strict";
382
156
  import_os = require("os");
383
157
  import_path = require("path");
384
158
  import_fs = require("fs");
385
- import_crypto2 = require("crypto");
386
- init_workspaces();
159
+ import_crypto = require("crypto");
387
160
  DEFAULT_CONFIG = {
388
161
  serverUrl: "https://api.adhf.dev",
389
162
  apiToken: null,
@@ -399,17 +172,15 @@ var init_config = __esm({
399
172
  setupDate: null,
400
173
  configuredCLIs: [],
401
174
  enabledIdes: [],
402
- recentCliWorkspaces: [],
403
175
  workspaces: [],
404
176
  defaultWorkspaceId: null,
405
- recentWorkspaceActivity: [],
406
177
  recentActivity: [],
407
- recentSessionReads: {},
178
+ sessionReads: {},
179
+ sessionReadMarkers: {},
408
180
  machineNickname: null,
409
181
  machineId: void 0,
410
182
  machineSecret: null,
411
183
  registeredMachineId: void 0,
412
- cliHistory: [],
413
184
  providerSettings: {},
414
185
  ideSettings: {},
415
186
  disableUpstream: false
@@ -433,7 +204,7 @@ function checkDateRotation() {
433
204
  const today = getDateStr();
434
205
  if (today !== currentDate) {
435
206
  currentDate = today;
436
- currentLogFile = path4.join(LOG_DIR, `daemon-${currentDate}.log`);
207
+ currentLogFile = path3.join(LOG_DIR, `daemon-${currentDate}.log`);
437
208
  cleanOldLogs();
438
209
  }
439
210
  }
@@ -447,7 +218,7 @@ function cleanOldLogs() {
447
218
  const dateMatch = file.match(/daemon-(\d{4}-\d{2}-\d{2})/);
448
219
  if (dateMatch && dateMatch[1] < cutoffStr) {
449
220
  try {
450
- fs2.unlinkSync(path4.join(LOG_DIR, file));
221
+ fs2.unlinkSync(path3.join(LOG_DIR, file));
451
222
  } catch {
452
223
  }
453
224
  }
@@ -564,17 +335,17 @@ function installGlobalInterceptor() {
564
335
  writeToFile(`Log file: ${currentLogFile}`);
565
336
  writeToFile(`Log level: ${currentLevel}`);
566
337
  }
567
- var fs2, path4, os4, LEVEL_NUM, LEVEL_LABEL, currentLevel, LOG_DIR, MAX_LOG_SIZE, MAX_LOG_DAYS, currentDate, currentLogFile, writeCount, RING_BUFFER_SIZE, ringBuffer, origConsoleLog, origConsoleError, origConsoleWarn, LOG, interceptorInstalled, LOG_PATH;
338
+ var fs2, path3, os4, LEVEL_NUM, LEVEL_LABEL, currentLevel, LOG_DIR, MAX_LOG_SIZE, MAX_LOG_DAYS, currentDate, currentLogFile, writeCount, RING_BUFFER_SIZE, ringBuffer, origConsoleLog, origConsoleError, origConsoleWarn, LOG, interceptorInstalled, LOG_PATH;
568
339
  var init_logger = __esm({
569
340
  "src/logging/logger.ts"() {
570
341
  "use strict";
571
342
  fs2 = __toESM(require("fs"));
572
- path4 = __toESM(require("path"));
343
+ path3 = __toESM(require("path"));
573
344
  os4 = __toESM(require("os"));
574
345
  LEVEL_NUM = { debug: 0, info: 1, warn: 2, error: 3 };
575
346
  LEVEL_LABEL = { debug: "DBG", info: "INF", warn: "WRN", error: "ERR" };
576
347
  currentLevel = "info";
577
- LOG_DIR = process.platform === "win32" ? path4.join(process.env.LOCALAPPDATA || process.env.APPDATA || path4.join(os4.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path4.join(os4.homedir(), "Library", "Logs", "adhdev") : path4.join(os4.homedir(), ".local", "share", "adhdev", "logs");
348
+ LOG_DIR = process.platform === "win32" ? path3.join(process.env.LOCALAPPDATA || process.env.APPDATA || path3.join(os4.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path3.join(os4.homedir(), "Library", "Logs", "adhdev") : path3.join(os4.homedir(), ".local", "share", "adhdev", "logs");
578
349
  MAX_LOG_SIZE = 5 * 1024 * 1024;
579
350
  MAX_LOG_DAYS = 7;
580
351
  try {
@@ -582,16 +353,16 @@ var init_logger = __esm({
582
353
  } catch {
583
354
  }
584
355
  currentDate = getDateStr();
585
- currentLogFile = path4.join(LOG_DIR, `daemon-${currentDate}.log`);
356
+ currentLogFile = path3.join(LOG_DIR, `daemon-${currentDate}.log`);
586
357
  cleanOldLogs();
587
358
  try {
588
- const oldLog = path4.join(LOG_DIR, "daemon.log");
359
+ const oldLog = path3.join(LOG_DIR, "daemon.log");
589
360
  if (fs2.existsSync(oldLog)) {
590
361
  const stat = fs2.statSync(oldLog);
591
362
  const oldDate = stat.mtime.toISOString().slice(0, 10);
592
- fs2.renameSync(oldLog, path4.join(LOG_DIR, `daemon-${oldDate}.log`));
363
+ fs2.renameSync(oldLog, path3.join(LOG_DIR, `daemon-${oldDate}.log`));
593
364
  }
594
- const oldLogBackup = path4.join(LOG_DIR, "daemon.log.old");
365
+ const oldLogBackup = path3.join(LOG_DIR, "daemon.log.old");
595
366
  if (fs2.existsSync(oldLogBackup)) {
596
367
  fs2.unlinkSync(oldLogBackup);
597
368
  }
@@ -623,7 +394,7 @@ var init_logger = __esm({
623
394
  }
624
395
  };
625
396
  interceptorInstalled = false;
626
- LOG_PATH = path4.join(LOG_DIR, `daemon-${getDateStr()}.log`);
397
+ LOG_PATH = path3.join(LOG_DIR, `daemon-${getDateStr()}.log`);
627
398
  }
628
399
  });
629
400
 
@@ -951,7 +722,7 @@ function findBinary(name) {
951
722
  }
952
723
  }
953
724
  function isScriptBinary(binaryPath) {
954
- if (!path10.isAbsolute(binaryPath)) return false;
725
+ if (!path9.isAbsolute(binaryPath)) return false;
955
726
  try {
956
727
  const fs12 = require("fs");
957
728
  const resolved = fs12.realpathSync(binaryPath);
@@ -967,7 +738,7 @@ function isScriptBinary(binaryPath) {
967
738
  }
968
739
  }
969
740
  function looksLikeMachOOrElf(filePath) {
970
- if (!path10.isAbsolute(filePath)) return false;
741
+ if (!path9.isAbsolute(filePath)) return false;
971
742
  try {
972
743
  const fs12 = require("fs");
973
744
  const resolved = fs12.realpathSync(filePath);
@@ -1081,12 +852,12 @@ function normalizeCliProviderForRuntime(raw) {
1081
852
  }
1082
853
  };
1083
854
  }
1084
- var os12, path10, import_child_process5, pty2, ProviderCliAdapter;
855
+ var os12, path9, import_child_process5, pty2, ProviderCliAdapter;
1085
856
  var init_provider_cli_adapter = __esm({
1086
857
  "src/cli-adapters/provider-cli-adapter.ts"() {
1087
858
  "use strict";
1088
859
  os12 = __toESM(require("os"));
1089
- path10 = __toESM(require("path"));
860
+ path9 = __toESM(require("path"));
1090
861
  import_child_process5 = require("child_process");
1091
862
  init_logger();
1092
863
  init_terminal_screen();
@@ -1096,9 +867,9 @@ var init_provider_cli_adapter = __esm({
1096
867
  if (os12.platform() !== "win32") {
1097
868
  try {
1098
869
  const fs12 = require("fs");
1099
- const ptyDir = path10.resolve(path10.dirname(require.resolve("node-pty")), "..");
870
+ const ptyDir = path9.resolve(path9.dirname(require.resolve("node-pty")), "..");
1100
871
  const platformArch = `${os12.platform()}-${os12.arch()}`;
1101
- const helper = path10.join(ptyDir, "prebuilds", platformArch, "spawn-helper");
872
+ const helper = path9.join(ptyDir, "prebuilds", platformArch, "spawn-helper");
1102
873
  if (fs12.existsSync(helper)) {
1103
874
  const stat = fs12.statSync(helper);
1104
875
  if (!(stat.mode & 73)) {
@@ -1287,7 +1058,7 @@ var init_provider_cli_adapter = __esm({
1287
1058
  LOG.info("CLI", `[${this.cliType}] Spawning in ${this.workingDir}`);
1288
1059
  let shellCmd;
1289
1060
  let shellArgs;
1290
- const useShellUnix = !isWin && (!!spawnConfig.shell || !path10.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
1061
+ const useShellUnix = !isWin && (!!spawnConfig.shell || !path9.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
1291
1062
  const useShell = isWin ? !!spawnConfig.shell : useShellUnix;
1292
1063
  if (useShell) {
1293
1064
  if (!spawnConfig.shell && !isWin) {
@@ -1712,7 +1483,7 @@ ${data.message || ""}`.trim();
1712
1483
  if (this.startupParseGate) {
1713
1484
  const deadline = Date.now() + 1e4;
1714
1485
  while (this.startupParseGate && Date.now() < deadline) {
1715
- await new Promise((resolve10) => setTimeout(resolve10, 50));
1486
+ await new Promise((resolve9) => setTimeout(resolve9, 50));
1716
1487
  }
1717
1488
  }
1718
1489
  if (!this.ready) throw new Error(`${this.cliName} not ready (status: ${this.currentStatus})`);
@@ -1880,17 +1651,17 @@ ${data.message || ""}`.trim();
1880
1651
  }
1881
1652
  }
1882
1653
  waitForStopped(timeoutMs) {
1883
- return new Promise((resolve10) => {
1654
+ return new Promise((resolve9) => {
1884
1655
  const startedAt = Date.now();
1885
1656
  const timer = setInterval(() => {
1886
1657
  if (!this.ptyProcess || this.currentStatus === "stopped") {
1887
1658
  clearInterval(timer);
1888
- resolve10(true);
1659
+ resolve9(true);
1889
1660
  return;
1890
1661
  }
1891
1662
  if (Date.now() - startedAt >= timeoutMs) {
1892
1663
  clearInterval(timer);
1893
- resolve10(false);
1664
+ resolve9(false);
1894
1665
  }
1895
1666
  }, 100);
1896
1667
  });
@@ -2106,7 +1877,6 @@ __export(index_exports, {
2106
1877
  ProviderLoader: () => ProviderLoader,
2107
1878
  SessionHostPtyTransportFactory: () => SessionHostPtyTransportFactory,
2108
1879
  VersionArchive: () => VersionArchive,
2109
- addCliHistory: () => addCliHistory,
2110
1880
  appendRecentActivity: () => appendRecentActivity,
2111
1881
  buildSessionEntries: () => buildSessionEntries,
2112
1882
  buildStatusSnapshot: () => buildStatusSnapshot,
@@ -2124,7 +1894,6 @@ __export(index_exports, {
2124
1894
  getRecentActivity: () => getRecentActivity,
2125
1895
  getRecentCommands: () => getRecentCommands,
2126
1896
  getRecentLogs: () => getRecentLogs,
2127
- getWorkspaceActivity: () => getWorkspaceActivity,
2128
1897
  getWorkspaceState: () => getWorkspaceState,
2129
1898
  hasCdpManager: () => hasCdpManager,
2130
1899
  initDaemonComponents: () => initDaemonComponents,
@@ -2158,58 +1927,182 @@ __export(index_exports, {
2158
1927
  });
2159
1928
  module.exports = __toCommonJS(index_exports);
2160
1929
  init_config();
2161
- init_workspaces();
2162
1930
 
2163
- // src/config/workspace-activity.ts
2164
- var path2 = __toESM(require("path"));
2165
- init_workspaces();
2166
- var MAX_ACTIVITY = 30;
2167
- function normWorkspacePath(p) {
1931
+ // src/config/workspaces.ts
1932
+ var fs = __toESM(require("fs"));
1933
+ var os = __toESM(require("os"));
1934
+ var path = __toESM(require("path"));
1935
+ var import_crypto2 = require("crypto");
1936
+ var MAX_WORKSPACES = 50;
1937
+ function expandPath(p) {
1938
+ const t = (p || "").trim();
1939
+ if (!t) return "";
1940
+ if (t.startsWith("~")) return path.join(os.homedir(), t.slice(1).replace(/^\//, ""));
1941
+ return path.resolve(t);
1942
+ }
1943
+ function validateWorkspacePath(absPath) {
2168
1944
  try {
2169
- return path2.resolve(expandPath(p));
2170
- } catch {
2171
- return path2.resolve(p);
1945
+ if (!absPath) return { ok: false, error: "Path required" };
1946
+ if (!fs.existsSync(absPath)) return { ok: false, error: "Path does not exist" };
1947
+ const st = fs.statSync(absPath);
1948
+ if (!st.isDirectory()) return { ok: false, error: "Not a directory" };
1949
+ return { ok: true };
1950
+ } catch (e) {
1951
+ return { ok: false, error: e?.message || "Invalid path" };
2172
1952
  }
2173
1953
  }
2174
- function appendWorkspaceActivity(config, rawPath, meta) {
2175
- const abs = normWorkspacePath(rawPath);
2176
- if (!abs) return config;
2177
- const prev = config.recentWorkspaceActivity || [];
2178
- const filtered = prev.filter((e) => normWorkspacePath(e.path) !== abs);
1954
+ function defaultWorkspaceLabel(absPath) {
1955
+ const base = path.basename(absPath) || absPath;
1956
+ return base;
1957
+ }
1958
+ function getDefaultWorkspacePath(config) {
1959
+ const id = config.defaultWorkspaceId;
1960
+ if (!id) return null;
1961
+ const w = (config.workspaces || []).find((x) => x.id === id);
1962
+ if (!w) return null;
1963
+ const abs = expandPath(w.path);
1964
+ if (validateWorkspacePath(abs).ok !== true) return null;
1965
+ return abs;
1966
+ }
1967
+ function getWorkspaceState(config) {
1968
+ const workspaces = [...config.workspaces || []].sort((a, b) => b.addedAt - a.addedAt);
1969
+ const defaultWorkspacePath = getDefaultWorkspacePath(config);
1970
+ return {
1971
+ workspaces,
1972
+ defaultWorkspaceId: config.defaultWorkspaceId ?? null,
1973
+ defaultWorkspacePath
1974
+ };
1975
+ }
1976
+ function resolveLaunchDirectory(args, config) {
1977
+ const a = args || {};
1978
+ if (a.dir != null && String(a.dir).trim()) {
1979
+ const abs = expandPath(String(a.dir).trim());
1980
+ if (abs && validateWorkspacePath(abs).ok === true) {
1981
+ return { ok: true, path: abs, source: "dir" };
1982
+ }
1983
+ return {
1984
+ ok: false,
1985
+ code: "WORKSPACE_LAUNCH_CONTEXT_REQUIRED",
1986
+ message: abs ? "Directory path is not valid or does not exist" : "Invalid directory path"
1987
+ };
1988
+ }
1989
+ if (a.workspaceId) {
1990
+ const w = (config.workspaces || []).find((x) => x.id === a.workspaceId);
1991
+ if (w) {
1992
+ const abs = expandPath(w.path);
1993
+ if (validateWorkspacePath(abs).ok === true) {
1994
+ return { ok: true, path: abs, source: "workspaceId" };
1995
+ }
1996
+ }
1997
+ return {
1998
+ ok: false,
1999
+ code: "WORKSPACE_LAUNCH_CONTEXT_REQUIRED",
2000
+ message: "Saved workspace not found or path is no longer valid"
2001
+ };
2002
+ }
2003
+ if (a.useDefaultWorkspace === true) {
2004
+ const d = getDefaultWorkspacePath(config);
2005
+ if (d) return { ok: true, path: d, source: "defaultWorkspace" };
2006
+ return {
2007
+ ok: false,
2008
+ code: "WORKSPACE_LAUNCH_CONTEXT_REQUIRED",
2009
+ message: "No default workspace is set"
2010
+ };
2011
+ }
2012
+ if (a.useHome === true) {
2013
+ return { ok: true, path: os.homedir(), source: "home" };
2014
+ }
2015
+ return {
2016
+ ok: false,
2017
+ code: "WORKSPACE_LAUNCH_CONTEXT_REQUIRED",
2018
+ message: "Choose a directory, saved workspace, default workspace, or home before launching."
2019
+ };
2020
+ }
2021
+ function resolveIdeWorkspaceFromArgs(args, config) {
2022
+ const ar = args || {};
2023
+ if (ar.workspace) {
2024
+ const abs = expandPath(ar.workspace);
2025
+ if (abs && validateWorkspacePath(abs).ok === true) return abs;
2026
+ }
2027
+ if (ar.workspaceId) {
2028
+ const w = (config.workspaces || []).find((x) => x.id === ar.workspaceId);
2029
+ if (w) {
2030
+ const abs = expandPath(w.path);
2031
+ if (validateWorkspacePath(abs).ok === true) return abs;
2032
+ }
2033
+ }
2034
+ if (ar.useDefaultWorkspace === true) {
2035
+ return getDefaultWorkspacePath(config) || void 0;
2036
+ }
2037
+ return void 0;
2038
+ }
2039
+ function resolveIdeLaunchWorkspace(args, config) {
2040
+ const direct = resolveIdeWorkspaceFromArgs(args, config);
2041
+ if (direct) return direct;
2042
+ if (args?.useDefaultWorkspace === false) return void 0;
2043
+ return getDefaultWorkspacePath(config) || void 0;
2044
+ }
2045
+ function findWorkspaceByPath(config, rawPath) {
2046
+ const abs = path.resolve(expandPath(rawPath));
2047
+ if (!abs) return void 0;
2048
+ return (config.workspaces || []).find((w) => path.resolve(expandPath(w.path)) === abs);
2049
+ }
2050
+ function addWorkspaceEntry(config, rawPath, label, options) {
2051
+ const abs = expandPath(rawPath);
2052
+ const createIfMissing = options?.createIfMissing === true;
2053
+ if (!abs) return { error: "Path required" };
2054
+ if (!fs.existsSync(abs) && createIfMissing) {
2055
+ try {
2056
+ fs.mkdirSync(abs, { recursive: true });
2057
+ } catch (e) {
2058
+ return { error: e?.message || "Could not create directory" };
2059
+ }
2060
+ }
2061
+ const v = validateWorkspacePath(abs);
2062
+ if (!v.ok) return { error: v.error };
2063
+ const list = [...config.workspaces || []];
2064
+ if (list.some((w) => path.resolve(w.path) === abs)) {
2065
+ return { error: "Workspace already in list" };
2066
+ }
2067
+ if (list.length >= MAX_WORKSPACES) {
2068
+ return { error: `Maximum ${MAX_WORKSPACES} workspaces` };
2069
+ }
2179
2070
  const entry = {
2071
+ id: (0, import_crypto2.randomUUID)(),
2180
2072
  path: abs,
2181
- lastUsedAt: Date.now(),
2182
- kind: meta?.kind,
2183
- agentType: meta?.agentType
2073
+ label: (label || "").trim() || defaultWorkspaceLabel(abs),
2074
+ addedAt: Date.now()
2184
2075
  };
2185
- const recentWorkspaceActivity = [entry, ...filtered].slice(0, MAX_ACTIVITY);
2186
- return { ...config, recentWorkspaceActivity };
2076
+ list.push(entry);
2077
+ return { config: { ...config, workspaces: list }, entry };
2187
2078
  }
2188
- function getWorkspaceActivity(config, limit = 20) {
2189
- const list = [...config.recentWorkspaceActivity || []];
2190
- list.sort((a, b) => b.lastUsedAt - a.lastUsedAt);
2191
- return list.slice(0, limit);
2079
+ function removeWorkspaceEntry(config, id) {
2080
+ const list = (config.workspaces || []).filter((w) => w.id !== id);
2081
+ if (list.length === (config.workspaces || []).length) return { error: "Workspace not found" };
2082
+ let defaultWorkspaceId = config.defaultWorkspaceId;
2083
+ if (defaultWorkspaceId === id) defaultWorkspaceId = null;
2084
+ return { config: { ...config, workspaces: list, defaultWorkspaceId } };
2192
2085
  }
2193
- function removeActivityForPath(config, rawPath) {
2194
- const n = normWorkspacePath(rawPath);
2195
- return {
2196
- ...config,
2197
- recentWorkspaceActivity: (config.recentWorkspaceActivity || []).filter(
2198
- (e) => normWorkspacePath(e.path) !== n
2199
- )
2200
- };
2086
+ function setDefaultWorkspaceId(config, id) {
2087
+ if (id === null) {
2088
+ return { config: { ...config, defaultWorkspaceId: null } };
2089
+ }
2090
+ const w = (config.workspaces || []).find((x) => x.id === id);
2091
+ if (!w) return { error: "Workspace not found" };
2092
+ const abs = expandPath(w.path);
2093
+ if (validateWorkspacePath(abs).ok !== true) return { error: "Workspace path is no longer valid" };
2094
+ return { config: { ...config, defaultWorkspaceId: id } };
2201
2095
  }
2202
2096
 
2203
2097
  // src/config/recent-activity.ts
2204
- var path3 = __toESM(require("path"));
2205
- init_workspaces();
2206
- var MAX_ACTIVITY2 = 30;
2098
+ var path2 = __toESM(require("path"));
2099
+ var MAX_ACTIVITY = 30;
2207
2100
  function normalizeWorkspace(workspace) {
2208
2101
  if (!workspace) return "";
2209
2102
  try {
2210
- return path3.resolve(expandPath(workspace));
2103
+ return path2.resolve(expandPath(workspace));
2211
2104
  } catch {
2212
- return path3.resolve(workspace);
2105
+ return path2.resolve(workspace);
2213
2106
  }
2214
2107
  }
2215
2108
  function buildRecentActivityKey(entry) {
@@ -2225,24 +2118,33 @@ function appendRecentActivity(config, entry) {
2225
2118
  const filtered = (config.recentActivity || []).filter((item) => item.id !== nextEntry.id);
2226
2119
  return {
2227
2120
  ...config,
2228
- recentActivity: [nextEntry, ...filtered].slice(0, MAX_ACTIVITY2)
2121
+ recentActivity: [nextEntry, ...filtered].slice(0, MAX_ACTIVITY)
2229
2122
  };
2230
2123
  }
2231
2124
  function getRecentActivity(config, limit = 20) {
2232
2125
  return [...config.recentActivity || []].sort((a, b) => b.lastUsedAt - a.lastUsedAt).slice(0, limit);
2233
2126
  }
2234
- function getRecentSessionSeenAt(config, recentKey) {
2235
- return config.recentSessionReads?.[recentKey] || 0;
2127
+ function getSessionSeenAt(config, sessionId) {
2128
+ return config.sessionReads?.[sessionId] || 0;
2236
2129
  }
2237
- function markRecentSessionSeen(config, recentKey, seenAt = Date.now()) {
2238
- const prev = config.recentSessionReads || {};
2239
- const nextSeenAt = Math.max(prev[recentKey] || 0, seenAt);
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 : "";
2240
2138
  return {
2241
2139
  ...config,
2242
- recentSessionReads: {
2140
+ sessionReads: {
2243
2141
  ...prev,
2244
- [recentKey]: nextSeenAt
2245
- }
2142
+ [sessionId]: nextSeenAt
2143
+ },
2144
+ sessionReadMarkers: nextMarker ? {
2145
+ ...prevMarkers,
2146
+ [sessionId]: nextMarker
2147
+ } : prevMarkers
2246
2148
  };
2247
2149
  }
2248
2150
 
@@ -2353,15 +2255,15 @@ function parseVersion(raw) {
2353
2255
  return match ? match[1] : raw.split("\n")[0].slice(0, 100);
2354
2256
  }
2355
2257
  function execAsync(cmd, timeoutMs = 5e3) {
2356
- return new Promise((resolve10) => {
2258
+ return new Promise((resolve9) => {
2357
2259
  const child = (0, import_child_process2.exec)(cmd, { encoding: "utf-8", timeout: timeoutMs }, (err, stdout) => {
2358
2260
  if (err || !stdout?.trim()) {
2359
- resolve10(null);
2261
+ resolve9(null);
2360
2262
  } else {
2361
- resolve10(stdout.trim());
2263
+ resolve9(stdout.trim());
2362
2264
  }
2363
2265
  });
2364
- child.on("error", () => resolve10(null));
2266
+ child.on("error", () => resolve9(null));
2365
2267
  });
2366
2268
  }
2367
2269
  async function detectCLIs(providerLoader) {
@@ -2528,7 +2430,7 @@ var DaemonCdpManager = class {
2528
2430
  * Returns multiple entries if multiple IDE windows are open on same port
2529
2431
  */
2530
2432
  static listAllTargets(port) {
2531
- return new Promise((resolve10) => {
2433
+ return new Promise((resolve9) => {
2532
2434
  const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
2533
2435
  let data = "";
2534
2436
  res.on("data", (chunk) => data += chunk.toString());
@@ -2544,16 +2446,16 @@ var DaemonCdpManager = class {
2544
2446
  (t) => !isNonMain(t.title || "") && t.url?.includes("workbench.html") && !t.url?.includes("agent")
2545
2447
  );
2546
2448
  const fallbackPages = pages.filter((t) => !isNonMain(t.title || ""));
2547
- resolve10(mainPages.length > 0 ? mainPages : fallbackPages);
2449
+ resolve9(mainPages.length > 0 ? mainPages : fallbackPages);
2548
2450
  } catch {
2549
- resolve10([]);
2451
+ resolve9([]);
2550
2452
  }
2551
2453
  });
2552
2454
  });
2553
- req.on("error", () => resolve10([]));
2455
+ req.on("error", () => resolve9([]));
2554
2456
  req.setTimeout(2e3, () => {
2555
2457
  req.destroy();
2556
- resolve10([]);
2458
+ resolve9([]);
2557
2459
  });
2558
2460
  });
2559
2461
  }
@@ -2593,7 +2495,7 @@ var DaemonCdpManager = class {
2593
2495
  }
2594
2496
  }
2595
2497
  findTargetOnPort(port) {
2596
- return new Promise((resolve10) => {
2498
+ return new Promise((resolve9) => {
2597
2499
  const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
2598
2500
  let data = "";
2599
2501
  res.on("data", (chunk) => data += chunk.toString());
@@ -2604,7 +2506,7 @@ var DaemonCdpManager = class {
2604
2506
  (t) => (t.type === "page" || t.type === "browser" || t.type === "Page") && t.webSocketDebuggerUrl
2605
2507
  );
2606
2508
  if (pages.length === 0) {
2607
- resolve10(targets.find((t) => t.webSocketDebuggerUrl) || null);
2509
+ resolve9(targets.find((t) => t.webSocketDebuggerUrl) || null);
2608
2510
  return;
2609
2511
  }
2610
2512
  const mainPages = pages.filter((t) => !this.isNonMainTitle(t.title || ""));
@@ -2614,24 +2516,24 @@ var DaemonCdpManager = class {
2614
2516
  const specific = list.find((t) => t.id === this._targetId);
2615
2517
  if (specific) {
2616
2518
  this._pageTitle = specific.title || "";
2617
- resolve10(specific);
2519
+ resolve9(specific);
2618
2520
  } else {
2619
2521
  this.log(`[CDP] Target ${this._targetId} not found in page list`);
2620
- resolve10(null);
2522
+ resolve9(null);
2621
2523
  }
2622
2524
  return;
2623
2525
  }
2624
2526
  this._pageTitle = list[0]?.title || "";
2625
- resolve10(list[0]);
2527
+ resolve9(list[0]);
2626
2528
  } catch {
2627
- resolve10(null);
2529
+ resolve9(null);
2628
2530
  }
2629
2531
  });
2630
2532
  });
2631
- req.on("error", () => resolve10(null));
2533
+ req.on("error", () => resolve9(null));
2632
2534
  req.setTimeout(2e3, () => {
2633
2535
  req.destroy();
2634
- resolve10(null);
2536
+ resolve9(null);
2635
2537
  });
2636
2538
  });
2637
2539
  }
@@ -2642,7 +2544,7 @@ var DaemonCdpManager = class {
2642
2544
  this.extensionProviders = providers;
2643
2545
  }
2644
2546
  connectToTarget(wsUrl) {
2645
- return new Promise((resolve10) => {
2547
+ return new Promise((resolve9) => {
2646
2548
  this.ws = new import_ws.default(wsUrl);
2647
2549
  this.ws.on("open", async () => {
2648
2550
  this._connected = true;
@@ -2652,17 +2554,17 @@ var DaemonCdpManager = class {
2652
2554
  }
2653
2555
  this.connectBrowserWs().catch(() => {
2654
2556
  });
2655
- resolve10(true);
2557
+ resolve9(true);
2656
2558
  });
2657
2559
  this.ws.on("message", (data) => {
2658
2560
  try {
2659
2561
  const msg = JSON.parse(data.toString());
2660
2562
  if (msg.id && this.pending.has(msg.id)) {
2661
- const { resolve: resolve11, reject } = this.pending.get(msg.id);
2563
+ const { resolve: resolve10, reject } = this.pending.get(msg.id);
2662
2564
  this.pending.delete(msg.id);
2663
2565
  this.failureCount = 0;
2664
2566
  if (msg.error) reject(new Error(msg.error.message));
2665
- else resolve11(msg.result);
2567
+ else resolve10(msg.result);
2666
2568
  } else if (msg.method === "Runtime.executionContextCreated") {
2667
2569
  this.contexts.add(msg.params.context.id);
2668
2570
  } else if (msg.method === "Runtime.executionContextDestroyed") {
@@ -2685,7 +2587,7 @@ var DaemonCdpManager = class {
2685
2587
  this.ws.on("error", (err) => {
2686
2588
  this.log(`[CDP] WebSocket error: ${err.message}`);
2687
2589
  this._connected = false;
2688
- resolve10(false);
2590
+ resolve9(false);
2689
2591
  });
2690
2592
  });
2691
2593
  }
@@ -2699,7 +2601,7 @@ var DaemonCdpManager = class {
2699
2601
  return;
2700
2602
  }
2701
2603
  this.log(`[CDP] Connecting browser WS for target discovery...`);
2702
- await new Promise((resolve10, reject) => {
2604
+ await new Promise((resolve9, reject) => {
2703
2605
  this.browserWs = new import_ws.default(browserWsUrl);
2704
2606
  this.browserWs.on("open", async () => {
2705
2607
  this._browserConnected = true;
@@ -2709,16 +2611,16 @@ var DaemonCdpManager = class {
2709
2611
  } catch (e) {
2710
2612
  this.log(`[CDP] setDiscoverTargets failed: ${e.message}`);
2711
2613
  }
2712
- resolve10();
2614
+ resolve9();
2713
2615
  });
2714
2616
  this.browserWs.on("message", (data) => {
2715
2617
  try {
2716
2618
  const msg = JSON.parse(data.toString());
2717
2619
  if (msg.id && this.browserPending.has(msg.id)) {
2718
- const { resolve: resolve11, reject: reject2 } = this.browserPending.get(msg.id);
2620
+ const { resolve: resolve10, reject: reject2 } = this.browserPending.get(msg.id);
2719
2621
  this.browserPending.delete(msg.id);
2720
2622
  if (msg.error) reject2(new Error(msg.error.message));
2721
- else resolve11(msg.result);
2623
+ else resolve10(msg.result);
2722
2624
  }
2723
2625
  } catch {
2724
2626
  }
@@ -2738,31 +2640,31 @@ var DaemonCdpManager = class {
2738
2640
  }
2739
2641
  }
2740
2642
  getBrowserWsUrl() {
2741
- return new Promise((resolve10) => {
2643
+ return new Promise((resolve9) => {
2742
2644
  const req = http.get(`http://127.0.0.1:${this.port}/json/version`, (res) => {
2743
2645
  let data = "";
2744
2646
  res.on("data", (chunk) => data += chunk.toString());
2745
2647
  res.on("end", () => {
2746
2648
  try {
2747
2649
  const info = JSON.parse(data);
2748
- resolve10(info.webSocketDebuggerUrl || null);
2650
+ resolve9(info.webSocketDebuggerUrl || null);
2749
2651
  } catch {
2750
- resolve10(null);
2652
+ resolve9(null);
2751
2653
  }
2752
2654
  });
2753
2655
  });
2754
- req.on("error", () => resolve10(null));
2656
+ req.on("error", () => resolve9(null));
2755
2657
  req.setTimeout(3e3, () => {
2756
2658
  req.destroy();
2757
- resolve10(null);
2659
+ resolve9(null);
2758
2660
  });
2759
2661
  });
2760
2662
  }
2761
2663
  sendBrowser(method, params = {}, timeoutMs = 15e3) {
2762
- return new Promise((resolve10, reject) => {
2664
+ return new Promise((resolve9, reject) => {
2763
2665
  if (!this.browserWs || !this._browserConnected) return reject(new Error("Browser WS not connected"));
2764
2666
  const id = this.browserMsgId++;
2765
- this.browserPending.set(id, { resolve: resolve10, reject });
2667
+ this.browserPending.set(id, { resolve: resolve9, reject });
2766
2668
  this.browserWs.send(JSON.stringify({ id, method, params }));
2767
2669
  setTimeout(() => {
2768
2670
  if (this.browserPending.has(id)) {
@@ -2802,11 +2704,11 @@ var DaemonCdpManager = class {
2802
2704
  }
2803
2705
  // ─── CDP Protocol ────────────────────────────────────────
2804
2706
  sendInternal(method, params = {}, timeoutMs = 15e3) {
2805
- return new Promise((resolve10, reject) => {
2707
+ return new Promise((resolve9, reject) => {
2806
2708
  if (!this.ws || !this._connected) return reject(new Error("CDP not connected"));
2807
2709
  if (this.ws.readyState !== import_ws.default.OPEN) return reject(new Error("WebSocket not open"));
2808
2710
  const id = this.msgId++;
2809
- this.pending.set(id, { resolve: resolve10, reject });
2711
+ this.pending.set(id, { resolve: resolve9, reject });
2810
2712
  this.ws.send(JSON.stringify({ id, method, params }));
2811
2713
  setTimeout(() => {
2812
2714
  if (this.pending.has(id)) {
@@ -3055,7 +2957,7 @@ var DaemonCdpManager = class {
3055
2957
  const browserWs = this.browserWs;
3056
2958
  let msgId = this.browserMsgId;
3057
2959
  const sendWs = (method, params = {}, sessionId) => {
3058
- return new Promise((resolve10, reject) => {
2960
+ return new Promise((resolve9, reject) => {
3059
2961
  const mid = msgId++;
3060
2962
  this.browserMsgId = msgId;
3061
2963
  const handler = (raw) => {
@@ -3064,7 +2966,7 @@ var DaemonCdpManager = class {
3064
2966
  if (msg.id === mid) {
3065
2967
  browserWs.removeListener("message", handler);
3066
2968
  if (msg.error) reject(new Error(msg.error.message || JSON.stringify(msg.error)));
3067
- else resolve10(msg.result);
2969
+ else resolve9(msg.result);
3068
2970
  }
3069
2971
  } catch {
3070
2972
  }
@@ -3255,14 +3157,14 @@ var DaemonCdpManager = class {
3255
3157
  if (!ws || ws.readyState !== import_ws.default.OPEN) {
3256
3158
  throw new Error("CDP not connected");
3257
3159
  }
3258
- return new Promise((resolve10, reject) => {
3160
+ return new Promise((resolve9, reject) => {
3259
3161
  const id = getNextId();
3260
3162
  pendingMap.set(id, {
3261
3163
  resolve: (result) => {
3262
3164
  if (result?.result?.subtype === "error") {
3263
3165
  reject(new Error(result.result.description));
3264
3166
  } else {
3265
- resolve10(result?.result?.value);
3167
+ resolve9(result?.result?.value);
3266
3168
  }
3267
3169
  },
3268
3170
  reject
@@ -3294,10 +3196,10 @@ var DaemonCdpManager = class {
3294
3196
  throw new Error("CDP not connected");
3295
3197
  }
3296
3198
  const sendViaSession = (method, params = {}) => {
3297
- return new Promise((resolve10, reject) => {
3199
+ return new Promise((resolve9, reject) => {
3298
3200
  const pendingMap = this._browserConnected ? this.browserPending : this.pending;
3299
3201
  const id = this._browserConnected ? this.browserMsgId++ : this.msgId++;
3300
- pendingMap.set(id, { resolve: resolve10, reject });
3202
+ pendingMap.set(id, { resolve: resolve9, reject });
3301
3203
  ws.send(JSON.stringify({ id, sessionId, method, params }));
3302
3204
  setTimeout(() => {
3303
3205
  if (pendingMap.has(id)) {
@@ -4004,9 +3906,9 @@ var ExtensionProviderInstance = class {
4004
3906
 
4005
3907
  // src/config/chat-history.ts
4006
3908
  var fs3 = __toESM(require("fs"));
4007
- var path5 = __toESM(require("path"));
3909
+ var path4 = __toESM(require("path"));
4008
3910
  var os5 = __toESM(require("os"));
4009
- var HISTORY_DIR = path5.join(os5.homedir(), ".adhdev", "history");
3911
+ var HISTORY_DIR = path4.join(os5.homedir(), ".adhdev", "history");
4010
3912
  var RETAIN_DAYS = 30;
4011
3913
  var ChatHistoryWriter = class {
4012
3914
  /** Last seen message count per agent (deduplication) */
@@ -4049,11 +3951,11 @@ var ChatHistoryWriter = class {
4049
3951
  });
4050
3952
  }
4051
3953
  if (newMessages.length === 0) return;
4052
- const dir = path5.join(HISTORY_DIR, this.sanitize(agentType));
3954
+ const dir = path4.join(HISTORY_DIR, this.sanitize(agentType));
4053
3955
  fs3.mkdirSync(dir, { recursive: true });
4054
3956
  const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
4055
3957
  const filePrefix = instanceId ? `${this.sanitize(instanceId)}_` : "";
4056
- const filePath = path5.join(dir, `${filePrefix}${date}.jsonl`);
3958
+ const filePath = path4.join(dir, `${filePrefix}${date}.jsonl`);
4057
3959
  const lines = newMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
4058
3960
  fs3.appendFileSync(filePath, lines, "utf-8");
4059
3961
  const prevCount = this.lastSeenCounts.get(dedupKey) || 0;
@@ -4097,11 +3999,11 @@ ${next}`;
4097
3999
  this.lastSeenTerminal.set(dedupKey, next);
4098
4000
  return;
4099
4001
  }
4100
- const dir = path5.join(HISTORY_DIR, this.sanitize(agentType));
4002
+ const dir = path4.join(HISTORY_DIR, this.sanitize(agentType));
4101
4003
  fs3.mkdirSync(dir, { recursive: true });
4102
4004
  const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
4103
4005
  const filePrefix = instanceId ? `${this.sanitize(instanceId)}_` : "";
4104
- const filePath = path5.join(dir, `${filePrefix}${date}.terminal.log`);
4006
+ const filePath = path4.join(dir, `${filePrefix}${date}.terminal.log`);
4105
4007
  fs3.appendFileSync(filePath, delta, "utf-8");
4106
4008
  this.lastSeenTerminal.set(dedupKey, next);
4107
4009
  if (!this.rotated) {
@@ -4125,10 +4027,10 @@ ${next}`;
4125
4027
  const cutoff = Date.now() - RETAIN_DAYS * 24 * 60 * 60 * 1e3;
4126
4028
  const agentDirs = fs3.readdirSync(HISTORY_DIR, { withFileTypes: true }).filter((d) => d.isDirectory());
4127
4029
  for (const dir of agentDirs) {
4128
- const dirPath = path5.join(HISTORY_DIR, dir.name);
4030
+ const dirPath = path4.join(HISTORY_DIR, dir.name);
4129
4031
  const files = fs3.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl") || f.endsWith(".terminal.log"));
4130
4032
  for (const file of files) {
4131
- const filePath = path5.join(dirPath, file);
4033
+ const filePath = path4.join(dirPath, file);
4132
4034
  const stat = fs3.statSync(filePath);
4133
4035
  if (stat.mtimeMs < cutoff) {
4134
4036
  fs3.unlinkSync(filePath);
@@ -4146,7 +4048,7 @@ ${next}`;
4146
4048
  function readChatHistory(agentType, offset = 0, limit = 30, instanceId) {
4147
4049
  try {
4148
4050
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
4149
- const dir = path5.join(HISTORY_DIR, sanitized);
4051
+ const dir = path4.join(HISTORY_DIR, sanitized);
4150
4052
  if (!fs3.existsSync(dir)) return { messages: [], hasMore: false };
4151
4053
  const sanitizedInstance = instanceId?.replace(/[^a-zA-Z0-9_-]/g, "_");
4152
4054
  const files = fs3.readdirSync(dir).filter((f) => {
@@ -4160,7 +4062,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, instanceId) {
4160
4062
  const needed = offset + limit + 1;
4161
4063
  for (const file of files) {
4162
4064
  if (allMessages.length >= needed) break;
4163
- const filePath = path5.join(dir, file);
4065
+ const filePath = path4.join(dir, file);
4164
4066
  const content = fs3.readFileSync(filePath, "utf-8");
4165
4067
  const lines = content.trim().split("\n").filter(Boolean);
4166
4068
  for (let i = lines.length - 1; i >= 0; i--) {
@@ -5228,11 +5130,18 @@ function buildSessionEntries(allStates, cdpManagers) {
5228
5130
  for (const state of acpStates) {
5229
5131
  sessions.push(buildAcpSession(state));
5230
5132
  }
5133
+ const extensionParentIds = new Set(
5134
+ sessions.filter((session) => session.transport === "cdp-webview" && !!session.parentId).map((session) => session.parentId)
5135
+ );
5136
+ for (const session of sessions) {
5137
+ if (session.transport === "cdp-page" && extensionParentIds.has(session.id)) {
5138
+ session.surfaceHidden = true;
5139
+ }
5140
+ }
5231
5141
  return sessions;
5232
5142
  }
5233
5143
 
5234
5144
  // src/commands/handler.ts
5235
- init_config();
5236
5145
  init_logger();
5237
5146
 
5238
5147
  // src/commands/chat-commands.ts
@@ -6057,7 +5966,7 @@ async function handleResolveAction(h, args) {
6057
5966
 
6058
5967
  // src/commands/cdp-commands.ts
6059
5968
  var fs4 = __toESM(require("fs"));
6060
- var path6 = __toESM(require("path"));
5969
+ var path5 = __toESM(require("path"));
6061
5970
  var os6 = __toESM(require("os"));
6062
5971
  var KEY_TO_VK = {
6063
5972
  Backspace: 8,
@@ -6288,11 +6197,11 @@ function resolveSafePath(requestedPath) {
6288
6197
  const home = os6.homedir();
6289
6198
  let resolved;
6290
6199
  if (requestedPath.startsWith("~")) {
6291
- resolved = path6.join(home, requestedPath.slice(1));
6292
- } else if (path6.isAbsolute(requestedPath)) {
6200
+ resolved = path5.join(home, requestedPath.slice(1));
6201
+ } else if (path5.isAbsolute(requestedPath)) {
6293
6202
  resolved = requestedPath;
6294
6203
  } else {
6295
- resolved = path6.resolve(requestedPath);
6204
+ resolved = path5.resolve(requestedPath);
6296
6205
  }
6297
6206
  return resolved;
6298
6207
  }
@@ -6308,7 +6217,7 @@ async function handleFileRead(h, args) {
6308
6217
  async function handleFileWrite(h, args) {
6309
6218
  try {
6310
6219
  const filePath = resolveSafePath(args?.path);
6311
- fs4.mkdirSync(path6.dirname(filePath), { recursive: true });
6220
+ fs4.mkdirSync(path5.dirname(filePath), { recursive: true });
6312
6221
  fs4.writeFileSync(filePath, args?.content || "", "utf-8");
6313
6222
  return { success: true, path: filePath };
6314
6223
  } catch (e) {
@@ -6322,7 +6231,7 @@ async function handleFileList(h, args) {
6322
6231
  const files = entries.map((e) => ({
6323
6232
  name: e.name,
6324
6233
  type: e.isDirectory() ? "directory" : "file",
6325
- size: e.isFile() ? fs4.statSync(path6.join(dirPath, e.name)).size : void 0
6234
+ size: e.isFile() ? fs4.statSync(path5.join(dirPath, e.name)).size : void 0
6326
6235
  }));
6327
6236
  return { success: true, files, path: dirPath };
6328
6237
  } catch (e) {
@@ -6334,7 +6243,6 @@ async function handleFileListBrowse(h, args) {
6334
6243
  }
6335
6244
 
6336
6245
  // src/commands/stream-commands.ts
6337
- init_config();
6338
6246
  init_logger();
6339
6247
  async function handleFocusSession(h, args) {
6340
6248
  if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
@@ -6488,13 +6396,12 @@ function handleGetIdeExtensions(h, args) {
6488
6396
  const loader = h.ctx.providerLoader;
6489
6397
  if (!loader) return { success: false, error: "ProviderLoader not initialized" };
6490
6398
  const allExtProviders = loader.getByCategory?.("extension") || [];
6491
- const config = loadConfig();
6492
6399
  if (ideType) {
6493
6400
  const extensions = allExtProviders.map((p) => ({
6494
6401
  type: p.type,
6495
6402
  name: p.name,
6496
6403
  extensionId: p.extensionId,
6497
- enabled: config.ideSettings?.[ideType]?.extensions?.[p.type]?.enabled === true
6404
+ enabled: loader.getIdeExtensionEnabledState?.(ideType, p.type) === true
6498
6405
  }));
6499
6406
  return { success: true, ideType, extensions };
6500
6407
  }
@@ -6505,7 +6412,7 @@ function handleGetIdeExtensions(h, args) {
6505
6412
  type: p.type,
6506
6413
  name: p.name,
6507
6414
  extensionId: p.extensionId,
6508
- enabled: config.ideSettings?.[ide]?.extensions?.[p.type]?.enabled === true
6415
+ enabled: loader.getIdeExtensionEnabledState?.(ide, p.type) === true
6509
6416
  }));
6510
6417
  }
6511
6418
  return { success: true, ideExtensions: result };
@@ -6528,7 +6435,6 @@ function handleSetIdeExtension(h, args) {
6528
6435
 
6529
6436
  // src/commands/workspace-commands.ts
6530
6437
  init_config();
6531
- init_workspaces();
6532
6438
  function handleWorkspaceList() {
6533
6439
  const config = loadConfig();
6534
6440
  const state = getWorkspaceState(config);
@@ -6536,9 +6442,7 @@ function handleWorkspaceList() {
6536
6442
  success: true,
6537
6443
  workspaces: state.workspaces,
6538
6444
  defaultWorkspaceId: state.defaultWorkspaceId,
6539
- defaultWorkspacePath: state.defaultWorkspacePath,
6540
- legacyRecentPaths: config.recentCliWorkspaces || [],
6541
- activity: getWorkspaceActivity(config, 25)
6445
+ defaultWorkspacePath: state.defaultWorkspacePath
6542
6446
  };
6543
6447
  }
6544
6448
  function handleWorkspaceAdd(args) {
@@ -6549,10 +6453,9 @@ function handleWorkspaceAdd(args) {
6549
6453
  const config = loadConfig();
6550
6454
  const result = addWorkspaceEntry(config, rawPath, label, { createIfMissing });
6551
6455
  if ("error" in result) return { success: false, error: result.error };
6552
- let cfg = appendWorkspaceActivity(result.config, result.entry.path, {});
6553
- saveConfig(cfg);
6554
- const state = getWorkspaceState(cfg);
6555
- return { success: true, entry: result.entry, ...state, activity: getWorkspaceActivity(cfg, 25) };
6456
+ saveConfig(result.config);
6457
+ const state = getWorkspaceState(result.config);
6458
+ return { success: true, entry: result.entry, ...state };
6556
6459
  }
6557
6460
  function handleWorkspaceRemove(args) {
6558
6461
  const id = (args?.id || "").trim();
@@ -6561,13 +6464,9 @@ function handleWorkspaceRemove(args) {
6561
6464
  const removed = (config.workspaces || []).find((w) => w.id === id);
6562
6465
  const result = removeWorkspaceEntry(config, id);
6563
6466
  if ("error" in result) return { success: false, error: result.error };
6564
- let cfg = result.config;
6565
- if (removed) {
6566
- cfg = removeActivityForPath(cfg, removed.path);
6567
- }
6568
- saveConfig(cfg);
6569
- const state = getWorkspaceState(cfg);
6570
- return { success: true, removedId: id, ...state, activity: getWorkspaceActivity(cfg, 25) };
6467
+ saveConfig(result.config);
6468
+ const state = getWorkspaceState(result.config);
6469
+ return { success: true, removedId: id, ...state };
6571
6470
  }
6572
6471
  function handleWorkspaceSetDefault(args) {
6573
6472
  const clear = args?.clear === true || args?.id === null || args?.id === "";
@@ -6579,8 +6478,7 @@ function handleWorkspaceSetDefault(args) {
6579
6478
  const state2 = getWorkspaceState(result2.config);
6580
6479
  return {
6581
6480
  success: true,
6582
- ...state2,
6583
- activity: getWorkspaceActivity(result2.config, 25)
6481
+ ...state2
6584
6482
  };
6585
6483
  }
6586
6484
  const pathArg = args?.path != null && String(args.path).trim() ? String(args.path).trim() : "";
@@ -6604,18 +6502,12 @@ function handleWorkspaceSetDefault(args) {
6604
6502
  }
6605
6503
  const result = setDefaultWorkspaceId(config, nextId);
6606
6504
  if ("error" in result) return { success: false, error: result.error };
6607
- let out = result.config;
6608
- const ap = getDefaultWorkspacePath(out);
6609
- if (ap) {
6610
- out = appendWorkspaceActivity(out, ap, { kind: "default" });
6611
- }
6612
- saveConfig(out);
6613
- const state = getWorkspaceState(out);
6614
- return { success: true, ...state, activity: getWorkspaceActivity(out, 25) };
6505
+ saveConfig(result.config);
6506
+ const state = getWorkspaceState(result.config);
6507
+ return { success: true, ...state };
6615
6508
  }
6616
6509
 
6617
6510
  // src/commands/handler.ts
6618
- init_workspaces();
6619
6511
  var COMMAND_DEBUG_LEVELS = /* @__PURE__ */ new Set([
6620
6512
  "pty_input",
6621
6513
  "pty_resize",
@@ -6942,22 +6834,7 @@ var DaemonCommandHandler = class {
6942
6834
  return handleFileList(this, args);
6943
6835
  case "file_list_browse":
6944
6836
  return handleFileListBrowse(this, args);
6945
- // ─── VSCode API commands (not available) ────
6946
- case "vscode_command_exec":
6947
- case "execute_vscode_command": {
6948
- const resolvedCmd = args?.commandId || args?.command;
6949
- if (resolvedCmd === "adhdev.captureCdpScreenshot") {
6950
- return handleScreenshot(this, args);
6951
- }
6952
- return { success: false, error: `VSCode command not available: ${resolvedCmd || cmd}` };
6953
- }
6954
6837
  // ─── Workspace cmds ──────────────
6955
- case "get_recent_workspaces":
6956
- return this.handleGetRecentWorkspaces(args);
6957
- case "get_cli_history": {
6958
- const config = loadConfig();
6959
- return { success: true, history: config.cliHistory || [] };
6960
- }
6961
6838
  case "workspace_list":
6962
6839
  return handleWorkspaceList();
6963
6840
  case "workspace_add":
@@ -6965,7 +6842,6 @@ var DaemonCommandHandler = class {
6965
6842
  case "workspace_remove":
6966
6843
  return handleWorkspaceRemove(args);
6967
6844
  case "workspace_set_default":
6968
- case "workspace_set_active":
6969
6845
  return handleWorkspaceSetDefault(args);
6970
6846
  // ─── Script manage ───────────────────
6971
6847
  case "refresh_scripts":
@@ -7011,19 +6887,6 @@ var DaemonCommandHandler = class {
7011
6887
  }
7012
6888
  }
7013
6889
  // ─── Misc (kept in handler — too small to extract) ───────
7014
- async handleGetRecentWorkspaces(_args) {
7015
- const config = loadConfig();
7016
- const cliRecent = config.recentCliWorkspaces || [];
7017
- const ws = getWorkspaceState(config);
7018
- return {
7019
- success: true,
7020
- result: cliRecent,
7021
- workspaces: ws.workspaces,
7022
- defaultWorkspaceId: ws.defaultWorkspaceId,
7023
- defaultWorkspacePath: ws.defaultWorkspacePath,
7024
- activity: getWorkspaceActivity(config, 25)
7025
- };
7026
- }
7027
6890
  async handleRefreshScripts(_args) {
7028
6891
  if (this._ctx.providerLoader) {
7029
6892
  await this._ctx.providerLoader.fetchLatest().catch(() => {
@@ -7041,7 +6904,7 @@ var DaemonCommandHandler = class {
7041
6904
  try {
7042
6905
  const http3 = await import("http");
7043
6906
  const postData = JSON.stringify(body);
7044
- const result = await new Promise((resolve10, reject) => {
6907
+ const result = await new Promise((resolve9, reject) => {
7045
6908
  const req = http3.request({
7046
6909
  hostname: "127.0.0.1",
7047
6910
  port: 19280,
@@ -7053,9 +6916,9 @@ var DaemonCommandHandler = class {
7053
6916
  res.on("data", (chunk) => data += chunk);
7054
6917
  res.on("end", () => {
7055
6918
  try {
7056
- resolve10(JSON.parse(data));
6919
+ resolve9(JSON.parse(data));
7057
6920
  } catch {
7058
- resolve10({ raw: data });
6921
+ resolve9({ raw: data });
7059
6922
  }
7060
6923
  });
7061
6924
  });
@@ -7073,15 +6936,15 @@ var DaemonCommandHandler = class {
7073
6936
  if (!providerType) return { success: false, error: "providerType required" };
7074
6937
  try {
7075
6938
  const http3 = await import("http");
7076
- const result = await new Promise((resolve10, reject) => {
6939
+ const result = await new Promise((resolve9, reject) => {
7077
6940
  http3.get(`http://127.0.0.1:19280/api/providers/${providerType}/${endpoint}`, (res) => {
7078
6941
  let data = "";
7079
6942
  res.on("data", (chunk) => data += chunk);
7080
6943
  res.on("end", () => {
7081
6944
  try {
7082
- resolve10(JSON.parse(data));
6945
+ resolve9(JSON.parse(data));
7083
6946
  } catch {
7084
- resolve10({ raw: data });
6947
+ resolve9({ raw: data });
7085
6948
  }
7086
6949
  });
7087
6950
  }).on("error", reject);
@@ -7095,7 +6958,7 @@ var DaemonCommandHandler = class {
7095
6958
  try {
7096
6959
  const http3 = await import("http");
7097
6960
  const postData = JSON.stringify(args || {});
7098
- const result = await new Promise((resolve10, reject) => {
6961
+ const result = await new Promise((resolve9, reject) => {
7099
6962
  const req = http3.request({
7100
6963
  hostname: "127.0.0.1",
7101
6964
  port: 19280,
@@ -7107,9 +6970,9 @@ var DaemonCommandHandler = class {
7107
6970
  res.on("data", (chunk) => data += chunk);
7108
6971
  res.on("end", () => {
7109
6972
  try {
7110
- resolve10(JSON.parse(data));
6973
+ resolve9(JSON.parse(data));
7111
6974
  } catch {
7112
- resolve10({ raw: data });
6975
+ resolve9({ raw: data });
7113
6976
  }
7114
6977
  });
7115
6978
  });
@@ -7128,11 +6991,11 @@ var DaemonCommandHandler = class {
7128
6991
  var import_child_process4 = require("child_process");
7129
6992
  var net = __toESM(require("net"));
7130
6993
  var os8 = __toESM(require("os"));
7131
- var path8 = __toESM(require("path"));
6994
+ var path7 = __toESM(require("path"));
7132
6995
 
7133
6996
  // src/providers/provider-loader.ts
7134
6997
  var fs5 = __toESM(require("fs"));
7135
- var path7 = __toESM(require("path"));
6998
+ var path6 = __toESM(require("path"));
7136
6999
  var os7 = __toESM(require("os"));
7137
7000
  var chokidar = __toESM(require("chokidar"));
7138
7001
  init_logger();
@@ -7153,12 +7016,12 @@ var ProviderLoader = class _ProviderLoader {
7153
7016
  static META_FILE = ".meta.json";
7154
7017
  constructor(options) {
7155
7018
  this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
7156
- const defaultProvidersDir = path7.join(os7.homedir(), ".adhdev", "providers");
7019
+ const defaultProvidersDir = path6.join(os7.homedir(), ".adhdev", "providers");
7157
7020
  if (options?.userDir) {
7158
7021
  this.userDir = options.userDir;
7159
7022
  this.log(`Config 'providerDir' applied: ${this.userDir}`);
7160
7023
  } else {
7161
- const localRepoPath = path7.resolve(__dirname, "../../../../../adhdev-providers");
7024
+ const localRepoPath = path6.resolve(__dirname, "../../../../../adhdev-providers");
7162
7025
  if (fs5.existsSync(localRepoPath)) {
7163
7026
  this.userDir = localRepoPath;
7164
7027
  this.log(`Auto-detected local public repository: ${this.userDir} (Dev workspace speedup)`);
@@ -7167,7 +7030,7 @@ var ProviderLoader = class _ProviderLoader {
7167
7030
  this.log(`Using default user providers directory: ${this.userDir}`);
7168
7031
  }
7169
7032
  }
7170
- this.upstreamDir = path7.join(defaultProvidersDir, ".upstream");
7033
+ this.upstreamDir = path6.join(defaultProvidersDir, ".upstream");
7171
7034
  this.disableUpstream = options?.disableUpstream ?? false;
7172
7035
  }
7173
7036
  log(msg) {
@@ -7197,7 +7060,7 @@ var ProviderLoader = class _ProviderLoader {
7197
7060
  * Canonical provider directory shape for a given root.
7198
7061
  */
7199
7062
  getProviderDir(root, category, type) {
7200
- return path7.join(root, category, type);
7063
+ return path6.join(root, category, type);
7201
7064
  }
7202
7065
  /**
7203
7066
  * Canonical user override directory for a provider.
@@ -7224,7 +7087,7 @@ var ProviderLoader = class _ProviderLoader {
7224
7087
  resolveProviderFile(type, ...segments) {
7225
7088
  const dir = this.findProviderDirInternal(type);
7226
7089
  if (!dir) return null;
7227
- return path7.join(dir, ...segments);
7090
+ return path6.join(dir, ...segments);
7228
7091
  }
7229
7092
  /**
7230
7093
  * Load all providers (3-tier priority)
@@ -7262,7 +7125,7 @@ var ProviderLoader = class _ProviderLoader {
7262
7125
  if (!fs5.existsSync(this.upstreamDir)) return false;
7263
7126
  try {
7264
7127
  return fs5.readdirSync(this.upstreamDir).some(
7265
- (d) => fs5.statSync(path7.join(this.upstreamDir, d)).isDirectory()
7128
+ (d) => fs5.statSync(path6.join(this.upstreamDir, d)).isDirectory()
7266
7129
  );
7267
7130
  } catch {
7268
7131
  return false;
@@ -7347,16 +7210,23 @@ var ProviderLoader = class _ProviderLoader {
7347
7210
  isEnabled(type, ideType) {
7348
7211
  if (!ideType) return true;
7349
7212
  try {
7350
- const { loadConfig: loadConfig2 } = (init_config(), __toCommonJS(config_exports));
7351
- const config = loadConfig2();
7352
- const baseIdeType = ideType.split("_")[0];
7353
- const val = config.ideSettings?.[baseIdeType]?.extensions?.[type]?.enabled;
7354
- return val === true;
7213
+ return this.getIdeExtensionEnabledState(ideType, type);
7355
7214
  } catch {
7356
7215
  return false;
7357
7216
  }
7358
7217
  }
7359
7218
  /**
7219
+ * Resolve per-IDE extension enabled state using the same normalization
7220
+ * that runtime attach/remove uses.
7221
+ */
7222
+ getIdeExtensionEnabledState(ideType, extensionType) {
7223
+ const { loadConfig: loadConfig2 } = (init_config(), __toCommonJS(config_exports));
7224
+ const config = loadConfig2();
7225
+ const baseIdeType = ideType.split("_")[0];
7226
+ const val = config.ideSettings?.[baseIdeType]?.extensions?.[extensionType]?.enabled;
7227
+ return val === true;
7228
+ }
7229
+ /**
7360
7230
  * Save IDE extension enabled setting
7361
7231
  */
7362
7232
  setIdeExtensionEnabled(ideType, extensionType, enabled) {
@@ -7554,14 +7424,14 @@ var ProviderLoader = class _ProviderLoader {
7554
7424
  this.log(` [loadScriptsFromDir] ${type}: providerDir not found`);
7555
7425
  return null;
7556
7426
  }
7557
- const dir = path7.join(providerDir, scriptDir);
7427
+ const dir = path6.join(providerDir, scriptDir);
7558
7428
  if (!fs5.existsSync(dir)) {
7559
7429
  this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
7560
7430
  return null;
7561
7431
  }
7562
7432
  const cached = this.scriptsCache.get(dir);
7563
7433
  if (cached) return cached;
7564
- const scriptsJs = path7.join(dir, "scripts.js");
7434
+ const scriptsJs = path6.join(dir, "scripts.js");
7565
7435
  if (fs5.existsSync(scriptsJs)) {
7566
7436
  try {
7567
7437
  delete require.cache[require.resolve(scriptsJs)];
@@ -7600,7 +7470,7 @@ var ProviderLoader = class _ProviderLoader {
7600
7470
  });
7601
7471
  const handleChange = (filePath) => {
7602
7472
  if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
7603
- this.log(`File changed: ${path7.basename(filePath)}, reloading...`);
7473
+ this.log(`File changed: ${path6.basename(filePath)}, reloading...`);
7604
7474
  this.reload();
7605
7475
  }
7606
7476
  };
@@ -7655,7 +7525,7 @@ var ProviderLoader = class _ProviderLoader {
7655
7525
  }
7656
7526
  const https = require("https");
7657
7527
  const { execSync: execSync7 } = require("child_process");
7658
- const metaPath = path7.join(this.upstreamDir, _ProviderLoader.META_FILE);
7528
+ const metaPath = path6.join(this.upstreamDir, _ProviderLoader.META_FILE);
7659
7529
  let prevEtag = "";
7660
7530
  let prevTimestamp = 0;
7661
7531
  try {
@@ -7672,7 +7542,7 @@ var ProviderLoader = class _ProviderLoader {
7672
7542
  return { updated: false };
7673
7543
  }
7674
7544
  try {
7675
- const etag = await new Promise((resolve10, reject) => {
7545
+ const etag = await new Promise((resolve9, reject) => {
7676
7546
  const options = {
7677
7547
  method: "HEAD",
7678
7548
  hostname: "github.com",
@@ -7690,7 +7560,7 @@ var ProviderLoader = class _ProviderLoader {
7690
7560
  headers: { "User-Agent": "adhdev-launcher" },
7691
7561
  timeout: 1e4
7692
7562
  }, (res2) => {
7693
- resolve10(res2.headers.etag || res2.headers["last-modified"] || "");
7563
+ resolve9(res2.headers.etag || res2.headers["last-modified"] || "");
7694
7564
  });
7695
7565
  req2.on("error", reject);
7696
7566
  req2.on("timeout", () => {
@@ -7699,7 +7569,7 @@ var ProviderLoader = class _ProviderLoader {
7699
7569
  });
7700
7570
  req2.end();
7701
7571
  } else {
7702
- resolve10(res.headers.etag || res.headers["last-modified"] || "");
7572
+ resolve9(res.headers.etag || res.headers["last-modified"] || "");
7703
7573
  }
7704
7574
  });
7705
7575
  req.on("error", reject);
@@ -7715,17 +7585,17 @@ var ProviderLoader = class _ProviderLoader {
7715
7585
  return { updated: false };
7716
7586
  }
7717
7587
  this.log("Downloading latest providers from GitHub...");
7718
- const tmpTar = path7.join(os7.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
7719
- const tmpExtract = path7.join(os7.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
7588
+ const tmpTar = path6.join(os7.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
7589
+ const tmpExtract = path6.join(os7.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
7720
7590
  await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
7721
7591
  fs5.mkdirSync(tmpExtract, { recursive: true });
7722
7592
  execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
7723
7593
  const extracted = fs5.readdirSync(tmpExtract);
7724
7594
  const rootDir = extracted.find(
7725
- (d) => fs5.statSync(path7.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
7595
+ (d) => fs5.statSync(path6.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
7726
7596
  );
7727
7597
  if (!rootDir) throw new Error("Unexpected tarball structure");
7728
- const sourceDir = path7.join(tmpExtract, rootDir);
7598
+ const sourceDir = path6.join(tmpExtract, rootDir);
7729
7599
  const backupDir = this.upstreamDir + ".bak";
7730
7600
  if (fs5.existsSync(this.upstreamDir)) {
7731
7601
  if (fs5.existsSync(backupDir)) fs5.rmSync(backupDir, { recursive: true, force: true });
@@ -7763,7 +7633,7 @@ var ProviderLoader = class _ProviderLoader {
7763
7633
  downloadFile(url, destPath) {
7764
7634
  const https = require("https");
7765
7635
  const http3 = require("http");
7766
- return new Promise((resolve10, reject) => {
7636
+ return new Promise((resolve9, reject) => {
7767
7637
  const doRequest = (reqUrl, redirectCount = 0) => {
7768
7638
  if (redirectCount > 5) {
7769
7639
  reject(new Error("Too many redirects"));
@@ -7783,7 +7653,7 @@ var ProviderLoader = class _ProviderLoader {
7783
7653
  res.pipe(ws);
7784
7654
  ws.on("finish", () => {
7785
7655
  ws.close();
7786
- resolve10();
7656
+ resolve9();
7787
7657
  });
7788
7658
  ws.on("error", reject);
7789
7659
  });
@@ -7800,8 +7670,8 @@ var ProviderLoader = class _ProviderLoader {
7800
7670
  copyDirRecursive(src, dest) {
7801
7671
  fs5.mkdirSync(dest, { recursive: true });
7802
7672
  for (const entry of fs5.readdirSync(src, { withFileTypes: true })) {
7803
- const srcPath = path7.join(src, entry.name);
7804
- const destPath = path7.join(dest, entry.name);
7673
+ const srcPath = path6.join(src, entry.name);
7674
+ const destPath = path6.join(dest, entry.name);
7805
7675
  if (entry.isDirectory()) {
7806
7676
  this.copyDirRecursive(srcPath, destPath);
7807
7677
  } else {
@@ -7812,7 +7682,7 @@ var ProviderLoader = class _ProviderLoader {
7812
7682
  /** .meta.json save */
7813
7683
  writeMeta(metaPath, etag, timestamp) {
7814
7684
  try {
7815
- fs5.mkdirSync(path7.dirname(metaPath), { recursive: true });
7685
+ fs5.mkdirSync(path6.dirname(metaPath), { recursive: true });
7816
7686
  fs5.writeFileSync(metaPath, JSON.stringify({
7817
7687
  etag,
7818
7688
  timestamp,
@@ -7829,7 +7699,7 @@ var ProviderLoader = class _ProviderLoader {
7829
7699
  const scan = (d) => {
7830
7700
  try {
7831
7701
  for (const entry of fs5.readdirSync(d, { withFileTypes: true })) {
7832
- if (entry.isDirectory()) scan(path7.join(d, entry.name));
7702
+ if (entry.isDirectory()) scan(path6.join(d, entry.name));
7833
7703
  else if (entry.name === "provider.json") count++;
7834
7704
  }
7835
7705
  } catch {
@@ -7928,17 +7798,17 @@ var ProviderLoader = class _ProviderLoader {
7928
7798
  for (const root of searchRoots) {
7929
7799
  if (!fs5.existsSync(root)) continue;
7930
7800
  const candidate = this.getProviderDir(root, cat, type);
7931
- if (fs5.existsSync(path7.join(candidate, "provider.json"))) return candidate;
7932
- const catDir = path7.join(root, cat);
7801
+ if (fs5.existsSync(path6.join(candidate, "provider.json"))) return candidate;
7802
+ const catDir = path6.join(root, cat);
7933
7803
  if (fs5.existsSync(catDir)) {
7934
7804
  try {
7935
7805
  for (const entry of fs5.readdirSync(catDir, { withFileTypes: true })) {
7936
7806
  if (!entry.isDirectory()) continue;
7937
- const jsonPath = path7.join(catDir, entry.name, "provider.json");
7807
+ const jsonPath = path6.join(catDir, entry.name, "provider.json");
7938
7808
  if (fs5.existsSync(jsonPath)) {
7939
7809
  try {
7940
7810
  const data = JSON.parse(fs5.readFileSync(jsonPath, "utf-8"));
7941
- if (data.type === type) return path7.join(catDir, entry.name);
7811
+ if (data.type === type) return path6.join(catDir, entry.name);
7942
7812
  } catch {
7943
7813
  }
7944
7814
  }
@@ -7955,7 +7825,7 @@ var ProviderLoader = class _ProviderLoader {
7955
7825
  * (template substitution is NOT applied here — scripts.js handles that)
7956
7826
  */
7957
7827
  buildScriptWrappersFromDir(dir) {
7958
- const scriptsJs = path7.join(dir, "scripts.js");
7828
+ const scriptsJs = path6.join(dir, "scripts.js");
7959
7829
  if (fs5.existsSync(scriptsJs)) {
7960
7830
  try {
7961
7831
  delete require.cache[require.resolve(scriptsJs)];
@@ -7969,7 +7839,7 @@ var ProviderLoader = class _ProviderLoader {
7969
7839
  for (const file of fs5.readdirSync(dir)) {
7970
7840
  if (!file.endsWith(".js")) continue;
7971
7841
  const scriptName = toCamel(file.replace(".js", ""));
7972
- const filePath = path7.join(dir, file);
7842
+ const filePath = path6.join(dir, file);
7973
7843
  result[scriptName] = (...args) => {
7974
7844
  try {
7975
7845
  let content = fs5.readFileSync(filePath, "utf-8");
@@ -8029,7 +7899,7 @@ var ProviderLoader = class _ProviderLoader {
8029
7899
  }
8030
7900
  const hasJson = entries.some((e) => e.name === "provider.json");
8031
7901
  if (hasJson) {
8032
- const jsonPath = path7.join(d, "provider.json");
7902
+ const jsonPath = path6.join(d, "provider.json");
8033
7903
  try {
8034
7904
  const raw = fs5.readFileSync(jsonPath, "utf-8");
8035
7905
  const mod = JSON.parse(raw);
@@ -8042,7 +7912,7 @@ var ProviderLoader = class _ProviderLoader {
8042
7912
  delete mod.extensionIdPattern_flags;
8043
7913
  }
8044
7914
  const hasCompatibility = Array.isArray(mod.compatibility);
8045
- const scriptsPath = path7.join(d, "scripts.js");
7915
+ const scriptsPath = path6.join(d, "scripts.js");
8046
7916
  if (!hasCompatibility && fs5.existsSync(scriptsPath)) {
8047
7917
  try {
8048
7918
  delete require.cache[require.resolve(scriptsPath)];
@@ -8068,7 +7938,7 @@ var ProviderLoader = class _ProviderLoader {
8068
7938
  if (!entry.isDirectory()) continue;
8069
7939
  if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
8070
7940
  if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
8071
- scan(path7.join(d, entry.name));
7941
+ scan(path6.join(d, entry.name));
8072
7942
  }
8073
7943
  }
8074
7944
  };
@@ -8148,17 +8018,17 @@ async function findFreePort(ports) {
8148
8018
  throw new Error("No free port found");
8149
8019
  }
8150
8020
  function checkPortFree(port) {
8151
- return new Promise((resolve10) => {
8021
+ return new Promise((resolve9) => {
8152
8022
  const server = net.createServer();
8153
8023
  server.unref();
8154
- server.on("error", () => resolve10(false));
8024
+ server.on("error", () => resolve9(false));
8155
8025
  server.listen(port, "127.0.0.1", () => {
8156
- server.close(() => resolve10(true));
8026
+ server.close(() => resolve9(true));
8157
8027
  });
8158
8028
  });
8159
8029
  }
8160
8030
  async function isCdpActive(port) {
8161
- return new Promise((resolve10) => {
8031
+ return new Promise((resolve9) => {
8162
8032
  const req = require("http").get(`http://127.0.0.1:${port}/json/version`, {
8163
8033
  timeout: 2e3
8164
8034
  }, (res) => {
@@ -8167,16 +8037,16 @@ async function isCdpActive(port) {
8167
8037
  res.on("end", () => {
8168
8038
  try {
8169
8039
  const info = JSON.parse(data);
8170
- resolve10(!!info["WebKit-Version"] || !!info["Browser"]);
8040
+ resolve9(!!info["WebKit-Version"] || !!info["Browser"]);
8171
8041
  } catch {
8172
- resolve10(false);
8042
+ resolve9(false);
8173
8043
  }
8174
8044
  });
8175
8045
  });
8176
- req.on("error", () => resolve10(false));
8046
+ req.on("error", () => resolve9(false));
8177
8047
  req.on("timeout", () => {
8178
8048
  req.destroy();
8179
- resolve10(false);
8049
+ resolve9(false);
8180
8050
  });
8181
8051
  });
8182
8052
  }
@@ -8295,8 +8165,8 @@ function detectCurrentWorkspace(ideId) {
8295
8165
  const appNameMap = getMacAppIdentifiers();
8296
8166
  const appName = appNameMap[ideId];
8297
8167
  if (appName) {
8298
- const storagePath = path8.join(
8299
- process.env.APPDATA || path8.join(os8.homedir(), "AppData", "Roaming"),
8168
+ const storagePath = path7.join(
8169
+ process.env.APPDATA || path7.join(os8.homedir(), "AppData", "Roaming"),
8300
8170
  appName,
8301
8171
  "storage.json"
8302
8172
  );
@@ -8465,15 +8335,13 @@ function getAvailableIdeIds() {
8465
8335
 
8466
8336
  // src/commands/router.ts
8467
8337
  init_config();
8468
- init_workspaces();
8469
- init_config();
8470
8338
  init_logger();
8471
8339
 
8472
8340
  // src/logging/command-log.ts
8473
8341
  var fs6 = __toESM(require("fs"));
8474
- var path9 = __toESM(require("path"));
8342
+ var path8 = __toESM(require("path"));
8475
8343
  var os9 = __toESM(require("os"));
8476
- var LOG_DIR2 = process.platform === "win32" ? path9.join(process.env.LOCALAPPDATA || process.env.APPDATA || path9.join(os9.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path9.join(os9.homedir(), "Library", "Logs", "adhdev") : path9.join(os9.homedir(), ".local", "share", "adhdev", "logs");
8344
+ var LOG_DIR2 = process.platform === "win32" ? path8.join(process.env.LOCALAPPDATA || process.env.APPDATA || path8.join(os9.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path8.join(os9.homedir(), "Library", "Logs", "adhdev") : path8.join(os9.homedir(), ".local", "share", "adhdev", "logs");
8477
8345
  var MAX_FILE_SIZE = 5 * 1024 * 1024;
8478
8346
  var MAX_DAYS = 7;
8479
8347
  try {
@@ -8511,13 +8379,13 @@ function getDateStr2() {
8511
8379
  return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
8512
8380
  }
8513
8381
  var currentDate2 = getDateStr2();
8514
- var currentFile = path9.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
8382
+ var currentFile = path8.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
8515
8383
  var writeCount2 = 0;
8516
8384
  function checkRotation() {
8517
8385
  const today = getDateStr2();
8518
8386
  if (today !== currentDate2) {
8519
8387
  currentDate2 = today;
8520
- currentFile = path9.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
8388
+ currentFile = path8.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
8521
8389
  cleanOldFiles();
8522
8390
  }
8523
8391
  }
@@ -8531,7 +8399,7 @@ function cleanOldFiles() {
8531
8399
  const dateMatch = file.match(/commands-(\d{4}-\d{2}-\d{2})/);
8532
8400
  if (dateMatch && dateMatch[1] < cutoffStr) {
8533
8401
  try {
8534
- fs6.unlinkSync(path9.join(LOG_DIR2, file));
8402
+ fs6.unlinkSync(path8.join(LOG_DIR2, file));
8535
8403
  } catch {
8536
8404
  }
8537
8405
  }
@@ -8553,59 +8421,202 @@ function checkSize() {
8553
8421
  } catch {
8554
8422
  }
8555
8423
  }
8556
- var SKIP_COMMANDS = /* @__PURE__ */ new Set([
8557
- "heartbeat",
8558
- "status_report"
8559
- ]);
8560
- function logCommand(entry) {
8561
- if (SKIP_COMMANDS.has(entry.cmd)) return;
8562
- try {
8563
- if (++writeCount2 % 500 === 0) {
8564
- checkRotation();
8565
- checkSize();
8566
- }
8567
- const line = JSON.stringify({
8568
- ts: entry.ts,
8569
- cmd: entry.cmd,
8570
- src: entry.source,
8571
- ...entry.args ? { args: maskArgs(entry.args) } : {},
8572
- ...entry.success !== void 0 ? { ok: entry.success } : {},
8573
- ...entry.error ? { err: entry.error } : {},
8574
- ...entry.durationMs !== void 0 ? { ms: entry.durationMs } : {}
8575
- });
8576
- fs6.appendFileSync(currentFile, line + "\n");
8577
- } catch {
8424
+ var SKIP_COMMANDS = /* @__PURE__ */ new Set([
8425
+ "heartbeat",
8426
+ "status_report"
8427
+ ]);
8428
+ function logCommand(entry) {
8429
+ if (SKIP_COMMANDS.has(entry.cmd)) return;
8430
+ try {
8431
+ if (++writeCount2 % 500 === 0) {
8432
+ checkRotation();
8433
+ checkSize();
8434
+ }
8435
+ const line = JSON.stringify({
8436
+ ts: entry.ts,
8437
+ cmd: entry.cmd,
8438
+ src: entry.source,
8439
+ ...entry.args ? { args: maskArgs(entry.args) } : {},
8440
+ ...entry.success !== void 0 ? { ok: entry.success } : {},
8441
+ ...entry.error ? { err: entry.error } : {},
8442
+ ...entry.durationMs !== void 0 ? { ms: entry.durationMs } : {}
8443
+ });
8444
+ fs6.appendFileSync(currentFile, line + "\n");
8445
+ } catch {
8446
+ }
8447
+ }
8448
+ function getRecentCommands(count = 50) {
8449
+ try {
8450
+ if (!fs6.existsSync(currentFile)) return [];
8451
+ const content = fs6.readFileSync(currentFile, "utf-8");
8452
+ const lines = content.trim().split("\n").filter(Boolean);
8453
+ return lines.slice(-count).map((line) => {
8454
+ try {
8455
+ const parsed = JSON.parse(line);
8456
+ return {
8457
+ ts: parsed.ts,
8458
+ cmd: parsed.cmd,
8459
+ source: parsed.src,
8460
+ args: parsed.args,
8461
+ success: parsed.ok,
8462
+ error: parsed.err,
8463
+ durationMs: parsed.ms
8464
+ };
8465
+ } catch {
8466
+ return { ts: "", cmd: "parse_error", source: "unknown" };
8467
+ }
8468
+ });
8469
+ } catch {
8470
+ return [];
8471
+ }
8472
+ }
8473
+ cleanOldFiles();
8474
+
8475
+ // src/commands/router.ts
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" };
8578
8539
  }
8540
+ const unread = completionMarker ? completionMarker !== seenCompletionMarker : hasContentChange && lastUsedAt > lastSeenAt && lastRole !== "user" && lastRole !== "human";
8541
+ return { unread, inboxBucket: unread ? "task_complete" : "idle" };
8579
8542
  }
8580
- function getRecentCommands(count = 50) {
8581
- try {
8582
- if (!fs6.existsSync(currentFile)) return [];
8583
- const content = fs6.readFileSync(currentFile, "utf-8");
8584
- const lines = content.trim().split("\n").filter(Boolean);
8585
- return lines.slice(-count).map((line) => {
8586
- try {
8587
- const parsed = JSON.parse(line);
8588
- return {
8589
- ts: parsed.ts,
8590
- cmd: parsed.cmd,
8591
- source: parsed.src,
8592
- args: parsed.args,
8593
- success: parsed.ok,
8594
- error: parsed.err,
8595
- durationMs: parsed.ms
8596
- };
8597
- } catch {
8598
- return { ts: "", cmd: "parse_error", source: "unknown" };
8599
- }
8600
- });
8601
- } catch {
8602
- return [];
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
+ }
8603
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
+ };
8604
8617
  }
8605
- cleanOldFiles();
8606
8618
 
8607
8619
  // src/commands/router.ts
8608
- init_logger();
8609
8620
  var fs7 = __toESM(require("fs"));
8610
8621
  var CHAT_COMMANDS = [
8611
8622
  "send_chat",
@@ -8614,6 +8625,7 @@ var CHAT_COMMANDS = [
8614
8625
  "set_mode",
8615
8626
  "change_model"
8616
8627
  ];
8628
+ var READ_DEBUG_ENABLED2 = process.argv.includes("--dev") || process.env.ADHDEV_READ_DEBUG === "1";
8617
8629
  var DaemonCommandRouter = class {
8618
8630
  deps;
8619
8631
  constructor(deps) {
@@ -8732,18 +8744,6 @@ var DaemonCommandRouter = class {
8732
8744
  };
8733
8745
  LOG.info("LaunchIDE", `target=${ideKey || "auto"}`);
8734
8746
  const result = await launchWithCdp(launchArgs);
8735
- if (result.success && (result.ideId || ideKey)) {
8736
- try {
8737
- addCliHistory({
8738
- category: "ide",
8739
- cliType: result.ideId || ideKey,
8740
- dir: resolvedWorkspace || "",
8741
- workspace: resolvedWorkspace || "",
8742
- newWindow: args?.newWindow === true
8743
- });
8744
- } catch {
8745
- }
8746
- }
8747
8747
  if (result.success && result.port && result.ideId && !this.deps.cdpManagers.has(result.ideId)) {
8748
8748
  const logFn = this.deps.getCdpLogFn ? this.deps.getCdpLogFn(result.ideId) : LOG.forComponent(`CDP:${result.ideId}`).asLogFn();
8749
8749
  const provider = this.deps.providerLoader.getMeta(result.ideId);
@@ -8760,11 +8760,7 @@ var DaemonCommandRouter = class {
8760
8760
  this.deps.onIdeConnected?.();
8761
8761
  if (result.success && resolvedWorkspace) {
8762
8762
  try {
8763
- let next = appendWorkspaceActivity(loadConfig(), resolvedWorkspace, {
8764
- kind: "ide",
8765
- agentType: result.ideId
8766
- });
8767
- next = appendRecentActivity(next, {
8763
+ const next = appendRecentActivity(loadConfig(), {
8768
8764
  kind: "ide",
8769
8765
  providerType: result.ideId || ideKey,
8770
8766
  providerName: result.ideId || ideKey,
@@ -8800,28 +8796,35 @@ var DaemonCommandRouter = class {
8800
8796
  updateConfig({ userName: name });
8801
8797
  return { success: true, userName: name };
8802
8798
  }
8803
- case "mark_recent_seen": {
8804
- const kind = args?.kind;
8805
- const providerType = args?.providerType;
8806
- if (!kind || !providerType) {
8807
- 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" };
8808
8803
  }
8809
- const recentKey = args?.recentKey || buildRecentActivityKey({
8810
- kind,
8811
- providerType,
8812
- workspace: args?.workspace || null
8813
- });
8814
- const next = markRecentSessionSeen(
8815
- loadConfig(),
8816
- recentKey,
8817
- typeof args?.seenAt === "number" ? args.seenAt : Date.now()
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
8818
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
+ }
8819
8821
  saveConfig(next);
8820
8822
  this.deps.onStatusChange?.();
8821
8823
  return {
8822
8824
  success: true,
8823
- recentKey,
8824
- seenAt: next.recentSessionReads?.[recentKey] || Date.now()
8825
+ sessionId,
8826
+ seenAt: next.sessionReads?.[sessionId] || Date.now(),
8827
+ completionMarker
8825
8828
  };
8826
8829
  }
8827
8830
  // ─── Daemon Self-Upgrade ───
@@ -8842,9 +8845,9 @@ var DaemonCommandRouter = class {
8842
8845
  setTimeout(() => {
8843
8846
  LOG.info("Upgrade", "Restarting daemon with new version...");
8844
8847
  try {
8845
- const path16 = require("path");
8848
+ const path15 = require("path");
8846
8849
  const fs12 = require("fs");
8847
- const pidFile = path16.join(process.env.HOME || process.env.USERPROFILE || "", ".adhdev", "daemon.pid");
8850
+ const pidFile = path15.join(process.env.HOME || process.env.USERPROFILE || "", ".adhdev", "daemon.pid");
8848
8851
  if (fs12.existsSync(pidFile)) fs12.unlinkSync(pidFile);
8849
8852
  } catch {
8850
8853
  }
@@ -8938,183 +8941,6 @@ var DaemonCommandRouter = class {
8938
8941
 
8939
8942
  // src/status/reporter.ts
8940
8943
  init_logger();
8941
-
8942
- // src/status/snapshot.ts
8943
- var os10 = __toESM(require("os"));
8944
- init_config();
8945
- init_workspaces();
8946
- init_terminal_screen();
8947
- function buildDetectedIdeInfos(detectedIdes, cdpManagers) {
8948
- return detectedIdes.filter((ide) => ide.installed !== false).map((ide) => ({
8949
- id: ide.id,
8950
- type: ide.id,
8951
- name: ide.displayName || ide.name || ide.id,
8952
- running: isCdpConnected(cdpManagers, ide.id),
8953
- ...ide.path ? { path: ide.path } : {}
8954
- }));
8955
- }
8956
- function buildAvailableProviders(providerLoader) {
8957
- return providerLoader.getAll().map((provider) => ({
8958
- type: provider.type,
8959
- name: provider.displayName || provider.type,
8960
- displayName: provider.displayName || provider.type,
8961
- icon: provider.icon || "\u{1F4BB}",
8962
- category: provider.category
8963
- }));
8964
- }
8965
- function parseMessageTime(value) {
8966
- if (typeof value === "number" && Number.isFinite(value)) return value;
8967
- if (typeof value === "string") {
8968
- const parsed = Date.parse(value);
8969
- if (Number.isFinite(parsed)) return parsed;
8970
- }
8971
- return 0;
8972
- }
8973
- function getSessionMessageUpdatedAt(session) {
8974
- const lastMessage = session.activeChat?.messages?.at?.(-1);
8975
- if (!lastMessage) return 0;
8976
- return parseMessageTime(lastMessage.timestamp) || parseMessageTime(lastMessage.receivedAt) || parseMessageTime(lastMessage.createdAt) || 0;
8977
- }
8978
- function getSessionLastUsedAt(session) {
8979
- return getSessionMessageUpdatedAt(session) || session.lastUpdated || Date.now();
8980
- }
8981
- function getSessionKind(session) {
8982
- return session.transport === "cdp-page" || session.transport === "cdp-webview" ? "ide" : session.transport === "acp" ? "acp" : "cli";
8983
- }
8984
- function getLastMessageRole(session) {
8985
- const role = session.activeChat?.messages?.at?.(-1)?.role;
8986
- return typeof role === "string" ? role : "";
8987
- }
8988
- function getUnreadState(hasContentChange, status, lastUsedAt, lastSeenAt, lastRole) {
8989
- if (status === "waiting_approval") {
8990
- return { unread: false, inboxBucket: "needs_attention" };
8991
- }
8992
- if (status === "generating" || status === "starting") {
8993
- return { unread: false, inboxBucket: "working" };
8994
- }
8995
- const unread = hasContentChange && lastUsedAt > lastSeenAt && lastRole !== "user" && lastRole !== "human";
8996
- return { unread, inboxBucket: unread ? "task_complete" : "idle" };
8997
- }
8998
- function buildRecentSessions(sessions, recentActivity, readState) {
8999
- const live = sessions.filter((session) => !session.parentId && session.status !== "stopped").map((session) => {
9000
- const kind = getSessionKind(session);
9001
- const recentKey = buildRecentActivityKey({
9002
- kind,
9003
- providerType: session.providerType,
9004
- workspace: session.workspace
9005
- });
9006
- const lastSeenAt = readState[recentKey] || 0;
9007
- const lastUsedAt = getSessionLastUsedAt(session);
9008
- const { unread, inboxBucket } = getUnreadState(
9009
- getSessionMessageUpdatedAt(session) > 0,
9010
- session.status,
9011
- lastUsedAt,
9012
- lastSeenAt,
9013
- getLastMessageRole(session)
9014
- );
9015
- return {
9016
- id: session.id,
9017
- recentKey,
9018
- sessionId: session.id,
9019
- providerType: session.providerType,
9020
- providerName: session.providerName,
9021
- kind,
9022
- title: session.activeChat?.title || session.title || session.providerName,
9023
- workspace: session.workspace,
9024
- currentModel: session.currentModel,
9025
- status: session.status,
9026
- lastUsedAt,
9027
- unread,
9028
- lastSeenAt,
9029
- inboxBucket
9030
- };
9031
- });
9032
- const seen = new Set(live.map((item) => `${item.kind}:${item.providerType}:${item.workspace || ""}`));
9033
- const persisted = recentActivity.filter((item) => !seen.has(`${item.kind}:${item.providerType}:${item.workspace || ""}`)).map((item) => {
9034
- const lastSeenAt = readState[item.id] || 0;
9035
- const unread = item.lastUsedAt > lastSeenAt;
9036
- return {
9037
- id: item.id,
9038
- recentKey: item.id,
9039
- sessionId: item.sessionId || null,
9040
- providerType: item.providerType,
9041
- providerName: item.providerName,
9042
- kind: item.kind,
9043
- title: item.title || item.providerName,
9044
- workspace: item.workspace,
9045
- currentModel: item.currentModel,
9046
- lastUsedAt: item.lastUsedAt,
9047
- unread,
9048
- lastSeenAt,
9049
- inboxBucket: unread ? "task_complete" : "idle"
9050
- };
9051
- });
9052
- return [...live, ...persisted].sort((a, b) => b.lastUsedAt - a.lastUsedAt).slice(0, 12);
9053
- }
9054
- function buildStatusSnapshot(options) {
9055
- const cfg = loadConfig();
9056
- const wsState = getWorkspaceState(cfg);
9057
- const memSnap = getHostMemorySnapshot();
9058
- const recentActivity = getRecentActivity(cfg, 20);
9059
- const sessions = buildSessionEntries(
9060
- options.allStates,
9061
- options.cdpManagers
9062
- );
9063
- const readState = cfg.recentSessionReads || {};
9064
- for (const session of sessions) {
9065
- const kind = getSessionKind(session);
9066
- const recentKey = buildRecentActivityKey({
9067
- kind,
9068
- providerType: session.providerType,
9069
- workspace: session.workspace
9070
- });
9071
- const lastSeenAt = getRecentSessionSeenAt(cfg, recentKey);
9072
- const lastUsedAt = getSessionLastUsedAt(session);
9073
- const { unread, inboxBucket } = getUnreadState(
9074
- getSessionMessageUpdatedAt(session) > 0,
9075
- session.status,
9076
- lastUsedAt,
9077
- lastSeenAt,
9078
- getLastMessageRole(session)
9079
- );
9080
- session.recentKey = recentKey;
9081
- session.lastSeenAt = lastSeenAt;
9082
- session.unread = unread;
9083
- session.inboxBucket = inboxBucket;
9084
- }
9085
- const terminalBackend = getTerminalBackendRuntimeStatus();
9086
- return {
9087
- instanceId: options.instanceId,
9088
- version: options.version,
9089
- daemonMode: options.daemonMode,
9090
- machine: {
9091
- hostname: os10.hostname(),
9092
- platform: os10.platform(),
9093
- arch: os10.arch(),
9094
- cpus: os10.cpus().length,
9095
- totalMem: memSnap.totalMem,
9096
- freeMem: memSnap.freeMem,
9097
- availableMem: memSnap.availableMem,
9098
- loadavg: os10.loadavg(),
9099
- uptime: os10.uptime(),
9100
- release: os10.release()
9101
- },
9102
- machineNickname: options.machineNickname ?? cfg.machineNickname ?? null,
9103
- timestamp: options.timestamp ?? Date.now(),
9104
- detectedIdes: buildDetectedIdeInfos(options.detectedIdes, options.cdpManagers),
9105
- ...options.p2p ? { p2p: options.p2p } : {},
9106
- sessions,
9107
- workspaces: wsState.workspaces,
9108
- defaultWorkspaceId: wsState.defaultWorkspaceId,
9109
- defaultWorkspacePath: wsState.defaultWorkspacePath,
9110
- workspaceActivity: getWorkspaceActivity(cfg, 15),
9111
- recentSessions: buildRecentSessions(sessions, recentActivity, readState),
9112
- terminalBackend,
9113
- availableProviders: buildAvailableProviders(options.providerLoader)
9114
- };
9115
- }
9116
-
9117
- // src/status/reporter.ts
9118
8944
  var DaemonStatusReporter = class {
9119
8945
  deps;
9120
8946
  log;
@@ -9262,10 +9088,11 @@ var DaemonStatusReporter = class {
9262
9088
  currentModel: session.currentModel,
9263
9089
  currentPlan: session.currentPlan,
9264
9090
  currentAutoApprove: session.currentAutoApprove,
9265
- recentKey: session.recentKey,
9091
+ lastUpdated: session.lastUpdated,
9266
9092
  unread: session.unread,
9267
9093
  lastSeenAt: session.lastSeenAt,
9268
9094
  inboxBucket: session.inboxBucket,
9095
+ surfaceHidden: session.surfaceHidden,
9269
9096
  controlValues: session.controlValues,
9270
9097
  providerControls: session.providerControls,
9271
9098
  acpConfigOptions: session.acpConfigOptions,
@@ -9307,12 +9134,11 @@ init_logger();
9307
9134
 
9308
9135
  // src/commands/cli-manager.ts
9309
9136
  var os13 = __toESM(require("os"));
9310
- var path11 = __toESM(require("path"));
9137
+ var path10 = __toESM(require("path"));
9311
9138
  var crypto4 = __toESM(require("crypto"));
9312
9139
  var import_chalk = __toESM(require("chalk"));
9313
9140
  init_provider_cli_adapter();
9314
9141
  init_config();
9315
- init_workspaces();
9316
9142
 
9317
9143
  // src/providers/cli-provider-instance.ts
9318
9144
  var crypto3 = __toESM(require("crypto"));
@@ -9988,13 +9814,13 @@ var AcpProviderInstance = class {
9988
9814
  }
9989
9815
  this.currentStatus = "waiting_approval";
9990
9816
  this.detectStatusTransition();
9991
- const approved = await new Promise((resolve10) => {
9992
- this.permissionResolvers.push(resolve10);
9817
+ const approved = await new Promise((resolve9) => {
9818
+ this.permissionResolvers.push(resolve9);
9993
9819
  setTimeout(() => {
9994
- const idx = this.permissionResolvers.indexOf(resolve10);
9820
+ const idx = this.permissionResolvers.indexOf(resolve9);
9995
9821
  if (idx >= 0) {
9996
9822
  this.permissionResolvers.splice(idx, 1);
9997
- resolve10(false);
9823
+ resolve9(false);
9998
9824
  }
9999
9825
  }, 3e5);
10000
9826
  });
@@ -10469,24 +10295,6 @@ var DaemonCliManager = class {
10469
10295
  const hash = require("crypto").createHash("md5").update(require("path").resolve(dir)).digest("hex").slice(0, 8);
10470
10296
  return `${cliType}_${hash}`;
10471
10297
  }
10472
- persistRecentDir(cliType, dir) {
10473
- try {
10474
- const normalizedType = this.providerLoader.resolveAlias(cliType);
10475
- const provider = this.providerLoader.getByAlias(cliType);
10476
- const actKind = provider?.category === "acp" ? "acp" : "cli";
10477
- let next = loadConfig();
10478
- console.log(colorize("cyan", ` \u{1F4C2} Saving recent workspace: ${dir}`));
10479
- const recent = next.recentCliWorkspaces || [];
10480
- if (!recent.includes(dir)) {
10481
- next = { ...next, recentCliWorkspaces: [dir, ...recent].slice(0, 10) };
10482
- }
10483
- next = appendWorkspaceActivity(next, dir, { kind: actKind, agentType: normalizedType });
10484
- saveConfig(next);
10485
- console.log(colorize("green", ` \u2713 Recent workspace saved: ${dir}`));
10486
- } catch (e) {
10487
- console.error(colorize("red", ` \u2717 Failed to save recent workspace: ${e}`));
10488
- }
10489
- }
10490
10298
  persistRecentActivity(entry) {
10491
10299
  try {
10492
10300
  saveConfig(appendRecentActivity(loadConfig(), entry));
@@ -10576,7 +10384,7 @@ var DaemonCliManager = class {
10576
10384
  async startSession(cliType, workingDir, cliArgs, initialModel) {
10577
10385
  const trimmed = (workingDir || "").trim();
10578
10386
  if (!trimmed) throw new Error("working directory required");
10579
- const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) : path11.resolve(trimmed);
10387
+ const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) : path10.resolve(trimmed);
10580
10388
  const normalizedType = this.providerLoader.resolveAlias(cliType);
10581
10389
  const provider = this.providerLoader.getByAlias(cliType);
10582
10390
  const key = crypto4.randomUUID();
@@ -10647,11 +10455,6 @@ ${installInfo}`
10647
10455
  LOG.warn("CLI", `[ACP] Initial model set failed: ${e?.message}`);
10648
10456
  }
10649
10457
  }
10650
- try {
10651
- addCliHistory({ category: "acp", cliType: normalizedType, dir: resolvedDir, workspace: resolvedDir, cliArgs, model: initialModel });
10652
- } catch (e) {
10653
- LOG.warn("CLI", `ACP history save failed: ${e?.message}`);
10654
- }
10655
10458
  this.persistRecentActivity({
10656
10459
  kind: "acp",
10657
10460
  providerType: normalizedType,
@@ -10718,11 +10521,6 @@ ${installInfo}`
10718
10521
  this.adapters.set(key, adapter);
10719
10522
  console.log(colorize("green", ` \u2713 CLI started: ${cliInfo.displayName} v${cliInfo.version || "unknown"} in ${resolvedDir}`));
10720
10523
  }
10721
- try {
10722
- addCliHistory({ category: "cli", cliType, dir: resolvedDir, workspace: resolvedDir, cliArgs, model: initialModel });
10723
- } catch (e) {
10724
- LOG.warn("CLI", `CLI history save failed: ${e?.message}`);
10725
- }
10726
10524
  this.persistRecentActivity({
10727
10525
  kind: "cli",
10728
10526
  providerType: normalizedType,
@@ -10875,7 +10673,6 @@ ${installInfo}`
10875
10673
  newKey = k;
10876
10674
  }
10877
10675
  }
10878
- this.persistRecentDir(cliType, dir);
10879
10676
  return { success: true, cliType, dir, id: newKey, launchSource };
10880
10677
  }
10881
10678
  case "stop_cli": {
@@ -10918,7 +10715,6 @@ ${installInfo}`
10918
10715
  const found = this.findAdapter(cliType, { instanceKey: args?.targetSessionId, dir });
10919
10716
  if (found) await this.stopSession(found.key);
10920
10717
  await this.startSession(cliType, dir);
10921
- this.persistRecentDir(cliType, dir);
10922
10718
  return { success: true, restarted: true };
10923
10719
  }
10924
10720
  case "agent_command": {
@@ -11741,11 +11537,11 @@ var ProviderInstanceManager = class {
11741
11537
 
11742
11538
  // src/providers/version-archive.ts
11743
11539
  var fs8 = __toESM(require("fs"));
11744
- var path12 = __toESM(require("path"));
11540
+ var path11 = __toESM(require("path"));
11745
11541
  var os14 = __toESM(require("os"));
11746
11542
  var import_child_process7 = require("child_process");
11747
11543
  var import_os3 = require("os");
11748
- var ARCHIVE_PATH = path12.join(os14.homedir(), ".adhdev", "version-history.json");
11544
+ var ARCHIVE_PATH = path11.join(os14.homedir(), ".adhdev", "version-history.json");
11749
11545
  var MAX_ENTRIES_PER_PROVIDER = 20;
11750
11546
  var VersionArchive = class {
11751
11547
  history = {};
@@ -11792,7 +11588,7 @@ var VersionArchive = class {
11792
11588
  }
11793
11589
  save() {
11794
11590
  try {
11795
- fs8.mkdirSync(path12.dirname(ARCHIVE_PATH), { recursive: true });
11591
+ fs8.mkdirSync(path11.dirname(ARCHIVE_PATH), { recursive: true });
11796
11592
  fs8.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
11797
11593
  } catch {
11798
11594
  }
@@ -11833,7 +11629,7 @@ function checkPathExists2(paths) {
11833
11629
  for (const p of paths) {
11834
11630
  if (p.includes("*")) {
11835
11631
  const home = os14.homedir();
11836
- const resolved = p.replace(/\*/g, home.split(path12.sep).pop() || "");
11632
+ const resolved = p.replace(/\*/g, home.split(path11.sep).pop() || "");
11837
11633
  if (fs8.existsSync(resolved)) return resolved;
11838
11634
  } else {
11839
11635
  if (fs8.existsSync(p)) return p;
@@ -11843,7 +11639,7 @@ function checkPathExists2(paths) {
11843
11639
  }
11844
11640
  function getMacAppVersion(appPath) {
11845
11641
  if ((0, import_os3.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
11846
- const plistPath = path12.join(appPath, "Contents", "Info.plist");
11642
+ const plistPath = path11.join(appPath, "Contents", "Info.plist");
11847
11643
  if (!fs8.existsSync(plistPath)) return null;
11848
11644
  const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
11849
11645
  return raw || null;
@@ -11870,7 +11666,7 @@ async function detectAllVersions(loader, archive) {
11870
11666
  const cliBin = provider.cli ? findBinary2(provider.cli) : null;
11871
11667
  let resolvedBin = cliBin;
11872
11668
  if (!resolvedBin && appPath && currentOs === "darwin") {
11873
- const bundled = path12.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
11669
+ const bundled = path11.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
11874
11670
  if (provider.cli && fs8.existsSync(bundled)) resolvedBin = bundled;
11875
11671
  }
11876
11672
  info.installed = !!(appPath || resolvedBin);
@@ -11911,7 +11707,7 @@ async function detectAllVersions(loader, archive) {
11911
11707
  // src/daemon/dev-server.ts
11912
11708
  var http2 = __toESM(require("http"));
11913
11709
  var fs11 = __toESM(require("fs"));
11914
- var path15 = __toESM(require("path"));
11710
+ var path14 = __toESM(require("path"));
11915
11711
 
11916
11712
  // src/daemon/scaffold-template.ts
11917
11713
  function generateFiles(type, name, category, opts = {}) {
@@ -12247,7 +12043,7 @@ init_logger();
12247
12043
 
12248
12044
  // src/daemon/dev-cdp-handlers.ts
12249
12045
  var fs9 = __toESM(require("fs"));
12250
- var path13 = __toESM(require("path"));
12046
+ var path12 = __toESM(require("path"));
12251
12047
  init_logger();
12252
12048
  async function handleCdpEvaluate(ctx, req, res) {
12253
12049
  const body = await ctx.readBody(req);
@@ -12426,17 +12222,17 @@ async function handleScriptHints(ctx, type, _req, res) {
12426
12222
  return;
12427
12223
  }
12428
12224
  let scriptsPath = "";
12429
- const directScripts = path13.join(dir, "scripts.js");
12225
+ const directScripts = path12.join(dir, "scripts.js");
12430
12226
  if (fs9.existsSync(directScripts)) {
12431
12227
  scriptsPath = directScripts;
12432
12228
  } else {
12433
- const scriptsDir = path13.join(dir, "scripts");
12229
+ const scriptsDir = path12.join(dir, "scripts");
12434
12230
  if (fs9.existsSync(scriptsDir)) {
12435
12231
  const versions = fs9.readdirSync(scriptsDir).filter((d) => {
12436
- return fs9.statSync(path13.join(scriptsDir, d)).isDirectory();
12232
+ return fs9.statSync(path12.join(scriptsDir, d)).isDirectory();
12437
12233
  }).sort().reverse();
12438
12234
  for (const ver of versions) {
12439
- const p = path13.join(scriptsDir, ver, "scripts.js");
12235
+ const p = path12.join(scriptsDir, ver, "scripts.js");
12440
12236
  if (fs9.existsSync(p)) {
12441
12237
  scriptsPath = p;
12442
12238
  break;
@@ -13491,7 +13287,7 @@ async function handleCliRaw(ctx, req, res) {
13491
13287
 
13492
13288
  // src/daemon/dev-auto-implement.ts
13493
13289
  var fs10 = __toESM(require("fs"));
13494
- var path14 = __toESM(require("path"));
13290
+ var path13 = __toESM(require("path"));
13495
13291
  var os15 = __toESM(require("os"));
13496
13292
  function getDefaultAutoImplReference(ctx, category, type) {
13497
13293
  if (category === "cli") {
@@ -13511,22 +13307,22 @@ function getLatestScriptVersionDir(scriptsDir) {
13511
13307
  if (!fs10.existsSync(scriptsDir)) return null;
13512
13308
  const versions = fs10.readdirSync(scriptsDir).filter((d) => {
13513
13309
  try {
13514
- return fs10.statSync(path14.join(scriptsDir, d)).isDirectory();
13310
+ return fs10.statSync(path13.join(scriptsDir, d)).isDirectory();
13515
13311
  } catch {
13516
13312
  return false;
13517
13313
  }
13518
13314
  }).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
13519
13315
  if (versions.length === 0) return null;
13520
- return path14.join(scriptsDir, versions[0]);
13316
+ return path13.join(scriptsDir, versions[0]);
13521
13317
  }
13522
13318
  function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
13523
- const canonicalUserDir = path14.resolve(ctx.providerLoader.getUserProviderDir(category, type));
13524
- const desiredDir = requestedDir ? path14.resolve(requestedDir) : canonicalUserDir;
13525
- const upstreamRoot = path14.resolve(ctx.providerLoader.getUpstreamDir());
13526
- if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path14.sep}`)) {
13319
+ const canonicalUserDir = path13.resolve(ctx.providerLoader.getUserProviderDir(category, type));
13320
+ const desiredDir = requestedDir ? path13.resolve(requestedDir) : canonicalUserDir;
13321
+ const upstreamRoot = path13.resolve(ctx.providerLoader.getUpstreamDir());
13322
+ if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path13.sep}`)) {
13527
13323
  return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
13528
13324
  }
13529
- if (path14.basename(desiredDir) !== type) {
13325
+ if (path13.basename(desiredDir) !== type) {
13530
13326
  return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
13531
13327
  }
13532
13328
  const sourceDir = ctx.findProviderDir(type);
@@ -13534,11 +13330,11 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
13534
13330
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
13535
13331
  }
13536
13332
  if (!fs10.existsSync(desiredDir)) {
13537
- fs10.mkdirSync(path14.dirname(desiredDir), { recursive: true });
13333
+ fs10.mkdirSync(path13.dirname(desiredDir), { recursive: true });
13538
13334
  fs10.cpSync(sourceDir, desiredDir, { recursive: true });
13539
13335
  ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
13540
13336
  }
13541
- const providerJson = path14.join(desiredDir, "provider.json");
13337
+ const providerJson = path13.join(desiredDir, "provider.json");
13542
13338
  if (!fs10.existsSync(providerJson)) {
13543
13339
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
13544
13340
  }
@@ -13561,13 +13357,13 @@ function loadAutoImplReferenceScripts(ctx, referenceType) {
13561
13357
  const refDir = ctx.findProviderDir(referenceType);
13562
13358
  if (!refDir || !fs10.existsSync(refDir)) return {};
13563
13359
  const referenceScripts = {};
13564
- const scriptsDir = path14.join(refDir, "scripts");
13360
+ const scriptsDir = path13.join(refDir, "scripts");
13565
13361
  const latestDir = getLatestScriptVersionDir(scriptsDir);
13566
13362
  if (!latestDir) return referenceScripts;
13567
13363
  for (const file of fs10.readdirSync(latestDir)) {
13568
13364
  if (!file.endsWith(".js")) continue;
13569
13365
  try {
13570
- referenceScripts[file] = fs10.readFileSync(path14.join(latestDir, file), "utf-8");
13366
+ referenceScripts[file] = fs10.readFileSync(path13.join(latestDir, file), "utf-8");
13571
13367
  } catch {
13572
13368
  }
13573
13369
  }
@@ -13618,9 +13414,9 @@ async function handleAutoImplement(ctx, type, req, res) {
13618
13414
  });
13619
13415
  const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
13620
13416
  const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference);
13621
- const tmpDir = path14.join(os15.tmpdir(), "adhdev-autoimpl");
13417
+ const tmpDir = path13.join(os15.tmpdir(), "adhdev-autoimpl");
13622
13418
  if (!fs10.existsSync(tmpDir)) fs10.mkdirSync(tmpDir, { recursive: true });
13623
- const promptFile = path14.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
13419
+ const promptFile = path13.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
13624
13420
  fs10.writeFileSync(promptFile, prompt, "utf-8");
13625
13421
  ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
13626
13422
  const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
@@ -13991,7 +13787,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
13991
13787
  setMode: "set_mode.js"
13992
13788
  };
13993
13789
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
13994
- const scriptsDir = path14.join(providerDir, "scripts");
13790
+ const scriptsDir = path13.join(providerDir, "scripts");
13995
13791
  const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
13996
13792
  if (latestScriptsDir) {
13997
13793
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -14002,7 +13798,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
14002
13798
  for (const file of fs10.readdirSync(latestScriptsDir)) {
14003
13799
  if (file.endsWith(".js") && targetFileNames.has(file)) {
14004
13800
  try {
14005
- const content = fs10.readFileSync(path14.join(latestScriptsDir, file), "utf-8");
13801
+ const content = fs10.readFileSync(path13.join(latestScriptsDir, file), "utf-8");
14006
13802
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
14007
13803
  lines.push("```javascript");
14008
13804
  lines.push(content);
@@ -14019,7 +13815,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
14019
13815
  lines.push("");
14020
13816
  for (const file of refFiles) {
14021
13817
  try {
14022
- const content = fs10.readFileSync(path14.join(latestScriptsDir, file), "utf-8");
13818
+ const content = fs10.readFileSync(path13.join(latestScriptsDir, file), "utf-8");
14023
13819
  lines.push(`### \`${file}\` \u{1F512}`);
14024
13820
  lines.push("```javascript");
14025
13821
  lines.push(content);
@@ -14060,10 +13856,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
14060
13856
  lines.push("");
14061
13857
  }
14062
13858
  }
14063
- const docsDir = path14.join(providerDir, "../../docs");
13859
+ const docsDir = path13.join(providerDir, "../../docs");
14064
13860
  const loadGuide = (name) => {
14065
13861
  try {
14066
- const p = path14.join(docsDir, name);
13862
+ const p = path13.join(docsDir, name);
14067
13863
  if (fs10.existsSync(p)) return fs10.readFileSync(p, "utf-8");
14068
13864
  } catch {
14069
13865
  }
@@ -14237,7 +14033,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
14237
14033
  parseApproval: "parse_approval.js"
14238
14034
  };
14239
14035
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
14240
- const scriptsDir = path14.join(providerDir, "scripts");
14036
+ const scriptsDir = path13.join(providerDir, "scripts");
14241
14037
  const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
14242
14038
  if (latestScriptsDir) {
14243
14039
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -14249,7 +14045,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
14249
14045
  if (!file.endsWith(".js")) continue;
14250
14046
  if (!targetFileNames.has(file)) continue;
14251
14047
  try {
14252
- const content = fs10.readFileSync(path14.join(latestScriptsDir, file), "utf-8");
14048
+ const content = fs10.readFileSync(path13.join(latestScriptsDir, file), "utf-8");
14253
14049
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
14254
14050
  lines.push("```javascript");
14255
14051
  lines.push(content);
@@ -14265,7 +14061,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
14265
14061
  lines.push("");
14266
14062
  for (const file of refFiles) {
14267
14063
  try {
14268
- const content = fs10.readFileSync(path14.join(latestScriptsDir, file), "utf-8");
14064
+ const content = fs10.readFileSync(path13.join(latestScriptsDir, file), "utf-8");
14269
14065
  lines.push(`### \`${file}\` \u{1F512}`);
14270
14066
  lines.push("```javascript");
14271
14067
  lines.push(content);
@@ -14298,10 +14094,10 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
14298
14094
  lines.push("");
14299
14095
  }
14300
14096
  }
14301
- const docsDir = path14.join(providerDir, "../../docs");
14097
+ const docsDir = path13.join(providerDir, "../../docs");
14302
14098
  const loadGuide = (name) => {
14303
14099
  try {
14304
- const p = path14.join(docsDir, name);
14100
+ const p = path13.join(docsDir, name);
14305
14101
  if (fs10.existsSync(p)) return fs10.readFileSync(p, "utf-8");
14306
14102
  } catch {
14307
14103
  }
@@ -14559,8 +14355,8 @@ var DevServer = class _DevServer {
14559
14355
  }
14560
14356
  getEndpointList() {
14561
14357
  return this.routes.map((r) => {
14562
- const path16 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
14563
- return `${r.method.padEnd(5)} ${path16}`;
14358
+ const path15 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
14359
+ return `${r.method.padEnd(5)} ${path15}`;
14564
14360
  });
14565
14361
  }
14566
14362
  async start(port = DEV_SERVER_PORT) {
@@ -14591,15 +14387,15 @@ var DevServer = class _DevServer {
14591
14387
  this.json(res, 500, { error: e.message });
14592
14388
  }
14593
14389
  });
14594
- return new Promise((resolve10, reject) => {
14390
+ return new Promise((resolve9, reject) => {
14595
14391
  this.server.listen(port, "127.0.0.1", () => {
14596
14392
  this.log(`Dev server listening on http://127.0.0.1:${port}`);
14597
- resolve10();
14393
+ resolve9();
14598
14394
  });
14599
14395
  this.server.on("error", (e) => {
14600
14396
  if (e.code === "EADDRINUSE") {
14601
14397
  this.log(`Port ${port} in use, skipping dev server`);
14602
- resolve10();
14398
+ resolve9();
14603
14399
  } else {
14604
14400
  reject(e);
14605
14401
  }
@@ -14682,20 +14478,20 @@ var DevServer = class _DevServer {
14682
14478
  child.stderr?.on("data", (d) => {
14683
14479
  stderr += d.toString().slice(0, 2e3);
14684
14480
  });
14685
- await new Promise((resolve10) => {
14481
+ await new Promise((resolve9) => {
14686
14482
  const timer = setTimeout(() => {
14687
14483
  child.kill();
14688
- resolve10();
14484
+ resolve9();
14689
14485
  }, 3e3);
14690
14486
  child.on("exit", () => {
14691
14487
  clearTimeout(timer);
14692
- resolve10();
14488
+ resolve9();
14693
14489
  });
14694
14490
  child.stdout?.once("data", () => {
14695
14491
  setTimeout(() => {
14696
14492
  child.kill();
14697
14493
  clearTimeout(timer);
14698
- resolve10();
14494
+ resolve9();
14699
14495
  }, 500);
14700
14496
  });
14701
14497
  });
@@ -14842,12 +14638,12 @@ var DevServer = class _DevServer {
14842
14638
  // ─── DevConsole SPA ───
14843
14639
  getConsoleDistDir() {
14844
14640
  const candidates = [
14845
- path15.resolve(__dirname, "../../web-devconsole/dist"),
14846
- path15.resolve(__dirname, "../../../web-devconsole/dist"),
14847
- path15.join(process.cwd(), "packages/web-devconsole/dist")
14641
+ path14.resolve(__dirname, "../../web-devconsole/dist"),
14642
+ path14.resolve(__dirname, "../../../web-devconsole/dist"),
14643
+ path14.join(process.cwd(), "packages/web-devconsole/dist")
14848
14644
  ];
14849
14645
  for (const dir of candidates) {
14850
- if (fs11.existsSync(path15.join(dir, "index.html"))) return dir;
14646
+ if (fs11.existsSync(path14.join(dir, "index.html"))) return dir;
14851
14647
  }
14852
14648
  return null;
14853
14649
  }
@@ -14857,7 +14653,7 @@ var DevServer = class _DevServer {
14857
14653
  this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
14858
14654
  return;
14859
14655
  }
14860
- const htmlPath = path15.join(distDir, "index.html");
14656
+ const htmlPath = path14.join(distDir, "index.html");
14861
14657
  try {
14862
14658
  const html = fs11.readFileSync(htmlPath, "utf-8");
14863
14659
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
@@ -14882,15 +14678,15 @@ var DevServer = class _DevServer {
14882
14678
  this.json(res, 404, { error: "Not found" });
14883
14679
  return;
14884
14680
  }
14885
- const safePath = path15.normalize(pathname).replace(/^\.\.\//, "");
14886
- const filePath = path15.join(distDir, safePath);
14681
+ const safePath = path14.normalize(pathname).replace(/^\.\.\//, "");
14682
+ const filePath = path14.join(distDir, safePath);
14887
14683
  if (!filePath.startsWith(distDir)) {
14888
14684
  this.json(res, 403, { error: "Forbidden" });
14889
14685
  return;
14890
14686
  }
14891
14687
  try {
14892
14688
  const content = fs11.readFileSync(filePath);
14893
- const ext = path15.extname(filePath);
14689
+ const ext = path14.extname(filePath);
14894
14690
  const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
14895
14691
  res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
14896
14692
  res.end(content);
@@ -15003,9 +14799,9 @@ var DevServer = class _DevServer {
15003
14799
  const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
15004
14800
  if (entry.isDirectory()) {
15005
14801
  files.push({ path: rel, size: 0, type: "dir" });
15006
- scan(path15.join(d, entry.name), rel);
14802
+ scan(path14.join(d, entry.name), rel);
15007
14803
  } else {
15008
- const stat = fs11.statSync(path15.join(d, entry.name));
14804
+ const stat = fs11.statSync(path14.join(d, entry.name));
15009
14805
  files.push({ path: rel, size: stat.size, type: "file" });
15010
14806
  }
15011
14807
  }
@@ -15028,7 +14824,7 @@ var DevServer = class _DevServer {
15028
14824
  this.json(res, 404, { error: `Provider directory not found: ${type}` });
15029
14825
  return;
15030
14826
  }
15031
- const fullPath = path15.resolve(dir, path15.normalize(filePath));
14827
+ const fullPath = path14.resolve(dir, path14.normalize(filePath));
15032
14828
  if (!fullPath.startsWith(dir)) {
15033
14829
  this.json(res, 403, { error: "Forbidden" });
15034
14830
  return;
@@ -15053,14 +14849,14 @@ var DevServer = class _DevServer {
15053
14849
  this.json(res, 404, { error: `Provider directory not found: ${type}` });
15054
14850
  return;
15055
14851
  }
15056
- const fullPath = path15.resolve(dir, path15.normalize(filePath));
14852
+ const fullPath = path14.resolve(dir, path14.normalize(filePath));
15057
14853
  if (!fullPath.startsWith(dir)) {
15058
14854
  this.json(res, 403, { error: "Forbidden" });
15059
14855
  return;
15060
14856
  }
15061
14857
  try {
15062
14858
  if (fs11.existsSync(fullPath)) fs11.copyFileSync(fullPath, fullPath + ".bak");
15063
- fs11.mkdirSync(path15.dirname(fullPath), { recursive: true });
14859
+ fs11.mkdirSync(path14.dirname(fullPath), { recursive: true });
15064
14860
  fs11.writeFileSync(fullPath, content, "utf-8");
15065
14861
  this.log(`File saved: ${fullPath} (${content.length} chars)`);
15066
14862
  this.providerLoader.reload();
@@ -15077,7 +14873,7 @@ var DevServer = class _DevServer {
15077
14873
  return;
15078
14874
  }
15079
14875
  for (const name of ["scripts.js", "provider.json"]) {
15080
- const p = path15.join(dir, name);
14876
+ const p = path14.join(dir, name);
15081
14877
  if (fs11.existsSync(p)) {
15082
14878
  const source = fs11.readFileSync(p, "utf-8");
15083
14879
  this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
@@ -15098,8 +14894,8 @@ var DevServer = class _DevServer {
15098
14894
  this.json(res, 404, { error: `Provider not found: ${type}` });
15099
14895
  return;
15100
14896
  }
15101
- const target = fs11.existsSync(path15.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
15102
- const targetPath = path15.join(dir, target);
14897
+ const target = fs11.existsSync(path14.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
14898
+ const targetPath = path14.join(dir, target);
15103
14899
  try {
15104
14900
  if (fs11.existsSync(targetPath)) fs11.copyFileSync(targetPath, targetPath + ".bak");
15105
14901
  fs11.writeFileSync(targetPath, source, "utf-8");
@@ -15204,14 +15000,14 @@ var DevServer = class _DevServer {
15204
15000
  child.stderr?.on("data", (d) => {
15205
15001
  stderr += d.toString();
15206
15002
  });
15207
- await new Promise((resolve10) => {
15003
+ await new Promise((resolve9) => {
15208
15004
  const timer = setTimeout(() => {
15209
15005
  child.kill();
15210
- resolve10();
15006
+ resolve9();
15211
15007
  }, timeout);
15212
15008
  child.on("exit", () => {
15213
15009
  clearTimeout(timer);
15214
- resolve10();
15010
+ resolve9();
15215
15011
  });
15216
15012
  });
15217
15013
  const elapsed = Date.now() - start;
@@ -15259,7 +15055,7 @@ var DevServer = class _DevServer {
15259
15055
  }
15260
15056
  let targetDir;
15261
15057
  targetDir = this.providerLoader.getUserProviderDir(category, type);
15262
- const jsonPath = path15.join(targetDir, "provider.json");
15058
+ const jsonPath = path14.join(targetDir, "provider.json");
15263
15059
  if (fs11.existsSync(jsonPath)) {
15264
15060
  this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
15265
15061
  return;
@@ -15271,8 +15067,8 @@ var DevServer = class _DevServer {
15271
15067
  const createdFiles = ["provider.json"];
15272
15068
  if (result.files) {
15273
15069
  for (const [relPath, content] of Object.entries(result.files)) {
15274
- const fullPath = path15.join(targetDir, relPath);
15275
- fs11.mkdirSync(path15.dirname(fullPath), { recursive: true });
15070
+ const fullPath = path14.join(targetDir, relPath);
15071
+ fs11.mkdirSync(path14.dirname(fullPath), { recursive: true });
15276
15072
  fs11.writeFileSync(fullPath, content, "utf-8");
15277
15073
  createdFiles.push(relPath);
15278
15074
  }
@@ -15325,22 +15121,22 @@ var DevServer = class _DevServer {
15325
15121
  if (!fs11.existsSync(scriptsDir)) return null;
15326
15122
  const versions = fs11.readdirSync(scriptsDir).filter((d) => {
15327
15123
  try {
15328
- return fs11.statSync(path15.join(scriptsDir, d)).isDirectory();
15124
+ return fs11.statSync(path14.join(scriptsDir, d)).isDirectory();
15329
15125
  } catch {
15330
15126
  return false;
15331
15127
  }
15332
15128
  }).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
15333
15129
  if (versions.length === 0) return null;
15334
- return path15.join(scriptsDir, versions[0]);
15130
+ return path14.join(scriptsDir, versions[0]);
15335
15131
  }
15336
15132
  resolveAutoImplWritableProviderDir(category, type, requestedDir) {
15337
- const canonicalUserDir = path15.resolve(this.providerLoader.getUserProviderDir(category, type));
15338
- const desiredDir = requestedDir ? path15.resolve(requestedDir) : canonicalUserDir;
15339
- const upstreamRoot = path15.resolve(this.providerLoader.getUpstreamDir());
15340
- if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path15.sep}`)) {
15133
+ const canonicalUserDir = path14.resolve(this.providerLoader.getUserProviderDir(category, type));
15134
+ const desiredDir = requestedDir ? path14.resolve(requestedDir) : canonicalUserDir;
15135
+ const upstreamRoot = path14.resolve(this.providerLoader.getUpstreamDir());
15136
+ if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path14.sep}`)) {
15341
15137
  return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
15342
15138
  }
15343
- if (path15.basename(desiredDir) !== type) {
15139
+ if (path14.basename(desiredDir) !== type) {
15344
15140
  return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
15345
15141
  }
15346
15142
  const sourceDir = this.findProviderDir(type);
@@ -15348,11 +15144,11 @@ var DevServer = class _DevServer {
15348
15144
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
15349
15145
  }
15350
15146
  if (!fs11.existsSync(desiredDir)) {
15351
- fs11.mkdirSync(path15.dirname(desiredDir), { recursive: true });
15147
+ fs11.mkdirSync(path14.dirname(desiredDir), { recursive: true });
15352
15148
  fs11.cpSync(sourceDir, desiredDir, { recursive: true });
15353
15149
  this.log(`Auto-implement writable copy created: ${desiredDir}`);
15354
15150
  }
15355
- const providerJson = path15.join(desiredDir, "provider.json");
15151
+ const providerJson = path14.join(desiredDir, "provider.json");
15356
15152
  if (!fs11.existsSync(providerJson)) {
15357
15153
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
15358
15154
  }
@@ -15400,7 +15196,7 @@ var DevServer = class _DevServer {
15400
15196
  setMode: "set_mode.js"
15401
15197
  };
15402
15198
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
15403
- const scriptsDir = path15.join(providerDir, "scripts");
15199
+ const scriptsDir = path14.join(providerDir, "scripts");
15404
15200
  const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
15405
15201
  if (latestScriptsDir) {
15406
15202
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -15411,7 +15207,7 @@ var DevServer = class _DevServer {
15411
15207
  for (const file of fs11.readdirSync(latestScriptsDir)) {
15412
15208
  if (file.endsWith(".js") && targetFileNames.has(file)) {
15413
15209
  try {
15414
- const content = fs11.readFileSync(path15.join(latestScriptsDir, file), "utf-8");
15210
+ const content = fs11.readFileSync(path14.join(latestScriptsDir, file), "utf-8");
15415
15211
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
15416
15212
  lines.push("```javascript");
15417
15213
  lines.push(content);
@@ -15428,7 +15224,7 @@ var DevServer = class _DevServer {
15428
15224
  lines.push("");
15429
15225
  for (const file of refFiles) {
15430
15226
  try {
15431
- const content = fs11.readFileSync(path15.join(latestScriptsDir, file), "utf-8");
15227
+ const content = fs11.readFileSync(path14.join(latestScriptsDir, file), "utf-8");
15432
15228
  lines.push(`### \`${file}\` \u{1F512}`);
15433
15229
  lines.push("```javascript");
15434
15230
  lines.push(content);
@@ -15469,10 +15265,10 @@ var DevServer = class _DevServer {
15469
15265
  lines.push("");
15470
15266
  }
15471
15267
  }
15472
- const docsDir = path15.join(providerDir, "../../docs");
15268
+ const docsDir = path14.join(providerDir, "../../docs");
15473
15269
  const loadGuide = (name) => {
15474
15270
  try {
15475
- const p = path15.join(docsDir, name);
15271
+ const p = path14.join(docsDir, name);
15476
15272
  if (fs11.existsSync(p)) return fs11.readFileSync(p, "utf-8");
15477
15273
  } catch {
15478
15274
  }
@@ -15646,7 +15442,7 @@ var DevServer = class _DevServer {
15646
15442
  parseApproval: "parse_approval.js"
15647
15443
  };
15648
15444
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
15649
- const scriptsDir = path15.join(providerDir, "scripts");
15445
+ const scriptsDir = path14.join(providerDir, "scripts");
15650
15446
  const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
15651
15447
  if (latestScriptsDir) {
15652
15448
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -15658,7 +15454,7 @@ var DevServer = class _DevServer {
15658
15454
  if (!file.endsWith(".js")) continue;
15659
15455
  if (!targetFileNames.has(file)) continue;
15660
15456
  try {
15661
- const content = fs11.readFileSync(path15.join(latestScriptsDir, file), "utf-8");
15457
+ const content = fs11.readFileSync(path14.join(latestScriptsDir, file), "utf-8");
15662
15458
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
15663
15459
  lines.push("```javascript");
15664
15460
  lines.push(content);
@@ -15674,7 +15470,7 @@ var DevServer = class _DevServer {
15674
15470
  lines.push("");
15675
15471
  for (const file of refFiles) {
15676
15472
  try {
15677
- const content = fs11.readFileSync(path15.join(latestScriptsDir, file), "utf-8");
15473
+ const content = fs11.readFileSync(path14.join(latestScriptsDir, file), "utf-8");
15678
15474
  lines.push(`### \`${file}\` \u{1F512}`);
15679
15475
  lines.push("```javascript");
15680
15476
  lines.push(content);
@@ -15707,10 +15503,10 @@ var DevServer = class _DevServer {
15707
15503
  lines.push("");
15708
15504
  }
15709
15505
  }
15710
- const docsDir = path15.join(providerDir, "../../docs");
15506
+ const docsDir = path14.join(providerDir, "../../docs");
15711
15507
  const loadGuide = (name) => {
15712
15508
  try {
15713
- const p = path15.join(docsDir, name);
15509
+ const p = path14.join(docsDir, name);
15714
15510
  if (fs11.existsSync(p)) return fs11.readFileSync(p, "utf-8");
15715
15511
  } catch {
15716
15512
  }
@@ -15867,14 +15663,14 @@ data: ${JSON.stringify(msg.data)}
15867
15663
  res.end(JSON.stringify(data, null, 2));
15868
15664
  }
15869
15665
  async readBody(req) {
15870
- return new Promise((resolve10) => {
15666
+ return new Promise((resolve9) => {
15871
15667
  let body = "";
15872
15668
  req.on("data", (chunk) => body += chunk);
15873
15669
  req.on("end", () => {
15874
15670
  try {
15875
- resolve10(JSON.parse(body));
15671
+ resolve9(JSON.parse(body));
15876
15672
  } catch {
15877
- resolve10({});
15673
+ resolve9({});
15878
15674
  }
15879
15675
  });
15880
15676
  });
@@ -16291,7 +16087,7 @@ async function waitForReady(endpoint, timeoutMs = STARTUP_TIMEOUT_MS) {
16291
16087
  const deadline = Date.now() + timeoutMs;
16292
16088
  while (Date.now() < deadline) {
16293
16089
  if (await canConnect(endpoint)) return;
16294
- await new Promise((resolve10) => setTimeout(resolve10, STARTUP_POLL_MS));
16090
+ await new Promise((resolve9) => setTimeout(resolve9, STARTUP_POLL_MS));
16295
16091
  }
16296
16092
  throw new Error(`Session host did not become ready within ${timeoutMs}ms`);
16297
16093
  }
@@ -16446,10 +16242,10 @@ async function installExtension(ide, extension) {
16446
16242
  const buffer = Buffer.from(await res.arrayBuffer());
16447
16243
  const fs12 = await import("fs");
16448
16244
  fs12.writeFileSync(vsixPath, buffer);
16449
- return new Promise((resolve10) => {
16245
+ return new Promise((resolve9) => {
16450
16246
  const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
16451
16247
  (0, import_child_process8.exec)(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
16452
- resolve10({
16248
+ resolve9({
16453
16249
  extensionId: extension.id,
16454
16250
  marketplaceId: extension.marketplaceId,
16455
16251
  success: !error,
@@ -16462,11 +16258,11 @@ async function installExtension(ide, extension) {
16462
16258
  } catch (e) {
16463
16259
  }
16464
16260
  }
16465
- return new Promise((resolve10) => {
16261
+ return new Promise((resolve9) => {
16466
16262
  const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
16467
16263
  (0, import_child_process8.exec)(cmd, { timeout: 6e4 }, (error, stdout, stderr) => {
16468
16264
  if (error) {
16469
- resolve10({
16265
+ resolve9({
16470
16266
  extensionId: extension.id,
16471
16267
  marketplaceId: extension.marketplaceId,
16472
16268
  success: false,
@@ -16474,7 +16270,7 @@ async function installExtension(ide, extension) {
16474
16270
  error: stderr || error.message
16475
16271
  });
16476
16272
  } else {
16477
- resolve10({
16273
+ resolve9({
16478
16274
  extensionId: extension.id,
16479
16275
  marketplaceId: extension.marketplaceId,
16480
16276
  success: true,
@@ -16778,7 +16574,6 @@ async function shutdownDaemonComponents(components) {
16778
16574
  ProviderLoader,
16779
16575
  SessionHostPtyTransportFactory,
16780
16576
  VersionArchive,
16781
- addCliHistory,
16782
16577
  appendRecentActivity,
16783
16578
  buildSessionEntries,
16784
16579
  buildStatusSnapshot,
@@ -16796,7 +16591,6 @@ async function shutdownDaemonComponents(components) {
16796
16591
  getRecentActivity,
16797
16592
  getRecentCommands,
16798
16593
  getRecentLogs,
16799
- getWorkspaceActivity,
16800
16594
  getWorkspaceState,
16801
16595
  hasCdpManager,
16802
16596
  initDaemonComponents,