@adhdev/daemon-core 0.9.5 → 0.9.6
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/index.js +59 -9
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +59 -9
- package/dist/index.mjs.map +1 -1
- package/dist/providers/cli-provider-instance.d.ts +7 -0
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +1 -1
- package/src/providers/cli-provider-instance.ts +59 -15
- package/src/providers/provider-schema.ts +1 -0
|
@@ -51,6 +51,13 @@ export declare class CliProviderInstance implements ProviderInstance {
|
|
|
51
51
|
private runtimeMessages;
|
|
52
52
|
private lastPersistedHistoryMessages;
|
|
53
53
|
private lastCanonicalHermesSyncMtimeMs;
|
|
54
|
+
private lastCanonicalHermesExistCheckAt;
|
|
55
|
+
private lastCanonicalHermesWatchPath;
|
|
56
|
+
private lastCanonicalClaudeRebuildMtimeMs;
|
|
57
|
+
private lastCanonicalClaudeCheckAt;
|
|
58
|
+
private cachedSqliteDb;
|
|
59
|
+
private cachedSqliteDbPath;
|
|
60
|
+
private cachedSqliteDbMissingUntil;
|
|
54
61
|
readonly instanceId: string;
|
|
55
62
|
private suppressIdleHistoryReplay;
|
|
56
63
|
private errorMessage;
|
package/package.json
CHANGED
|
@@ -161,6 +161,16 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
161
161
|
private runtimeMessages: Array<{ key: string; message: ChatMessage }> = [];
|
|
162
162
|
private lastPersistedHistoryMessages: PersistableCliHistoryMessage[] = [];
|
|
163
163
|
private lastCanonicalHermesSyncMtimeMs = 0;
|
|
164
|
+
private lastCanonicalHermesExistCheckAt = 0;
|
|
165
|
+
private lastCanonicalHermesWatchPath: string | undefined = undefined;
|
|
166
|
+
private lastCanonicalClaudeRebuildMtimeMs = 0;
|
|
167
|
+
private lastCanonicalClaudeCheckAt = 0;
|
|
168
|
+
private cachedSqliteDb: {
|
|
169
|
+
prepare(sql: string): { get(...values: Array<string | number>): unknown };
|
|
170
|
+
close(): void;
|
|
171
|
+
} | null = null;
|
|
172
|
+
private cachedSqliteDbPath: string | null = null;
|
|
173
|
+
private cachedSqliteDbMissingUntil = 0;
|
|
164
174
|
readonly instanceId: string;
|
|
165
175
|
private suppressIdleHistoryReplay = false;
|
|
166
176
|
private errorMessage: string | undefined = undefined;
|
|
@@ -281,7 +291,13 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
281
291
|
timestampFormat?: 'unix_ms' | 'unix_s' | 'iso';
|
|
282
292
|
}): string | null {
|
|
283
293
|
const resolvedDbPath = probe.dbPath.replace(/^~/, os.homedir());
|
|
284
|
-
if (
|
|
294
|
+
// Skip existsSync if we already confirmed DB is missing (cache for 10s)
|
|
295
|
+
const now = Date.now();
|
|
296
|
+
if (this.cachedSqliteDbMissingUntil > now) return null;
|
|
297
|
+
if (!fs.existsSync(resolvedDbPath)) {
|
|
298
|
+
this.cachedSqliteDbMissingUntil = now + 10_000;
|
|
299
|
+
return null;
|
|
300
|
+
}
|
|
285
301
|
|
|
286
302
|
const directories = this.getProbeDirectories();
|
|
287
303
|
const minCreatedAt = Math.max(0, this.startedAt - 60_000);
|
|
@@ -486,6 +502,9 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
486
502
|
this.adapter.shutdown();
|
|
487
503
|
this.monitor.reset();
|
|
488
504
|
this.appliedEffectKeys.clear();
|
|
505
|
+
try { this.cachedSqliteDb?.close(); } catch { /* noop */ }
|
|
506
|
+
this.cachedSqliteDb = null;
|
|
507
|
+
this.cachedSqliteDbPath = null;
|
|
489
508
|
}
|
|
490
509
|
|
|
491
510
|
private completedDebounceTimer: NodeJS.Timeout | null = null;
|
|
@@ -944,13 +963,38 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
944
963
|
const watchPath = canonicalHistory.watchPath
|
|
945
964
|
.replace(/^~/, os.homedir())
|
|
946
965
|
.replace('{{sessionId}}', this.providerSessionId);
|
|
947
|
-
|
|
966
|
+
// Throttle existsSync: check file existence at most once per 2s
|
|
967
|
+
const now = Date.now();
|
|
968
|
+
if (watchPath !== this.lastCanonicalHermesWatchPath || now - this.lastCanonicalHermesExistCheckAt >= 2_000) {
|
|
969
|
+
this.lastCanonicalHermesWatchPath = watchPath;
|
|
970
|
+
this.lastCanonicalHermesExistCheckAt = now;
|
|
971
|
+
if (!fs.existsSync(watchPath)) return false;
|
|
972
|
+
} else if (this.lastCanonicalHermesSyncMtimeMs === 0) {
|
|
973
|
+
// First check: file existence not yet confirmed, must verify
|
|
974
|
+
if (!fs.existsSync(watchPath)) return false;
|
|
975
|
+
}
|
|
948
976
|
const stat = fs.statSync(watchPath);
|
|
949
977
|
if (stat.mtimeMs <= this.lastCanonicalHermesSyncMtimeMs) return true;
|
|
950
978
|
rebuilt = rebuildHermesSavedHistoryFromCanonicalSession(this.providerSessionId);
|
|
951
979
|
if (rebuilt) this.lastCanonicalHermesSyncMtimeMs = stat.mtimeMs;
|
|
952
980
|
} else if (canonicalHistory.format === 'claude-jsonl') {
|
|
981
|
+
// Throttle: only check for changes at most once per 2s
|
|
982
|
+
const now = Date.now();
|
|
983
|
+
if (now - this.lastCanonicalClaudeCheckAt < 2_000 && this.lastCanonicalClaudeRebuildMtimeMs !== 0) {
|
|
984
|
+
return true;
|
|
985
|
+
}
|
|
986
|
+
this.lastCanonicalClaudeCheckAt = now;
|
|
987
|
+
// Only rebuild if the transcript file has changed since last rebuild
|
|
988
|
+
const claudeProjectsDir = path.join(os.homedir(), '.claude', 'projects');
|
|
989
|
+
const workspaceSegment = typeof this.workingDir === 'string'
|
|
990
|
+
? this.workingDir.replace(/[\\/]/g, '-').replace(/^-+/, '')
|
|
991
|
+
: '';
|
|
992
|
+
const transcriptFile = path.join(claudeProjectsDir, workspaceSegment, `${this.providerSessionId}.jsonl`);
|
|
993
|
+
let transcriptMtime = 0;
|
|
994
|
+
try { transcriptMtime = fs.statSync(transcriptFile).mtimeMs; } catch { /* not found yet */ }
|
|
995
|
+
if (transcriptMtime > 0 && transcriptMtime <= this.lastCanonicalClaudeRebuildMtimeMs) return true;
|
|
953
996
|
rebuilt = rebuildClaudeSavedHistoryFromNativeProject(this.providerSessionId, this.workingDir);
|
|
997
|
+
if (rebuilt) this.lastCanonicalClaudeRebuildMtimeMs = transcriptMtime || Date.now();
|
|
954
998
|
}
|
|
955
999
|
if (!rebuilt) return false;
|
|
956
1000
|
const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId, 0, this.provider.historyBehavior);
|
|
@@ -1023,24 +1067,24 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
1023
1067
|
}
|
|
1024
1068
|
|
|
1025
1069
|
private querySqliteText(dbPath: string, query: string, params: Array<string | number>): string | null {
|
|
1026
|
-
let db: {
|
|
1027
|
-
prepare(sql: string): { get(...values: Array<string | number>): unknown };
|
|
1028
|
-
close(): void;
|
|
1029
|
-
} | null = null;
|
|
1030
1070
|
try {
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1071
|
+
if (this.cachedSqliteDb === null || this.cachedSqliteDbPath !== dbPath) {
|
|
1072
|
+
try { this.cachedSqliteDb?.close(); } catch { /* noop */ }
|
|
1073
|
+
this.cachedSqliteDb = null;
|
|
1074
|
+
this.cachedSqliteDbPath = null;
|
|
1075
|
+
const DatabaseSync = getDatabaseSync();
|
|
1076
|
+
this.cachedSqliteDb = new DatabaseSync(dbPath, { readOnly: true });
|
|
1077
|
+
this.cachedSqliteDbPath = dbPath;
|
|
1078
|
+
}
|
|
1079
|
+
const row = this.cachedSqliteDb!.prepare(query).get(...params) as { id?: unknown } | undefined;
|
|
1034
1080
|
const sessionId = typeof row?.id === 'string' ? row.id.trim() : '';
|
|
1035
1081
|
return sessionId || null;
|
|
1036
1082
|
} catch {
|
|
1083
|
+
// Close cached connection on error so we retry fresh next tick
|
|
1084
|
+
try { this.cachedSqliteDb?.close(); } catch { /* noop */ }
|
|
1085
|
+
this.cachedSqliteDb = null;
|
|
1086
|
+
this.cachedSqliteDbPath = null;
|
|
1037
1087
|
return null;
|
|
1038
|
-
} finally {
|
|
1039
|
-
try {
|
|
1040
|
-
db?.close();
|
|
1041
|
-
} catch {
|
|
1042
|
-
// noop
|
|
1043
|
-
}
|
|
1044
1088
|
}
|
|
1045
1089
|
}
|
|
1046
1090
|
}
|