Project Files
src / thought-state.ts
import fs from "fs";
import path from "path";
import crypto from "crypto";
export interface ThoughtState {
signatures: Record<string, string>; // hash(text) -> thought_signature
}
export function getThoughtStatePath(wd: string): string {
// Use a separate file to avoid conflict with legacy array-based thought-signatures.json
return path.join(wd, "thought-signatures-image.json");
}
export function computeContentHash(text: string): string {
return crypto
.createHash("sha256")
.update(text ? text.trim().replace(/\s+/g, " ") : "")
.digest("hex");
}
export function loadThoughtState(wd: string): ThoughtState {
try {
// 1. Try loading the new isolated file
const fp = getThoughtStatePath(wd);
if (fs.existsSync(fp)) {
const content = fs.readFileSync(fp, "utf-8");
const parsed = JSON.parse(content);
if (parsed.signatures && !Array.isArray(parsed.signatures)) {
return parsed;
}
}
// 2. Fallback: Try loading the legacy file (migration)
const legacyFp = path.join(wd, "thought_signatures.json");
if (fs.existsSync(legacyFp)) {
const content = fs.readFileSync(legacyFp, "utf-8");
const parsed = JSON.parse(content);
if (parsed.signatures && Array.isArray(parsed.signatures)) {
const newSigs: Record<string, string> = {};
for (const s of parsed.signatures) {
if (s.contentHash && s.signature) {
newSigs[s.contentHash] = s.signature;
}
}
return { signatures: newSigs };
}
}
// 3. Fallback: Try loading the V3 file (migration from previous isolated strategy)
const v3Fp = path.join(wd, "thought_signatures_v3.json");
if (fs.existsSync(v3Fp)) {
const content = fs.readFileSync(v3Fp, "utf-8");
const parsed = JSON.parse(content);
if (parsed.signatures && Array.isArray(parsed.signatures)) {
const newSigs: Record<string, string> = {};
for (const s of parsed.signatures) {
// V3 format had { signature, contentHash, timestamp }
if (s.contentHash && s.signature) {
newSigs[s.contentHash] = s.signature;
}
}
return { signatures: newSigs };
}
}
} catch { }
return { signatures: {} };
}
export function saveThoughtState(wd: string, state: ThoughtState) {
try {
const fp = getThoughtStatePath(wd);
fs.writeFileSync(fp, JSON.stringify(state, null, 2), "utf-8");
} catch { }
}