@hacky.software/opencode-todo-supervisor 0.0.0-stage → 0.3.1
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/LICENSE +21 -0
- package/README.md +366 -2
- package/index.ts +3 -0
- package/package.json +61 -4
- package/src/index.ts +186 -0
- package/src/log.ts +77 -0
- package/src/machine.test.ts +779 -0
- package/src/markdown.test.ts +135 -0
- package/src/markdown.ts +159 -0
- package/src/options.test.ts +42 -0
- package/src/options.ts +100 -0
- package/src/panel.test.ts +193 -0
- package/src/panel.ts +289 -0
- package/src/rpc.test.ts +226 -0
- package/src/rpc.ts +290 -0
- package/src/storage.test.ts +101 -0
- package/src/storage.ts +186 -0
- package/src/supervisor.test.ts +37 -0
- package/src/supervisor.ts +1269 -0
- package/src/tools.test.ts +260 -0
- package/src/tools.ts +405 -0
- package/src/tui.tsx +658 -0
- package/tui.ts +2 -0
package/src/log.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// todo-supervisor — logging.
|
|
2
|
+
//
|
|
3
|
+
// Why this exists (verified 2026-10-15, OpenCode 2.0.24):
|
|
4
|
+
// - `console.log` inside plugins is swallowed by the plugin runtime;
|
|
5
|
+
// - `console.error` reaches stderr, which is visible in standalone/CLI
|
|
6
|
+
// contexts (`opencode2 run --standalone --print-logs`) but is discarded by
|
|
7
|
+
// the detached background service;
|
|
8
|
+
// - there is no logger API on the plugin context.
|
|
9
|
+
//
|
|
10
|
+
// So: mirror to stderr AND append to `<data>/opencode/log/todo-supervisor.log`
|
|
11
|
+
// so the background service stays greppable by the `[todo-supervisor]` prefix.
|
|
12
|
+
import { appendFileSync, mkdirSync, renameSync, statSync } from "node:fs"
|
|
13
|
+
import { homedir } from "node:os"
|
|
14
|
+
import { join } from "node:path"
|
|
15
|
+
|
|
16
|
+
const MAX_BYTES = 2_000_000
|
|
17
|
+
|
|
18
|
+
let cached: string | undefined
|
|
19
|
+
|
|
20
|
+
function targetFile(): string | undefined {
|
|
21
|
+
if (cached !== undefined) return cached || undefined
|
|
22
|
+
try {
|
|
23
|
+
const dataHome = process.env.XDG_DATA_HOME || join(homedir(), ".local", "share")
|
|
24
|
+
const dir = join(dataHome, "opencode", "log")
|
|
25
|
+
mkdirSync(dir, { recursive: true })
|
|
26
|
+
cached = join(dir, "todo-supervisor.log")
|
|
27
|
+
} catch {
|
|
28
|
+
cached = ""
|
|
29
|
+
}
|
|
30
|
+
return cached || undefined
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function rotate(file: string) {
|
|
34
|
+
try {
|
|
35
|
+
if (statSync(file).size > MAX_BYTES) renameSync(file, `${file}.1`)
|
|
36
|
+
} catch {
|
|
37
|
+
// file missing or rename failed — appending either way is fine
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function format(value: unknown): string {
|
|
42
|
+
if (typeof value === "string") return value
|
|
43
|
+
try {
|
|
44
|
+
return JSON.stringify(value)
|
|
45
|
+
} catch {
|
|
46
|
+
return String(value)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function log(...args: unknown[]): void {
|
|
51
|
+
const line = `${new Date().toISOString()} [todo-supervisor] ${args.map(format).join(" ")}`
|
|
52
|
+
console.error(line)
|
|
53
|
+
const file = targetFile()
|
|
54
|
+
if (!file) return
|
|
55
|
+
try {
|
|
56
|
+
rotate(file)
|
|
57
|
+
appendFileSync(file, `${line}\n`)
|
|
58
|
+
} catch {
|
|
59
|
+
// never let logging break the plugin
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* File-only variant (no stderr) for environments that own the terminal — the
|
|
65
|
+
* TUI plugin shares this log so both sides stay greppable by the prefix.
|
|
66
|
+
*/
|
|
67
|
+
export function logFile(prefix: string, ...args: unknown[]): void {
|
|
68
|
+
const line = `${new Date().toISOString()} [todo-supervisor/${prefix}] ${args.map(format).join(" ")}`
|
|
69
|
+
const file = targetFile()
|
|
70
|
+
if (!file) return
|
|
71
|
+
try {
|
|
72
|
+
rotate(file)
|
|
73
|
+
appendFileSync(file, `${line}\n`)
|
|
74
|
+
} catch {
|
|
75
|
+
// never let logging break the plugin
|
|
76
|
+
}
|
|
77
|
+
}
|