Skip to content

Commit 2f71f86

Browse files
authored
fix: use stable per-project tmp log directories (#9)
1 parent 84eb544 commit 2f71f86

3 files changed

Lines changed: 41 additions & 19 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ Yes. Set `OPENCODE_MEMORY_AUTODREAM=0`. You can also tune gates with:
174174

175175
### Logs
176176

177-
Logs are written to `$TMPDIR/opencode-memory-logs/`:
177+
Logs are written to `/tmp/opencode-claude-memory/<project-hash>/`:
178178
- `extract-*.log`: automatic memory extraction
179179
- `dream-*.log`: auto-dream consolidation
180180

bin/opencode-memory

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -204,13 +204,7 @@ AUTODREAM_STALE_LOCK_SECS=$((60 * 60))
204204

205205
WORKING_DIR="${OPENCODE_MEMORY_DIR:-$(pwd)}"
206206

207-
TMP_BASE_DIR="${TMPDIR:-/tmp}"
208-
while [ "$TMP_BASE_DIR" != "/" ] && [ "${TMP_BASE_DIR%/}" != "$TMP_BASE_DIR" ]; do
209-
TMP_BASE_DIR="${TMP_BASE_DIR%/}"
210-
done
211-
if [ -z "$TMP_BASE_DIR" ]; then
212-
TMP_BASE_DIR="/"
213-
fi
207+
LOG_BASE_DIR="/tmp/opencode-claude-memory"
214208

215209
# Scope lock files at project root granularity (not per-subdirectory).
216210
PROJECT_SCOPE_DIR="$WORKING_DIR"
@@ -221,7 +215,7 @@ fi
221215
PROJECT_KEY="$(printf '%s' "$PROJECT_SCOPE_DIR" | cksum | awk '{print $1}')"
222216

223217
# Lock files (prevent concurrent work on the same project)
224-
LOCK_DIR="$TMP_BASE_DIR/opencode-memory-locks"
218+
LOCK_DIR="/tmp/opencode-memory-locks"
225219
mkdir -p "$LOCK_DIR"
226220
EXTRACT_LOCK_FILE="$LOCK_DIR/${PROJECT_KEY}.extract.lock"
227221

@@ -230,7 +224,7 @@ mkdir -p "$STATE_DIR"
230224
CONSOLIDATION_LOCK_FILE="$STATE_DIR/${PROJECT_KEY}.consolidate-lock"
231225

232226
# Logs
233-
LOG_DIR="$TMP_BASE_DIR/opencode-memory-logs"
227+
LOG_DIR="$LOG_BASE_DIR/${PROJECT_KEY}"
234228
mkdir -p "$LOG_DIR"
235229
TASK_LOG_PREFIX="$(date +%Y%m%d-%H%M%S)-${PROJECT_KEY}"
236230
EXTRACT_LOG_FILE="$LOG_DIR/extract-${TASK_LOG_PREFIX}.log"

test/opencode-memory.test.ts

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { afterEach, describe, expect, test } from "bun:test"
2-
import { chmodSync, existsSync, mkdtempSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "fs"
2+
import { chmodSync, existsSync, mkdtempSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "fs"
33
import { tmpdir } from "os"
4-
import { join } from "path"
4+
import { dirname, join } from "path"
55
import { spawnSync } from "child_process"
66

77
const tempRoots: string[] = []
8+
const tempLogDirs = new Set<string>()
89
const scriptPath = join(process.cwd(), "bin", "opencode-memory")
910

1011
function makeTempRoot(): string {
@@ -18,17 +19,42 @@ function writeExecutable(filePath: string, content: string): void {
1819
chmodSync(filePath, 0o755)
1920
}
2021

22+
function rememberLogDirFromPath(logPath: string): void {
23+
tempLogDirs.add(dirname(logPath))
24+
}
25+
26+
function findRecentExtractLog(startedAt: number): string {
27+
const logRoot = join("/tmp", "opencode-claude-memory")
28+
const projectDirs = readdirSync(logRoot).map((entry) => join(logRoot, entry))
29+
30+
const extractLogs = projectDirs.flatMap((dir) =>
31+
readdirSync(dir)
32+
.filter((name) => name.startsWith("extract-"))
33+
.map((name) => join(dir, name)),
34+
)
35+
36+
const recentLog = extractLogs.find((logPath) => statSync(logPath).mtimeMs >= startedAt)
37+
expect(recentLog).toBeDefined()
38+
39+
return recentLog ?? ""
40+
}
41+
2142
afterEach(() => {
2243
while (tempRoots.length > 0) {
2344
const root = tempRoots.pop()
2445
if (root) {
2546
rmSync(root, { recursive: true, force: true })
2647
}
2748
}
49+
50+
for (const logDir of tempLogDirs) {
51+
rmSync(logDir, { recursive: true, force: true })
52+
}
53+
tempLogDirs.clear()
2854
})
2955

3056
describe("opencode-memory wrapper", () => {
31-
test("normalizes TMPDIR before composing extraction log paths", () => {
57+
test("writes extraction logs under a stable per-project /tmp directory", () => {
3258
const root = makeTempRoot()
3359
const fakeBin = join(root, "bin")
3460
const homeDir = join(root, "home")
@@ -60,6 +86,7 @@ exit 0
6086
`,
6187
)
6288

89+
const startedAt = Date.now()
6390
const result = spawnSync("bash", [scriptPath, "--help"], {
6491
cwd: root,
6592
encoding: "utf-8",
@@ -82,7 +109,10 @@ exit 0
82109
expect(logPathMatch).not.toBeNull()
83110

84111
const logPath = logPathMatch?.[1].trim() ?? ""
85-
expect(logPath.startsWith(join(root, "tmp", "opencode-memory-logs", "extract-"))).toBe(true)
112+
rememberLogDirFromPath(logPath)
113+
expect(logPath).toMatch(/^\/tmp\/opencode-claude-memory\/[^/]+\/extract-/)
114+
expect(statSync(logPath).mtimeMs).toBeGreaterThanOrEqual(startedAt)
115+
expect(logPath).toContain("/extract-")
86116
expect(existsSync(logPath)).toBe(true)
87117
expect(readFileSync(logPath, "utf-8")).toContain("extraction ok")
88118
})
@@ -119,6 +149,7 @@ exit 0
119149
`,
120150
)
121151

152+
const startedAt = Date.now()
122153
const result = spawnSync("bash", [scriptPath, "--help"], {
123154
cwd: root,
124155
encoding: "utf-8",
@@ -137,11 +168,8 @@ exit 0
137168
expect(result.status).toBe(0)
138169
expect(result.stderr).toBe("")
139170

140-
const logDir = join(root, "tmp", "opencode-memory-logs")
141-
const logFiles = readdirSync(logDir)
142-
expect(logFiles).toHaveLength(1)
143-
144-
const logPath = join(logDir, logFiles[0] ?? "")
171+
const logPath = findRecentExtractLog(startedAt)
172+
rememberLogDirFromPath(logPath)
145173
expect(readFileSync(logPath, "utf-8")).toContain("extraction ok")
146174
})
147175
})

0 commit comments

Comments
 (0)