agentic-relay 5.0.8 → 5.0.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/install.mjs +106 -1
- package/package.json +1 -1
package/bin/install.mjs
CHANGED
|
@@ -36,6 +36,7 @@ import { fileURLToPath } from "url";
|
|
|
36
36
|
import { createInterface } from "readline/promises";
|
|
37
37
|
import { stdin, stdout } from "process";
|
|
38
38
|
import { execSync } from "child_process";
|
|
39
|
+
import { randomBytes, createHash } from "crypto";
|
|
39
40
|
import { parseInstallArgs } from "./lib/install-args.mjs";
|
|
40
41
|
import {
|
|
41
42
|
npmGlobalPrefix,
|
|
@@ -63,6 +64,8 @@ const SIGNUP_URL = "https://attentionmarket-auth.vercel.app";
|
|
|
63
64
|
const API_BASE =
|
|
64
65
|
"https://peruwnbrqkvmrldhpoom.supabase.co/functions/v1/api-v1";
|
|
65
66
|
const MCP_URL = "https://peruwnbrqkvmrldhpoom.supabase.co/functions/v1/mcp";
|
|
67
|
+
const CLI_AUTH_URL =
|
|
68
|
+
"https://peruwnbrqkvmrldhpoom.supabase.co/functions/v1/cli-auth";
|
|
66
69
|
const SERVER_NAME = "agent-relay";
|
|
67
70
|
|
|
68
71
|
// ═══════════════════════════════════════════════════════════════════════
|
|
@@ -728,6 +731,94 @@ function linkGlobalCli() {
|
|
|
728
731
|
return "failed";
|
|
729
732
|
}
|
|
730
733
|
|
|
734
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
735
|
+
|
|
736
|
+
// Open a URL in the user's default browser (best-effort, per platform).
|
|
737
|
+
function openBrowser(url) {
|
|
738
|
+
const cmd =
|
|
739
|
+
process.platform === "darwin"
|
|
740
|
+
? "open"
|
|
741
|
+
: process.platform === "win32"
|
|
742
|
+
? "start \"\""
|
|
743
|
+
: "xdg-open";
|
|
744
|
+
try {
|
|
745
|
+
execSync(`${cmd} "${url}"`, { stdio: "ignore" });
|
|
746
|
+
return true;
|
|
747
|
+
} catch {
|
|
748
|
+
return false;
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
/**
|
|
753
|
+
* Browser sign-in via the `cli-auth` device-authorization flow: open a page,
|
|
754
|
+
* the user verifies their phone (which mints their key), and we poll until the
|
|
755
|
+
* key is released to us. PKCE (the verifier stays on this machine) is what makes
|
|
756
|
+
* the released key safe. Returns an am_live_ key, or null if it didn't complete.
|
|
757
|
+
*/
|
|
758
|
+
async function browserAuth() {
|
|
759
|
+
const codeVerifier = randomBytes(32).toString("hex");
|
|
760
|
+
const codeChallenge = createHash("sha256").update(codeVerifier).digest("hex");
|
|
761
|
+
|
|
762
|
+
let start;
|
|
763
|
+
try {
|
|
764
|
+
const r = await fetch(CLI_AUTH_URL, {
|
|
765
|
+
method: "POST",
|
|
766
|
+
headers: { "Content-Type": "application/json" },
|
|
767
|
+
body: JSON.stringify({ action: "start", code_challenge: codeChallenge }),
|
|
768
|
+
});
|
|
769
|
+
start = await r.json().catch(() => ({}));
|
|
770
|
+
if (!r.ok || !start.session_id) {
|
|
771
|
+
throw new Error(start.error || `HTTP ${r.status}`);
|
|
772
|
+
}
|
|
773
|
+
} catch (err) {
|
|
774
|
+
warn(`Couldn't start browser sign-in (${err.message}).`);
|
|
775
|
+
return null;
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
const {
|
|
779
|
+
session_id,
|
|
780
|
+
user_code,
|
|
781
|
+
authorize_url,
|
|
782
|
+
interval = 3,
|
|
783
|
+
expires_in = 600,
|
|
784
|
+
} = start;
|
|
785
|
+
|
|
786
|
+
console.log("");
|
|
787
|
+
log("Opening your browser to authorize…");
|
|
788
|
+
const opened = openBrowser(authorize_url);
|
|
789
|
+
console.log("");
|
|
790
|
+
console.log(opened ? " If it didn't open, visit:" : " Open this link to authorize:");
|
|
791
|
+
console.log(` \x1b[4m${authorize_url}\x1b[0m`);
|
|
792
|
+
if (user_code) console.log(` Verification code: \x1b[1m${user_code}\x1b[0m`);
|
|
793
|
+
console.log("");
|
|
794
|
+
log("Waiting for you to finish in the browser…");
|
|
795
|
+
|
|
796
|
+
const deadline = Date.now() + expires_in * 1000;
|
|
797
|
+
while (Date.now() < deadline) {
|
|
798
|
+
await sleep(interval * 1000);
|
|
799
|
+
try {
|
|
800
|
+
const r = await fetch(CLI_AUTH_URL, {
|
|
801
|
+
method: "POST",
|
|
802
|
+
headers: { "Content-Type": "application/json" },
|
|
803
|
+
body: JSON.stringify({ action: "poll", session_id, code_verifier: codeVerifier }),
|
|
804
|
+
});
|
|
805
|
+
const data = await r.json().catch(() => ({}));
|
|
806
|
+
if (r.ok && data.status === "authorized" && data.api_key_live) {
|
|
807
|
+
return data.api_key_live;
|
|
808
|
+
}
|
|
809
|
+
if (r.status === 410 || data.status === "expired") {
|
|
810
|
+
warn("That sign-in link expired. Let's try again.");
|
|
811
|
+
return null;
|
|
812
|
+
}
|
|
813
|
+
// status "pending" → keep polling
|
|
814
|
+
} catch {
|
|
815
|
+
// transient network blip — keep polling until the deadline
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
warn("Timed out waiting for browser authorization.");
|
|
819
|
+
return null;
|
|
820
|
+
}
|
|
821
|
+
|
|
731
822
|
async function setupApiKeyInteractive() {
|
|
732
823
|
// Verify-then-refresh: on a reinstall, keep a cached key that still works, but
|
|
733
824
|
// wipe a stale/revoked one and prompt for a fresh key — so a dead key never
|
|
@@ -753,12 +844,26 @@ async function setupApiKeyInteractive() {
|
|
|
753
844
|
return false;
|
|
754
845
|
}
|
|
755
846
|
|
|
847
|
+
// Seamless path: browser sign-in — no key to find, type, or paste. Verify
|
|
848
|
+
// your phone in the browser and we pick up the minted key automatically.
|
|
849
|
+
const browserKey = await browserAuth();
|
|
850
|
+
if (browserKey) {
|
|
851
|
+
const check = await verifyKey(browserKey);
|
|
852
|
+
if (check.ok) {
|
|
853
|
+
saveApiKey(browserKey);
|
|
854
|
+
return true;
|
|
855
|
+
}
|
|
856
|
+
warn(`Signed in, but the key didn't verify (${check.detail}).`);
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
// Fallback: paste a key manually (browser couldn't open, timed out, or you
|
|
860
|
+
// already have a key).
|
|
756
861
|
console.log("");
|
|
757
862
|
log("API key setup");
|
|
758
863
|
console.log("");
|
|
759
864
|
console.log(" Your API key starts with \x1b[1mam_live_\x1b[0m.");
|
|
760
865
|
console.log(
|
|
761
|
-
` Don't have one?
|
|
866
|
+
` Don't have one? Re-run and choose the browser sign-in, or sign up at \x1b[4m${SIGNUP_URL}\x1b[0m.`,
|
|
762
867
|
);
|
|
763
868
|
console.log("");
|
|
764
869
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentic-relay",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.9",
|
|
4
4
|
"description": "Install Agent Relay across 17+ agents — Claude Code, Codex, Cursor, Gemini CLI, Goose, Windsurf, Cline, BoltAI, Claude Desktop, VS Code, Amazon Q, Roo Code, Witsy, LibreChat, OpenClaw, Tome, Raycast — hire verified expert agents to build with you, plus the `agentrelay` CLI for live specialist sessions and deliverable fetch",
|
|
5
5
|
"bin": {
|
|
6
6
|
"agentrelay": "bin/cli.mjs"
|