open-plan-annotator 0.2.13 → 0.2.15
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.
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"name": "open-plan-annotator",
|
|
13
13
|
"source": "./",
|
|
14
14
|
"description": "Interactive plan annotation UI: review, strikethrough, and comment on Claude's plans before approving. Fully local, no external services.",
|
|
15
|
-
"version": "0.2.
|
|
15
|
+
"version": "0.2.15",
|
|
16
16
|
"author": {
|
|
17
17
|
"name": "ndom91"
|
|
18
18
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "open-plan-annotator",
|
|
3
3
|
"description": "Interactive plan annotation UI: review, strikethrough, and comment on Claude's plans before approving. Fully local, no external services.",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.15",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "ndom91"
|
|
7
7
|
},
|
|
@@ -65,13 +65,12 @@ child.stdout.on("data", (chunk) => {
|
|
|
65
65
|
if (!trimmed) continue;
|
|
66
66
|
try {
|
|
67
67
|
JSON.parse(trimmed);
|
|
68
|
-
// Valid JSON —
|
|
68
|
+
// Valid JSON — write directly to fd 1 (bypasses Node stream buffering),
|
|
69
|
+
// detach child, and exit immediately.
|
|
69
70
|
forwarded = true;
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
});
|
|
74
|
-
return;
|
|
71
|
+
fs.writeSync(1, trimmed + "\n");
|
|
72
|
+
child.unref();
|
|
73
|
+
process.exit(0);
|
|
75
74
|
} catch {
|
|
76
75
|
// Not JSON yet, keep buffering
|
|
77
76
|
}
|
|
@@ -81,7 +80,9 @@ child.stdout.on("data", (chunk) => {
|
|
|
81
80
|
child.on("close", (code) => {
|
|
82
81
|
if (!forwarded) {
|
|
83
82
|
// Binary exited without producing valid JSON — forward whatever we have
|
|
84
|
-
if (stdout.trim())
|
|
83
|
+
if (stdout.trim()) {
|
|
84
|
+
fs.writeSync(1, stdout);
|
|
85
|
+
}
|
|
85
86
|
process.exit(code || 1);
|
|
86
87
|
}
|
|
87
88
|
});
|
package/opencode/bridge.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { spawn } from "node:child_process";
|
|
1
|
+
import { execFileSync, spawn } from "node:child_process";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { existsSync, statSync } from "node:fs";
|
|
4
|
-
import { dirname } from "node:path";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
|
|
7
|
-
const
|
|
7
|
+
const PKG_ROOT = fileURLToPath(new URL("..", import.meta.url));
|
|
8
|
+
const BINARY_PATH = join(PKG_ROOT, "bin", "open-plan-annotator-binary");
|
|
9
|
+
const INSTALL_SCRIPT = join(PKG_ROOT, "install.cjs");
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
* @typedef {{
|
|
@@ -97,10 +99,42 @@ function validateHookOutput(value) {
|
|
|
97
99
|
throw new Error("unsupported decision payload");
|
|
98
100
|
}
|
|
99
101
|
|
|
102
|
+
/** Ensure the compiled binary exists, downloading if necessary. */
|
|
103
|
+
function ensureBinary() {
|
|
104
|
+
if (existsSync(BINARY_PATH)) return;
|
|
105
|
+
|
|
106
|
+
// Try to find node on PATH for running the install script
|
|
107
|
+
try {
|
|
108
|
+
execFileSync(process.execPath, [INSTALL_SCRIPT], {
|
|
109
|
+
cwd: PKG_ROOT,
|
|
110
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
111
|
+
});
|
|
112
|
+
} catch {
|
|
113
|
+
// Retry with "node" explicitly in case process.execPath is bun
|
|
114
|
+
try {
|
|
115
|
+
execFileSync("node", [INSTALL_SCRIPT], {
|
|
116
|
+
cwd: PKG_ROOT,
|
|
117
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
118
|
+
});
|
|
119
|
+
} catch {
|
|
120
|
+
// ignore — we'll check below
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (!existsSync(BINARY_PATH)) {
|
|
125
|
+
throw new Error(
|
|
126
|
+
`open-plan-annotator: binary not found at ${BINARY_PATH}. ` +
|
|
127
|
+
`Try running: node ${INSTALL_SCRIPT}`,
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
100
132
|
/**
|
|
101
133
|
* @param {{ plan: string, sessionId?: string, cwd?: string }} options
|
|
102
134
|
*/
|
|
103
135
|
export async function runPlanReview(options) {
|
|
136
|
+
ensureBinary();
|
|
137
|
+
|
|
104
138
|
const payload = buildHookPayload(options);
|
|
105
139
|
|
|
106
140
|
const result = await new Promise((resolve, reject) => {
|
|
@@ -112,11 +146,12 @@ export async function runPlanReview(options) {
|
|
|
112
146
|
cwd = dirname(cwd);
|
|
113
147
|
}
|
|
114
148
|
} catch {
|
|
115
|
-
|
|
116
|
-
cwd = dirname(WRAPPER_PATH);
|
|
149
|
+
cwd = PKG_ROOT;
|
|
117
150
|
}
|
|
118
151
|
|
|
119
|
-
|
|
152
|
+
// Spawn the compiled binary directly (skip the Node wrapper).
|
|
153
|
+
// This avoids issues with bun vs node runtime differences.
|
|
154
|
+
const child = spawn(BINARY_PATH, [], {
|
|
120
155
|
cwd,
|
|
121
156
|
stdio: ["pipe", "pipe", "pipe"],
|
|
122
157
|
env: process.env,
|
|
@@ -177,4 +212,4 @@ export async function runPlanReview(options) {
|
|
|
177
212
|
approved: false,
|
|
178
213
|
feedback: decision.message,
|
|
179
214
|
};
|
|
180
|
-
}
|
|
215
|
+
}
|