forum-skill 0.1.1 → 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 +46 -3
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -4,6 +4,7 @@ import path from "node:path";
|
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import fs$1 from "node:fs/promises";
|
|
6
6
|
import os from "node:os";
|
|
7
|
+
import { spawn } from "node:child_process";
|
|
7
8
|
import readline from "node:readline";
|
|
8
9
|
|
|
9
10
|
//#region src/adapters/aider.ts
|
|
@@ -764,14 +765,22 @@ async function pollOnce(args) {
|
|
|
764
765
|
try {
|
|
765
766
|
payload = await res.json();
|
|
766
767
|
} catch {}
|
|
767
|
-
|
|
768
|
+
const errorCode = extractErrorCode(payload.error);
|
|
769
|
+
switch (errorCode) {
|
|
768
770
|
case "authorization_pending": return { kind: "pending" };
|
|
769
771
|
case "slow_down": return { kind: "slow_down" };
|
|
770
772
|
case "access_denied": throw new DeviceFlowDeniedError();
|
|
771
773
|
case "expired_token": throw new DeviceFlowExpiredError();
|
|
772
|
-
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}`);
|
|
773
775
|
}
|
|
774
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
|
+
}
|
|
775
784
|
async function pollUntilDone(opts) {
|
|
776
785
|
const sleep = opts.sleepImpl ?? defaultSleep;
|
|
777
786
|
let interval = opts.interval;
|
|
@@ -847,7 +856,11 @@ async function runInteractiveRegister() {
|
|
|
847
856
|
baseUrl,
|
|
848
857
|
input
|
|
849
858
|
});
|
|
850
|
-
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);
|
|
851
864
|
let dots = 0;
|
|
852
865
|
try {
|
|
853
866
|
const issued = await pollUntilDone({
|
|
@@ -877,6 +890,36 @@ async function runInteractiveRegister() {
|
|
|
877
890
|
throw e;
|
|
878
891
|
}
|
|
879
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
|
+
}
|
|
880
923
|
|
|
881
924
|
//#endregion
|
|
882
925
|
//#region src/lib/cliVersionCheck.ts
|
package/package.json
CHANGED