adhdev 0.8.19 → 0.8.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -65,14 +65,6 @@ function asBoolean(value, fallback) {
65
65
  }
66
66
  function normalizeConfig(raw) {
67
67
  const parsed = isPlainObject(raw) ? raw : {};
68
- const legacySessionReads = isPlainObject(parsed.recentSessionReads) ? parsed.recentSessionReads : {};
69
- const sessionReads = isPlainObject(parsed.sessionReads) ? parsed.sessionReads : {};
70
- const mergedSessionReads = Object.fromEntries(
71
- Object.entries({ ...legacySessionReads, ...sessionReads }).filter(([, value]) => typeof value === "number" && Number.isFinite(value))
72
- );
73
- const sessionReadMarkers = Object.fromEntries(
74
- Object.entries(isPlainObject(parsed.sessionReadMarkers) ? parsed.sessionReadMarkers : {}).filter(([, value]) => typeof value === "string")
75
- );
76
68
  return {
77
69
  serverUrl: typeof parsed.serverUrl === "string" && parsed.serverUrl.trim() ? parsed.serverUrl : DEFAULT_CONFIG.serverUrl,
78
70
  selectedIde: asNullableString(parsed.selectedIde),
@@ -85,10 +77,6 @@ function normalizeConfig(raw) {
85
77
  enabledIdes: asStringArray(parsed.enabledIdes),
86
78
  workspaces: Array.isArray(parsed.workspaces) ? parsed.workspaces : [],
87
79
  defaultWorkspaceId: asNullableString(parsed.defaultWorkspaceId) ?? asNullableString(parsed.activeWorkspaceId),
88
- recentActivity: Array.isArray(parsed.recentActivity) ? parsed.recentActivity : [],
89
- savedProviderSessions: Array.isArray(parsed.savedProviderSessions) ? parsed.savedProviderSessions : [],
90
- sessionReads: mergedSessionReads,
91
- sessionReadMarkers,
92
80
  machineNickname: asNullableString(parsed.machineNickname),
93
81
  machineId: asOptionalString(parsed.machineId),
94
82
  machineSecret: parsed.machineSecret === null ? null : asOptionalString(parsed.machineSecret),
@@ -129,6 +117,30 @@ function getConfigDir() {
129
117
  function getConfigPath() {
130
118
  return (0, import_path.join)(getConfigDir(), "config.json");
131
119
  }
120
+ function migrateStateToStateFile(raw) {
121
+ const statePath = (0, import_path.join)(getConfigDir(), "state.json");
122
+ if ((0, import_fs.existsSync)(statePath)) return;
123
+ const recentActivity = Array.isArray(raw.recentActivity) ? raw.recentActivity : [];
124
+ const savedProviderSessions = Array.isArray(raw.savedProviderSessions) ? raw.savedProviderSessions : [];
125
+ const legacySessionReads = isPlainObject(raw.recentSessionReads) ? raw.recentSessionReads : {};
126
+ const sessionReads = isPlainObject(raw.sessionReads) ? raw.sessionReads : {};
127
+ const sessionReadMarkers = isPlainObject(raw.sessionReadMarkers) ? raw.sessionReadMarkers : {};
128
+ const hasData = recentActivity.length > 0 || savedProviderSessions.length > 0 || Object.keys(sessionReads).length > 0 || Object.keys(legacySessionReads).length > 0 || Object.keys(sessionReadMarkers).length > 0;
129
+ if (!hasData) return;
130
+ const mergedReads = Object.fromEntries(
131
+ Object.entries({ ...legacySessionReads, ...sessionReads }).filter(([, v]) => typeof v === "number" && Number.isFinite(v))
132
+ );
133
+ const cleanedMarkers = Object.fromEntries(
134
+ Object.entries(sessionReadMarkers).filter(([, v]) => typeof v === "string")
135
+ );
136
+ const state = {
137
+ recentActivity,
138
+ savedProviderSessions,
139
+ sessionReads: mergedReads,
140
+ sessionReadMarkers: cleanedMarkers
141
+ };
142
+ (0, import_fs.writeFileSync)(statePath, JSON.stringify(state, null, 2), { encoding: "utf-8", mode: 384 });
143
+ }
132
144
  function loadConfig() {
133
145
  const configPath = getConfigPath();
134
146
  if (!(0, import_fs.existsSync)(configPath)) {
@@ -142,6 +154,7 @@ function loadConfig() {
142
154
  try {
143
155
  const raw = (0, import_fs.readFileSync)(configPath, "utf-8");
144
156
  const parsed = JSON.parse(raw);
157
+ migrateStateToStateFile(parsed);
145
158
  const normalizedInput = normalizeConfig(parsed);
146
159
  const ensured = ensureMachineId(normalizedInput);
147
160
  const normalized = ensured.config;
@@ -213,10 +226,6 @@ var init_config = __esm({
213
226
  enabledIdes: [],
214
227
  workspaces: [],
215
228
  defaultWorkspaceId: null,
216
- recentActivity: [],
217
- savedProviderSessions: [],
218
- sessionReads: {},
219
- sessionReadMarkers: {},
220
229
  machineNickname: null,
221
230
  machineId: void 0,
222
231
  machineSecret: null,
@@ -420,35 +429,35 @@ function buildRecentActivityKeyForEntry(entry) {
420
429
  }
421
430
  return buildRecentActivityKey(entry);
422
431
  }
423
- function appendRecentActivity(config2, entry) {
432
+ function appendRecentActivity(state, entry) {
424
433
  const nextEntry = {
425
434
  ...entry,
426
435
  workspace: entry.workspace ? normalizeWorkspace(entry.workspace) : void 0,
427
436
  id: buildRecentActivityKeyForEntry(entry),
428
437
  lastUsedAt: entry.lastUsedAt || Date.now()
429
438
  };
430
- const filtered = (config2.recentActivity || []).filter((item) => item.id !== nextEntry.id);
439
+ const filtered = (state.recentActivity || []).filter((item) => item.id !== nextEntry.id);
431
440
  return {
432
- ...config2,
441
+ ...state,
433
442
  recentActivity: [nextEntry, ...filtered].slice(0, MAX_ACTIVITY)
434
443
  };
435
444
  }
436
- function getRecentActivity(config2, limit = 20) {
437
- return [...config2.recentActivity || []].sort((a, b) => b.lastUsedAt - a.lastUsedAt).slice(0, limit);
445
+ function getRecentActivity(state, limit = 20) {
446
+ return [...state.recentActivity || []].sort((a, b) => b.lastUsedAt - a.lastUsedAt).slice(0, limit);
438
447
  }
439
- function getSessionSeenAt(config2, sessionId) {
440
- return config2.sessionReads?.[sessionId] || 0;
448
+ function getSessionSeenAt(state, sessionId) {
449
+ return state.sessionReads?.[sessionId] || 0;
441
450
  }
442
- function getSessionSeenMarker(config2, sessionId) {
443
- return config2.sessionReadMarkers?.[sessionId] || "";
451
+ function getSessionSeenMarker(state, sessionId) {
452
+ return state.sessionReadMarkers?.[sessionId] || "";
444
453
  }
445
- function markSessionSeen(config2, sessionId, seenAt = Date.now(), completionMarker) {
446
- const prev = config2.sessionReads || {};
454
+ function markSessionSeen(state, sessionId, seenAt = Date.now(), completionMarker) {
455
+ const prev = state.sessionReads || {};
447
456
  const nextSeenAt = Math.max(prev[sessionId] || 0, seenAt);
448
- const prevMarkers = config2.sessionReadMarkers || {};
457
+ const prevMarkers = state.sessionReadMarkers || {};
449
458
  const nextMarker = typeof completionMarker === "string" ? completionMarker : "";
450
459
  return {
451
- ...config2,
460
+ ...state,
452
461
  sessionReads: {
453
462
  ...prev,
454
463
  [sessionId]: nextSeenAt
@@ -481,11 +490,11 @@ function normalizeWorkspace2(workspace) {
481
490
  function buildSavedProviderSessionKey(providerSessionId) {
482
491
  return `saved:${providerSessionId.trim()}`;
483
492
  }
484
- function upsertSavedProviderSession(config2, entry) {
493
+ function upsertSavedProviderSession(state, entry) {
485
494
  const providerSessionId = typeof entry.providerSessionId === "string" ? entry.providerSessionId.trim() : "";
486
- if (!providerSessionId) return config2;
495
+ if (!providerSessionId) return state;
487
496
  const id = buildSavedProviderSessionKey(providerSessionId);
488
- const existing = (config2.savedProviderSessions || []).find((item) => item.id === id);
497
+ const existing = (state.savedProviderSessions || []).find((item) => item.id === id);
489
498
  const nextEntry = {
490
499
  id,
491
500
  kind: entry.kind,
@@ -498,14 +507,14 @@ function upsertSavedProviderSession(config2, entry) {
498
507
  createdAt: existing?.createdAt || entry.createdAt || Date.now(),
499
508
  lastUsedAt: entry.lastUsedAt || Date.now()
500
509
  };
501
- const filtered = (config2.savedProviderSessions || []).filter((item) => item.id !== id);
510
+ const filtered = (state.savedProviderSessions || []).filter((item) => item.id !== id);
502
511
  return {
503
- ...config2,
512
+ ...state,
504
513
  savedProviderSessions: [nextEntry, ...filtered].slice(0, MAX_SAVED_SESSIONS)
505
514
  };
506
515
  }
507
- function getSavedProviderSessions(config2, filters) {
508
- return [...config2.savedProviderSessions || []].filter((entry) => {
516
+ function getSavedProviderSessions(state, filters) {
517
+ return [...state.savedProviderSessions || []].filter((entry) => {
509
518
  if (filters?.providerType && entry.providerType !== filters.providerType) return false;
510
519
  if (filters?.kind && entry.kind !== filters.kind) return false;
511
520
  return true;
@@ -521,6 +530,64 @@ var init_saved_sessions = __esm({
521
530
  }
522
531
  });
523
532
 
533
+ // ../../oss/packages/daemon-core/src/config/state-store.ts
534
+ function isPlainObject2(value) {
535
+ return !!value && typeof value === "object" && !Array.isArray(value);
536
+ }
537
+ function getStatePath() {
538
+ return (0, import_path2.join)(getConfigDir(), "state.json");
539
+ }
540
+ function normalizeState(raw) {
541
+ const parsed = isPlainObject2(raw) ? raw : {};
542
+ const sessionReads = Object.fromEntries(
543
+ Object.entries(isPlainObject2(parsed.sessionReads) ? parsed.sessionReads : {}).filter(([, value]) => typeof value === "number" && Number.isFinite(value))
544
+ );
545
+ const sessionReadMarkers = Object.fromEntries(
546
+ Object.entries(isPlainObject2(parsed.sessionReadMarkers) ? parsed.sessionReadMarkers : {}).filter(([, value]) => typeof value === "string")
547
+ );
548
+ return {
549
+ recentActivity: Array.isArray(parsed.recentActivity) ? parsed.recentActivity : [],
550
+ savedProviderSessions: Array.isArray(parsed.savedProviderSessions) ? parsed.savedProviderSessions : [],
551
+ sessionReads,
552
+ sessionReadMarkers
553
+ };
554
+ }
555
+ function loadState() {
556
+ const statePath = getStatePath();
557
+ if (!(0, import_fs2.existsSync)(statePath)) {
558
+ return { ...DEFAULT_STATE };
559
+ }
560
+ try {
561
+ const raw = (0, import_fs2.readFileSync)(statePath, "utf-8");
562
+ return normalizeState(JSON.parse(raw));
563
+ } catch {
564
+ return { ...DEFAULT_STATE };
565
+ }
566
+ }
567
+ function saveState(state) {
568
+ const statePath = getStatePath();
569
+ const normalized = normalizeState(state);
570
+ (0, import_fs2.writeFileSync)(statePath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
571
+ }
572
+ function resetState() {
573
+ saveState({ ...DEFAULT_STATE });
574
+ }
575
+ var import_fs2, import_path2, DEFAULT_STATE;
576
+ var init_state_store = __esm({
577
+ "../../oss/packages/daemon-core/src/config/state-store.ts"() {
578
+ "use strict";
579
+ import_fs2 = require("fs");
580
+ import_path2 = require("path");
581
+ init_config();
582
+ DEFAULT_STATE = {
583
+ recentActivity: [],
584
+ savedProviderSessions: [],
585
+ sessionReads: {},
586
+ sessionReadMarkers: {}
587
+ };
588
+ }
589
+ });
590
+
524
591
  // ../../oss/packages/daemon-core/src/detection/ide-detector.ts
525
592
  function registerIDEDefinition(def) {
526
593
  registeredIDEs.set(def.id, def);
@@ -564,9 +631,9 @@ function checkPathExists(paths) {
564
631
  if (p.includes("*")) {
565
632
  const username = home.split(/[\\/]/).pop() || "";
566
633
  const resolved = p.replace("*", username);
567
- if ((0, import_fs2.existsSync)(resolved)) return resolved;
634
+ if ((0, import_fs3.existsSync)(resolved)) return resolved;
568
635
  } else {
569
- if ((0, import_fs2.existsSync)(p)) return p;
636
+ if ((0, import_fs3.existsSync)(p)) return p;
570
637
  }
571
638
  }
572
639
  return null;
@@ -581,7 +648,7 @@ async function detectIDEs() {
581
648
  let resolvedCli = cliPath;
582
649
  if (!resolvedCli && appPath && os24 === "darwin") {
583
650
  const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
584
- if ((0, import_fs2.existsSync)(bundledCli)) resolvedCli = bundledCli;
651
+ if ((0, import_fs3.existsSync)(bundledCli)) resolvedCli = bundledCli;
585
652
  }
586
653
  if (!resolvedCli && appPath && os24 === "win32") {
587
654
  const { dirname: dirname9 } = await import("path");
@@ -594,7 +661,7 @@ async function detectIDEs() {
594
661
  `${appDir}\\\\resources\\\\app\\\\bin\\\\${def.cli}.cmd`
595
662
  ];
596
663
  for (const c of candidates) {
597
- if ((0, import_fs2.existsSync)(c)) {
664
+ if ((0, import_fs3.existsSync)(c)) {
598
665
  resolvedCli = c;
599
666
  break;
600
667
  }
@@ -614,12 +681,12 @@ async function detectIDEs() {
614
681
  }
615
682
  return results;
616
683
  }
617
- var import_child_process, import_fs2, import_os2, BUILTIN_IDE_DEFINITIONS, registeredIDEs;
684
+ var import_child_process, import_fs3, import_os2, BUILTIN_IDE_DEFINITIONS, registeredIDEs;
618
685
  var init_ide_detector = __esm({
619
686
  "../../oss/packages/daemon-core/src/detection/ide-detector.ts"() {
620
687
  "use strict";
621
688
  import_child_process = require("child_process");
622
- import_fs2 = require("fs");
689
+ import_fs3 = require("fs");
623
690
  import_os2 = require("os");
624
691
  BUILTIN_IDE_DEFINITIONS = [];
625
692
  registeredIDEs = /* @__PURE__ */ new Map();
@@ -8959,7 +9026,7 @@ __export(util_exports, {
8959
9026
  getSizableOrigin: () => getSizableOrigin,
8960
9027
  hexToUint8Array: () => hexToUint8Array,
8961
9028
  isObject: () => isObject,
8962
- isPlainObject: () => isPlainObject2,
9029
+ isPlainObject: () => isPlainObject3,
8963
9030
  issue: () => issue,
8964
9031
  joinValues: () => joinValues,
8965
9032
  jsonStringifyReplacer: () => jsonStringifyReplacer,
@@ -9128,7 +9195,7 @@ function slugify(input) {
9128
9195
  function isObject(data) {
9129
9196
  return typeof data === "object" && data !== null && !Array.isArray(data);
9130
9197
  }
9131
- function isPlainObject2(o) {
9198
+ function isPlainObject3(o) {
9132
9199
  if (isObject(o) === false)
9133
9200
  return false;
9134
9201
  const ctor = o.constructor;
@@ -9145,7 +9212,7 @@ function isPlainObject2(o) {
9145
9212
  return true;
9146
9213
  }
9147
9214
  function shallowClone(o) {
9148
- if (isPlainObject2(o))
9215
+ if (isPlainObject3(o))
9149
9216
  return { ...o };
9150
9217
  if (Array.isArray(o))
9151
9218
  return [...o];
@@ -9281,7 +9348,7 @@ function omit(schema, mask) {
9281
9348
  return clone(schema, def);
9282
9349
  }
9283
9350
  function extend(schema, shape) {
9284
- if (!isPlainObject2(shape)) {
9351
+ if (!isPlainObject3(shape)) {
9285
9352
  throw new Error("Invalid input to extend: expected a plain object");
9286
9353
  }
9287
9354
  const checks = schema._zod.def.checks;
@@ -9304,7 +9371,7 @@ function extend(schema, shape) {
9304
9371
  return clone(schema, def);
9305
9372
  }
9306
9373
  function safeExtend(schema, shape) {
9307
- if (!isPlainObject2(shape)) {
9374
+ if (!isPlainObject3(shape)) {
9308
9375
  throw new Error("Invalid input to safeExtend: expected a plain object");
9309
9376
  }
9310
9377
  const def = mergeDefs(schema._zod.def, {
@@ -10787,7 +10854,7 @@ function mergeValues(a, b) {
10787
10854
  if (a instanceof Date && b instanceof Date && +a === +b) {
10788
10855
  return { valid: true, data: a };
10789
10856
  }
10790
- if (isPlainObject2(a) && isPlainObject2(b)) {
10857
+ if (isPlainObject3(a) && isPlainObject3(b)) {
10791
10858
  const bKeys = Object.keys(b);
10792
10859
  const sharedKeys = Object.keys(a).filter((key) => bKeys.indexOf(key) !== -1);
10793
10860
  const newObj = { ...a, ...b };
@@ -11982,7 +12049,7 @@ var init_schemas = __esm({
11982
12049
  $ZodType.init(inst, def);
11983
12050
  inst._zod.parse = (payload, ctx) => {
11984
12051
  const input = payload.value;
11985
- if (!isPlainObject2(input)) {
12052
+ if (!isPlainObject3(input)) {
11986
12053
  payload.issues.push({
11987
12054
  expected: "record",
11988
12055
  code: "invalid_type",
@@ -26174,6 +26241,7 @@ var init_cli_manager = __esm({
26174
26241
  init_provider_cli_adapter();
26175
26242
  init_cli_detector();
26176
26243
  init_config();
26244
+ init_state_store();
26177
26245
  init_workspaces();
26178
26246
  init_recent_activity();
26179
26247
  init_saved_sessions();
@@ -26205,9 +26273,9 @@ var init_cli_manager = __esm({
26205
26273
  }
26206
26274
  persistRecentActivity(entry) {
26207
26275
  try {
26208
- let nextConfig = appendRecentActivity(loadConfig(), entry);
26276
+ let nextState = appendRecentActivity(loadState(), entry);
26209
26277
  if (entry.providerSessionId && (entry.kind === "cli" || entry.kind === "acp")) {
26210
- nextConfig = upsertSavedProviderSession(nextConfig, {
26278
+ nextState = upsertSavedProviderSession(nextState, {
26211
26279
  kind: entry.kind,
26212
26280
  providerType: entry.providerType,
26213
26281
  providerName: entry.providerName,
@@ -26217,7 +26285,7 @@ var init_cli_manager = __esm({
26217
26285
  title: entry.title
26218
26286
  });
26219
26287
  }
26220
- saveConfig(nextConfig);
26288
+ saveState(nextState);
26221
26289
  } catch (e) {
26222
26290
  console.error(colorize("red", ` \u2717 Failed to save recent activity: ${e}`));
26223
26291
  }
@@ -28759,14 +28827,14 @@ var init_provider_loader = __esm({
28759
28827
  */
28760
28828
  setIdeExtensionEnabled(ideType, extensionType, enabled) {
28761
28829
  try {
28762
- const { loadConfig: loadConfig2, saveConfig: saveConfig2 } = (init_config(), __toCommonJS(config_exports));
28830
+ const { loadConfig: loadConfig2, saveConfig: saveConfig3 } = (init_config(), __toCommonJS(config_exports));
28763
28831
  const config2 = loadConfig2();
28764
28832
  const baseIdeType = ideType.split("_")[0];
28765
28833
  if (!config2.ideSettings) config2.ideSettings = {};
28766
28834
  if (!config2.ideSettings[baseIdeType]) config2.ideSettings[baseIdeType] = {};
28767
28835
  if (!config2.ideSettings[baseIdeType].extensions) config2.ideSettings[baseIdeType].extensions = {};
28768
28836
  config2.ideSettings[baseIdeType].extensions[extensionType] = { enabled };
28769
- saveConfig2(config2);
28837
+ saveConfig3(config2);
28770
28838
  this.log(`IDE extension setting: ${ideType}.${extensionType}.enabled = ${enabled}`);
28771
28839
  return true;
28772
28840
  } catch (e) {
@@ -29331,12 +29399,12 @@ var init_provider_loader = __esm({
29331
29399
  }
29332
29400
  if (schemaDef.type === "select" && schemaDef.options && !schemaDef.options.includes(value)) return false;
29333
29401
  try {
29334
- const { loadConfig: loadConfig2, saveConfig: saveConfig2 } = (init_config(), __toCommonJS(config_exports));
29402
+ const { loadConfig: loadConfig2, saveConfig: saveConfig3 } = (init_config(), __toCommonJS(config_exports));
29335
29403
  const config2 = loadConfig2();
29336
29404
  if (!config2.providerSettings) config2.providerSettings = {};
29337
29405
  if (!config2.providerSettings[type]) config2.providerSettings[type] = {};
29338
29406
  config2.providerSettings[type][key] = value;
29339
- saveConfig2(config2);
29407
+ saveConfig3(config2);
29340
29408
  this.log(`Setting updated: ${type}.${key} = ${JSON.stringify(value)}`);
29341
29409
  return true;
29342
29410
  } catch (e) {
@@ -30122,16 +30190,17 @@ function buildRecentLaunches(recentActivity) {
30122
30190
  }
30123
30191
  function buildStatusSnapshot(options) {
30124
30192
  const cfg = loadConfig();
30193
+ const state = loadState();
30125
30194
  const wsState = getWorkspaceState(cfg);
30126
30195
  const memSnap = getHostMemorySnapshot();
30127
- const recentActivity = getRecentActivity(cfg, 20);
30196
+ const recentActivity = getRecentActivity(state, 20);
30128
30197
  const sessions = buildSessionEntries(
30129
30198
  options.allStates,
30130
30199
  options.cdpManagers
30131
30200
  );
30132
30201
  for (const session of sessions) {
30133
- const lastSeenAt = getSessionSeenAt(cfg, session.id);
30134
- const seenCompletionMarker = getSessionSeenMarker(cfg, session.id);
30202
+ const lastSeenAt = getSessionSeenAt(state, session.id);
30203
+ const seenCompletionMarker = getSessionSeenMarker(state, session.id);
30135
30204
  const lastUsedAt = getSessionLastUsedAt(session);
30136
30205
  const completionMarker = getSessionCompletionMarker(session);
30137
30206
  const { unread, inboxBucket } = session.surfaceHidden ? { unread: false, inboxBucket: "idle" } : getUnreadState(
@@ -30189,6 +30258,7 @@ var init_snapshot = __esm({
30189
30258
  "use strict";
30190
30259
  os15 = __toESM(require("os"));
30191
30260
  init_config();
30261
+ init_state_store();
30192
30262
  init_recent_activity();
30193
30263
  init_workspaces();
30194
30264
  init_host_memory();
@@ -30408,6 +30478,7 @@ var init_router = __esm({
30408
30478
  init_cli_manager();
30409
30479
  init_launch();
30410
30480
  init_config();
30481
+ init_state_store();
30411
30482
  init_workspaces();
30412
30483
  init_recent_activity();
30413
30484
  init_saved_sessions();
@@ -30510,9 +30581,9 @@ var init_router = __esm({
30510
30581
  const offset = Math.max(0, Number(args?.offset) || 0);
30511
30582
  const limit = Math.max(1, Math.min(100, Number(args?.limit) || 30));
30512
30583
  const { sessions: historySessions, hasMore } = listSavedHistorySessions(providerType, { offset, limit });
30513
- const config2 = loadConfig();
30514
- const savedSessions = getSavedProviderSessions(config2, { providerType, kind });
30515
- const recentSessions = getRecentActivity(config2, 200).filter((entry) => entry.providerType === providerType && entry.kind === kind && entry.providerSessionId);
30584
+ const state = loadState();
30585
+ const savedSessions = getSavedProviderSessions(state, { providerType, kind });
30586
+ const recentSessions = getRecentActivity(state, 200).filter((entry) => entry.providerType === providerType && entry.kind === kind && entry.providerSessionId);
30516
30587
  const savedSessionById = new Map(savedSessions.map((entry) => [entry.providerSessionId, entry]));
30517
30588
  const recentSessionById = new Map(recentSessions.map((entry) => [entry.providerSessionId, entry]));
30518
30589
  const providerMeta = this.deps.providerLoader.getMeta(providerType);
@@ -30603,19 +30674,19 @@ var init_router = __esm({
30603
30674
  this.deps.onIdeConnected?.();
30604
30675
  if (result.success && resolvedWorkspace) {
30605
30676
  try {
30606
- const next = appendRecentActivity(loadConfig(), {
30677
+ const next = appendRecentActivity(loadState(), {
30607
30678
  kind: "ide",
30608
30679
  providerType: result.ideId || ideKey,
30609
30680
  providerName: result.ideId || ideKey,
30610
30681
  workspace: resolvedWorkspace,
30611
30682
  title: result.ideId || ideKey
30612
30683
  });
30613
- saveConfig(next);
30684
+ saveState(next);
30614
30685
  } catch {
30615
30686
  }
30616
30687
  } else if (result.success && (result.ideId || ideKey)) {
30617
30688
  try {
30618
- saveConfig(appendRecentActivity(loadConfig(), {
30689
+ saveState(appendRecentActivity(loadState(), {
30619
30690
  kind: "ide",
30620
30691
  providerType: result.ideId || ideKey,
30621
30692
  providerName: result.ideId || ideKey,
@@ -30644,8 +30715,8 @@ var init_router = __esm({
30644
30715
  if (!sessionId || typeof sessionId !== "string") {
30645
30716
  return { success: false, error: "sessionId is required" };
30646
30717
  }
30647
- const currentConfig = loadConfig();
30648
- const prevSeenAt = currentConfig.sessionReads?.[sessionId] || 0;
30718
+ const currentState = loadState();
30719
+ const prevSeenAt = currentState.sessionReads?.[sessionId] || 0;
30649
30720
  const sessionEntries = buildSessionEntries(
30650
30721
  this.deps.instanceManager.collectAllStates(),
30651
30722
  this.deps.cdpManagers
@@ -30653,7 +30724,7 @@ var init_router = __esm({
30653
30724
  const targetSession = sessionEntries.find((entry) => entry.id === sessionId);
30654
30725
  const completionMarker = targetSession ? getSessionCompletionMarker(targetSession) : "";
30655
30726
  const next = markSessionSeen(
30656
- currentConfig,
30727
+ currentState,
30657
30728
  sessionId,
30658
30729
  typeof args?.seenAt === "number" ? args.seenAt : Date.now(),
30659
30730
  completionMarker
@@ -30661,7 +30732,7 @@ var init_router = __esm({
30661
30732
  if (READ_DEBUG_ENABLED2) {
30662
30733
  LOG.info("RecentRead", `mark_session_seen sessionId=${sessionId} seenAt=${String(args?.seenAt || "")} prevSeenAt=${String(prevSeenAt)} nextSeenAt=${String(next.sessionReads?.[sessionId] || 0)} marker=${completionMarker || "-"}`);
30663
30734
  }
30664
- saveConfig(next);
30735
+ saveState(next);
30665
30736
  this.deps.onStatusChange?.();
30666
30737
  return {
30667
30738
  success: true,
@@ -38147,6 +38218,7 @@ __export(src_exports, {
38147
38218
  launchWithCdp: () => launchWithCdp,
38148
38219
  listHostedCliRuntimes: () => listHostedCliRuntimes,
38149
38220
  loadConfig: () => loadConfig,
38221
+ loadState: () => loadState,
38150
38222
  logCommand: () => logCommand,
38151
38223
  markSetupComplete: () => markSetupComplete,
38152
38224
  maybeRunDaemonUpgradeHelperFromEnv: () => maybeRunDaemonUpgradeHelperFromEnv,
@@ -38156,7 +38228,9 @@ __export(src_exports, {
38156
38228
  readChatHistory: () => readChatHistory,
38157
38229
  registerExtensionProviders: () => registerExtensionProviders,
38158
38230
  resetConfig: () => resetConfig,
38231
+ resetState: () => resetState,
38159
38232
  saveConfig: () => saveConfig,
38233
+ saveState: () => saveState,
38160
38234
  setLogLevel: () => setLogLevel,
38161
38235
  setupIdeInstance: () => setupIdeInstance,
38162
38236
  shutdownDaemonComponents: () => shutdownDaemonComponents,
@@ -38172,6 +38246,7 @@ var init_src = __esm({
38172
38246
  init_workspaces();
38173
38247
  init_recent_activity();
38174
38248
  init_saved_sessions();
38249
+ init_state_store();
38175
38250
  init_ide_detector();
38176
38251
  init_cli_detector();
38177
38252
  init_host_memory();
@@ -39508,7 +39583,7 @@ var require_filesystem = __commonJS({
39508
39583
  var LDD_PATH = "/usr/bin/ldd";
39509
39584
  var SELF_PATH = "/proc/self/exe";
39510
39585
  var MAX_LENGTH = 2048;
39511
- var readFileSync17 = (path24) => {
39586
+ var readFileSync18 = (path24) => {
39512
39587
  const fd = fs19.openSync(path24, "r");
39513
39588
  const buffer = Buffer.alloc(MAX_LENGTH);
39514
39589
  const bytesRead = fs19.readSync(fd, buffer, 0, MAX_LENGTH, 0);
@@ -39533,7 +39608,7 @@ var require_filesystem = __commonJS({
39533
39608
  module2.exports = {
39534
39609
  LDD_PATH,
39535
39610
  SELF_PATH,
39536
- readFileSync: readFileSync17,
39611
+ readFileSync: readFileSync18,
39537
39612
  readFile
39538
39613
  };
39539
39614
  }
@@ -39582,7 +39657,7 @@ var require_detect_libc = __commonJS({
39582
39657
  "use strict";
39583
39658
  var childProcess = require("child_process");
39584
39659
  var { isLinux: isLinux2, getReport } = require_process();
39585
- var { LDD_PATH, SELF_PATH, readFile, readFileSync: readFileSync17 } = require_filesystem();
39660
+ var { LDD_PATH, SELF_PATH, readFile, readFileSync: readFileSync18 } = require_filesystem();
39586
39661
  var { interpreterPath } = require_elf();
39587
39662
  var cachedFamilyInterpreter;
39588
39663
  var cachedFamilyFilesystem;
@@ -39674,7 +39749,7 @@ var require_detect_libc = __commonJS({
39674
39749
  }
39675
39750
  cachedFamilyFilesystem = null;
39676
39751
  try {
39677
- const lddContent = readFileSync17(LDD_PATH);
39752
+ const lddContent = readFileSync18(LDD_PATH);
39678
39753
  cachedFamilyFilesystem = getFamilyFromLddContent(lddContent);
39679
39754
  } catch (e) {
39680
39755
  }
@@ -39699,7 +39774,7 @@ var require_detect_libc = __commonJS({
39699
39774
  }
39700
39775
  cachedFamilyInterpreter = null;
39701
39776
  try {
39702
- const selfContent = readFileSync17(SELF_PATH);
39777
+ const selfContent = readFileSync18(SELF_PATH);
39703
39778
  const path24 = interpreterPath(selfContent);
39704
39779
  cachedFamilyInterpreter = familyFromInterpreterPath(path24);
39705
39780
  } catch (e) {
@@ -39763,7 +39838,7 @@ var require_detect_libc = __commonJS({
39763
39838
  }
39764
39839
  cachedVersionFilesystem = null;
39765
39840
  try {
39766
- const lddContent = readFileSync17(LDD_PATH);
39841
+ const lddContent = readFileSync18(LDD_PATH);
39767
39842
  const versionMatch = lddContent.match(RE_GLIBC_VERSION);
39768
39843
  if (versionMatch) {
39769
39844
  cachedVersionFilesystem = versionMatch[1];
@@ -46420,25 +46495,25 @@ function resolvePackageVersion(options) {
46420
46495
  const injectedVersion = options?.injectedVersion || "unknown";
46421
46496
  const dir = options?.dirname || __dirname;
46422
46497
  const possiblePaths = [
46423
- (0, import_path2.join)(dir, "..", "..", "package.json"),
46424
- (0, import_path2.join)(dir, "..", "package.json"),
46425
- (0, import_path2.join)(dir, "package.json")
46498
+ (0, import_path3.join)(dir, "..", "..", "package.json"),
46499
+ (0, import_path3.join)(dir, "..", "package.json"),
46500
+ (0, import_path3.join)(dir, "package.json")
46426
46501
  ];
46427
46502
  for (const p of possiblePaths) {
46428
46503
  try {
46429
- const data = JSON.parse((0, import_fs3.readFileSync)(p, "utf-8"));
46504
+ const data = JSON.parse((0, import_fs4.readFileSync)(p, "utf-8"));
46430
46505
  if (data.version) return data.version;
46431
46506
  } catch {
46432
46507
  }
46433
46508
  }
46434
46509
  return injectedVersion;
46435
46510
  }
46436
- var import_fs3, import_path2;
46511
+ var import_fs4, import_path3;
46437
46512
  var init_version = __esm({
46438
46513
  "src/version.ts"() {
46439
46514
  "use strict";
46440
- import_fs3 = require("fs");
46441
- import_path2 = require("path");
46515
+ import_fs4 = require("fs");
46516
+ import_path3 = require("path");
46442
46517
  }
46443
46518
  });
46444
46519
 
@@ -46516,7 +46591,7 @@ var init_adhdev_daemon = __esm({
46516
46591
  import_ws3 = require("ws");
46517
46592
  import_chalk2 = __toESM(require("chalk"));
46518
46593
  init_version();
46519
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.19" });
46594
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.20" });
46520
46595
  DANGEROUS_PATTERNS = [
46521
46596
  /\brm\s+(-[a-z]*f|-[a-z]*r|--force|--recursive)/i,
46522
46597
  /\bsudo\b/i,
@@ -47872,7 +47947,7 @@ function registerSetupCommands(program2, providerLoader) {
47872
47947
  }
47873
47948
  });
47874
47949
  program2.command("logout").description("Log out from ADHDev (clear auth credentials, keep config)").option("-f, --force", "Skip confirmation prompt").action(async (options) => {
47875
- const { loadConfig: loadConfig2, saveConfig: saveConfig2 } = await Promise.resolve().then(() => (init_src(), src_exports));
47950
+ const { loadConfig: loadConfig2, saveConfig: saveConfig3 } = await Promise.resolve().then(() => (init_src(), src_exports));
47876
47951
  if (!options.force) {
47877
47952
  const inquirer2 = await import("inquirer");
47878
47953
  const { confirm } = await inquirer2.default.prompt([
@@ -47897,7 +47972,7 @@ function registerSetupCommands(program2, providerLoader) {
47897
47972
  config2.machineSecret = void 0;
47898
47973
  config2.userEmail = null;
47899
47974
  config2.userName = null;
47900
- saveConfig2(config2);
47975
+ saveConfig3(config2);
47901
47976
  console.log(import_chalk4.default.green("\n\u2713 Logged out successfully."));
47902
47977
  console.log(import_chalk4.default.gray(" Auth credentials cleared. IDE and workspace settings preserved."));
47903
47978
  console.log(import_chalk4.default.gray(" Run `adhdev setup` to log in again.\n"));