@devness/useai 0.8.2 → 0.8.3
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 +175 -57
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -684,7 +684,7 @@ var VERSION;
|
|
|
684
684
|
var init_version = __esm({
|
|
685
685
|
"../shared/dist/constants/version.js"() {
|
|
686
686
|
"use strict";
|
|
687
|
-
VERSION = "0.8.
|
|
687
|
+
VERSION = "0.8.3";
|
|
688
688
|
}
|
|
689
689
|
});
|
|
690
690
|
|
|
@@ -34181,8 +34181,8 @@ function enrichAutoSealedSession(sealedSessionId, session2, args) {
|
|
|
34181
34181
|
if (lastRecord.type === "session_seal" && lastRecord.data["seal"]) {
|
|
34182
34182
|
try {
|
|
34183
34183
|
const sealObj = JSON.parse(lastRecord.data["seal"]);
|
|
34184
|
-
duration3 = sealObj.duration_seconds
|
|
34185
|
-
endedAt = sealObj.ended_at
|
|
34184
|
+
duration3 = sealObj.duration_seconds || Math.round((new Date(lastRecord.timestamp).getTime() - new Date(startedAt2).getTime()) / 1e3);
|
|
34185
|
+
endedAt = sealObj.ended_at && sealObj.ended_at !== startedAt2 ? sealObj.ended_at : lastRecord.timestamp;
|
|
34186
34186
|
} catch {
|
|
34187
34187
|
duration3 = Math.round((new Date(lastRecord.timestamp).getTime() - new Date(startedAt2).getTime()) / 1e3);
|
|
34188
34188
|
endedAt = lastRecord.timestamp;
|
|
@@ -34270,7 +34270,10 @@ function enrichAutoSealedSession(sealedSessionId, session2, args) {
|
|
|
34270
34270
|
files_touched: filesTouched,
|
|
34271
34271
|
evaluation: args.evaluation ?? existing.evaluation,
|
|
34272
34272
|
session_score: sessionScore ?? existing.session_score,
|
|
34273
|
-
evaluation_framework: frameworkId ?? existing.evaluation_framework
|
|
34273
|
+
evaluation_framework: frameworkId ?? existing.evaluation_framework,
|
|
34274
|
+
// Fix duration/ended_at for auto-sealed sessions that had 0s duration
|
|
34275
|
+
duration_seconds: duration3 || existing.duration_seconds,
|
|
34276
|
+
ended_at: endedAt !== startedAt2 ? endedAt : existing.ended_at
|
|
34274
34277
|
};
|
|
34275
34278
|
} else {
|
|
34276
34279
|
allSessions.push(richSeal);
|
|
@@ -34856,9 +34859,111 @@ var init_html = __esm({
|
|
|
34856
34859
|
}
|
|
34857
34860
|
});
|
|
34858
34861
|
|
|
34859
|
-
// src/
|
|
34860
|
-
import {
|
|
34862
|
+
// src/reconcile.ts
|
|
34863
|
+
import { readFileSync as readFileSync6, existsSync as existsSync9 } from "fs";
|
|
34861
34864
|
import { join as join8 } from "path";
|
|
34865
|
+
function extractSealFromChain(sessionId) {
|
|
34866
|
+
const chainPath = join8(SEALED_DIR, `${sessionId}.jsonl`);
|
|
34867
|
+
if (!existsSync9(chainPath)) return null;
|
|
34868
|
+
try {
|
|
34869
|
+
const content = readFileSync6(chainPath, "utf-8").trim();
|
|
34870
|
+
const lines = content.split("\n").filter(Boolean);
|
|
34871
|
+
if (lines.length === 0) return null;
|
|
34872
|
+
const records = lines.map((line) => JSON.parse(line));
|
|
34873
|
+
const integrity = verifyChain(records);
|
|
34874
|
+
if (!integrity.valid) return null;
|
|
34875
|
+
const sealRecord = records.find((r) => r.type === "session_seal");
|
|
34876
|
+
if (!sealRecord || !sealRecord.data["seal"]) return null;
|
|
34877
|
+
const sealData = JSON.parse(sealRecord.data["seal"]);
|
|
34878
|
+
return sealData;
|
|
34879
|
+
} catch {
|
|
34880
|
+
return null;
|
|
34881
|
+
}
|
|
34882
|
+
}
|
|
34883
|
+
function reconcileSession(indexEntry) {
|
|
34884
|
+
const chainSeal = extractSealFromChain(indexEntry.session_id);
|
|
34885
|
+
if (chainSeal === null) {
|
|
34886
|
+
const chainPath = join8(SEALED_DIR, `${indexEntry.session_id}.jsonl`);
|
|
34887
|
+
const corrupted = existsSync9(chainPath);
|
|
34888
|
+
return { session: indexEntry, corrected: false, corrupted };
|
|
34889
|
+
}
|
|
34890
|
+
let corrected = false;
|
|
34891
|
+
const fixed = { ...indexEntry };
|
|
34892
|
+
for (const field of RECONCILE_FIELDS) {
|
|
34893
|
+
const chainValue = chainSeal[field];
|
|
34894
|
+
const indexValue = indexEntry[field];
|
|
34895
|
+
if (chainValue === void 0 || chainValue === null) continue;
|
|
34896
|
+
if (chainValue !== indexValue) {
|
|
34897
|
+
fixed[field] = chainValue;
|
|
34898
|
+
corrected = true;
|
|
34899
|
+
}
|
|
34900
|
+
}
|
|
34901
|
+
if (chainSeal.evaluation && JSON.stringify(chainSeal.evaluation) !== JSON.stringify(indexEntry.evaluation)) {
|
|
34902
|
+
fixed.evaluation = chainSeal.evaluation;
|
|
34903
|
+
corrected = true;
|
|
34904
|
+
}
|
|
34905
|
+
return { session: fixed, corrected, corrupted: false };
|
|
34906
|
+
}
|
|
34907
|
+
function reconcileSessions(sessions2) {
|
|
34908
|
+
const result = {
|
|
34909
|
+
checked: 0,
|
|
34910
|
+
corrected: 0,
|
|
34911
|
+
corrupted: 0,
|
|
34912
|
+
correctedIds: [],
|
|
34913
|
+
corruptedIds: []
|
|
34914
|
+
};
|
|
34915
|
+
const reconciled = [];
|
|
34916
|
+
for (const session2 of sessions2) {
|
|
34917
|
+
const { session: fixed, corrected, corrupted } = reconcileSession(session2);
|
|
34918
|
+
result.checked++;
|
|
34919
|
+
if (corrupted) {
|
|
34920
|
+
result.corrupted++;
|
|
34921
|
+
result.corruptedIds.push(session2.session_id);
|
|
34922
|
+
}
|
|
34923
|
+
if (corrected) {
|
|
34924
|
+
result.corrected++;
|
|
34925
|
+
result.correctedIds.push(session2.session_id);
|
|
34926
|
+
}
|
|
34927
|
+
reconciled.push(fixed);
|
|
34928
|
+
}
|
|
34929
|
+
if (result.corrected > 0) {
|
|
34930
|
+
const allSessions = readJson(SESSIONS_FILE, []);
|
|
34931
|
+
for (const correctedId of result.correctedIds) {
|
|
34932
|
+
const correctedSession = reconciled.find((s) => s.session_id === correctedId);
|
|
34933
|
+
const idx = allSessions.findIndex((s) => s.session_id === correctedId);
|
|
34934
|
+
if (correctedSession && idx >= 0) {
|
|
34935
|
+
allSessions[idx] = correctedSession;
|
|
34936
|
+
}
|
|
34937
|
+
}
|
|
34938
|
+
writeJson(SESSIONS_FILE, allSessions);
|
|
34939
|
+
}
|
|
34940
|
+
return { sessions: reconciled, result };
|
|
34941
|
+
}
|
|
34942
|
+
function reconcileForSync(sessions2) {
|
|
34943
|
+
const { sessions: reconciled, result } = reconcileSessions(sessions2);
|
|
34944
|
+
const filtered = reconciled.filter(
|
|
34945
|
+
(s) => !result.corruptedIds.includes(s.session_id)
|
|
34946
|
+
);
|
|
34947
|
+
return { sessions: filtered, result };
|
|
34948
|
+
}
|
|
34949
|
+
var RECONCILE_FIELDS;
|
|
34950
|
+
var init_reconcile = __esm({
|
|
34951
|
+
"src/reconcile.ts"() {
|
|
34952
|
+
"use strict";
|
|
34953
|
+
init_dist();
|
|
34954
|
+
RECONCILE_FIELDS = [
|
|
34955
|
+
"duration_seconds",
|
|
34956
|
+
"ended_at",
|
|
34957
|
+
"started_at",
|
|
34958
|
+
"session_score",
|
|
34959
|
+
"files_touched"
|
|
34960
|
+
];
|
|
34961
|
+
}
|
|
34962
|
+
});
|
|
34963
|
+
|
|
34964
|
+
// src/dashboard/local-api.ts
|
|
34965
|
+
import { existsSync as existsSync10, unlinkSync as unlinkSync4 } from "fs";
|
|
34966
|
+
import { join as join9 } from "path";
|
|
34862
34967
|
function json(res, status, data) {
|
|
34863
34968
|
const body = JSON.stringify(data);
|
|
34864
34969
|
res.writeHead(status, {
|
|
@@ -34914,7 +35019,8 @@ function calculateStreak(sessions2) {
|
|
|
34914
35019
|
}
|
|
34915
35020
|
function handleLocalSessions(_req, res) {
|
|
34916
35021
|
try {
|
|
34917
|
-
const
|
|
35022
|
+
const deduplicated = deduplicateSessions(readJson(SESSIONS_FILE, []));
|
|
35023
|
+
const { sessions: sessions2 } = reconcileSessions(deduplicated);
|
|
34918
35024
|
json(res, 200, sessions2);
|
|
34919
35025
|
} catch (err) {
|
|
34920
35026
|
json(res, 500, { error: err.message });
|
|
@@ -34922,7 +35028,8 @@ function handleLocalSessions(_req, res) {
|
|
|
34922
35028
|
}
|
|
34923
35029
|
function handleLocalStats(_req, res) {
|
|
34924
35030
|
try {
|
|
34925
|
-
const
|
|
35031
|
+
const deduplicated = deduplicateSessions(readJson(SESSIONS_FILE, []));
|
|
35032
|
+
const { sessions: sessions2 } = reconcileSessions(deduplicated);
|
|
34926
35033
|
let totalSeconds = 0;
|
|
34927
35034
|
let filesTouched = 0;
|
|
34928
35035
|
const byClient = {};
|
|
@@ -35037,7 +35144,8 @@ async function performSync() {
|
|
|
35037
35144
|
"Content-Type": "application/json",
|
|
35038
35145
|
"Authorization": `Bearer ${token}`
|
|
35039
35146
|
};
|
|
35040
|
-
const
|
|
35147
|
+
const deduplicated = deduplicateSessions(readJson(SESSIONS_FILE, []));
|
|
35148
|
+
const { sessions: sessions2 } = reconcileForSync(deduplicated);
|
|
35041
35149
|
const byDate = /* @__PURE__ */ new Map();
|
|
35042
35150
|
for (const s of sessions2) {
|
|
35043
35151
|
if (!s.started_at) continue;
|
|
@@ -35080,22 +35188,31 @@ async function performSync() {
|
|
|
35080
35188
|
}
|
|
35081
35189
|
if (syncInclude.milestones) {
|
|
35082
35190
|
const MILESTONE_CHUNK = 50;
|
|
35083
|
-
const
|
|
35084
|
-
const
|
|
35085
|
-
|
|
35086
|
-
|
|
35087
|
-
|
|
35088
|
-
|
|
35089
|
-
const chunk = sanitizedMilestones.slice(i, i + MILESTONE_CHUNK);
|
|
35090
|
-
const milestonesRes = await fetch(`${USEAI_API}/api/publish`, {
|
|
35091
|
-
method: "POST",
|
|
35092
|
-
headers,
|
|
35093
|
-
body: JSON.stringify({ milestones: chunk })
|
|
35191
|
+
const allMilestones = readJson(MILESTONES_FILE, []);
|
|
35192
|
+
const unpublished = allMilestones.filter((m) => !m.published && m.title && m.category);
|
|
35193
|
+
if (unpublished.length > 0) {
|
|
35194
|
+
const sanitizedMilestones = syncInclude.private_titles ? unpublished : unpublished.map((m) => {
|
|
35195
|
+
const { private_title: _, ...rest } = m;
|
|
35196
|
+
return rest;
|
|
35094
35197
|
});
|
|
35095
|
-
|
|
35096
|
-
const
|
|
35097
|
-
|
|
35198
|
+
for (let i = 0; i < sanitizedMilestones.length; i += MILESTONE_CHUNK) {
|
|
35199
|
+
const chunk = sanitizedMilestones.slice(i, i + MILESTONE_CHUNK);
|
|
35200
|
+
const milestonesRes = await fetch(`${USEAI_API}/api/publish`, {
|
|
35201
|
+
method: "POST",
|
|
35202
|
+
headers,
|
|
35203
|
+
body: JSON.stringify({ milestones: chunk })
|
|
35204
|
+
});
|
|
35205
|
+
if (!milestonesRes.ok) {
|
|
35206
|
+
const errBody = await milestonesRes.text();
|
|
35207
|
+
return { success: false, error: `Milestones publish failed (chunk ${Math.floor(i / MILESTONE_CHUNK) + 1}): ${milestonesRes.status} ${errBody}` };
|
|
35208
|
+
}
|
|
35098
35209
|
}
|
|
35210
|
+
const sentIds = new Set(unpublished.map((m) => m.id));
|
|
35211
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
35212
|
+
const updated = allMilestones.map(
|
|
35213
|
+
(m) => sentIds.has(m.id) ? { ...m, published: true, published_at: now2 } : m
|
|
35214
|
+
);
|
|
35215
|
+
writeJson(MILESTONES_FILE, updated);
|
|
35099
35216
|
}
|
|
35100
35217
|
}
|
|
35101
35218
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -35283,8 +35400,8 @@ function handleDeleteSession(req, res, sessionId) {
|
|
|
35283
35400
|
const remaining = milestones.filter((m) => m.session_id !== sessionId);
|
|
35284
35401
|
const milestonesRemoved = milestones.length - remaining.length;
|
|
35285
35402
|
if (milestonesRemoved > 0) writeJson(MILESTONES_FILE, remaining);
|
|
35286
|
-
const chainPath =
|
|
35287
|
-
if (
|
|
35403
|
+
const chainPath = join9(SEALED_DIR, `${sessionId}.jsonl`);
|
|
35404
|
+
if (existsSync10(chainPath)) unlinkSync4(chainPath);
|
|
35288
35405
|
json(res, 200, { deleted: true, session_id: sessionId, milestones_removed: milestonesRemoved });
|
|
35289
35406
|
} catch (err) {
|
|
35290
35407
|
json(res, 500, { error: err.message });
|
|
@@ -35306,8 +35423,8 @@ function handleDeleteConversation(req, res, conversationId) {
|
|
|
35306
35423
|
const milestonesRemoved = milestones.length - remainingMilestones.length;
|
|
35307
35424
|
if (milestonesRemoved > 0) writeJson(MILESTONES_FILE, remainingMilestones);
|
|
35308
35425
|
for (const sid of sessionIds) {
|
|
35309
|
-
const chainPath =
|
|
35310
|
-
if (
|
|
35426
|
+
const chainPath = join9(SEALED_DIR, `${sid}.jsonl`);
|
|
35427
|
+
if (existsSync10(chainPath)) unlinkSync4(chainPath);
|
|
35311
35428
|
}
|
|
35312
35429
|
json(res, 200, { deleted: true, conversation_id: conversationId, sessions_removed: sessionIds.size, milestones_removed: milestonesRemoved });
|
|
35313
35430
|
} catch (err) {
|
|
@@ -35389,6 +35506,7 @@ var init_local_api = __esm({
|
|
|
35389
35506
|
"use strict";
|
|
35390
35507
|
init_dist();
|
|
35391
35508
|
init_tools2();
|
|
35509
|
+
init_reconcile();
|
|
35392
35510
|
_onConfigUpdated = null;
|
|
35393
35511
|
USEAI_API = process.env.USEAI_API_URL || "https://api.useai.dev";
|
|
35394
35512
|
}
|
|
@@ -35401,8 +35519,8 @@ __export(daemon_exports, {
|
|
|
35401
35519
|
});
|
|
35402
35520
|
import { createServer } from "http";
|
|
35403
35521
|
import { createHash as createHash4, randomUUID as randomUUID4 } from "crypto";
|
|
35404
|
-
import { existsSync as
|
|
35405
|
-
import { join as
|
|
35522
|
+
import { existsSync as existsSync11, readdirSync as readdirSync2, readFileSync as readFileSync7, appendFileSync as appendFileSync2, renameSync as renameSync3, writeFileSync as writeFileSync6, unlinkSync as unlinkSync5, statSync } from "fs";
|
|
35523
|
+
import { join as join10 } from "path";
|
|
35406
35524
|
function getActiveUseaiSessionIds() {
|
|
35407
35525
|
const ids = /* @__PURE__ */ new Set();
|
|
35408
35526
|
for (const [, active] of sessions) {
|
|
@@ -35414,10 +35532,10 @@ function getActiveUseaiSessionIds() {
|
|
|
35414
35532
|
return ids;
|
|
35415
35533
|
}
|
|
35416
35534
|
function sealOrphanFile(sessionId) {
|
|
35417
|
-
const filePath =
|
|
35418
|
-
if (!
|
|
35535
|
+
const filePath = join10(ACTIVE_DIR, `${sessionId}.jsonl`);
|
|
35536
|
+
if (!existsSync11(filePath)) return;
|
|
35419
35537
|
try {
|
|
35420
|
-
const content =
|
|
35538
|
+
const content = readFileSync7(filePath, "utf-8").trim();
|
|
35421
35539
|
if (!content) return;
|
|
35422
35540
|
const lines = content.split("\n").filter(Boolean);
|
|
35423
35541
|
if (lines.length === 0) return;
|
|
@@ -35425,7 +35543,7 @@ function sealOrphanFile(sessionId) {
|
|
|
35425
35543
|
const lastRecord = JSON.parse(lines[lines.length - 1]);
|
|
35426
35544
|
if (lastRecord.type === "session_end" || lastRecord.type === "session_seal") {
|
|
35427
35545
|
try {
|
|
35428
|
-
renameSync3(filePath,
|
|
35546
|
+
renameSync3(filePath, join10(SEALED_DIR, `${sessionId}.jsonl`));
|
|
35429
35547
|
} catch {
|
|
35430
35548
|
}
|
|
35431
35549
|
return;
|
|
@@ -35485,7 +35603,7 @@ function sealOrphanFile(sessionId) {
|
|
|
35485
35603
|
}, endRecord.hash, daemonSigningKey)
|
|
35486
35604
|
) + "\n");
|
|
35487
35605
|
try {
|
|
35488
|
-
renameSync3(filePath,
|
|
35606
|
+
renameSync3(filePath, join10(SEALED_DIR, `${sessionId}.jsonl`));
|
|
35489
35607
|
} catch {
|
|
35490
35608
|
}
|
|
35491
35609
|
const convId = startData["conversation_id"] ?? void 0;
|
|
@@ -35515,7 +35633,7 @@ function sealOrphanFile(sessionId) {
|
|
|
35515
35633
|
}
|
|
35516
35634
|
}
|
|
35517
35635
|
function sealOrphanedSessions() {
|
|
35518
|
-
if (!
|
|
35636
|
+
if (!existsSync11(ACTIVE_DIR)) return;
|
|
35519
35637
|
const activeIds = getActiveUseaiSessionIds();
|
|
35520
35638
|
const mcpMap = readMcpMap();
|
|
35521
35639
|
const mappedUseaiIds = new Set(Object.values(mcpMap));
|
|
@@ -35527,7 +35645,7 @@ function sealOrphanedSessions() {
|
|
|
35527
35645
|
if (activeIds.has(sessionId)) continue;
|
|
35528
35646
|
if (mappedUseaiIds.has(sessionId)) {
|
|
35529
35647
|
try {
|
|
35530
|
-
const mtime = statSync(
|
|
35648
|
+
const mtime = statSync(join10(ACTIVE_DIR, file)).mtimeMs;
|
|
35531
35649
|
if (Date.now() - mtime < IDLE_TIMEOUT_MS) continue;
|
|
35532
35650
|
} catch {
|
|
35533
35651
|
continue;
|
|
@@ -35543,8 +35661,8 @@ function sealOrphanedSessions() {
|
|
|
35543
35661
|
}
|
|
35544
35662
|
}
|
|
35545
35663
|
function isSessionAlreadySealed(session2) {
|
|
35546
|
-
const activePath =
|
|
35547
|
-
return !
|
|
35664
|
+
const activePath = join10(ACTIVE_DIR, `${session2.sessionId}.jsonl`);
|
|
35665
|
+
return !existsSync11(activePath);
|
|
35548
35666
|
}
|
|
35549
35667
|
function sealRichness(s) {
|
|
35550
35668
|
let score = 0;
|
|
@@ -35631,10 +35749,10 @@ function autoSealSession(active) {
|
|
|
35631
35749
|
seal_signature: sealSignature,
|
|
35632
35750
|
auto_sealed: true
|
|
35633
35751
|
});
|
|
35634
|
-
const activePath =
|
|
35635
|
-
const sealedPath =
|
|
35752
|
+
const activePath = join10(ACTIVE_DIR, `${session2.sessionId}.jsonl`);
|
|
35753
|
+
const sealedPath = join10(SEALED_DIR, `${session2.sessionId}.jsonl`);
|
|
35636
35754
|
try {
|
|
35637
|
-
if (
|
|
35755
|
+
if (existsSync11(activePath)) {
|
|
35638
35756
|
renameSync3(activePath, sealedPath);
|
|
35639
35757
|
}
|
|
35640
35758
|
} catch {
|
|
@@ -35762,12 +35880,12 @@ function sendJsonRpcResult(res, rpcId, text) {
|
|
|
35762
35880
|
}));
|
|
35763
35881
|
}
|
|
35764
35882
|
function readChainMetadata(useaiSessionId) {
|
|
35765
|
-
const activePath =
|
|
35766
|
-
const sealedPath =
|
|
35767
|
-
const chainPath =
|
|
35883
|
+
const activePath = join10(ACTIVE_DIR, `${useaiSessionId}.jsonl`);
|
|
35884
|
+
const sealedPath = join10(SEALED_DIR, `${useaiSessionId}.jsonl`);
|
|
35885
|
+
const chainPath = existsSync11(activePath) ? activePath : existsSync11(sealedPath) ? sealedPath : null;
|
|
35768
35886
|
if (!chainPath) return null;
|
|
35769
35887
|
try {
|
|
35770
|
-
const firstLine =
|
|
35888
|
+
const firstLine = readFileSync7(chainPath, "utf-8").split("\n")[0];
|
|
35771
35889
|
if (!firstLine) return null;
|
|
35772
35890
|
const record2 = JSON.parse(firstLine);
|
|
35773
35891
|
const d = record2.data;
|
|
@@ -35788,8 +35906,8 @@ function readChainMetadata(useaiSessionId) {
|
|
|
35788
35906
|
function recoverStartSession(staleMcpSessionId, args, rpcId, res, req) {
|
|
35789
35907
|
const map = readMcpMap();
|
|
35790
35908
|
const prevSessionId = map[staleMcpSessionId];
|
|
35791
|
-
const prevActivePath = prevSessionId ?
|
|
35792
|
-
if (prevActivePath &&
|
|
35909
|
+
const prevActivePath = prevSessionId ? join10(ACTIVE_DIR, `${prevSessionId}.jsonl`) : null;
|
|
35910
|
+
if (prevActivePath && existsSync11(prevActivePath)) {
|
|
35793
35911
|
sealOrphanFile(prevSessionId);
|
|
35794
35912
|
}
|
|
35795
35913
|
const meta = prevSessionId ? readChainMetadata(prevSessionId) : null;
|
|
@@ -35815,7 +35933,7 @@ function recoverStartSession(staleMcpSessionId, args, rpcId, res, req) {
|
|
|
35815
35933
|
if (privateTitle) chainData["private_title"] = privateTitle;
|
|
35816
35934
|
if (model) chainData["model"] = model;
|
|
35817
35935
|
const record2 = buildChainRecord("session_start", newSessionId, chainData, "GENESIS", daemonSigningKey);
|
|
35818
|
-
const chainPath =
|
|
35936
|
+
const chainPath = join10(ACTIVE_DIR, `${newSessionId}.jsonl`);
|
|
35819
35937
|
appendFileSync2(chainPath, JSON.stringify(record2) + "\n");
|
|
35820
35938
|
writeMcpMapping(staleMcpSessionId, newSessionId);
|
|
35821
35939
|
sendJsonRpcResult(
|
|
@@ -35830,13 +35948,13 @@ function recoverHeartbeat(staleMcpSessionId, rpcId, res) {
|
|
|
35830
35948
|
const map = readMcpMap();
|
|
35831
35949
|
const useaiSessionId = map[staleMcpSessionId];
|
|
35832
35950
|
if (!useaiSessionId) return false;
|
|
35833
|
-
const chainPath =
|
|
35834
|
-
if (!
|
|
35951
|
+
const chainPath = join10(ACTIVE_DIR, `${useaiSessionId}.jsonl`);
|
|
35952
|
+
if (!existsSync11(chainPath)) {
|
|
35835
35953
|
sendJsonRpcResult(res, rpcId, "Session already ended (recovered).");
|
|
35836
35954
|
return true;
|
|
35837
35955
|
}
|
|
35838
35956
|
try {
|
|
35839
|
-
const content =
|
|
35957
|
+
const content = readFileSync7(chainPath, "utf-8").trim();
|
|
35840
35958
|
const lines = content.split("\n").filter(Boolean);
|
|
35841
35959
|
if (lines.length === 0) return false;
|
|
35842
35960
|
const firstRecord = JSON.parse(lines[0]);
|
|
@@ -35866,12 +35984,12 @@ function recoverEndSession(staleMcpSessionId, args, rpcId, res) {
|
|
|
35866
35984
|
const map = readMcpMap();
|
|
35867
35985
|
const useaiSessionId = map[staleMcpSessionId];
|
|
35868
35986
|
if (!useaiSessionId) return false;
|
|
35869
|
-
const activePath =
|
|
35870
|
-
const sealedPath =
|
|
35871
|
-
const chainPath =
|
|
35987
|
+
const activePath = join10(ACTIVE_DIR, `${useaiSessionId}.jsonl`);
|
|
35988
|
+
const sealedPath = join10(SEALED_DIR, `${useaiSessionId}.jsonl`);
|
|
35989
|
+
const chainPath = existsSync11(activePath) ? activePath : existsSync11(sealedPath) ? sealedPath : null;
|
|
35872
35990
|
if (!chainPath) return false;
|
|
35873
35991
|
const isAlreadySealed = chainPath === sealedPath;
|
|
35874
|
-
const content =
|
|
35992
|
+
const content = readFileSync7(chainPath, "utf-8").trim();
|
|
35875
35993
|
if (!content) return false;
|
|
35876
35994
|
const lines = content.split("\n").filter(Boolean);
|
|
35877
35995
|
if (lines.length === 0) return false;
|
|
@@ -36210,7 +36328,7 @@ async function startDaemon(port) {
|
|
|
36210
36328
|
const listenPort = port ?? DAEMON_PORT;
|
|
36211
36329
|
ensureDir();
|
|
36212
36330
|
try {
|
|
36213
|
-
if (
|
|
36331
|
+
if (existsSync11(KEYSTORE_FILE)) {
|
|
36214
36332
|
const ks = readJson(KEYSTORE_FILE, null);
|
|
36215
36333
|
if (ks) daemonSigningKey = decryptKeystore(ks);
|
|
36216
36334
|
}
|
|
@@ -36480,7 +36598,7 @@ async function startDaemon(port) {
|
|
|
36480
36598
|
}
|
|
36481
36599
|
}
|
|
36482
36600
|
try {
|
|
36483
|
-
if (
|
|
36601
|
+
if (existsSync11(DAEMON_PID_FILE)) {
|
|
36484
36602
|
unlinkSync5(DAEMON_PID_FILE);
|
|
36485
36603
|
}
|
|
36486
36604
|
} catch {
|