forked from anomalyco/opencode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtrace.ts
More file actions
94 lines (84 loc) · 2.21 KB
/
trace.ts
File metadata and controls
94 lines (84 loc) · 2.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// Dev-only JSONL event trace for direct interactive mode.
//
// Enable with OPENCODE_DIRECT_TRACE=1. Writes one JSON line per event to
// ~/.local/share/opencode/log/direct/<timestamp>-<pid>.jsonl. Also writes
// a latest.json pointer so you can quickly find the most recent trace.
//
// The trace captures the full closed loop: outbound prompts, inbound SDK
// events, reducer output, footer commits, and turn lifecycle markers.
// Useful for debugging stream ordering, permission behavior, and
// footer/transcript mismatches.
//
// Lazy-initialized: the first call to trace() decides whether tracing is
// active based on the env var, and subsequent calls return the cached result.
import fs from "fs"
import path from "path"
import { Global } from "@opencode-ai/core/global"
export type Trace = {
write(type: string, data?: unknown): void
}
let state: Trace | false | undefined
function stamp() {
return new Date()
.toISOString()
.replace(/[-:]/g, "")
.replace(/\.\d+Z$/, "Z")
}
function file() {
return path.join(Global.Path.log, "direct", `${stamp()}-${process.pid}.jsonl`)
}
function latest() {
return path.join(Global.Path.log, "direct", "latest.json")
}
function text(data: unknown) {
return JSON.stringify(
data,
(_key, value) => {
if (typeof value === "bigint") {
return String(value)
}
return value
},
0,
)
}
export function trace(): Trace | undefined {
if (state !== undefined) {
return state || undefined
}
if (!process.env.OPENCODE_DIRECT_TRACE) {
state = false
return undefined
}
const target = file()
fs.mkdirSync(path.dirname(target), { recursive: true })
fs.writeFileSync(
latest(),
text({
time: new Date().toISOString(),
pid: process.pid,
cwd: process.cwd(),
argv: process.argv.slice(2),
path: target,
}) + "\n",
)
state = {
write(type: string, data?: unknown) {
fs.appendFileSync(
target,
text({
time: new Date().toISOString(),
pid: process.pid,
type,
data,
}) + "\n",
)
},
}
state.write("trace.start", {
argv: process.argv.slice(2),
cwd: process.cwd(),
path: target,
})
return state
}