@adhdev/daemon-core 0.8.19 → 0.8.21

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.
@@ -4,11 +4,10 @@
4
4
  * Manages launcher config, machine auth, and user preferences.
5
5
  */
6
6
  import type { WorkspaceEntry } from './workspaces.js';
7
- import type { RecentActivityEntry } from './recent-activity.js';
8
- import type { SavedProviderSessionEntry } from './saved-sessions.js';
9
7
  export type { WorkspaceEntry } from './workspaces.js';
10
8
  export type { RecentActivityEntry } from './recent-activity.js';
11
9
  export type { SavedProviderSessionEntry } from './saved-sessions.js';
10
+ export type { DaemonState } from './state-store.js';
12
11
  export interface ADHDevConfig {
13
12
  serverUrl: string;
14
13
  selectedIde: string | null;
@@ -23,14 +22,6 @@ export interface ADHDevConfig {
23
22
  workspaces?: WorkspaceEntry[];
24
23
  /** Default workspace id (from workspaces[]) — never used implicitly for launch */
25
24
  defaultWorkspaceId?: string | null;
26
- /** Unified recent activity across IDE / CLI / ACP launch flows */
27
- recentActivity?: RecentActivityEntry[];
28
- /** Persistent resume-capable provider sessions keyed by providerSessionId */
29
- savedProviderSessions?: SavedProviderSessionEntry[];
30
- /** Last seen timestamps for live sessions, keyed by sessionId */
31
- sessionReads?: Record<string, number>;
32
- /** Last seen completion marker for live sessions, keyed by sessionId */
33
- sessionReadMarkers?: Record<string, string>;
34
25
  machineNickname: string | null;
35
26
  /**
36
27
  * Stable local machine ID (prefix: `mach_`) — generated locally on first run.
@@ -6,7 +6,7 @@
6
6
  * - deduped by provider session when available, else by kind + providerType + workspace
7
7
  * - used only for quick-launch shortcuts
8
8
  */
9
- import type { ADHDevConfig } from './config.js';
9
+ import type { DaemonState } from './state-store.js';
10
10
  export interface RecentActivityEntry {
11
11
  id: string;
12
12
  kind: 'ide' | 'cli' | 'acp';
@@ -20,10 +20,10 @@ export interface RecentActivityEntry {
20
20
  }
21
21
  export declare function buildRecentActivityKey(entry: Pick<RecentActivityEntry, 'kind' | 'providerType' | 'workspace'>): string;
22
22
  export declare function buildRecentActivityKeyForEntry(entry: Pick<RecentActivityEntry, 'kind' | 'providerType' | 'workspace' | 'providerSessionId'>): string;
23
- export declare function appendRecentActivity(config: ADHDevConfig, entry: Omit<RecentActivityEntry, 'id' | 'lastUsedAt'> & {
23
+ export declare function appendRecentActivity(state: DaemonState, entry: Omit<RecentActivityEntry, 'id' | 'lastUsedAt'> & {
24
24
  lastUsedAt?: number;
25
- }): ADHDevConfig;
26
- export declare function getRecentActivity(config: ADHDevConfig, limit?: number): RecentActivityEntry[];
27
- export declare function getSessionSeenAt(config: ADHDevConfig, sessionId: string): number;
28
- export declare function getSessionSeenMarker(config: ADHDevConfig, sessionId: string): string;
29
- export declare function markSessionSeen(config: ADHDevConfig, sessionId: string, seenAt?: number, completionMarker?: string | null): ADHDevConfig;
25
+ }): DaemonState;
26
+ export declare function getRecentActivity(state: DaemonState, limit?: number): RecentActivityEntry[];
27
+ export declare function getSessionSeenAt(state: DaemonState, sessionId: string): number;
28
+ export declare function getSessionSeenMarker(state: DaemonState, sessionId: string): string;
29
+ export declare function markSessionSeen(state: DaemonState, sessionId: string, seenAt?: number, completionMarker?: string | null): DaemonState;
@@ -1,4 +1,4 @@
1
- import type { ADHDevConfig } from './config.js';
1
+ import type { DaemonState } from './state-store.js';
2
2
  export interface SavedProviderSessionEntry {
3
3
  id: string;
4
4
  kind: 'cli' | 'acp';
@@ -12,11 +12,11 @@ export interface SavedProviderSessionEntry {
12
12
  lastUsedAt: number;
13
13
  }
14
14
  export declare function buildSavedProviderSessionKey(providerSessionId: string): string;
15
- export declare function upsertSavedProviderSession(config: ADHDevConfig, entry: Omit<SavedProviderSessionEntry, 'id' | 'createdAt' | 'lastUsedAt'> & {
15
+ export declare function upsertSavedProviderSession(state: DaemonState, entry: Omit<SavedProviderSessionEntry, 'id' | 'createdAt' | 'lastUsedAt'> & {
16
16
  createdAt?: number;
17
17
  lastUsedAt?: number;
18
- }): ADHDevConfig;
19
- export declare function getSavedProviderSessions(config: ADHDevConfig, filters?: {
18
+ }): DaemonState;
19
+ export declare function getSavedProviderSessions(state: DaemonState, filters?: {
20
20
  providerType?: string;
21
21
  kind?: SavedProviderSessionEntry['kind'];
22
22
  }): SavedProviderSessionEntry[];
@@ -0,0 +1,32 @@
1
+ /**
2
+ * ADHDev State Store — Runtime state persistence
3
+ *
4
+ * Separates volatile runtime state (sessions, activity, read markers)
5
+ * from static configuration (config.json).
6
+ *
7
+ * State is stored in ~/.adhdev/state.json
8
+ */
9
+ import type { RecentActivityEntry } from './recent-activity.js';
10
+ import type { SavedProviderSessionEntry } from './saved-sessions.js';
11
+ export interface DaemonState {
12
+ /** Unified recent activity across IDE / CLI / ACP launch flows */
13
+ recentActivity: RecentActivityEntry[];
14
+ /** Persistent resume-capable provider sessions keyed by providerSessionId */
15
+ savedProviderSessions: SavedProviderSessionEntry[];
16
+ /** Last seen timestamps for live sessions, keyed by sessionId */
17
+ sessionReads: Record<string, number>;
18
+ /** Last seen completion marker for live sessions, keyed by sessionId */
19
+ sessionReadMarkers: Record<string, string>;
20
+ }
21
+ /**
22
+ * Load runtime state from disk
23
+ */
24
+ export declare function loadState(): DaemonState;
25
+ /**
26
+ * Save runtime state to disk
27
+ */
28
+ export declare function saveState(state: DaemonState): void;
29
+ /**
30
+ * Reset runtime state
31
+ */
32
+ export declare function resetState(): void;
package/dist/index.d.ts CHANGED
@@ -22,6 +22,8 @@ export { appendRecentActivity, getRecentActivity } from './config/recent-activit
22
22
  export type { RecentActivityEntry } from './config/recent-activity.js';
23
23
  export { getSavedProviderSessions, upsertSavedProviderSession } from './config/saved-sessions.js';
24
24
  export type { SavedProviderSessionEntry } from './config/saved-sessions.js';
25
+ export { loadState, saveState, resetState } from './config/state-store.js';
26
+ export type { DaemonState } from './config/state-store.js';
25
27
  export { detectIDEs } from './detection/ide-detector.js';
26
28
  export type { IDEInfo } from './detection/ide-detector.js';
27
29
  export { detectCLIs } from './detection/cli-detector.js';
package/dist/index.js CHANGED
@@ -61,14 +61,6 @@ function asBoolean(value, fallback) {
61
61
  }
62
62
  function normalizeConfig(raw) {
63
63
  const parsed = isPlainObject(raw) ? raw : {};
64
- const legacySessionReads = isPlainObject(parsed.recentSessionReads) ? parsed.recentSessionReads : {};
65
- const sessionReads = isPlainObject(parsed.sessionReads) ? parsed.sessionReads : {};
66
- const mergedSessionReads = Object.fromEntries(
67
- Object.entries({ ...legacySessionReads, ...sessionReads }).filter(([, value]) => typeof value === "number" && Number.isFinite(value))
68
- );
69
- const sessionReadMarkers = Object.fromEntries(
70
- Object.entries(isPlainObject(parsed.sessionReadMarkers) ? parsed.sessionReadMarkers : {}).filter(([, value]) => typeof value === "string")
71
- );
72
64
  return {
73
65
  serverUrl: typeof parsed.serverUrl === "string" && parsed.serverUrl.trim() ? parsed.serverUrl : DEFAULT_CONFIG.serverUrl,
74
66
  selectedIde: asNullableString(parsed.selectedIde),
@@ -81,10 +73,6 @@ function normalizeConfig(raw) {
81
73
  enabledIdes: asStringArray(parsed.enabledIdes),
82
74
  workspaces: Array.isArray(parsed.workspaces) ? parsed.workspaces : [],
83
75
  defaultWorkspaceId: asNullableString(parsed.defaultWorkspaceId) ?? asNullableString(parsed.activeWorkspaceId),
84
- recentActivity: Array.isArray(parsed.recentActivity) ? parsed.recentActivity : [],
85
- savedProviderSessions: Array.isArray(parsed.savedProviderSessions) ? parsed.savedProviderSessions : [],
86
- sessionReads: mergedSessionReads,
87
- sessionReadMarkers,
88
76
  machineNickname: asNullableString(parsed.machineNickname),
89
77
  machineId: asOptionalString(parsed.machineId),
90
78
  machineSecret: parsed.machineSecret === null ? null : asOptionalString(parsed.machineSecret),
@@ -125,6 +113,30 @@ function getConfigDir() {
125
113
  function getConfigPath() {
126
114
  return (0, import_path.join)(getConfigDir(), "config.json");
127
115
  }
116
+ function migrateStateToStateFile(raw) {
117
+ const statePath = (0, import_path.join)(getConfigDir(), "state.json");
118
+ if ((0, import_fs.existsSync)(statePath)) return;
119
+ const recentActivity = Array.isArray(raw.recentActivity) ? raw.recentActivity : [];
120
+ const savedProviderSessions = Array.isArray(raw.savedProviderSessions) ? raw.savedProviderSessions : [];
121
+ const legacySessionReads = isPlainObject(raw.recentSessionReads) ? raw.recentSessionReads : {};
122
+ const sessionReads = isPlainObject(raw.sessionReads) ? raw.sessionReads : {};
123
+ const sessionReadMarkers = isPlainObject(raw.sessionReadMarkers) ? raw.sessionReadMarkers : {};
124
+ const hasData = recentActivity.length > 0 || savedProviderSessions.length > 0 || Object.keys(sessionReads).length > 0 || Object.keys(legacySessionReads).length > 0 || Object.keys(sessionReadMarkers).length > 0;
125
+ if (!hasData) return;
126
+ const mergedReads = Object.fromEntries(
127
+ Object.entries({ ...legacySessionReads, ...sessionReads }).filter(([, v]) => typeof v === "number" && Number.isFinite(v))
128
+ );
129
+ const cleanedMarkers = Object.fromEntries(
130
+ Object.entries(sessionReadMarkers).filter(([, v]) => typeof v === "string")
131
+ );
132
+ const state = {
133
+ recentActivity,
134
+ savedProviderSessions,
135
+ sessionReads: mergedReads,
136
+ sessionReadMarkers: cleanedMarkers
137
+ };
138
+ (0, import_fs.writeFileSync)(statePath, JSON.stringify(state, null, 2), { encoding: "utf-8", mode: 384 });
139
+ }
128
140
  function loadConfig() {
129
141
  const configPath = getConfigPath();
130
142
  if (!(0, import_fs.existsSync)(configPath)) {
@@ -138,6 +150,7 @@ function loadConfig() {
138
150
  try {
139
151
  const raw = (0, import_fs.readFileSync)(configPath, "utf-8");
140
152
  const parsed = JSON.parse(raw);
153
+ migrateStateToStateFile(parsed);
141
154
  const normalizedInput = normalizeConfig(parsed);
142
155
  const ensured = ensureMachineId(normalizedInput);
143
156
  const normalized = ensured.config;
@@ -209,10 +222,6 @@ var init_config = __esm({
209
222
  enabledIdes: [],
210
223
  workspaces: [],
211
224
  defaultWorkspaceId: null,
212
- recentActivity: [],
213
- savedProviderSessions: [],
214
- sessionReads: {},
215
- sessionReadMarkers: {},
216
225
  machineNickname: null,
217
226
  machineId: void 0,
218
227
  machineSecret: null,
@@ -2604,6 +2613,7 @@ __export(index_exports, {
2604
2613
  launchWithCdp: () => launchWithCdp,
2605
2614
  listHostedCliRuntimes: () => listHostedCliRuntimes,
2606
2615
  loadConfig: () => loadConfig,
2616
+ loadState: () => loadState,
2607
2617
  logCommand: () => logCommand,
2608
2618
  markSetupComplete: () => markSetupComplete,
2609
2619
  maybeRunDaemonUpgradeHelperFromEnv: () => maybeRunDaemonUpgradeHelperFromEnv,
@@ -2613,7 +2623,9 @@ __export(index_exports, {
2613
2623
  readChatHistory: () => readChatHistory,
2614
2624
  registerExtensionProviders: () => registerExtensionProviders,
2615
2625
  resetConfig: () => resetConfig,
2626
+ resetState: () => resetState,
2616
2627
  saveConfig: () => saveConfig,
2628
+ saveState: () => saveState,
2617
2629
  setLogLevel: () => setLogLevel,
2618
2630
  setupIdeInstance: () => setupIdeInstance,
2619
2631
  shutdownDaemonComponents: () => shutdownDaemonComponents,
@@ -2812,35 +2824,35 @@ function buildRecentActivityKeyForEntry(entry) {
2812
2824
  }
2813
2825
  return buildRecentActivityKey(entry);
2814
2826
  }
2815
- function appendRecentActivity(config, entry) {
2827
+ function appendRecentActivity(state, entry) {
2816
2828
  const nextEntry = {
2817
2829
  ...entry,
2818
2830
  workspace: entry.workspace ? normalizeWorkspace(entry.workspace) : void 0,
2819
2831
  id: buildRecentActivityKeyForEntry(entry),
2820
2832
  lastUsedAt: entry.lastUsedAt || Date.now()
2821
2833
  };
2822
- const filtered = (config.recentActivity || []).filter((item) => item.id !== nextEntry.id);
2834
+ const filtered = (state.recentActivity || []).filter((item) => item.id !== nextEntry.id);
2823
2835
  return {
2824
- ...config,
2836
+ ...state,
2825
2837
  recentActivity: [nextEntry, ...filtered].slice(0, MAX_ACTIVITY)
2826
2838
  };
2827
2839
  }
2828
- function getRecentActivity(config, limit = 20) {
2829
- return [...config.recentActivity || []].sort((a, b) => b.lastUsedAt - a.lastUsedAt).slice(0, limit);
2840
+ function getRecentActivity(state, limit = 20) {
2841
+ return [...state.recentActivity || []].sort((a, b) => b.lastUsedAt - a.lastUsedAt).slice(0, limit);
2830
2842
  }
2831
- function getSessionSeenAt(config, sessionId) {
2832
- return config.sessionReads?.[sessionId] || 0;
2843
+ function getSessionSeenAt(state, sessionId) {
2844
+ return state.sessionReads?.[sessionId] || 0;
2833
2845
  }
2834
- function getSessionSeenMarker(config, sessionId) {
2835
- return config.sessionReadMarkers?.[sessionId] || "";
2846
+ function getSessionSeenMarker(state, sessionId) {
2847
+ return state.sessionReadMarkers?.[sessionId] || "";
2836
2848
  }
2837
- function markSessionSeen(config, sessionId, seenAt = Date.now(), completionMarker) {
2838
- const prev = config.sessionReads || {};
2849
+ function markSessionSeen(state, sessionId, seenAt = Date.now(), completionMarker) {
2850
+ const prev = state.sessionReads || {};
2839
2851
  const nextSeenAt = Math.max(prev[sessionId] || 0, seenAt);
2840
- const prevMarkers = config.sessionReadMarkers || {};
2852
+ const prevMarkers = state.sessionReadMarkers || {};
2841
2853
  const nextMarker = typeof completionMarker === "string" ? completionMarker : "";
2842
2854
  return {
2843
- ...config,
2855
+ ...state,
2844
2856
  sessionReads: {
2845
2857
  ...prev,
2846
2858
  [sessionId]: nextSeenAt
@@ -2866,11 +2878,11 @@ function normalizeWorkspace2(workspace) {
2866
2878
  function buildSavedProviderSessionKey(providerSessionId) {
2867
2879
  return `saved:${providerSessionId.trim()}`;
2868
2880
  }
2869
- function upsertSavedProviderSession(config, entry) {
2881
+ function upsertSavedProviderSession(state, entry) {
2870
2882
  const providerSessionId = typeof entry.providerSessionId === "string" ? entry.providerSessionId.trim() : "";
2871
- if (!providerSessionId) return config;
2883
+ if (!providerSessionId) return state;
2872
2884
  const id = buildSavedProviderSessionKey(providerSessionId);
2873
- const existing = (config.savedProviderSessions || []).find((item) => item.id === id);
2885
+ const existing = (state.savedProviderSessions || []).find((item) => item.id === id);
2874
2886
  const nextEntry = {
2875
2887
  id,
2876
2888
  kind: entry.kind,
@@ -2883,23 +2895,75 @@ function upsertSavedProviderSession(config, entry) {
2883
2895
  createdAt: existing?.createdAt || entry.createdAt || Date.now(),
2884
2896
  lastUsedAt: entry.lastUsedAt || Date.now()
2885
2897
  };
2886
- const filtered = (config.savedProviderSessions || []).filter((item) => item.id !== id);
2898
+ const filtered = (state.savedProviderSessions || []).filter((item) => item.id !== id);
2887
2899
  return {
2888
- ...config,
2900
+ ...state,
2889
2901
  savedProviderSessions: [nextEntry, ...filtered].slice(0, MAX_SAVED_SESSIONS)
2890
2902
  };
2891
2903
  }
2892
- function getSavedProviderSessions(config, filters) {
2893
- return [...config.savedProviderSessions || []].filter((entry) => {
2904
+ function getSavedProviderSessions(state, filters) {
2905
+ return [...state.savedProviderSessions || []].filter((entry) => {
2894
2906
  if (filters?.providerType && entry.providerType !== filters.providerType) return false;
2895
2907
  if (filters?.kind && entry.kind !== filters.kind) return false;
2896
2908
  return true;
2897
2909
  }).sort((a, b) => b.lastUsedAt - a.lastUsedAt);
2898
2910
  }
2899
2911
 
2912
+ // src/config/state-store.ts
2913
+ var import_fs2 = require("fs");
2914
+ var import_path2 = require("path");
2915
+ init_config();
2916
+ var DEFAULT_STATE = {
2917
+ recentActivity: [],
2918
+ savedProviderSessions: [],
2919
+ sessionReads: {},
2920
+ sessionReadMarkers: {}
2921
+ };
2922
+ function isPlainObject2(value) {
2923
+ return !!value && typeof value === "object" && !Array.isArray(value);
2924
+ }
2925
+ function getStatePath() {
2926
+ return (0, import_path2.join)(getConfigDir(), "state.json");
2927
+ }
2928
+ function normalizeState(raw) {
2929
+ const parsed = isPlainObject2(raw) ? raw : {};
2930
+ const sessionReads = Object.fromEntries(
2931
+ Object.entries(isPlainObject2(parsed.sessionReads) ? parsed.sessionReads : {}).filter(([, value]) => typeof value === "number" && Number.isFinite(value))
2932
+ );
2933
+ const sessionReadMarkers = Object.fromEntries(
2934
+ Object.entries(isPlainObject2(parsed.sessionReadMarkers) ? parsed.sessionReadMarkers : {}).filter(([, value]) => typeof value === "string")
2935
+ );
2936
+ return {
2937
+ recentActivity: Array.isArray(parsed.recentActivity) ? parsed.recentActivity : [],
2938
+ savedProviderSessions: Array.isArray(parsed.savedProviderSessions) ? parsed.savedProviderSessions : [],
2939
+ sessionReads,
2940
+ sessionReadMarkers
2941
+ };
2942
+ }
2943
+ function loadState() {
2944
+ const statePath = getStatePath();
2945
+ if (!(0, import_fs2.existsSync)(statePath)) {
2946
+ return { ...DEFAULT_STATE };
2947
+ }
2948
+ try {
2949
+ const raw = (0, import_fs2.readFileSync)(statePath, "utf-8");
2950
+ return normalizeState(JSON.parse(raw));
2951
+ } catch {
2952
+ return { ...DEFAULT_STATE };
2953
+ }
2954
+ }
2955
+ function saveState(state) {
2956
+ const statePath = getStatePath();
2957
+ const normalized = normalizeState(state);
2958
+ (0, import_fs2.writeFileSync)(statePath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
2959
+ }
2960
+ function resetState() {
2961
+ saveState({ ...DEFAULT_STATE });
2962
+ }
2963
+
2900
2964
  // src/detection/ide-detector.ts
2901
2965
  var import_child_process = require("child_process");
2902
- var import_fs2 = require("fs");
2966
+ var import_fs3 = require("fs");
2903
2967
  var import_os2 = require("os");
2904
2968
  var BUILTIN_IDE_DEFINITIONS = [];
2905
2969
  var registeredIDEs = /* @__PURE__ */ new Map();
@@ -2945,9 +3009,9 @@ function checkPathExists(paths) {
2945
3009
  if (p.includes("*")) {
2946
3010
  const username = home.split(/[\\/]/).pop() || "";
2947
3011
  const resolved = p.replace("*", username);
2948
- if ((0, import_fs2.existsSync)(resolved)) return resolved;
3012
+ if ((0, import_fs3.existsSync)(resolved)) return resolved;
2949
3013
  } else {
2950
- if ((0, import_fs2.existsSync)(p)) return p;
3014
+ if ((0, import_fs3.existsSync)(p)) return p;
2951
3015
  }
2952
3016
  }
2953
3017
  return null;
@@ -2962,7 +3026,7 @@ async function detectIDEs() {
2962
3026
  let resolvedCli = cliPath;
2963
3027
  if (!resolvedCli && appPath && os18 === "darwin") {
2964
3028
  const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
2965
- if ((0, import_fs2.existsSync)(bundledCli)) resolvedCli = bundledCli;
3029
+ if ((0, import_fs3.existsSync)(bundledCli)) resolvedCli = bundledCli;
2966
3030
  }
2967
3031
  if (!resolvedCli && appPath && os18 === "win32") {
2968
3032
  const { dirname: dirname6 } = await import("path");
@@ -2975,7 +3039,7 @@ async function detectIDEs() {
2975
3039
  `${appDir}\\\\resources\\\\app\\\\bin\\\\${def.cli}.cmd`
2976
3040
  ];
2977
3041
  for (const c of candidates) {
2978
- if ((0, import_fs2.existsSync)(c)) {
3042
+ if ((0, import_fs3.existsSync)(c)) {
2979
3043
  resolvedCli = c;
2980
3044
  break;
2981
3045
  }
@@ -9609,9 +9673,9 @@ var DaemonCliManager = class {
9609
9673
  }
9610
9674
  persistRecentActivity(entry) {
9611
9675
  try {
9612
- let nextConfig = appendRecentActivity(loadConfig(), entry);
9676
+ let nextState = appendRecentActivity(loadState(), entry);
9613
9677
  if (entry.providerSessionId && (entry.kind === "cli" || entry.kind === "acp")) {
9614
- nextConfig = upsertSavedProviderSession(nextConfig, {
9678
+ nextState = upsertSavedProviderSession(nextState, {
9615
9679
  kind: entry.kind,
9616
9680
  providerType: entry.providerType,
9617
9681
  providerName: entry.providerName,
@@ -9621,7 +9685,7 @@ var DaemonCliManager = class {
9621
9685
  title: entry.title
9622
9686
  });
9623
9687
  }
9624
- saveConfig(nextConfig);
9688
+ saveState(nextState);
9625
9689
  } catch (e) {
9626
9690
  console.error(colorize("red", ` \u2717 Failed to save recent activity: ${e}`));
9627
9691
  }
@@ -10413,14 +10477,14 @@ var ProviderLoader = class _ProviderLoader {
10413
10477
  */
10414
10478
  setIdeExtensionEnabled(ideType, extensionType, enabled) {
10415
10479
  try {
10416
- const { loadConfig: loadConfig2, saveConfig: saveConfig2 } = (init_config(), __toCommonJS(config_exports));
10480
+ const { loadConfig: loadConfig2, saveConfig: saveConfig3 } = (init_config(), __toCommonJS(config_exports));
10417
10481
  const config = loadConfig2();
10418
10482
  const baseIdeType = ideType.split("_")[0];
10419
10483
  if (!config.ideSettings) config.ideSettings = {};
10420
10484
  if (!config.ideSettings[baseIdeType]) config.ideSettings[baseIdeType] = {};
10421
10485
  if (!config.ideSettings[baseIdeType].extensions) config.ideSettings[baseIdeType].extensions = {};
10422
10486
  config.ideSettings[baseIdeType].extensions[extensionType] = { enabled };
10423
- saveConfig2(config);
10487
+ saveConfig3(config);
10424
10488
  this.log(`IDE extension setting: ${ideType}.${extensionType}.enabled = ${enabled}`);
10425
10489
  return true;
10426
10490
  } catch (e) {
@@ -10985,12 +11049,12 @@ var ProviderLoader = class _ProviderLoader {
10985
11049
  }
10986
11050
  if (schemaDef.type === "select" && schemaDef.options && !schemaDef.options.includes(value)) return false;
10987
11051
  try {
10988
- const { loadConfig: loadConfig2, saveConfig: saveConfig2 } = (init_config(), __toCommonJS(config_exports));
11052
+ const { loadConfig: loadConfig2, saveConfig: saveConfig3 } = (init_config(), __toCommonJS(config_exports));
10989
11053
  const config = loadConfig2();
10990
11054
  if (!config.providerSettings) config.providerSettings = {};
10991
11055
  if (!config.providerSettings[type]) config.providerSettings[type] = {};
10992
11056
  config.providerSettings[type][key] = value;
10993
- saveConfig2(config);
11057
+ saveConfig3(config);
10994
11058
  this.log(`Setting updated: ${type}.${key} = ${JSON.stringify(value)}`);
10995
11059
  return true;
10996
11060
  } catch (e) {
@@ -11768,16 +11832,17 @@ function buildRecentLaunches(recentActivity) {
11768
11832
  }
11769
11833
  function buildStatusSnapshot(options) {
11770
11834
  const cfg = loadConfig();
11835
+ const state = loadState();
11771
11836
  const wsState = getWorkspaceState(cfg);
11772
11837
  const memSnap = getHostMemorySnapshot();
11773
- const recentActivity = getRecentActivity(cfg, 20);
11838
+ const recentActivity = getRecentActivity(state, 20);
11774
11839
  const sessions = buildSessionEntries(
11775
11840
  options.allStates,
11776
11841
  options.cdpManagers
11777
11842
  );
11778
11843
  for (const session of sessions) {
11779
- const lastSeenAt = getSessionSeenAt(cfg, session.id);
11780
- const seenCompletionMarker = getSessionSeenMarker(cfg, session.id);
11844
+ const lastSeenAt = getSessionSeenAt(state, session.id);
11845
+ const seenCompletionMarker = getSessionSeenMarker(state, session.id);
11781
11846
  const lastUsedAt = getSessionLastUsedAt(session);
11782
11847
  const completionMarker = getSessionCompletionMarker(session);
11783
11848
  const { unread, inboxBucket } = session.surfaceHidden ? { unread: false, inboxBucket: "idle" } : getUnreadState(
@@ -12115,9 +12180,9 @@ var DaemonCommandRouter = class {
12115
12180
  const offset = Math.max(0, Number(args?.offset) || 0);
12116
12181
  const limit = Math.max(1, Math.min(100, Number(args?.limit) || 30));
12117
12182
  const { sessions: historySessions, hasMore } = listSavedHistorySessions(providerType, { offset, limit });
12118
- const config = loadConfig();
12119
- const savedSessions = getSavedProviderSessions(config, { providerType, kind });
12120
- const recentSessions = getRecentActivity(config, 200).filter((entry) => entry.providerType === providerType && entry.kind === kind && entry.providerSessionId);
12183
+ const state = loadState();
12184
+ const savedSessions = getSavedProviderSessions(state, { providerType, kind });
12185
+ const recentSessions = getRecentActivity(state, 200).filter((entry) => entry.providerType === providerType && entry.kind === kind && entry.providerSessionId);
12121
12186
  const savedSessionById = new Map(savedSessions.map((entry) => [entry.providerSessionId, entry]));
12122
12187
  const recentSessionById = new Map(recentSessions.map((entry) => [entry.providerSessionId, entry]));
12123
12188
  const providerMeta = this.deps.providerLoader.getMeta(providerType);
@@ -12208,19 +12273,19 @@ var DaemonCommandRouter = class {
12208
12273
  this.deps.onIdeConnected?.();
12209
12274
  if (result.success && resolvedWorkspace) {
12210
12275
  try {
12211
- const next = appendRecentActivity(loadConfig(), {
12276
+ const next = appendRecentActivity(loadState(), {
12212
12277
  kind: "ide",
12213
12278
  providerType: result.ideId || ideKey,
12214
12279
  providerName: result.ideId || ideKey,
12215
12280
  workspace: resolvedWorkspace,
12216
12281
  title: result.ideId || ideKey
12217
12282
  });
12218
- saveConfig(next);
12283
+ saveState(next);
12219
12284
  } catch {
12220
12285
  }
12221
12286
  } else if (result.success && (result.ideId || ideKey)) {
12222
12287
  try {
12223
- saveConfig(appendRecentActivity(loadConfig(), {
12288
+ saveState(appendRecentActivity(loadState(), {
12224
12289
  kind: "ide",
12225
12290
  providerType: result.ideId || ideKey,
12226
12291
  providerName: result.ideId || ideKey,
@@ -12249,8 +12314,8 @@ var DaemonCommandRouter = class {
12249
12314
  if (!sessionId || typeof sessionId !== "string") {
12250
12315
  return { success: false, error: "sessionId is required" };
12251
12316
  }
12252
- const currentConfig = loadConfig();
12253
- const prevSeenAt = currentConfig.sessionReads?.[sessionId] || 0;
12317
+ const currentState = loadState();
12318
+ const prevSeenAt = currentState.sessionReads?.[sessionId] || 0;
12254
12319
  const sessionEntries = buildSessionEntries(
12255
12320
  this.deps.instanceManager.collectAllStates(),
12256
12321
  this.deps.cdpManagers
@@ -12258,7 +12323,7 @@ var DaemonCommandRouter = class {
12258
12323
  const targetSession = sessionEntries.find((entry) => entry.id === sessionId);
12259
12324
  const completionMarker = targetSession ? getSessionCompletionMarker(targetSession) : "";
12260
12325
  const next = markSessionSeen(
12261
- currentConfig,
12326
+ currentState,
12262
12327
  sessionId,
12263
12328
  typeof args?.seenAt === "number" ? args.seenAt : Date.now(),
12264
12329
  completionMarker
@@ -12266,7 +12331,7 @@ var DaemonCommandRouter = class {
12266
12331
  if (READ_DEBUG_ENABLED2) {
12267
12332
  LOG.info("RecentRead", `mark_session_seen sessionId=${sessionId} seenAt=${String(args?.seenAt || "")} prevSeenAt=${String(prevSeenAt)} nextSeenAt=${String(next.sessionReads?.[sessionId] || 0)} marker=${completionMarker || "-"}`);
12268
12333
  }
12269
- saveConfig(next);
12334
+ saveState(next);
12270
12335
  this.deps.onStatusChange?.();
12271
12336
  return {
12272
12337
  success: true,
@@ -19612,6 +19677,7 @@ async function shutdownDaemonComponents(components) {
19612
19677
  launchWithCdp,
19613
19678
  listHostedCliRuntimes,
19614
19679
  loadConfig,
19680
+ loadState,
19615
19681
  logCommand,
19616
19682
  markSetupComplete,
19617
19683
  maybeRunDaemonUpgradeHelperFromEnv,
@@ -19621,7 +19687,9 @@ async function shutdownDaemonComponents(components) {
19621
19687
  readChatHistory,
19622
19688
  registerExtensionProviders,
19623
19689
  resetConfig,
19690
+ resetState,
19624
19691
  saveConfig,
19692
+ saveState,
19625
19693
  setLogLevel,
19626
19694
  setupIdeInstance,
19627
19695
  shutdownDaemonComponents,