oh-aicoding-tool 0.1.8 → 0.1.9
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/bin/cli.js +103 -21
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -4,9 +4,11 @@ import path from "node:path";
|
|
|
4
4
|
import { spawnSync } from "node:child_process";
|
|
5
5
|
import { createRequire } from "node:module";
|
|
6
6
|
import { createInterface } from "node:readline/promises";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
7
8
|
|
|
8
|
-
const require = createRequire(import.meta.url);
|
|
9
|
-
|
|
9
|
+
const require = createRequire(import.meta.url);
|
|
10
|
+
const packageJsonPath = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "package.json");
|
|
11
|
+
|
|
10
12
|
const colorEnabled = process.stdout.isTTY && process.env.NO_COLOR !== "1";
|
|
11
13
|
const ansi = (code) => (colorEnabled ? `\x1b[${code}m` : "");
|
|
12
14
|
const rgb = (r, g, b) => (colorEnabled ? `\x1b[38;2;${r};${g};${b}m` : "");
|
|
@@ -46,16 +48,22 @@ function renderHeader(subtitle = "Interactive setup") {
|
|
|
46
48
|
console.log(`${paint("Space", t.gold)} toggle ${paint("Enter", t.gold)} continue ${paint("Up/Down", t.gold)} move ${paint("q", t.gold)} exit`);
|
|
47
49
|
}
|
|
48
50
|
|
|
49
|
-
function printHelp() {
|
|
50
|
-
console.log("oh-aicoding-tool");
|
|
51
|
-
console.log("");
|
|
52
|
-
console.log("Usage:");
|
|
53
|
-
console.log(" oh-aicoding-tool");
|
|
54
|
-
console.log(" oh-aicoding-tool
|
|
55
|
-
console.log(" oh-aicoding-tool
|
|
56
|
-
console.log(" oh-aicoding-tool
|
|
57
|
-
console.log(" oh-aicoding-tool report install
|
|
58
|
-
|
|
51
|
+
function printHelp() {
|
|
52
|
+
console.log("oh-aicoding-tool");
|
|
53
|
+
console.log("");
|
|
54
|
+
console.log("Usage:");
|
|
55
|
+
console.log(" oh-aicoding-tool");
|
|
56
|
+
console.log(" oh-aicoding-tool --version");
|
|
57
|
+
console.log(" oh-aicoding-tool debug-keys");
|
|
58
|
+
console.log(" oh-aicoding-tool langfuse [setup|check] [target]");
|
|
59
|
+
console.log(" oh-aicoding-tool report install opencode [--email user@company.com]");
|
|
60
|
+
console.log(" oh-aicoding-tool report install claude");
|
|
61
|
+
console.log(" oh-aicoding-tool report install both");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function readOwnPackage() {
|
|
65
|
+
return JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
|
66
|
+
}
|
|
59
67
|
|
|
60
68
|
function packageBinScript(packageName, preferredBin) {
|
|
61
69
|
const pkgPath = require.resolve(`${packageName}/package.json`);
|
|
@@ -110,10 +118,20 @@ function rawKeySeq(raw) {
|
|
|
110
118
|
|
|
111
119
|
function readKeyFromBuffer(buffer) {
|
|
112
120
|
if (!buffer) return { pending: true, rest: "" };
|
|
113
|
-
if (buffer === "\x1b" || buffer === "\
|
|
121
|
+
if (buffer === "\x1b" || buffer === "\x00" || buffer === "\xe0" || /^\x1b\[[0-9;?]*$/.test(buffer) || buffer === "\x1bO") {
|
|
114
122
|
return { pending: true, rest: buffer };
|
|
115
123
|
}
|
|
116
124
|
|
|
125
|
+
const csi = buffer.match(/^\x1b\[[0-9;?]*([A-Za-z~])/);
|
|
126
|
+
if (csi?.[1] === "A") return { key: { name: "up", sequence: csi[0] }, rest: buffer.slice(csi[0].length) };
|
|
127
|
+
if (csi?.[1] === "B") return { key: { name: "down", sequence: csi[0] }, rest: buffer.slice(csi[0].length) };
|
|
128
|
+
if (csi) return { key: { name: "", sequence: csi[0] }, rest: buffer.slice(csi[0].length) };
|
|
129
|
+
|
|
130
|
+
const ss3 = buffer.match(/^\x1bO([A-Za-z])/);
|
|
131
|
+
if (ss3?.[1] === "A") return { key: { name: "up", sequence: ss3[0] }, rest: buffer.slice(ss3[0].length) };
|
|
132
|
+
if (ss3?.[1] === "B") return { key: { name: "down", sequence: ss3[0] }, rest: buffer.slice(ss3[0].length) };
|
|
133
|
+
if (ss3) return { key: { name: "", sequence: ss3[0] }, rest: buffer.slice(ss3[0].length) };
|
|
134
|
+
|
|
117
135
|
const three = buffer.slice(0, 3);
|
|
118
136
|
if (three === "\x1b[A" || three === "\x1bOA") return { key: { name: "up", sequence: three }, rest: buffer.slice(3) };
|
|
119
137
|
if (three === "\x1b[B" || three === "\x1bOB") return { key: { name: "down", sequence: three }, rest: buffer.slice(3) };
|
|
@@ -132,6 +150,65 @@ function readKeyFromBuffer(buffer) {
|
|
|
132
150
|
return { key: { name: seq.toLowerCase(), sequence: seq }, rest: buffer.slice(1) };
|
|
133
151
|
}
|
|
134
152
|
|
|
153
|
+
function showControlChars(value) {
|
|
154
|
+
return value
|
|
155
|
+
.replaceAll("\x1b", "\\x1b")
|
|
156
|
+
.replaceAll("\x00", "\\x00")
|
|
157
|
+
.replaceAll("\xe0", "\\xe0")
|
|
158
|
+
.replaceAll("\r", "\\r")
|
|
159
|
+
.replaceAll("\n", "\\n")
|
|
160
|
+
.replaceAll("\x03", "\\x03");
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function keyHex(value) {
|
|
164
|
+
return [...Buffer.from(value, "latin1")].map((byte) => byte.toString(16).padStart(2, "0")).join(" ");
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async function debugKeys() {
|
|
168
|
+
const pkg = readOwnPackage();
|
|
169
|
+
console.log(`oh-aicoding-tool ${pkg.version}`);
|
|
170
|
+
console.log(`node ${process.version} ${process.platform} ${process.arch}`);
|
|
171
|
+
console.log(`stdin.isTTY=${process.stdin.isTTY} stdout.isTTY=${process.stdout.isTTY} rawMode=${process.stdin.isRaw}`);
|
|
172
|
+
console.log(`TERM=${process.env.TERM || ""} WT_SESSION=${process.env.WT_SESSION || ""} TERM_PROGRAM=${process.env.TERM_PROGRAM || ""}`);
|
|
173
|
+
console.log("Press Up, Down, Space, Enter, then q to exit this debug view.");
|
|
174
|
+
|
|
175
|
+
if (!process.stdin.isTTY) return 1;
|
|
176
|
+
|
|
177
|
+
return await new Promise((resolve) => {
|
|
178
|
+
let keyBuffer = "";
|
|
179
|
+
const stdin = process.stdin;
|
|
180
|
+
|
|
181
|
+
function cleanup(code) {
|
|
182
|
+
stdin.off("data", onData);
|
|
183
|
+
if (stdin.isTTY) stdin.setRawMode(false);
|
|
184
|
+
stdin.pause();
|
|
185
|
+
resolve(code);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function onData(raw) {
|
|
189
|
+
const seq = rawKeySeq(raw);
|
|
190
|
+
console.log(`raw hex=[${keyHex(seq)}] text=${showControlChars(seq)}`);
|
|
191
|
+
keyBuffer += seq;
|
|
192
|
+
while (keyBuffer) {
|
|
193
|
+
const result = readKeyFromBuffer(keyBuffer);
|
|
194
|
+
if (result.pending) {
|
|
195
|
+
console.log(`pending buffer hex=[${keyHex(result.rest)}] text=${showControlChars(result.rest)}`);
|
|
196
|
+
keyBuffer = result.rest;
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
keyBuffer = result.rest;
|
|
200
|
+
const key = result.key;
|
|
201
|
+
console.log(`parsed name=${key.name || "<unknown>"} sequence=${showControlChars(key.sequence || "")}`);
|
|
202
|
+
if (key.name === "q" || key.name === "ctrl-c") return cleanup(0);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
stdin.setRawMode(true);
|
|
207
|
+
stdin.on("data", onData);
|
|
208
|
+
stdin.resume();
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
135
212
|
async function askMultiChoice(rl, title, choices, subtitle) {
|
|
136
213
|
if (process.stdin.isTTY && process.stdout.isTTY) {
|
|
137
214
|
rl.pause();
|
|
@@ -273,14 +350,19 @@ async function interactive() {
|
|
|
273
350
|
}
|
|
274
351
|
}
|
|
275
352
|
|
|
276
|
-
async function main() {
|
|
277
|
-
const argv = process.argv.slice(2);
|
|
278
|
-
const [cmd, ...rest] = argv;
|
|
279
|
-
if (cmd === "--
|
|
280
|
-
|
|
281
|
-
return 0;
|
|
282
|
-
}
|
|
283
|
-
if (
|
|
353
|
+
async function main() {
|
|
354
|
+
const argv = process.argv.slice(2);
|
|
355
|
+
const [cmd, ...rest] = argv;
|
|
356
|
+
if (cmd === "--version" || cmd === "-v" || cmd === "version") {
|
|
357
|
+
console.log(readOwnPackage().version);
|
|
358
|
+
return 0;
|
|
359
|
+
}
|
|
360
|
+
if (cmd === "--help" || cmd === "-h" || cmd === "help") {
|
|
361
|
+
printHelp();
|
|
362
|
+
return 0;
|
|
363
|
+
}
|
|
364
|
+
if (cmd === "debug-keys") return await debugKeys();
|
|
365
|
+
if (!cmd) return await interactive();
|
|
284
366
|
if (cmd === "langfuse") return runPackageBin("oh-langfuse", "oh-langfuse", rest);
|
|
285
367
|
if (cmd === "report") return runPackageBin("oh-aireport", "oh-aireport", rest);
|
|
286
368
|
if (cmd === "setup" || cmd === "check") return runPackageBin("oh-langfuse", "oh-langfuse", argv);
|