forum-skill 0.1.0 → 0.1.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/cli.js +47 -3
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
1
2
|
import fs, { existsSync } from "node:fs";
|
|
2
3
|
import path from "node:path";
|
|
3
4
|
import { fileURLToPath } from "node:url";
|
|
4
5
|
import fs$1 from "node:fs/promises";
|
|
5
6
|
import os from "node:os";
|
|
7
|
+
import { spawn } from "node:child_process";
|
|
6
8
|
import readline from "node:readline";
|
|
7
9
|
|
|
8
10
|
//#region src/adapters/aider.ts
|
|
@@ -763,14 +765,22 @@ async function pollOnce(args) {
|
|
|
763
765
|
try {
|
|
764
766
|
payload = await res.json();
|
|
765
767
|
} catch {}
|
|
766
|
-
|
|
768
|
+
const errorCode = extractErrorCode(payload.error);
|
|
769
|
+
switch (errorCode) {
|
|
767
770
|
case "authorization_pending": return { kind: "pending" };
|
|
768
771
|
case "slow_down": return { kind: "slow_down" };
|
|
769
772
|
case "access_denied": throw new DeviceFlowDeniedError();
|
|
770
773
|
case "expired_token": throw new DeviceFlowExpiredError();
|
|
771
|
-
default: throw new DeviceFlowError(`unexpected poll response: HTTP ${res.status}: ${
|
|
774
|
+
default: throw new DeviceFlowError(`unexpected poll response: HTTP ${res.status}: ${errorCode ?? "(no error key)"}`, errorCode ?? `http_${res.status}`);
|
|
772
775
|
}
|
|
773
776
|
}
|
|
777
|
+
/** Pull the canonical error code out of either the flat or
|
|
778
|
+
* nested envelope shape. */
|
|
779
|
+
function extractErrorCode(err) {
|
|
780
|
+
if (typeof err === "string") return err;
|
|
781
|
+
if (err && typeof err === "object") return err.code;
|
|
782
|
+
return void 0;
|
|
783
|
+
}
|
|
774
784
|
async function pollUntilDone(opts) {
|
|
775
785
|
const sleep = opts.sleepImpl ?? defaultSleep;
|
|
776
786
|
let interval = opts.interval;
|
|
@@ -846,7 +856,11 @@ async function runInteractiveRegister() {
|
|
|
846
856
|
baseUrl,
|
|
847
857
|
input
|
|
848
858
|
});
|
|
849
|
-
process.stdout.write(
|
|
859
|
+
process.stdout.write(`
|
|
860
|
+
Registration started. Approve it from the browser tab that just opened:
|
|
861
|
+
|
|
862
|
+
${startRes.verificationUri}\n\n(If the tab didn't open, copy the URL above into your\n browser. The link expires at ${startRes.expiresAt}.)\n\nPolling every ${startRes.interval}s for approval...\n`);
|
|
863
|
+
openInBrowser(startRes.verificationUri);
|
|
850
864
|
let dots = 0;
|
|
851
865
|
try {
|
|
852
866
|
const issued = await pollUntilDone({
|
|
@@ -876,6 +890,36 @@ async function runInteractiveRegister() {
|
|
|
876
890
|
throw e;
|
|
877
891
|
}
|
|
878
892
|
}
|
|
893
|
+
/** Open `url` in the OS default browser. Best-effort — silently
|
|
894
|
+
* swallows everything (fork failure, missing binary, headless
|
|
895
|
+
* CI). The URL is also printed to stdout so the user can always
|
|
896
|
+
* copy-paste as a fallback. */
|
|
897
|
+
function openInBrowser(url) {
|
|
898
|
+
if (process.env["BROWSER"] === "none") return;
|
|
899
|
+
const cmd = process.platform === "darwin" ? {
|
|
900
|
+
bin: "open",
|
|
901
|
+
args: [url]
|
|
902
|
+
} : process.platform === "win32" ? {
|
|
903
|
+
bin: "cmd",
|
|
904
|
+
args: [
|
|
905
|
+
"/c",
|
|
906
|
+
"start",
|
|
907
|
+
"",
|
|
908
|
+
url
|
|
909
|
+
]
|
|
910
|
+
} : {
|
|
911
|
+
bin: "xdg-open",
|
|
912
|
+
args: [url]
|
|
913
|
+
};
|
|
914
|
+
try {
|
|
915
|
+
const child = spawn(cmd.bin, cmd.args, {
|
|
916
|
+
stdio: "ignore",
|
|
917
|
+
detached: true
|
|
918
|
+
});
|
|
919
|
+
child.on("error", () => {});
|
|
920
|
+
child.unref();
|
|
921
|
+
} catch {}
|
|
922
|
+
}
|
|
879
923
|
|
|
880
924
|
//#endregion
|
|
881
925
|
//#region src/lib/cliVersionCheck.ts
|
package/package.json
CHANGED