@actionway/cli 0.18.12 → 0.18.14
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/README.md
CHANGED
|
@@ -22,7 +22,7 @@ actionway doctor
|
|
|
22
22
|
actionway init
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
`doctor` 只输出脱敏后的 Node/npm、registry、global PATH
|
|
25
|
+
`doctor` 只输出脱敏后的 Node/npm、registry、global PATH、配置目录
|
|
26
26
|
和 OAuth discovery 检查;它不会修改 npm、代理、CA、PATH 或 PowerShell policy。
|
|
27
27
|
|
|
28
28
|
### Development 通道
|
|
@@ -48,8 +48,13 @@ actionway --agent-host=workbuddy tools search "generate a product image"
|
|
|
48
48
|
|
|
49
49
|
不带 `--agent-host` 表示用户直接使用 CLI。该声明不写入共享凭据,所以同一个用户和全局 CLI 可以交替被多个 Agent 使用。CLI 同时从每次进程的 Node.js 运行环境识别 Windows、macOS、WSL 或 Linux;这些字段只作为 Site 侧产品分析事件属性,不参与鉴权、计费或 Gateway 路由。
|
|
50
50
|
|
|
51
|
-
- **auth 唯一途径:Clerk OAuth(PKCE
|
|
52
|
-
`{public origin}/api/auth/cli-config`
|
|
51
|
+
- **auth 唯一途径:Clerk OAuth(PKCE)+ device 配对**。issuer / client_id 运行时从
|
|
52
|
+
`{public origin}/api/auth/cli-config` 发现;登录不依赖本机浏览器回调——CLI 展示
|
|
53
|
+
短码与 `{public origin}/cli/activate` 验证 URL,用户在任意设备的浏览器上登录并
|
|
54
|
+
批准后 CLI 轮询取回一次性授权码并在本地完成 PKCE token 交换(远端 / headless /
|
|
55
|
+
WSL 环境可直接使用,`--no-browser` 仅打印 URL 不尝试开浏览器);
|
|
56
|
+
fresh `actionway init` 会在 token 交换后的第一条账户请求中携带安装会话和本地
|
|
57
|
+
客户端上下文,由服务端同时完成 CLI 首次建户、获客归因和安装连接;
|
|
53
58
|
凭据存 `~/.actionway/credentials.json`(POSIX 上为 0600 owner-only 文件;
|
|
54
59
|
Windows 上 chmod 无效,保密性依赖 `%USERPROFILE%` 的继承 ACL——不要把
|
|
55
60
|
`ACTIONWAY_CONFIG_DIR` 指到共享目录)。CLI 从不打印或存储 OAuth client secret。
|
|
@@ -7,6 +7,6 @@ Register an existing media URL as an Actionway asset for later capability calls.
|
|
|
7
7
|
|
|
8
8
|
## Indicative price
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
$0.002
|
|
11
11
|
|
|
12
12
|
Prices are indicative catalog values refreshed with each skill release. Before calling, Inspect the chosen variant: Inspect's input Schema and USD quote are authoritative.
|
package/dist/index.js
CHANGED
|
@@ -12069,7 +12069,6 @@ var {
|
|
|
12069
12069
|
import { spawn } from "node:child_process";
|
|
12070
12070
|
import { createHash, randomBytes } from "node:crypto";
|
|
12071
12071
|
import { chmodSync as chmodSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync3, rmSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
12072
|
-
import { createServer } from "node:http";
|
|
12073
12072
|
import { join as join2 } from "node:path";
|
|
12074
12073
|
|
|
12075
12074
|
// src/lib/update-state.ts
|
|
@@ -12408,6 +12407,35 @@ function runUpdate(options = {}) {
|
|
|
12408
12407
|
return { ...status, updated: true, restart_required: true };
|
|
12409
12408
|
}
|
|
12410
12409
|
|
|
12410
|
+
// src/lib/client-context.ts
|
|
12411
|
+
var ACTIONWAY_AGENT_HOST_HEADER = "x-actionway-agent-host";
|
|
12412
|
+
var ACTIONWAY_RUNTIME_OS_HEADER = "x-actionway-runtime-os";
|
|
12413
|
+
var ACTIONWAY_AGENT_HOSTS = ["codex", "claude_code", "workbuddy"];
|
|
12414
|
+
function isActionwayAgentHost(value) {
|
|
12415
|
+
return typeof value === "string" && ACTIONWAY_AGENT_HOSTS.includes(value);
|
|
12416
|
+
}
|
|
12417
|
+
function detectRuntimeOs(platform = process.platform, env = process.env) {
|
|
12418
|
+
if (platform === "win32") return "windows";
|
|
12419
|
+
if (platform === "darwin") return "macos";
|
|
12420
|
+
if (platform === "linux") {
|
|
12421
|
+
if ((env.WSL_DISTRO_NAME ?? "").trim() || (env.WSL_INTEROP ?? "").trim()) return "wsl";
|
|
12422
|
+
return "linux";
|
|
12423
|
+
}
|
|
12424
|
+
return "other";
|
|
12425
|
+
}
|
|
12426
|
+
function localClientContext(agentHost, platform = process.platform, env = process.env) {
|
|
12427
|
+
return {
|
|
12428
|
+
...isActionwayAgentHost(agentHost) ? { agentHost } : {},
|
|
12429
|
+
runtimeOs: detectRuntimeOs(platform, env)
|
|
12430
|
+
};
|
|
12431
|
+
}
|
|
12432
|
+
function localClientContextHeaders(context) {
|
|
12433
|
+
return {
|
|
12434
|
+
...context.agentHost ? { [ACTIONWAY_AGENT_HOST_HEADER]: context.agentHost } : {},
|
|
12435
|
+
[ACTIONWAY_RUNTIME_OS_HEADER]: context.runtimeOs
|
|
12436
|
+
};
|
|
12437
|
+
}
|
|
12438
|
+
|
|
12411
12439
|
// src/auth/clerk.ts
|
|
12412
12440
|
var DEFAULT_GATEWAY_URL = "https://actionway.ai";
|
|
12413
12441
|
var SCOPES = "profile email offline_access";
|
|
@@ -12415,6 +12443,9 @@ var REFRESH_SKEW_S = 30;
|
|
|
12415
12443
|
var TOKEN_TIMEOUT_MS = 2e4;
|
|
12416
12444
|
var DISCOVERY_TIMEOUT_MS = 1e4;
|
|
12417
12445
|
var SESSION_TIMEOUT_MS = 2e4;
|
|
12446
|
+
var DEVICE_START_TIMEOUT_MS = 1e4;
|
|
12447
|
+
var DEVICE_POLL_TIMEOUT_MS = 1e4;
|
|
12448
|
+
var DEFAULT_POLL_INTERVAL_S = 3;
|
|
12418
12449
|
var DEFAULT_LOGIN_TIMEOUT_MS = 12e5;
|
|
12419
12450
|
function stripSlash(url) {
|
|
12420
12451
|
return url.replace(/\/+$/, "");
|
|
@@ -12524,116 +12555,80 @@ function randomBase64Url() {
|
|
|
12524
12555
|
function pkceChallenge(verifier) {
|
|
12525
12556
|
return createHash("sha256").update(verifier).digest("base64url");
|
|
12526
12557
|
}
|
|
12527
|
-
|
|
12528
|
-
|
|
12529
|
-
|
|
12530
|
-
|
|
12531
|
-
|
|
12532
|
-
|
|
12533
|
-
|
|
12534
|
-
|
|
12535
|
-
|
|
12536
|
-
|
|
12537
|
-
|
|
12538
|
-
|
|
12539
|
-
|
|
12540
|
-
|
|
12541
|
-
"
|
|
12542
|
-
|
|
12543
|
-
|
|
12544
|
-
|
|
12545
|
-
|
|
12546
|
-
|
|
12547
|
-
|
|
12548
|
-
|
|
12549
|
-
|
|
12550
|
-
|
|
12551
|
-
|
|
12552
|
-
|
|
12558
|
+
async function readDeviceJson(response) {
|
|
12559
|
+
let value;
|
|
12560
|
+
try {
|
|
12561
|
+
value = await response.json();
|
|
12562
|
+
} catch {
|
|
12563
|
+
throw new CliError("E_BACKEND", `Actionway sign-in returned an invalid response (${response.status})`);
|
|
12564
|
+
}
|
|
12565
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
12566
|
+
throw new CliError("E_BACKEND", `Actionway sign-in returned an invalid response (${response.status})`);
|
|
12567
|
+
}
|
|
12568
|
+
return value;
|
|
12569
|
+
}
|
|
12570
|
+
function deviceErrorDetail(value) {
|
|
12571
|
+
const error = value.error;
|
|
12572
|
+
const code = typeof error?.code === "string" ? error.code : "";
|
|
12573
|
+
const message = typeof error?.message === "string" ? error.message : "";
|
|
12574
|
+
return [code, message].filter(Boolean).join(": ");
|
|
12575
|
+
}
|
|
12576
|
+
async function startDevicePairing(gateway, codeChallenge, fetchImpl = fetch) {
|
|
12577
|
+
const response = await fetchImpl(`${stripSlash(gateway)}/api/auth/cli-device/start`, {
|
|
12578
|
+
method: "POST",
|
|
12579
|
+
headers: { Accept: "application/json", "Content-Type": "application/json" },
|
|
12580
|
+
body: JSON.stringify({ code_challenge: codeChallenge }),
|
|
12581
|
+
signal: AbortSignal.timeout(DEVICE_START_TIMEOUT_MS)
|
|
12582
|
+
});
|
|
12583
|
+
const value = await readDeviceJson(response);
|
|
12584
|
+
if (!response.ok) {
|
|
12585
|
+
const detail = deviceErrorDetail(value);
|
|
12586
|
+
throw new CliError(
|
|
12587
|
+
"E_BACKEND",
|
|
12588
|
+
`Actionway sign-in is unavailable (${response.status}${detail ? `; ${detail}` : ""})`,
|
|
12589
|
+
"check auth_context.gateway_url is the intended Actionway environment and run `actionway login` again"
|
|
12590
|
+
);
|
|
12591
|
+
}
|
|
12592
|
+
if (typeof value.device_code !== "string" || !value.device_code || typeof value.user_code !== "string" || !value.user_code || typeof value.verification_url !== "string" || typeof value.verification_url_complete !== "string" || typeof value.redirect_uri !== "string") {
|
|
12593
|
+
throw new CliError("E_BACKEND", "Actionway sign-in returned an invalid pairing response");
|
|
12594
|
+
}
|
|
12595
|
+
return {
|
|
12596
|
+
deviceCode: value.device_code,
|
|
12597
|
+
userCode: value.user_code,
|
|
12598
|
+
verificationUrl: value.verification_url,
|
|
12599
|
+
verificationUrlComplete: value.verification_url_complete,
|
|
12600
|
+
redirectUri: value.redirect_uri,
|
|
12601
|
+
expiresInS: typeof value.expires_in === "number" && value.expires_in > 0 ? value.expires_in : 900,
|
|
12602
|
+
intervalS: typeof value.interval === "number" && value.interval >= 1 && value.interval <= 30 ? value.interval : DEFAULT_POLL_INTERVAL_S
|
|
12603
|
+
};
|
|
12604
|
+
}
|
|
12605
|
+
async function pollDevicePairing(gateway, deviceCode, fetchImpl = fetch) {
|
|
12606
|
+
const response = await fetchImpl(`${stripSlash(gateway)}/api/auth/cli-device/poll`, {
|
|
12607
|
+
method: "POST",
|
|
12608
|
+
headers: { Accept: "application/json", "Content-Type": "application/json" },
|
|
12609
|
+
body: JSON.stringify({ device_code: deviceCode }),
|
|
12610
|
+
signal: AbortSignal.timeout(DEVICE_POLL_TIMEOUT_MS)
|
|
12611
|
+
});
|
|
12612
|
+
const value = await readDeviceJson(response);
|
|
12613
|
+
if (!response.ok) {
|
|
12614
|
+
const detail = deviceErrorDetail(value);
|
|
12615
|
+
throw new CliError("E_BACKEND", `Actionway sign-in polling failed (${response.status}${detail ? `; ${detail}` : ""})`);
|
|
12616
|
+
}
|
|
12617
|
+
switch (value.status) {
|
|
12618
|
+
case "pending":
|
|
12619
|
+
return { status: "pending" };
|
|
12620
|
+
case "approved":
|
|
12621
|
+
if (typeof value.code !== "string" || !value.code) {
|
|
12622
|
+
throw new CliError("E_BACKEND", "Actionway sign-in returned an invalid approval response");
|
|
12623
|
+
}
|
|
12624
|
+
return { status: "approved", code: value.code };
|
|
12625
|
+
case "denied":
|
|
12626
|
+
return { status: "denied" };
|
|
12627
|
+
case "expired":
|
|
12628
|
+
return { status: "expired" };
|
|
12629
|
+
default:
|
|
12630
|
+
throw new CliError("E_BACKEND", "Actionway sign-in returned an unknown pairing status");
|
|
12553
12631
|
}
|
|
12554
|
-
};
|
|
12555
|
-
function callbackLocale(acceptLanguage) {
|
|
12556
|
-
const header = Array.isArray(acceptLanguage) ? acceptLanguage.join(",") : acceptLanguage || "";
|
|
12557
|
-
const languages = header.split(",").map((entry, index) => {
|
|
12558
|
-
const [tag = "", ...parameters] = entry.trim().toLowerCase().split(";");
|
|
12559
|
-
const quality = parameters.find((value) => value.trim().startsWith("q="));
|
|
12560
|
-
const parsedQuality = quality ? Number.parseFloat(quality.split("=")[1] || "0") : 1;
|
|
12561
|
-
return { tag, quality: Number.isFinite(parsedQuality) ? parsedQuality : 0, index };
|
|
12562
|
-
}).filter(({ quality }) => quality > 0).sort((left, right) => right.quality - left.quality || left.index - right.index);
|
|
12563
|
-
for (const { tag } of languages) {
|
|
12564
|
-
if (tag === "zh" || tag.startsWith("zh-")) return "zh-CN";
|
|
12565
|
-
if (tag === "en" || tag.startsWith("en-")) return "en";
|
|
12566
|
-
}
|
|
12567
|
-
return "en";
|
|
12568
|
-
}
|
|
12569
|
-
function callbackPage(status, locale = "en") {
|
|
12570
|
-
const success = status === "success";
|
|
12571
|
-
const copy = CALLBACK_COPY[locale];
|
|
12572
|
-
const title = success ? copy.successTitle : copy.errorTitle;
|
|
12573
|
-
const message = success ? copy.successMessage : copy.errorMessage;
|
|
12574
|
-
const statusText = success ? copy.successStatus : copy.errorStatus;
|
|
12575
|
-
const accent = success ? "#a6f46f" : "#ff8b81";
|
|
12576
|
-
const accentRgb = success ? "166,244,111" : "255,139,129";
|
|
12577
|
-
const icon = success ? '<path d="m8.5 12.5 2.2 2.2 4.8-5.2"/>' : '<path d="M12 8v5m0 3.5v.01"/>';
|
|
12578
|
-
return `<!doctype html>
|
|
12579
|
-
<html lang="${locale}">
|
|
12580
|
-
<head>
|
|
12581
|
-
<meta charset="utf-8">
|
|
12582
|
-
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
12583
|
-
<meta name="color-scheme" content="dark">
|
|
12584
|
-
<title>Actionway \xB7 ${title}</title>
|
|
12585
|
-
<style>
|
|
12586
|
-
:root{color-scheme:dark}*{box-sizing:border-box}html,body{margin:0;min-height:100%}
|
|
12587
|
-
body{min-height:100vh;display:grid;place-items:center;overflow:hidden;padding:32px;color:#f4f6f1;background:#070908;font-family:Inter,ui-sans-serif,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif}
|
|
12588
|
-
body:before{content:"";position:fixed;inset:-20%;pointer-events:none;background:radial-gradient(circle at 22% 18%,rgba(${accentRgb},.13),transparent 25%),radial-gradient(circle at 82% 76%,rgba(109,130,255,.1),transparent 24%);filter:blur(8px)}
|
|
12589
|
-
body:after{content:"";position:fixed;inset:0;pointer-events:none;opacity:.32;background-image:linear-gradient(rgba(255,255,255,.045) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.045) 1px,transparent 1px);background-size:48px 48px;mask-image:radial-gradient(circle at center,black,transparent 78%)}
|
|
12590
|
-
main{position:relative;width:min(100%,720px);overflow:hidden;border:1px solid rgba(255,255,255,.11);border-radius:30px;background:linear-gradient(145deg,rgba(28,31,29,.92),rgba(13,15,14,.96));box-shadow:0 44px 120px rgba(0,0,0,.62),inset 0 1px 0 rgba(255,255,255,.07);animation:enter .7s cubic-bezier(.2,.8,.2,1) both}
|
|
12591
|
-
main:before{content:"";position:absolute;inset:0;pointer-events:none;background:linear-gradient(110deg,transparent 24%,rgba(255,255,255,.035) 44%,transparent 60%)}
|
|
12592
|
-
.topbar{position:relative;display:flex;align-items:center;justify-content:space-between;padding:22px 26px;border-bottom:1px solid rgba(255,255,255,.08)}
|
|
12593
|
-
.brand{display:flex;align-items:center;gap:11px;font-size:15px;font-weight:650;letter-spacing:-.02em}
|
|
12594
|
-
.brand-mark{position:relative;display:grid;place-items:center;width:29px;height:29px;border:1px solid rgba(255,255,255,.15);border-radius:9px;color:#111;background:#f1f4ed;font:750 10px/1 ui-monospace,SFMono-Regular,Menlo,monospace;box-shadow:0 8px 22px rgba(0,0,0,.24)}
|
|
12595
|
-
.secure{display:flex;align-items:center;gap:8px;color:#8e978f;font:600 10px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.12em;text-transform:uppercase}
|
|
12596
|
-
.secure-dot{width:6px;height:6px;border-radius:50%;background:${accent};box-shadow:0 0 16px rgba(${accentRgb},.8);animation:pulse 2.2s ease-in-out infinite}
|
|
12597
|
-
.content{position:relative;padding:54px 58px 42px}
|
|
12598
|
-
.orb{position:absolute;top:42px;right:48px;display:grid;place-items:center;width:96px;height:96px;border:1px solid rgba(${accentRgb},.28);border-radius:50%;color:${accent};background:radial-gradient(circle at 35% 28%,rgba(255,255,255,.12),rgba(${accentRgb},.06) 46%,rgba(0,0,0,.08));box-shadow:0 0 0 12px rgba(${accentRgb},.035),0 0 70px rgba(${accentRgb},.13);animation:float 4.8s ease-in-out infinite}
|
|
12599
|
-
.orb:before,.orb:after{content:"";position:absolute;border:1px solid rgba(${accentRgb},.14);border-radius:50%}.orb:before{inset:-12px}.orb:after{inset:11px}
|
|
12600
|
-
.orb svg{position:relative;z-index:1;width:42px;height:42px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
|
|
12601
|
-
.eyebrow{margin:0 0 20px;color:${accent};font:650 11px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.16em;text-transform:uppercase}
|
|
12602
|
-
h1{max-width:500px;margin:0;color:#f4f6f1;font-size:clamp(48px,7vw,74px);font-weight:620;line-height:.98;letter-spacing:-.065em}
|
|
12603
|
-
body[data-locale="en"] h1{font-size:clamp(42px,6vw,64px);letter-spacing:-.05em}
|
|
12604
|
-
h1 span{color:#7d857e}
|
|
12605
|
-
.message{max-width:450px;margin:26px 0 38px;color:#9ba39c;font-size:16px;line-height:1.75}
|
|
12606
|
-
.terminal{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:15px;padding:17px 18px;border:1px solid rgba(255,255,255,.09);border-radius:15px;background:rgba(4,6,5,.5);box-shadow:inset 0 1px rgba(255,255,255,.025)}
|
|
12607
|
-
.prompt{color:${accent};font:700 18px/1 ui-monospace,SFMono-Regular,Menlo,monospace}
|
|
12608
|
-
.terminal strong,.terminal small{display:block;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.terminal strong{color:#d7dcd5;font-size:12px}.terminal small{margin-top:5px;color:#677068;font-size:10px;letter-spacing:.04em}
|
|
12609
|
-
.terminal-check{display:grid;place-items:center;width:26px;height:26px;border-radius:50%;color:#071006;background:${accent};font-size:13px;font-weight:900;box-shadow:0 0 22px rgba(${accentRgb},.2)}
|
|
12610
|
-
footer{position:relative;display:flex;justify-content:space-between;gap:18px;padding:19px 26px;border-top:1px solid rgba(255,255,255,.075);color:#5f6760;font:550 9px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace;text-transform:uppercase;letter-spacing:.13em}
|
|
12611
|
-
@keyframes enter{from{opacity:0;transform:translateY(18px) scale(.985)}to{opacity:1;transform:none}}@keyframes float{50%{transform:translateY(-7px)}}@keyframes pulse{50%{opacity:.45;box-shadow:0 0 8px rgba(${accentRgb},.35)}}
|
|
12612
|
-
@media(max-width:640px){body{padding:16px;overflow:auto}main{border-radius:23px}.topbar{padding:18px 20px}.content{padding:38px 26px 30px}.orb{position:relative;top:auto;right:auto;width:76px;height:76px;margin:0 0 36px}h1{font-size:48px}.message{font-size:15px}footer{padding:17px 20px;flex-direction:column;gap:5px}}
|
|
12613
|
-
@media(prefers-reduced-motion:reduce){main,.orb,.secure-dot{animation:none}}
|
|
12614
|
-
</style>
|
|
12615
|
-
</head>
|
|
12616
|
-
<body data-locale="${locale}">
|
|
12617
|
-
<main>
|
|
12618
|
-
<header class="topbar">
|
|
12619
|
-
<div class="brand"><span class="brand-mark">AW</span><span>Actionway</span></div>
|
|
12620
|
-
<div class="secure"><span class="secure-dot"></span><span>${copy.secure}</span></div>
|
|
12621
|
-
</header>
|
|
12622
|
-
<section class="content">
|
|
12623
|
-
<div class="orb"><svg viewBox="0 0 24 24" aria-hidden="true">${icon}</svg></div>
|
|
12624
|
-
<p class="eyebrow">${copy.eyebrow}</p>
|
|
12625
|
-
<h1>${title}<br><span>Actionway CLI</span></h1>
|
|
12626
|
-
<p class="message">${message}</p>
|
|
12627
|
-
<div class="terminal">
|
|
12628
|
-
<span class="prompt">\u203A</span>
|
|
12629
|
-
<span><strong>${statusText}</strong><small>${copy.session}</small></span>
|
|
12630
|
-
<span class="terminal-check">${success ? "\u2713" : "!"}</span>
|
|
12631
|
-
</div>
|
|
12632
|
-
</section>
|
|
12633
|
-
<footer><span>${copy.callback}</span><span>${copy.flow}</span></footer>
|
|
12634
|
-
</main>
|
|
12635
|
-
</body>
|
|
12636
|
-
</html>`;
|
|
12637
12632
|
}
|
|
12638
12633
|
function openBrowser(url, onNotice) {
|
|
12639
12634
|
onNotice(`Opening your browser. If it does not open, use:
|
|
@@ -12644,62 +12639,6 @@ ${url}`);
|
|
|
12644
12639
|
child.once("error", () => void 0);
|
|
12645
12640
|
child.unref();
|
|
12646
12641
|
}
|
|
12647
|
-
async function waitForCode(state, timeoutMs) {
|
|
12648
|
-
let resolveCode;
|
|
12649
|
-
let rejectCode;
|
|
12650
|
-
const code = new Promise((resolve3, reject) => {
|
|
12651
|
-
resolveCode = resolve3;
|
|
12652
|
-
rejectCode = reject;
|
|
12653
|
-
});
|
|
12654
|
-
const server = createServer((request, response) => {
|
|
12655
|
-
const url = new URL(request.url || "/", "http://127.0.0.1");
|
|
12656
|
-
if (request.method !== "GET" || url.pathname !== "/callback") {
|
|
12657
|
-
response.writeHead(404).end();
|
|
12658
|
-
return;
|
|
12659
|
-
}
|
|
12660
|
-
const receivedCode = url.searchParams.get("code");
|
|
12661
|
-
const oauthError = url.searchParams.get("error_description") || url.searchParams.get("error");
|
|
12662
|
-
const locale = callbackLocale(request.headers["accept-language"]);
|
|
12663
|
-
if (oauthError || url.searchParams.get("state") !== state || !receivedCode) {
|
|
12664
|
-
response.writeHead(400, { "Content-Type": "text/html; charset=utf-8" });
|
|
12665
|
-
response.end(callbackPage("error", locale));
|
|
12666
|
-
rejectCode(new CliError("E_BACKEND", oauthError || "OAuth callback validation failed."));
|
|
12667
|
-
return;
|
|
12668
|
-
}
|
|
12669
|
-
response.writeHead(200, {
|
|
12670
|
-
"Cache-Control": "no-store",
|
|
12671
|
-
"Content-Type": "text/html; charset=utf-8",
|
|
12672
|
-
"Referrer-Policy": "no-referrer"
|
|
12673
|
-
});
|
|
12674
|
-
response.end(callbackPage("success", locale), () => {
|
|
12675
|
-
resolveCode(receivedCode);
|
|
12676
|
-
server.close();
|
|
12677
|
-
});
|
|
12678
|
-
});
|
|
12679
|
-
await new Promise((resolve3, reject) => {
|
|
12680
|
-
server.once("error", reject);
|
|
12681
|
-
server.listen(0, "127.0.0.1", resolve3);
|
|
12682
|
-
});
|
|
12683
|
-
const port = server.address().port;
|
|
12684
|
-
const timer = setTimeout(() => {
|
|
12685
|
-
rejectCode(
|
|
12686
|
-
new CliError(
|
|
12687
|
-
"E_BACKEND",
|
|
12688
|
-
`login timed out after ${Math.round(timeoutMs / 1e3)} seconds`,
|
|
12689
|
-
"run `actionway login` again and ask the user to finish the browser sign-in promptly; pass --timeout-seconds <n> to allow more time"
|
|
12690
|
-
)
|
|
12691
|
-
);
|
|
12692
|
-
server.close();
|
|
12693
|
-
}, timeoutMs);
|
|
12694
|
-
return {
|
|
12695
|
-
redirectUri: `http://127.0.0.1:${port}/callback`,
|
|
12696
|
-
code: code.finally(() => clearTimeout(timer)),
|
|
12697
|
-
close: () => {
|
|
12698
|
-
clearTimeout(timer);
|
|
12699
|
-
return new Promise((resolve3) => server.listening ? server.close(() => resolve3()) : resolve3());
|
|
12700
|
-
}
|
|
12701
|
-
};
|
|
12702
|
-
}
|
|
12703
12642
|
async function readJsonObject(response) {
|
|
12704
12643
|
const value = await response.json();
|
|
12705
12644
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
@@ -12770,9 +12709,19 @@ async function loadFreshCredentials(env = process.env, fetchImpl = fetch) {
|
|
|
12770
12709
|
saveCredentials(next, env);
|
|
12771
12710
|
return next;
|
|
12772
12711
|
}
|
|
12773
|
-
async function fetchCliSession(gateway, accessToken, fetchImpl = fetch) {
|
|
12774
|
-
const
|
|
12775
|
-
|
|
12712
|
+
async function fetchCliSession(gateway, accessToken, fetchImpl = fetch, context = {}) {
|
|
12713
|
+
const url = new URL(`${stripSlash(gateway)}/api/auth/cli-session`);
|
|
12714
|
+
if (context.installAttribution) {
|
|
12715
|
+
url.searchParams.set("install_session_id", context.installAttribution.installSessionId);
|
|
12716
|
+
url.searchParams.set("install_source", context.installAttribution.installSource);
|
|
12717
|
+
}
|
|
12718
|
+
const response = await fetchImpl(url, {
|
|
12719
|
+
headers: {
|
|
12720
|
+
Accept: "application/json",
|
|
12721
|
+
Authorization: `Bearer ${accessToken}`,
|
|
12722
|
+
"x-actionway-cli-version": getCliVersion(),
|
|
12723
|
+
...context.clientContext ? localClientContextHeaders(context.clientContext) : {}
|
|
12724
|
+
},
|
|
12776
12725
|
signal: AbortSignal.timeout(SESSION_TIMEOUT_MS)
|
|
12777
12726
|
});
|
|
12778
12727
|
if (response.status === 401) return null;
|
|
@@ -12792,9 +12741,13 @@ async function fetchCliSession(gateway, accessToken, fetchImpl = fetch) {
|
|
|
12792
12741
|
walletId: value.walletId
|
|
12793
12742
|
};
|
|
12794
12743
|
}
|
|
12744
|
+
function defaultSleep(ms) {
|
|
12745
|
+
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
12746
|
+
}
|
|
12795
12747
|
async function login(options = {}) {
|
|
12796
12748
|
const env = options.env ?? process.env;
|
|
12797
12749
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
12750
|
+
const sleep = options.sleepImpl ?? defaultSleep;
|
|
12798
12751
|
const onNotice = options.onNotice ?? ((message) => process.stderr.write(`${message}
|
|
12799
12752
|
`));
|
|
12800
12753
|
const gateway = resolveGatewayUrl(options.gateway, env);
|
|
@@ -12841,35 +12794,63 @@ async function login(options = {}) {
|
|
|
12841
12794
|
issuer ||= discovered.issuer;
|
|
12842
12795
|
}
|
|
12843
12796
|
const timeoutMs = options.timeoutSeconds !== void 0 && Number.isFinite(options.timeoutSeconds) && options.timeoutSeconds > 0 ? options.timeoutSeconds * 1e3 : DEFAULT_LOGIN_TIMEOUT_MS;
|
|
12844
|
-
const verifier = randomBase64Url();
|
|
12845
|
-
const state = randomBase64Url();
|
|
12846
|
-
const callback = await waitForCode(state, timeoutMs);
|
|
12847
12797
|
try {
|
|
12848
|
-
const
|
|
12849
|
-
|
|
12850
|
-
|
|
12851
|
-
|
|
12852
|
-
|
|
12853
|
-
|
|
12854
|
-
|
|
12855
|
-
|
|
12856
|
-
|
|
12857
|
-
|
|
12858
|
-
|
|
12859
|
-
|
|
12860
|
-
|
|
12798
|
+
const verifier = randomBase64Url();
|
|
12799
|
+
const pairing = await startDevicePairing(gateway, pkceChallenge(verifier), fetchImpl);
|
|
12800
|
+
onNotice(
|
|
12801
|
+
`Sign in to Actionway on any device:
|
|
12802
|
+
${pairing.verificationUrl}
|
|
12803
|
+
One-time code: ${pairing.userCode}`
|
|
12804
|
+
);
|
|
12805
|
+
if (options.noBrowser) onNotice(`Open this URL to approve the sign-in:
|
|
12806
|
+
${pairing.verificationUrlComplete}`);
|
|
12807
|
+
else openBrowser(pairing.verificationUrlComplete, onNotice);
|
|
12808
|
+
const deadline = Date.now() + Math.min(timeoutMs, pairing.expiresInS * 1e3);
|
|
12809
|
+
let approvalCode = null;
|
|
12810
|
+
for (; ; ) {
|
|
12811
|
+
const poll = await pollDevicePairing(gateway, pairing.deviceCode, fetchImpl);
|
|
12812
|
+
if (poll.status === "approved") {
|
|
12813
|
+
approvalCode = poll.code;
|
|
12814
|
+
break;
|
|
12815
|
+
}
|
|
12816
|
+
if (poll.status === "denied") {
|
|
12817
|
+
throw new CliError(
|
|
12818
|
+
"E_BACKEND",
|
|
12819
|
+
"the sign-in request was denied in the browser",
|
|
12820
|
+
"run `actionway login` again and approve the request on the activation page"
|
|
12821
|
+
);
|
|
12822
|
+
}
|
|
12823
|
+
if (poll.status === "expired") {
|
|
12824
|
+
throw new CliError(
|
|
12825
|
+
"E_BACKEND",
|
|
12826
|
+
"the sign-in code expired before it was approved",
|
|
12827
|
+
"run `actionway login` again and enter the fresh code promptly"
|
|
12828
|
+
);
|
|
12829
|
+
}
|
|
12830
|
+
if (Date.now() >= deadline) {
|
|
12831
|
+
throw new CliError(
|
|
12832
|
+
"E_BACKEND",
|
|
12833
|
+
`login timed out after ${Math.round(timeoutMs / 1e3)} seconds`,
|
|
12834
|
+
"run `actionway login` again and ask the user to approve the sign-in promptly; pass --timeout-seconds <n> to allow more time"
|
|
12835
|
+
);
|
|
12836
|
+
}
|
|
12837
|
+
await sleep(pairing.intervalS * 1e3);
|
|
12838
|
+
}
|
|
12861
12839
|
const tokens = await tokenRequest(
|
|
12862
12840
|
issuer,
|
|
12863
12841
|
new URLSearchParams({
|
|
12864
12842
|
grant_type: "authorization_code",
|
|
12865
12843
|
client_id: clientId,
|
|
12866
|
-
code:
|
|
12844
|
+
code: approvalCode,
|
|
12867
12845
|
code_verifier: verifier,
|
|
12868
|
-
redirect_uri:
|
|
12846
|
+
redirect_uri: pairing.redirectUri
|
|
12869
12847
|
}),
|
|
12870
12848
|
fetchImpl
|
|
12871
12849
|
);
|
|
12872
|
-
const account = await fetchCliSession(gateway, tokens.accessToken, fetchImpl
|
|
12850
|
+
const account = await fetchCliSession(gateway, tokens.accessToken, fetchImpl, {
|
|
12851
|
+
...options.installAttribution ? { installAttribution: options.installAttribution } : {},
|
|
12852
|
+
...options.clientContext ? { clientContext: options.clientContext } : {}
|
|
12853
|
+
});
|
|
12873
12854
|
if (!account) {
|
|
12874
12855
|
throw new CliError("E_BACKEND", "Actionway did not accept the OAuth token", "run `actionway login` again");
|
|
12875
12856
|
}
|
|
@@ -12894,8 +12875,6 @@ ${authorizeUrl}`);
|
|
|
12894
12875
|
return { credentials, account };
|
|
12895
12876
|
} catch (error) {
|
|
12896
12877
|
return withAuthContext(error);
|
|
12897
|
-
} finally {
|
|
12898
|
-
await callback.close();
|
|
12899
12878
|
}
|
|
12900
12879
|
}
|
|
12901
12880
|
function whoamiSnapshot(env = process.env) {
|
|
@@ -12945,8 +12924,8 @@ function failFromError2(err, fallbackHint) {
|
|
|
12945
12924
|
...fallbackHint ? { hint: fallbackHint } : {}
|
|
12946
12925
|
});
|
|
12947
12926
|
}
|
|
12948
|
-
function registerAuthCommands(program2) {
|
|
12949
|
-
program2.command("login").description("Authenticate with Actionway in
|
|
12927
|
+
function registerAuthCommands(program2, getClientContext = () => ({ runtimeOs: "other" })) {
|
|
12928
|
+
program2.command("login").description("Authenticate with Actionway by approving a one-time code in any browser (Clerk OAuth with PKCE).").option("--gateway <url>", "Actionway public origin").option("--client-id <id>", "Actionway OAuth client id (must be paired with --issuer; default: both discovered from the public origin)").option("--issuer <url>", "Actionway OAuth issuer (must be paired with --client-id; default: both discovered from the public origin)").option("--timeout-seconds <n>", "how long to wait for the sign-in to be approved").option("--no-browser", "print the verification URL instead of opening a browser (use on remote/headless machines)").action(async (opts) => {
|
|
12950
12929
|
try {
|
|
12951
12930
|
const { credentials, account } = await login({
|
|
12952
12931
|
...opts.gateway ? { gateway: opts.gateway } : {},
|
|
@@ -12954,6 +12933,7 @@ function registerAuthCommands(program2) {
|
|
|
12954
12933
|
...opts.issuer ? { issuer: opts.issuer } : {},
|
|
12955
12934
|
...opts.timeoutSeconds ? { timeoutSeconds: Number(opts.timeoutSeconds) } : {},
|
|
12956
12935
|
...opts.browser === false ? { noBrowser: true } : {},
|
|
12936
|
+
clientContext: getClientContext(),
|
|
12957
12937
|
// 授权 URL / 浏览器提示走 stderr NDJSON 事件(stdout 保持结果协议)。
|
|
12958
12938
|
onNotice: (message) => emitEvent({ event: "auth", message })
|
|
12959
12939
|
});
|
|
@@ -13035,7 +13015,6 @@ function registerAccountCommands(program2, getTransport2) {
|
|
|
13035
13015
|
// src/commands/doctor.ts
|
|
13036
13016
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
13037
13017
|
import { existsSync as existsSync2, rmSync as rmSync2, statSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
13038
|
-
import { createServer as createServer2 } from "node:http";
|
|
13039
13018
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
13040
13019
|
import { dirname as dirname3, join as join3, posix, win32 } from "node:path";
|
|
13041
13020
|
function pass(id, message) {
|
|
@@ -13087,13 +13066,6 @@ function defaultWritable(path) {
|
|
|
13087
13066
|
return false;
|
|
13088
13067
|
}
|
|
13089
13068
|
}
|
|
13090
|
-
function checkLoopback() {
|
|
13091
|
-
return new Promise((resolve3, reject) => {
|
|
13092
|
-
const server = createServer2();
|
|
13093
|
-
server.once("error", reject);
|
|
13094
|
-
server.listen(0, "127.0.0.1", () => server.close((error) => error ? reject(error) : resolve3()));
|
|
13095
|
-
});
|
|
13096
|
-
}
|
|
13097
13069
|
function defaultResolveCommand(name) {
|
|
13098
13070
|
const result = process.platform === "win32" ? spawnSync2("where.exe", [name], { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"], timeout: 5e3, windowsHide: true }) : spawnSync2("/bin/sh", ["-c", `command -v -- ${name}`], { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"], timeout: 5e3 });
|
|
13099
13071
|
if (result.error || result.status !== 0) return null;
|
|
@@ -13122,7 +13094,6 @@ async function diagnoseActionway(options = {}, dependencies = {}) {
|
|
|
13122
13094
|
const pathExists = dependencies.pathExists ?? existsSync2;
|
|
13123
13095
|
const pathWritable = dependencies.pathWritable ?? defaultWritable;
|
|
13124
13096
|
const fetchOAuth = dependencies.fetchOAuth ?? fetchCliOAuthConfig;
|
|
13125
|
-
const loopback = dependencies.checkLoopback ?? checkLoopback;
|
|
13126
13097
|
const readPolicy = dependencies.readPowerShellPolicy ?? powerShellPolicy;
|
|
13127
13098
|
const resolveCommand = dependencies.resolveCommand ?? defaultResolveCommand;
|
|
13128
13099
|
const checks = [];
|
|
@@ -13132,17 +13103,7 @@ async function diagnoseActionway(options = {}, dependencies = {}) {
|
|
|
13132
13103
|
checks.push(
|
|
13133
13104
|
Number.isFinite(nodeMajor) && nodeMajor >= 20 ? pass("node", `Node.js ${nodeVersion} is supported.`) : fail2("node", `Node.js ${nodeVersion || "unknown"} is unsupported.`, "install Node.js 20 or newer and reopen the terminal")
|
|
13134
13105
|
);
|
|
13135
|
-
|
|
13136
|
-
checks.push(
|
|
13137
|
-
warn(
|
|
13138
|
-
"execution_environment",
|
|
13139
|
-
"WSL detected; browser loopback may not share the Windows host network namespace.",
|
|
13140
|
-
"run Actionway login from the Windows host if the browser callback cannot return"
|
|
13141
|
-
)
|
|
13142
|
-
);
|
|
13143
|
-
} else {
|
|
13144
|
-
checks.push(pass("execution_environment", `${platform}/${architecture} host environment detected.`));
|
|
13145
|
-
}
|
|
13106
|
+
checks.push(pass("execution_environment", `${platform}/${architecture} host environment detected.`));
|
|
13146
13107
|
checks.push(
|
|
13147
13108
|
pathWritable(configDir) ? pass("config_dir", `Configuration directory is writable: ${configDir}`) : fail2("config_dir", `Configuration directory is not writable: ${configDir}`, "set ACTIONWAY_CONFIG_DIR to a user-writable directory")
|
|
13148
13109
|
);
|
|
@@ -13204,18 +13165,6 @@ async function diagnoseActionway(options = {}, dependencies = {}) {
|
|
|
13204
13165
|
)
|
|
13205
13166
|
);
|
|
13206
13167
|
}
|
|
13207
|
-
try {
|
|
13208
|
-
await loopback();
|
|
13209
|
-
checks.push(pass("loopback", "A random 127.0.0.1 callback port can be opened."));
|
|
13210
|
-
} catch (error) {
|
|
13211
|
-
checks.push(
|
|
13212
|
-
fail2(
|
|
13213
|
-
"loopback",
|
|
13214
|
-
`Cannot open the local OAuth callback: ${error instanceof Error ? error.message : String(error)}`,
|
|
13215
|
-
"run login from a normal host terminal and check firewall or sandbox policy"
|
|
13216
|
-
)
|
|
13217
|
-
);
|
|
13218
|
-
}
|
|
13219
13168
|
if (options.network === false) {
|
|
13220
13169
|
checks.push({ id: "npm_registry", status: "skip", message: "npm registry check was skipped." });
|
|
13221
13170
|
checks.push({ id: "actionway_oauth", status: "skip", message: "Actionway OAuth discovery check was skipped." });
|
|
@@ -13259,7 +13208,7 @@ async function diagnoseActionway(options = {}, dependencies = {}) {
|
|
|
13259
13208
|
}
|
|
13260
13209
|
function registerDoctorCommand(program2) {
|
|
13261
13210
|
const distribution = cliDistribution();
|
|
13262
|
-
program2.command("doctor").description("Diagnose Node, npm, PATH, registry, configuration, and
|
|
13211
|
+
program2.command("doctor").description("Diagnose Node, npm, PATH, registry, configuration, and Actionway OAuth discovery readiness.").option("--no-network", "skip npm registry and Actionway OAuth discovery checks").action(async (options) => {
|
|
13263
13212
|
const report = await diagnoseActionway({ network: options.network !== false });
|
|
13264
13213
|
const command = process.platform === "win32" ? `${distribution.commandName}.cmd` : distribution.commandName;
|
|
13265
13214
|
ok({
|
|
@@ -13360,35 +13309,6 @@ function materializeSkill(options = {}) {
|
|
|
13360
13309
|
};
|
|
13361
13310
|
}
|
|
13362
13311
|
|
|
13363
|
-
// src/lib/client-context.ts
|
|
13364
|
-
var ACTIONWAY_AGENT_HOST_HEADER = "x-actionway-agent-host";
|
|
13365
|
-
var ACTIONWAY_RUNTIME_OS_HEADER = "x-actionway-runtime-os";
|
|
13366
|
-
var ACTIONWAY_AGENT_HOSTS = ["codex", "claude_code", "workbuddy"];
|
|
13367
|
-
function isActionwayAgentHost(value) {
|
|
13368
|
-
return typeof value === "string" && ACTIONWAY_AGENT_HOSTS.includes(value);
|
|
13369
|
-
}
|
|
13370
|
-
function detectRuntimeOs(platform = process.platform, env = process.env) {
|
|
13371
|
-
if (platform === "win32") return "windows";
|
|
13372
|
-
if (platform === "darwin") return "macos";
|
|
13373
|
-
if (platform === "linux") {
|
|
13374
|
-
if ((env.WSL_DISTRO_NAME ?? "").trim() || (env.WSL_INTEROP ?? "").trim()) return "wsl";
|
|
13375
|
-
return "linux";
|
|
13376
|
-
}
|
|
13377
|
-
return "other";
|
|
13378
|
-
}
|
|
13379
|
-
function localClientContext(agentHost, platform = process.platform, env = process.env) {
|
|
13380
|
-
return {
|
|
13381
|
-
...isActionwayAgentHost(agentHost) ? { agentHost } : {},
|
|
13382
|
-
runtimeOs: detectRuntimeOs(platform, env)
|
|
13383
|
-
};
|
|
13384
|
-
}
|
|
13385
|
-
function localClientContextHeaders(context) {
|
|
13386
|
-
return {
|
|
13387
|
-
...context.agentHost ? { [ACTIONWAY_AGENT_HOST_HEADER]: context.agentHost } : {},
|
|
13388
|
-
[ACTIONWAY_RUNTIME_OS_HEADER]: context.runtimeOs
|
|
13389
|
-
};
|
|
13390
|
-
}
|
|
13391
|
-
|
|
13392
13312
|
// src/lib/install-session.ts
|
|
13393
13313
|
var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
13394
13314
|
var ANALYTICS_TIMEOUT_MS = 3e3;
|
|
@@ -13521,7 +13441,7 @@ function registerInitCommand(program2, getClientContext = () => ({ runtimeOs: "o
|
|
|
13521
13441
|
const distribution = cliDistribution();
|
|
13522
13442
|
program2.command("init").description(
|
|
13523
13443
|
"Complete browser authentication and stage the Actionway Skill for your agent to install. The CLI never writes into an agent's own configuration directory."
|
|
13524
|
-
).option("--gateway <url>", "Actionway public origin").option("--client-id <id>", "Actionway OAuth client id (must be paired with --issuer)").option("--issuer <url>", "Actionway OAuth issuer (must be paired with --client-id)").option("--timeout-seconds <n>", "how long to wait for
|
|
13444
|
+
).option("--gateway <url>", "Actionway public origin").option("--client-id <id>", "Actionway OAuth client id (must be paired with --issuer)").option("--issuer <url>", "Actionway OAuth issuer (must be paired with --client-id)").option("--timeout-seconds <n>", "how long to wait for the sign-in to be approved").option("--install-session-id <uuid>", "onboarding install session id").option("--no-browser", "print the verification URL instead of opening a browser (use on remote/headless machines)").addOption(new Option("--skill-only").hideHelp()).action(async (opts) => {
|
|
13525
13445
|
try {
|
|
13526
13446
|
const clientContext = getClientContext();
|
|
13527
13447
|
const invocation = clientContext.agentHost ? `${distribution.commandName} --agent-host=${clientContext.agentHost}` : distribution.commandName;
|
|
@@ -13539,23 +13459,32 @@ function registerInitCommand(program2, getClientContext = () => ({ runtimeOs: "o
|
|
|
13539
13459
|
clientContext
|
|
13540
13460
|
});
|
|
13541
13461
|
let loginStarted = false;
|
|
13462
|
+
let account;
|
|
13542
13463
|
if (!whoamiSnapshot()) {
|
|
13543
13464
|
loginStarted = true;
|
|
13544
|
-
await login({
|
|
13465
|
+
const loginResult = await login({
|
|
13545
13466
|
...opts.gateway ? { gateway: opts.gateway } : {},
|
|
13546
13467
|
...opts.clientId ? { clientId: opts.clientId } : {},
|
|
13547
13468
|
...opts.issuer ? { issuer: opts.issuer } : {},
|
|
13548
13469
|
...opts.timeoutSeconds ? { timeoutSeconds: Number(opts.timeoutSeconds) } : {},
|
|
13549
13470
|
...opts.browser === false ? { noBrowser: true } : {},
|
|
13471
|
+
installAttribution: { installSessionId, installSource },
|
|
13472
|
+
clientContext,
|
|
13550
13473
|
onNotice: (message) => emitEvent({ event: "auth", message })
|
|
13551
13474
|
});
|
|
13475
|
+
account = {
|
|
13476
|
+
userId: loginResult.account.userId,
|
|
13477
|
+
workspaceId: loginResult.account.workspaceId,
|
|
13478
|
+
walletId: loginResult.account.walletId
|
|
13479
|
+
};
|
|
13480
|
+
} else {
|
|
13481
|
+
account = await connectInstallSession({
|
|
13482
|
+
...opts.gateway ? { explicitGateway: opts.gateway } : {},
|
|
13483
|
+
installSessionId,
|
|
13484
|
+
installSource,
|
|
13485
|
+
clientContext
|
|
13486
|
+
});
|
|
13552
13487
|
}
|
|
13553
|
-
const account = await connectInstallSession({
|
|
13554
|
-
...opts.gateway ? { explicitGateway: opts.gateway } : {},
|
|
13555
|
-
installSessionId,
|
|
13556
|
-
installSource,
|
|
13557
|
-
clientContext
|
|
13558
|
-
});
|
|
13559
13488
|
const snapshot = whoamiSnapshot();
|
|
13560
13489
|
ok({
|
|
13561
13490
|
initialized: true,
|
|
@@ -13891,7 +13820,7 @@ function buildProgram() {
|
|
|
13891
13820
|
registerDoctorCommand(program2);
|
|
13892
13821
|
registerUpdateCommand(program2);
|
|
13893
13822
|
registerDevelopmentStatusCommand(program2);
|
|
13894
|
-
registerAuthCommands(program2);
|
|
13823
|
+
registerAuthCommands(program2, getClientContext);
|
|
13895
13824
|
registerAccountCommands(program2, getTransport2);
|
|
13896
13825
|
registerToolsCommands(program2, getTransport2);
|
|
13897
13826
|
registerActionCommand(program2, generate_video_default, actionDeps);
|
package/package.json
CHANGED