Commit 1cf02268b941
Changed files (6)
dots
config
claude
pi
agent
extensions
ai-storage
home
common
dev
dots/config/claude/hooks/bun.lock
@@ -0,0 +1,17 @@
+{
+ "lockfileVersion": 1,
+ "configVersion": 1,
+ "workspaces": {
+ "": {
+ "name": "claude-hooks",
+ "devDependencies": {
+ "@types/node": "^25.3.2",
+ },
+ },
+ },
+ "packages": {
+ "@types/node": ["@types/node@25.3.2", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-RpV6r/ij22zRRdyBPcxDeKAzH43phWVKEjL2iksqo1Vz3CuBUrgmPpPhALKiRfU7OMCmeeO9vECBMsV0hMTG8Q=="],
+
+ "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="],
+ }
+}
dots/config/claude/hooks/lib.ts
@@ -106,7 +106,7 @@ export function appendLog(file: string, line: string): void {
}
export function sessionLogPath(d: Date = now()): string {
- return join(SESSIONS_DIR, yearMonth(d), `${dateStr(d)}_session-log.txt`);
+ return join(SESSIONS_DIR, yearMonth(d), `${dateStr(d)}_session-log_${host()}.txt`);
}
// ── Read stdin (for hooks that receive JSON) ───────────────────────
dots/config/claude/hooks/package.json
@@ -2,5 +2,8 @@
"name": "claude-hooks",
"version": "1.0.0",
"type": "module",
- "description": "TypeScript hooks for Claude Code — unified AI storage"
+ "description": "TypeScript hooks for Claude Code — unified AI storage",
+ "devDependencies": {
+ "@types/node": "^25.3.2"
+ }
}
dots/config/claude/hooks/tsconfig.json
@@ -0,0 +1,12 @@
+{
+ "compilerOptions": {
+ "target": "ESNext",
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "types": ["node"],
+ "strict": true,
+ "skipLibCheck": true,
+ "noEmit": true
+ },
+ "include": ["*.ts"]
+}
dots/pi/agent/extensions/ai-storage/index.ts
@@ -110,11 +110,17 @@ export default function (pi: ExtensionAPI) {
};
}
+ /** Session-log filename includes hostname to avoid syncthing conflicts
+ * when multiple machines append to the same daily log file. */
+ function sessionLogFile(sessionDir: string, date: string): string {
+ return join(sessionDir, `${date}_session-log_${hostname()}.txt`);
+ }
+
async function logSessionStart() {
const tool = detectTool();
const { yearMonth, date, timestamp } = getDateInfo();
const sessionDir = join(SESSIONS_DIR, yearMonth);
- const logFile = join(sessionDir, `${date}_session-log.txt`);
+ const logFile = sessionLogFile(sessionDir, date);
await mkdir(sessionDir, { recursive: true });
await appendFile(logFile, `${timestamp} - Session started (${tool})\n`);
@@ -123,7 +129,7 @@ export default function (pi: ExtensionAPI) {
async function appendToSessionLog(message: string) {
const { yearMonth, date, timestamp } = getDateInfo();
const sessionDir = join(SESSIONS_DIR, yearMonth);
- const logFile = join(sessionDir, `${date}_session-log.txt`);
+ const logFile = sessionLogFile(sessionDir, date);
await mkdir(sessionDir, { recursive: true });
await appendFile(logFile, `${timestamp} - ${message}\n`);
@@ -1092,15 +1098,27 @@ After generating the summary, use the save_session_to_history tool to save it${c
description: "View today's session log",
handler: async (_args, ctx) => {
const { yearMonth, date } = getDateInfo();
- const logFile = join(SESSIONS_DIR, yearMonth, `${date}_session-log.txt`);
+ const sessionDir = join(SESSIONS_DIR, yearMonth);
- if (!existsSync(logFile)) {
+ // Read all session-log files for today (one per hostname)
+ let allContent = "";
+ if (existsSync(sessionDir)) {
+ const files = await readdir(sessionDir);
+ const logFiles = files.filter((f) => f.startsWith(`${date}_session-log`) && f.endsWith(".txt"));
+ for (const f of logFiles) {
+ try {
+ allContent += await readFile(join(sessionDir, f), "utf-8");
+ } catch {}
+ }
+ }
+
+ if (!allContent.trim()) {
ctx.ui.notify("No session log for today", "info");
return;
}
try {
- const content = await readFile(logFile, "utf-8");
+ const content = allContent;
const lines = content.trim().split("\n").reverse(); // Most recent first
const theme = ctx.ui.theme;
home/common/dev/ai.nix
@@ -12,8 +12,8 @@ let
in
{
# Ensure claude-sync directory structure exists (legacy, still used by claude)
+ # NOTE: claude-sync/history is no longer synced — tool-outputs stay local
xdg.dataFile = {
- "claude-sync/history/.keep".text = "";
"claude-sync/projects/.keep".text = "";
"claude-sync/todos/.keep".text = "";
"claude-sync/plans/.keep".text = "";
@@ -58,11 +58,9 @@ in
# Symlink claude directories to synced location
# force = true because claude-code may recreate these dirs during operation
+ # NOTE: claude/history is intentionally NOT symlinked — tool-outputs are
+ # machine-local (large, ephemeral debug data that causes syncthing conflicts).
xdg.configFile = {
- "claude/history" = {
- source = config.lib.file.mkOutOfStoreSymlink "${claudeSyncDir}/history";
- force = true;
- };
"claude/projects" = {
source = config.lib.file.mkOutOfStoreSymlink "${claudeSyncDir}/projects";
force = true;