@cortexkit/aft-opencode 0.18.1 → 0.18.2

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/dist/tui.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // package.json
3
3
  var package_default = {
4
4
  name: "@cortexkit/aft-opencode",
5
- version: "0.18.1",
5
+ version: "0.18.2",
6
6
  type: "module",
7
7
  description: "OpenCode plugin for Agent File Tools (AFT) \u2014 tree-sitter and lsp powered code analysis",
8
8
  main: "dist/index.js",
@@ -16,6 +16,7 @@ var package_default = {
16
16
  "dist",
17
17
  "src/tui",
18
18
  "src/shared",
19
+ "src/logger.ts",
19
20
  "README.md"
20
21
  ],
21
22
  scripts: {
@@ -34,11 +35,11 @@ var package_default = {
34
35
  zod: "^4.1.8"
35
36
  },
36
37
  optionalDependencies: {
37
- "@cortexkit/aft-darwin-arm64": "0.18.1",
38
- "@cortexkit/aft-darwin-x64": "0.18.1",
39
- "@cortexkit/aft-linux-arm64": "0.18.1",
40
- "@cortexkit/aft-linux-x64": "0.18.1",
41
- "@cortexkit/aft-win32-x64": "0.18.1"
38
+ "@cortexkit/aft-darwin-arm64": "0.18.2",
39
+ "@cortexkit/aft-darwin-x64": "0.18.2",
40
+ "@cortexkit/aft-linux-arm64": "0.18.2",
41
+ "@cortexkit/aft-linux-x64": "0.18.2",
42
+ "@cortexkit/aft-win32-x64": "0.18.2"
42
43
  },
43
44
  devDependencies: {
44
45
  "@types/node": "^22.0.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/aft-opencode",
3
- "version": "0.18.1",
3
+ "version": "0.18.2",
4
4
  "type": "module",
5
5
  "description": "OpenCode plugin for Agent File Tools (AFT) — tree-sitter and lsp powered code analysis",
6
6
  "main": "dist/index.js",
@@ -14,6 +14,7 @@
14
14
  "dist",
15
15
  "src/tui",
16
16
  "src/shared",
17
+ "src/logger.ts",
17
18
  "README.md"
18
19
  ],
19
20
  "scripts": {
@@ -32,11 +33,11 @@
32
33
  "zod": "^4.1.8"
33
34
  },
34
35
  "optionalDependencies": {
35
- "@cortexkit/aft-darwin-arm64": "0.18.1",
36
- "@cortexkit/aft-darwin-x64": "0.18.1",
37
- "@cortexkit/aft-linux-arm64": "0.18.1",
38
- "@cortexkit/aft-linux-x64": "0.18.1",
39
- "@cortexkit/aft-win32-x64": "0.18.1"
36
+ "@cortexkit/aft-darwin-arm64": "0.18.2",
37
+ "@cortexkit/aft-darwin-x64": "0.18.2",
38
+ "@cortexkit/aft-linux-arm64": "0.18.2",
39
+ "@cortexkit/aft-linux-x64": "0.18.2",
40
+ "@cortexkit/aft-win32-x64": "0.18.2"
40
41
  },
41
42
  "devDependencies": {
42
43
  "@types/node": "^22.0.0",
package/src/logger.ts ADDED
@@ -0,0 +1,99 @@
1
+ import * as fs from "node:fs";
2
+ import * as os from "node:os";
3
+ import * as path from "node:path";
4
+
5
+ const TAG = "[aft-plugin]";
6
+ const logFile = path.join(os.tmpdir(), "aft-plugin.log");
7
+
8
+ /**
9
+ * When AFT_LOG_STDERR=1, logs go to stderr (useful for subprocess tests that
10
+ * capture stderr output). Otherwise logs go to the temp file.
11
+ */
12
+ const useStderr = process.env.AFT_LOG_STDERR === "1";
13
+
14
+ let buffer: string[] = [];
15
+ let flushTimer: ReturnType<typeof setTimeout> | null = null;
16
+ const FLUSH_INTERVAL_MS = 500;
17
+ const BUFFER_SIZE_LIMIT = 50;
18
+
19
+ function flush(): void {
20
+ if (buffer.length === 0) return;
21
+ const data = buffer.join("");
22
+ buffer = [];
23
+ try {
24
+ if (useStderr) {
25
+ process.stderr.write(data);
26
+ } else {
27
+ fs.appendFileSync(logFile, data);
28
+ }
29
+ } catch {
30
+ // Intentional: logging must never throw
31
+ }
32
+ }
33
+
34
+ function scheduleFlush(): void {
35
+ if (flushTimer) return;
36
+ flushTimer = setTimeout(() => {
37
+ flushTimer = null;
38
+ flush();
39
+ }, FLUSH_INTERVAL_MS);
40
+ // Don't prevent Node from exiting
41
+ if (flushTimer && typeof flushTimer === "object" && "unref" in flushTimer) {
42
+ flushTimer.unref();
43
+ }
44
+ }
45
+
46
+ function write(level: string, message: string, data?: unknown, sessionId?: string): void {
47
+ try {
48
+ const timestamp = new Date().toISOString();
49
+ const serialized = data === undefined ? "" : ` ${JSON.stringify(data)}`;
50
+ const sessionPrefix = sessionId ? ` [${sessionId}]` : "";
51
+ const line = `[${timestamp}] ${level} ${TAG}${sessionPrefix} ${message}${serialized}\n`;
52
+ if (useStderr) {
53
+ // Write immediately in stderr mode (subprocess tests need it before exit)
54
+ process.stderr.write(line);
55
+ return;
56
+ }
57
+ buffer.push(line);
58
+ if (buffer.length >= BUFFER_SIZE_LIMIT) {
59
+ flush();
60
+ } else {
61
+ scheduleFlush();
62
+ }
63
+ } catch {
64
+ // Intentional: logging must never throw
65
+ }
66
+ }
67
+ export function log(message: string, data?: unknown): void {
68
+ write("INFO", message, data);
69
+ }
70
+
71
+ export function warn(message: string, data?: unknown): void {
72
+ write("WARN", message, data);
73
+ }
74
+
75
+ export function error(message: string, data?: unknown): void {
76
+ write("ERROR", message, data);
77
+ }
78
+
79
+ /**
80
+ * Log with a session-id prefix. Use for messages that originate from a
81
+ * specific OpenCode session (per-request errors, timeouts, crashes during
82
+ * a session's tool call). Bridge-lifecycle logs (spawn, version, idle) are
83
+ * project-scoped, not session-scoped — use `log`/`warn`/`error` for those.
84
+ */
85
+ export function sessionLog(sessionId: string, message: string, data?: unknown): void {
86
+ write("INFO", message, data, sessionId);
87
+ }
88
+
89
+ export function sessionWarn(sessionId: string, message: string, data?: unknown): void {
90
+ write("WARN", message, data, sessionId);
91
+ }
92
+
93
+ export function sessionError(sessionId: string, message: string, data?: unknown): void {
94
+ write("ERROR", message, data, sessionId);
95
+ }
96
+
97
+ export function getLogFilePath(): string {
98
+ return logFile;
99
+ }