poe-code 3.0.86 → 3.0.88
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.
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import { exec } from "node:child_process";
|
|
2
|
+
import readline from "node:readline";
|
|
1
3
|
import { buildProviderContext, createExecutionResources, resolveCommandFlags, applyIsolatedConfiguration } from "./shared.js";
|
|
2
4
|
import { loadConfiguredServices } from "../../services/config.js";
|
|
3
5
|
import { ValidationError } from "../errors.js";
|
|
4
6
|
import { combineMutationObservers, createMutationReporter } from "../../services/mutation-events.js";
|
|
7
|
+
import { createOAuthClient } from "@poe-code/auth";
|
|
8
|
+
import { text, log } from "@poe-code/design-system";
|
|
5
9
|
export function registerLoginCommand(program, container) {
|
|
6
10
|
program
|
|
7
11
|
.command("login")
|
|
@@ -55,6 +59,9 @@ async function resolveApiKeyInput(container, options) {
|
|
|
55
59
|
if (envKey && envKey.trim().length > 0) {
|
|
56
60
|
return envKey;
|
|
57
61
|
}
|
|
62
|
+
if (container.env.getVariable("POE_CODE_OAUTH_LOGIN") === "1") {
|
|
63
|
+
return resolveApiKeyViaOAuth();
|
|
64
|
+
}
|
|
58
65
|
const descriptor = container.promptLibrary.loginApiKey();
|
|
59
66
|
const response = await container.prompts(descriptor);
|
|
60
67
|
const value = response[descriptor.name];
|
|
@@ -66,6 +73,50 @@ async function resolveApiKeyInput(container, options) {
|
|
|
66
73
|
}
|
|
67
74
|
return value;
|
|
68
75
|
}
|
|
76
|
+
async function resolveApiKeyViaOAuth() {
|
|
77
|
+
const rl = readline.createInterface({
|
|
78
|
+
input: process.stdin
|
|
79
|
+
});
|
|
80
|
+
try {
|
|
81
|
+
const client = createOAuthClient({
|
|
82
|
+
clientId: "client_f520ee4d8ca84a13ba876a8731d264d0",
|
|
83
|
+
authorizationEndpoint: "https://poe.com/oauth/authorize",
|
|
84
|
+
tokenEndpoint: "https://api.poe.com/token",
|
|
85
|
+
openBrowser: (url) => openInBrowser(url).catch(() => {
|
|
86
|
+
log.warn("Could not open browser automatically.");
|
|
87
|
+
}),
|
|
88
|
+
readLine: () => new Promise((resolve) => {
|
|
89
|
+
rl.once("line", (line) => resolve(line));
|
|
90
|
+
})
|
|
91
|
+
});
|
|
92
|
+
const authorization = await client.authorize();
|
|
93
|
+
log.message(`${text.muted("Authorize at")} ${text.link(authorization.authorizationUrl)}`);
|
|
94
|
+
log.message(text.muted("Waiting for authorization. You can also paste the redirect URL here:"));
|
|
95
|
+
const result = await authorization.waitForResult();
|
|
96
|
+
return result.apiKey;
|
|
97
|
+
}
|
|
98
|
+
finally {
|
|
99
|
+
rl.close();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function openInBrowser(url) {
|
|
103
|
+
return new Promise((resolve, reject) => {
|
|
104
|
+
const platform = process.platform;
|
|
105
|
+
const command = platform === "darwin"
|
|
106
|
+
? `open "${url}"`
|
|
107
|
+
: platform === "win32"
|
|
108
|
+
? `start "" "${url}"`
|
|
109
|
+
: `xdg-open "${url}"`;
|
|
110
|
+
exec(command, (error) => {
|
|
111
|
+
if (error) {
|
|
112
|
+
reject(error);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
resolve();
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
}
|
|
69
120
|
async function reconfigureServices(input) {
|
|
70
121
|
const { program, container, apiKey, configuredServices } = input;
|
|
71
122
|
const serviceNames = Object.keys(configuredServices);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/cli/commands/login.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/cli/commands/login.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -465,11 +465,180 @@ var init_create_auth_store = __esm({
|
|
|
465
465
|
}
|
|
466
466
|
});
|
|
467
467
|
|
|
468
|
+
// packages/auth/src/oauth-client.ts
|
|
469
|
+
import http from "node:http";
|
|
470
|
+
import crypto from "node:crypto";
|
|
471
|
+
function createOAuthClient(config2) {
|
|
472
|
+
const fetchFn = config2.fetch ?? globalThis.fetch;
|
|
473
|
+
return {
|
|
474
|
+
authorize: () => startAuthorization(config2, fetchFn)
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
function generateCodeVerifier() {
|
|
478
|
+
return crypto.randomBytes(32).toString("base64url");
|
|
479
|
+
}
|
|
480
|
+
function generateCodeChallenge(verifier) {
|
|
481
|
+
return crypto.createHash("sha256").update(verifier).digest("base64url");
|
|
482
|
+
}
|
|
483
|
+
async function startAuthorization(config2, fetchFn) {
|
|
484
|
+
const codeVerifier = generateCodeVerifier();
|
|
485
|
+
const codeChallenge = generateCodeChallenge(codeVerifier);
|
|
486
|
+
const server = config2.createServer ? config2.createServer() : http.createServer();
|
|
487
|
+
const port = await startServer(server);
|
|
488
|
+
const redirectUri = `http://127.0.0.1:${port}/callback`;
|
|
489
|
+
const authorizationUrl = buildAuthorizationUrl({
|
|
490
|
+
endpoint: config2.authorizationEndpoint,
|
|
491
|
+
clientId: config2.clientId,
|
|
492
|
+
redirectUri,
|
|
493
|
+
codeChallenge
|
|
494
|
+
});
|
|
495
|
+
const waitForResult = async () => {
|
|
496
|
+
try {
|
|
497
|
+
const code = await waitForAuthorizationCode(server, config2, authorizationUrl);
|
|
498
|
+
return await exchangeCodeForApiKey({
|
|
499
|
+
tokenEndpoint: config2.tokenEndpoint,
|
|
500
|
+
code,
|
|
501
|
+
codeVerifier,
|
|
502
|
+
clientId: config2.clientId,
|
|
503
|
+
redirectUri,
|
|
504
|
+
fetchFn
|
|
505
|
+
});
|
|
506
|
+
} finally {
|
|
507
|
+
server.close();
|
|
508
|
+
}
|
|
509
|
+
};
|
|
510
|
+
return { authorizationUrl, waitForResult };
|
|
511
|
+
}
|
|
512
|
+
function startServer(server) {
|
|
513
|
+
return new Promise((resolve) => {
|
|
514
|
+
server.listen(0, "127.0.0.1", () => {
|
|
515
|
+
const address = server.address();
|
|
516
|
+
resolve(address.port);
|
|
517
|
+
});
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
function buildAuthorizationUrl(params) {
|
|
521
|
+
const url2 = new URL(params.endpoint);
|
|
522
|
+
url2.searchParams.set("response_type", "code");
|
|
523
|
+
url2.searchParams.set("client_id", params.clientId);
|
|
524
|
+
url2.searchParams.set("scope", "apikey:create");
|
|
525
|
+
url2.searchParams.set("code_challenge", params.codeChallenge);
|
|
526
|
+
url2.searchParams.set("code_challenge_method", "S256");
|
|
527
|
+
url2.searchParams.set("redirect_uri", params.redirectUri);
|
|
528
|
+
return url2.toString();
|
|
529
|
+
}
|
|
530
|
+
function waitForAuthorizationCode(server, config2, authorizationUrl) {
|
|
531
|
+
return new Promise((resolve, reject) => {
|
|
532
|
+
let settled = false;
|
|
533
|
+
const settle = (fn) => {
|
|
534
|
+
if (!settled) {
|
|
535
|
+
settled = true;
|
|
536
|
+
fn();
|
|
537
|
+
}
|
|
538
|
+
};
|
|
539
|
+
server.on("request", (req, res) => {
|
|
540
|
+
const url2 = new URL(req.url, `http://127.0.0.1`);
|
|
541
|
+
if (url2.pathname !== "/callback") {
|
|
542
|
+
res.writeHead(404);
|
|
543
|
+
res.end("Not found");
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
const error2 = url2.searchParams.get("error");
|
|
547
|
+
if (error2) {
|
|
548
|
+
const description = url2.searchParams.get("error_description") ?? error2;
|
|
549
|
+
res.writeHead(400);
|
|
550
|
+
res.end(`Authorization failed: ${description}`);
|
|
551
|
+
settle(() => reject(new Error(`OAuth authorization failed: ${error2} \u2014 ${description}`)));
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
554
|
+
const code = url2.searchParams.get("code");
|
|
555
|
+
if (!code) {
|
|
556
|
+
res.writeHead(400);
|
|
557
|
+
res.end("Missing authorization code");
|
|
558
|
+
settle(() => reject(new Error("OAuth callback missing authorization code")));
|
|
559
|
+
return;
|
|
560
|
+
}
|
|
561
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
562
|
+
res.end(buildSuccessPage());
|
|
563
|
+
settle(() => resolve(code));
|
|
564
|
+
});
|
|
565
|
+
if (config2.readLine) {
|
|
566
|
+
config2.readLine().then((input) => {
|
|
567
|
+
const code = extractCodeFromInput(input);
|
|
568
|
+
if (code) {
|
|
569
|
+
settle(() => resolve(code));
|
|
570
|
+
}
|
|
571
|
+
}).catch(() => {
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
if (config2.openBrowser) {
|
|
575
|
+
config2.openBrowser(authorizationUrl).catch(
|
|
576
|
+
(err) => settle(() => reject(err))
|
|
577
|
+
);
|
|
578
|
+
}
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
function extractCodeFromInput(input) {
|
|
582
|
+
const trimmed = input.replace(/[\r\n]/g, "").trim();
|
|
583
|
+
if (trimmed.length === 0) {
|
|
584
|
+
return null;
|
|
585
|
+
}
|
|
586
|
+
try {
|
|
587
|
+
const url2 = new URL(trimmed);
|
|
588
|
+
return url2.searchParams.get("code");
|
|
589
|
+
} catch {
|
|
590
|
+
return trimmed;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
async function exchangeCodeForApiKey(params) {
|
|
594
|
+
const body = new URLSearchParams({
|
|
595
|
+
grant_type: "authorization_code",
|
|
596
|
+
code: params.code,
|
|
597
|
+
code_verifier: params.codeVerifier,
|
|
598
|
+
client_id: params.clientId,
|
|
599
|
+
redirect_uri: params.redirectUri
|
|
600
|
+
});
|
|
601
|
+
const response = await params.fetchFn(params.tokenEndpoint, {
|
|
602
|
+
method: "POST",
|
|
603
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
604
|
+
body: body.toString()
|
|
605
|
+
});
|
|
606
|
+
if (!response.ok) {
|
|
607
|
+
const text4 = await response.text();
|
|
608
|
+
throw new Error(`Token exchange failed (${response.status}): ${text4}`);
|
|
609
|
+
}
|
|
610
|
+
const data = await response.json();
|
|
611
|
+
if (typeof data.api_key !== "string" || data.api_key.length === 0) {
|
|
612
|
+
throw new Error("Token response missing api_key field");
|
|
613
|
+
}
|
|
614
|
+
return {
|
|
615
|
+
apiKey: data.api_key,
|
|
616
|
+
expiresIn: typeof data.api_key_expires_in === "number" ? data.api_key_expires_in : null
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
function buildSuccessPage() {
|
|
620
|
+
return [
|
|
621
|
+
"<!DOCTYPE html>",
|
|
622
|
+
"<html><head><meta charset=utf-8><title>Connected to Poe</title></head>",
|
|
623
|
+
'<body style="font-family:system-ui,sans-serif;display:flex;align-items:center;justify-content:center;min-height:100vh;margin:0">',
|
|
624
|
+
'<div style="text-align:center">',
|
|
625
|
+
"<h1>Connected to Poe</h1>",
|
|
626
|
+
'<p style="color:#666">You can close this tab and return to your terminal.</p>',
|
|
627
|
+
"</div></body></html>"
|
|
628
|
+
].join("");
|
|
629
|
+
}
|
|
630
|
+
var init_oauth_client = __esm({
|
|
631
|
+
"packages/auth/src/oauth-client.ts"() {
|
|
632
|
+
"use strict";
|
|
633
|
+
}
|
|
634
|
+
});
|
|
635
|
+
|
|
468
636
|
// packages/auth/src/index.ts
|
|
469
637
|
var init_src = __esm({
|
|
470
638
|
"packages/auth/src/index.ts"() {
|
|
471
639
|
"use strict";
|
|
472
640
|
init_create_auth_store();
|
|
641
|
+
init_oauth_client();
|
|
473
642
|
init_encrypted_file_auth_store();
|
|
474
643
|
init_keychain_auth_store();
|
|
475
644
|
}
|
|
@@ -11904,6 +12073,8 @@ var init_wrap = __esm({
|
|
|
11904
12073
|
});
|
|
11905
12074
|
|
|
11906
12075
|
// src/cli/commands/login.ts
|
|
12076
|
+
import { exec as exec2 } from "node:child_process";
|
|
12077
|
+
import readline from "node:readline";
|
|
11907
12078
|
function registerLoginCommand(program, container) {
|
|
11908
12079
|
program.command("login").description("Store a Poe API key for reuse across commands.").option("--api-key <key>", "Poe API key").action(async (options) => {
|
|
11909
12080
|
await executeLogin(program, container, options);
|
|
@@ -11956,6 +12127,9 @@ async function resolveApiKeyInput(container, options) {
|
|
|
11956
12127
|
if (envKey && envKey.trim().length > 0) {
|
|
11957
12128
|
return envKey;
|
|
11958
12129
|
}
|
|
12130
|
+
if (container.env.getVariable("POE_CODE_OAUTH_LOGIN") === "1") {
|
|
12131
|
+
return resolveApiKeyViaOAuth();
|
|
12132
|
+
}
|
|
11959
12133
|
const descriptor = container.promptLibrary.loginApiKey();
|
|
11960
12134
|
const response = await container.prompts(descriptor);
|
|
11961
12135
|
const value = response[descriptor.name];
|
|
@@ -11967,6 +12141,44 @@ async function resolveApiKeyInput(container, options) {
|
|
|
11967
12141
|
}
|
|
11968
12142
|
return value;
|
|
11969
12143
|
}
|
|
12144
|
+
async function resolveApiKeyViaOAuth() {
|
|
12145
|
+
const rl = readline.createInterface({
|
|
12146
|
+
input: process.stdin
|
|
12147
|
+
});
|
|
12148
|
+
try {
|
|
12149
|
+
const client = createOAuthClient({
|
|
12150
|
+
clientId: "client_f520ee4d8ca84a13ba876a8731d264d0",
|
|
12151
|
+
authorizationEndpoint: "https://poe.com/oauth/authorize",
|
|
12152
|
+
tokenEndpoint: "https://api.poe.com/token",
|
|
12153
|
+
openBrowser: (url2) => openInBrowser(url2).catch(() => {
|
|
12154
|
+
log2.warn("Could not open browser automatically.");
|
|
12155
|
+
}),
|
|
12156
|
+
readLine: () => new Promise((resolve) => {
|
|
12157
|
+
rl.once("line", (line) => resolve(line));
|
|
12158
|
+
})
|
|
12159
|
+
});
|
|
12160
|
+
const authorization = await client.authorize();
|
|
12161
|
+
log2.message(`${text.muted("Authorize at")} ${text.link(authorization.authorizationUrl)}`);
|
|
12162
|
+
log2.message(text.muted("Waiting for authorization. You can also paste the redirect URL here:"));
|
|
12163
|
+
const result = await authorization.waitForResult();
|
|
12164
|
+
return result.apiKey;
|
|
12165
|
+
} finally {
|
|
12166
|
+
rl.close();
|
|
12167
|
+
}
|
|
12168
|
+
}
|
|
12169
|
+
function openInBrowser(url2) {
|
|
12170
|
+
return new Promise((resolve, reject) => {
|
|
12171
|
+
const platform = process.platform;
|
|
12172
|
+
const command = platform === "darwin" ? `open "${url2}"` : platform === "win32" ? `start "" "${url2}"` : `xdg-open "${url2}"`;
|
|
12173
|
+
exec2(command, (error2) => {
|
|
12174
|
+
if (error2) {
|
|
12175
|
+
reject(error2);
|
|
12176
|
+
} else {
|
|
12177
|
+
resolve();
|
|
12178
|
+
}
|
|
12179
|
+
});
|
|
12180
|
+
});
|
|
12181
|
+
}
|
|
11970
12182
|
async function reconfigureServices(input) {
|
|
11971
12183
|
const { program, container, apiKey, configuredServices } = input;
|
|
11972
12184
|
const serviceNames = Object.keys(configuredServices);
|
|
@@ -12022,6 +12234,8 @@ var init_login = __esm({
|
|
|
12022
12234
|
init_config();
|
|
12023
12235
|
init_errors();
|
|
12024
12236
|
init_mutation_events();
|
|
12237
|
+
init_src();
|
|
12238
|
+
init_src4();
|
|
12025
12239
|
}
|
|
12026
12240
|
});
|
|
12027
12241
|
|
|
@@ -13235,7 +13449,7 @@ var init_convert = __esm({
|
|
|
13235
13449
|
});
|
|
13236
13450
|
|
|
13237
13451
|
// packages/tiny-stdio-mcp-server/src/server.ts
|
|
13238
|
-
import * as
|
|
13452
|
+
import * as readline2 from "readline";
|
|
13239
13453
|
function createServer(options) {
|
|
13240
13454
|
const tools = /* @__PURE__ */ new Map();
|
|
13241
13455
|
let initialized = false;
|
|
@@ -13381,7 +13595,7 @@ function createServer(options) {
|
|
|
13381
13595
|
activeTransport = transport;
|
|
13382
13596
|
activeSDKTransport = null;
|
|
13383
13597
|
return new Promise((resolve) => {
|
|
13384
|
-
const rl =
|
|
13598
|
+
const rl = readline2.createInterface({
|
|
13385
13599
|
input: transport.readable,
|
|
13386
13600
|
crlfDelay: Infinity
|
|
13387
13601
|
});
|
|
@@ -30404,7 +30618,7 @@ var require_schemes = __commonJS({
|
|
|
30404
30618
|
urnComponent.nss = (uuidComponent.uuid || "").toLowerCase();
|
|
30405
30619
|
return urnComponent;
|
|
30406
30620
|
}
|
|
30407
|
-
var
|
|
30621
|
+
var http2 = (
|
|
30408
30622
|
/** @type {SchemeHandler} */
|
|
30409
30623
|
{
|
|
30410
30624
|
scheme: "http",
|
|
@@ -30417,7 +30631,7 @@ var require_schemes = __commonJS({
|
|
|
30417
30631
|
/** @type {SchemeHandler} */
|
|
30418
30632
|
{
|
|
30419
30633
|
scheme: "https",
|
|
30420
|
-
domainHost:
|
|
30634
|
+
domainHost: http2.domainHost,
|
|
30421
30635
|
parse: httpParse,
|
|
30422
30636
|
serialize: httpSerialize
|
|
30423
30637
|
}
|
|
@@ -30461,7 +30675,7 @@ var require_schemes = __commonJS({
|
|
|
30461
30675
|
var SCHEMES = (
|
|
30462
30676
|
/** @type {Record<SchemeName, SchemeHandler>} */
|
|
30463
30677
|
{
|
|
30464
|
-
http,
|
|
30678
|
+
http: http2,
|
|
30465
30679
|
https,
|
|
30466
30680
|
ws,
|
|
30467
30681
|
wss,
|
|
@@ -36328,11 +36542,11 @@ async function buildLoop(options) {
|
|
|
36328
36542
|
worktreeBranch = entry.branch;
|
|
36329
36543
|
const worktreePath = entry.path;
|
|
36330
36544
|
const symlinkFn = fs3.symlink ?? ((target, path22) => fsPromises8.symlink(target, path22));
|
|
36331
|
-
const
|
|
36545
|
+
const exec3 = worktreeDeps.exec;
|
|
36332
36546
|
const dirsToLink = [".poe-code-ralph", ".agents/poe-code-ralph"];
|
|
36333
36547
|
for (const dir of dirsToLink) {
|
|
36334
36548
|
try {
|
|
36335
|
-
await
|
|
36549
|
+
await exec3(`git check-ignore -q ${dir}`, { cwd: originalCwd });
|
|
36336
36550
|
} catch {
|
|
36337
36551
|
continue;
|
|
36338
36552
|
}
|
|
@@ -38382,7 +38596,7 @@ var init_package = __esm({
|
|
|
38382
38596
|
"package.json"() {
|
|
38383
38597
|
package_default = {
|
|
38384
38598
|
name: "poe-code",
|
|
38385
|
-
version: "3.0.
|
|
38599
|
+
version: "3.0.88",
|
|
38386
38600
|
description: "CLI tool to configure Poe API for developer workflows.",
|
|
38387
38601
|
type: "module",
|
|
38388
38602
|
main: "./dist/index.js",
|