vana-cli 0.15.0
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/LICENSE +21 -0
- package/README.md +320 -0
- package/dist/cli/auth.d.ts +119 -0
- package/dist/cli/auth.d.ts.map +1 -0
- package/dist/cli/auth.js +528 -0
- package/dist/cli/auth.js.map +1 -0
- package/dist/cli/bin.d.ts +3 -0
- package/dist/cli/bin.d.ts.map +1 -0
- package/dist/cli/bin.js +15 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/index.d.ts +92 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +4703 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/main.d.ts +2 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +10 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/mcp-server.d.ts +15 -0
- package/dist/cli/mcp-server.d.ts.map +1 -0
- package/dist/cli/mcp-server.js +199 -0
- package/dist/cli/mcp-server.js.map +1 -0
- package/dist/cli/queries.d.ts +128 -0
- package/dist/cli/queries.d.ts.map +1 -0
- package/dist/cli/queries.js +422 -0
- package/dist/cli/queries.js.map +1 -0
- package/dist/cli/render/capabilities.d.ts +9 -0
- package/dist/cli/render/capabilities.d.ts.map +1 -0
- package/dist/cli/render/capabilities.js +24 -0
- package/dist/cli/render/capabilities.js.map +1 -0
- package/dist/cli/render/connect-renderer.d.ts +23 -0
- package/dist/cli/render/connect-renderer.d.ts.map +1 -0
- package/dist/cli/render/connect-renderer.js +259 -0
- package/dist/cli/render/connect-renderer.js.map +1 -0
- package/dist/cli/render/flow-theme.d.ts +17 -0
- package/dist/cli/render/flow-theme.d.ts.map +1 -0
- package/dist/cli/render/flow-theme.js +26 -0
- package/dist/cli/render/flow-theme.js.map +1 -0
- package/dist/cli/render/format.d.ts +27 -0
- package/dist/cli/render/format.d.ts.map +1 -0
- package/dist/cli/render/format.js +111 -0
- package/dist/cli/render/format.js.map +1 -0
- package/dist/cli/render/index.d.ts +8 -0
- package/dist/cli/render/index.d.ts.map +1 -0
- package/dist/cli/render/index.js +8 -0
- package/dist/cli/render/index.js.map +1 -0
- package/dist/cli/render/progress.d.ts +11 -0
- package/dist/cli/render/progress.d.ts.map +1 -0
- package/dist/cli/render/progress.js +56 -0
- package/dist/cli/render/progress.js.map +1 -0
- package/dist/cli/render/symbols.d.ts +11 -0
- package/dist/cli/render/symbols.d.ts.map +1 -0
- package/dist/cli/render/symbols.js +21 -0
- package/dist/cli/render/symbols.js.map +1 -0
- package/dist/cli/render/theme.d.ts +16 -0
- package/dist/cli/render/theme.d.ts.map +1 -0
- package/dist/cli/render/theme.js +57 -0
- package/dist/cli/render/theme.js.map +1 -0
- package/dist/cli/search-select.d.ts +17 -0
- package/dist/cli/search-select.d.ts.map +1 -0
- package/dist/cli/search-select.js +29 -0
- package/dist/cli/search-select.js.map +1 -0
- package/dist/cli/telemetry-contract.d.ts +146 -0
- package/dist/cli/telemetry-contract.d.ts.map +1 -0
- package/dist/cli/telemetry-contract.js +56 -0
- package/dist/cli/telemetry-contract.js.map +1 -0
- package/dist/cli/telemetry.d.ts +60 -0
- package/dist/cli/telemetry.d.ts.map +1 -0
- package/dist/cli/telemetry.js +621 -0
- package/dist/cli/telemetry.js.map +1 -0
- package/dist/cli/update-check.d.ts +21 -0
- package/dist/cli/update-check.d.ts.map +1 -0
- package/dist/cli/update-check.js +86 -0
- package/dist/cli/update-check.js.map +1 -0
- package/dist/connectors/index.d.ts +2 -0
- package/dist/connectors/index.d.ts.map +1 -0
- package/dist/connectors/index.js +2 -0
- package/dist/connectors/index.js.map +1 -0
- package/dist/connectors/registry.d.ts +55 -0
- package/dist/connectors/registry.d.ts.map +1 -0
- package/dist/connectors/registry.js +301 -0
- package/dist/connectors/registry.js.map +1 -0
- package/dist/core/cli-types.d.ts +722 -0
- package/dist/core/cli-types.d.ts.map +1 -0
- package/dist/core/cli-types.js +328 -0
- package/dist/core/cli-types.js.map +1 -0
- package/dist/core/constants.d.ts +33 -0
- package/dist/core/constants.d.ts.map +1 -0
- package/dist/core/constants.js +25 -0
- package/dist/core/constants.js.map +1 -0
- package/dist/core/errors.d.ts +47 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +50 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/grants.d.ts +19 -0
- package/dist/core/grants.d.ts.map +1 -0
- package/dist/core/grants.js +31 -0
- package/dist/core/grants.js.map +1 -0
- package/dist/core/index.d.ts +9 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +7 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/paths.d.ts +30 -0
- package/dist/core/paths.d.ts.map +1 -0
- package/dist/core/paths.js +95 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/state-store.d.ts +44 -0
- package/dist/core/state-store.d.ts.map +1 -0
- package/dist/core/state-store.js +101 -0
- package/dist/core/state-store.js.map +1 -0
- package/dist/core/types.d.ts +148 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/personal-server/client.d.ts +34 -0
- package/dist/personal-server/client.d.ts.map +1 -0
- package/dist/personal-server/client.js +108 -0
- package/dist/personal-server/client.js.map +1 -0
- package/dist/personal-server/index.d.ts +28 -0
- package/dist/personal-server/index.d.ts.map +1 -0
- package/dist/personal-server/index.js +157 -0
- package/dist/personal-server/index.js.map +1 -0
- package/dist/personal-server/scope-resolver.d.ts +22 -0
- package/dist/personal-server/scope-resolver.d.ts.map +1 -0
- package/dist/personal-server/scope-resolver.js +80 -0
- package/dist/personal-server/scope-resolver.js.map +1 -0
- package/dist/react/ConnectButton.d.ts +27 -0
- package/dist/react/ConnectButton.d.ts.map +1 -0
- package/dist/react/ConnectButton.js +39 -0
- package/dist/react/ConnectButton.js.map +1 -0
- package/dist/react/index.d.ts +4 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +4 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/useVanaConnect.d.ts +50 -0
- package/dist/react/useVanaConnect.d.ts.map +1 -0
- package/dist/react/useVanaConnect.js +114 -0
- package/dist/react/useVanaConnect.js.map +1 -0
- package/dist/react/useVanaData.d.ts +69 -0
- package/dist/react/useVanaData.d.ts.map +1 -0
- package/dist/react/useVanaData.js +144 -0
- package/dist/react/useVanaData.js.map +1 -0
- package/dist/runtime/core/contracts.d.ts +84 -0
- package/dist/runtime/core/contracts.d.ts.map +1 -0
- package/dist/runtime/core/contracts.js +2 -0
- package/dist/runtime/core/contracts.js.map +1 -0
- package/dist/runtime/core/index.d.ts +2 -0
- package/dist/runtime/core/index.d.ts.map +1 -0
- package/dist/runtime/core/index.js +2 -0
- package/dist/runtime/core/index.js.map +1 -0
- package/dist/runtime/index.d.ts +4 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +3 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/managed-playwright.d.ts +42 -0
- package/dist/runtime/managed-playwright.d.ts.map +1 -0
- package/dist/runtime/managed-playwright.js +178 -0
- package/dist/runtime/managed-playwright.js.map +1 -0
- package/dist/runtime/playwright/browser.d.ts +12 -0
- package/dist/runtime/playwright/browser.d.ts.map +1 -0
- package/dist/runtime/playwright/browser.js +229 -0
- package/dist/runtime/playwright/browser.js.map +1 -0
- package/dist/runtime/playwright/in-process-run.d.ts +6 -0
- package/dist/runtime/playwright/in-process-run.d.ts.map +1 -0
- package/dist/runtime/playwright/in-process-run.js +625 -0
- package/dist/runtime/playwright/in-process-run.js.map +1 -0
- package/dist/runtime/playwright/index.d.ts +3 -0
- package/dist/runtime/playwright/index.d.ts.map +1 -0
- package/dist/runtime/playwright/index.js +3 -0
- package/dist/runtime/playwright/index.js.map +1 -0
- package/dist/runtime/repo-paths.d.ts +2 -0
- package/dist/runtime/repo-paths.d.ts.map +1 -0
- package/dist/runtime/repo-paths.js +36 -0
- package/dist/runtime/repo-paths.js.map +1 -0
- package/dist/server/config.d.ts +38 -0
- package/dist/server/config.d.ts.map +1 -0
- package/dist/server/config.js +45 -0
- package/dist/server/config.js.map +1 -0
- package/dist/server/connect.d.ts +43 -0
- package/dist/server/connect.d.ts.map +1 -0
- package/dist/server/connect.js +115 -0
- package/dist/server/connect.js.map +1 -0
- package/dist/server/data-client.d.ts +31 -0
- package/dist/server/data-client.d.ts.map +1 -0
- package/dist/server/data-client.js +95 -0
- package/dist/server/data-client.js.map +1 -0
- package/dist/server/index.d.ts +8 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +8 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/manifest-signer.d.ts +25 -0
- package/dist/server/manifest-signer.d.ts.map +1 -0
- package/dist/server/manifest-signer.js +51 -0
- package/dist/server/manifest-signer.js.map +1 -0
- package/dist/server/request-signer.d.ts +31 -0
- package/dist/server/request-signer.d.ts.map +1 -0
- package/dist/server/request-signer.js +72 -0
- package/dist/server/request-signer.js.map +1 -0
- package/dist/server/session-relay.d.ts +39 -0
- package/dist/server/session-relay.d.ts.map +1 -0
- package/dist/server/session-relay.js +74 -0
- package/dist/server/session-relay.js.map +1 -0
- package/dist/server/webhook.d.ts +11 -0
- package/dist/server/webhook.d.ts.map +1 -0
- package/dist/server/webhook.js +18 -0
- package/dist/server/webhook.js.map +1 -0
- package/dist/skills/index.d.ts +4 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +3 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/paths.d.ts +33 -0
- package/dist/skills/paths.d.ts.map +1 -0
- package/dist/skills/paths.js +81 -0
- package/dist/skills/paths.js.map +1 -0
- package/dist/skills/registry.d.ts +48 -0
- package/dist/skills/registry.d.ts.map +1 -0
- package/dist/skills/registry.js +173 -0
- package/dist/skills/registry.js.map +1 -0
- package/package.json +147 -0
package/dist/cli/auth.js
ADDED
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credential management for Vana CLI authentication.
|
|
3
|
+
*
|
|
4
|
+
* Stores and retrieves auth credentials from ~/.vana/auth.json.
|
|
5
|
+
* Supports the device code flow for browser-based login and
|
|
6
|
+
* env var overrides for CI/automation.
|
|
7
|
+
*/
|
|
8
|
+
import { spawnSync } from "node:child_process";
|
|
9
|
+
import fs from "node:fs";
|
|
10
|
+
import fsp from "node:fs/promises";
|
|
11
|
+
import path from "node:path";
|
|
12
|
+
import os from "node:os";
|
|
13
|
+
const AUTH_FILE = "auth.json";
|
|
14
|
+
function getAuthFilePath() {
|
|
15
|
+
return path.join(os.homedir(), ".vana", AUTH_FILE);
|
|
16
|
+
}
|
|
17
|
+
function normalizeCredentials(creds) {
|
|
18
|
+
if (!creds.account || typeof creds.account.session_token !== "string") {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
const personalServer = creds.personal_server;
|
|
22
|
+
return {
|
|
23
|
+
account: creds.account,
|
|
24
|
+
personal_server: personalServer
|
|
25
|
+
? {
|
|
26
|
+
url: personalServer.url,
|
|
27
|
+
session_token: personalServer.session_token ?? personalServer.access_token ?? "",
|
|
28
|
+
expires_at: personalServer.expires_at,
|
|
29
|
+
}
|
|
30
|
+
: null,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Load credentials from disk or env vars.
|
|
35
|
+
*
|
|
36
|
+
* Priority:
|
|
37
|
+
* 1. Env vars (VANA_SESSION_TOKEN, VANA_PS_TOKEN, VANA_PS_URL)
|
|
38
|
+
* 2. File (~/.vana/auth.json)
|
|
39
|
+
*
|
|
40
|
+
* Returns null if no credentials are available or if they are expired.
|
|
41
|
+
*/
|
|
42
|
+
export function loadCredentials() {
|
|
43
|
+
// Check env var overrides first
|
|
44
|
+
const envSessionToken = process.env.VANA_SESSION_TOKEN;
|
|
45
|
+
const envPsToken = process.env.VANA_PS_TOKEN;
|
|
46
|
+
const envPsUrl = process.env.VANA_PS_URL ?? process.env.VANA_PERSONAL_SERVER_URL;
|
|
47
|
+
if (envSessionToken) {
|
|
48
|
+
// Build credentials from env vars — no expiry tracking for env-based tokens
|
|
49
|
+
const farFuture = new Date(Date.now() + 365 * 24 * 60 * 60 * 1000).toISOString();
|
|
50
|
+
return {
|
|
51
|
+
account: {
|
|
52
|
+
address: "env",
|
|
53
|
+
session_token: envSessionToken,
|
|
54
|
+
expires_at: farFuture,
|
|
55
|
+
},
|
|
56
|
+
personal_server: envPsToken && envPsUrl
|
|
57
|
+
? {
|
|
58
|
+
url: envPsUrl,
|
|
59
|
+
session_token: envPsToken,
|
|
60
|
+
expires_at: farFuture,
|
|
61
|
+
}
|
|
62
|
+
: null,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
// Read from file
|
|
66
|
+
const filePath = getAuthFilePath();
|
|
67
|
+
try {
|
|
68
|
+
const raw = fs.readFileSync(filePath, "utf8");
|
|
69
|
+
const creds = normalizeCredentials(JSON.parse(raw));
|
|
70
|
+
if (!creds) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
if (isExpired(creds)) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
return creds;
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Save credentials to ~/.vana/auth.json with 0600 permissions.
|
|
84
|
+
*/
|
|
85
|
+
export async function saveCredentials(creds) {
|
|
86
|
+
const filePath = getAuthFilePath();
|
|
87
|
+
const dir = path.dirname(filePath);
|
|
88
|
+
await fsp.mkdir(dir, { recursive: true });
|
|
89
|
+
await fsp.writeFile(filePath, JSON.stringify(creds, null, 2) + "\n", {
|
|
90
|
+
mode: 0o600,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Delete ~/.vana/auth.json.
|
|
95
|
+
*/
|
|
96
|
+
export async function clearCredentials() {
|
|
97
|
+
const filePath = getAuthFilePath();
|
|
98
|
+
try {
|
|
99
|
+
await fsp.unlink(filePath);
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
// Ignore if file doesn't exist
|
|
103
|
+
if (err.code !== "ENOENT") {
|
|
104
|
+
throw err;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Check if the account session token has expired.
|
|
110
|
+
*/
|
|
111
|
+
export function isExpired(creds) {
|
|
112
|
+
try {
|
|
113
|
+
const expiresAt = new Date(creds.account.expires_at);
|
|
114
|
+
return expiresAt.getTime() <= Date.now();
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Format an address for display: 0x2Ab3...fa1
|
|
122
|
+
*/
|
|
123
|
+
export function formatAddress(address) {
|
|
124
|
+
if (address.length <= 10)
|
|
125
|
+
return address;
|
|
126
|
+
return `${address.slice(0, 6)}...${address.slice(-3)}`;
|
|
127
|
+
}
|
|
128
|
+
function isWalletAddress(address) {
|
|
129
|
+
return /^0x[a-fA-F0-9]{40}$/.test(address);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Return human-readable time until expiry: "29 days", "3 hours", etc.
|
|
133
|
+
*/
|
|
134
|
+
export function formatExpiresIn(expiresAt) {
|
|
135
|
+
const ms = new Date(expiresAt).getTime() - Date.now();
|
|
136
|
+
if (ms <= 0)
|
|
137
|
+
return "expired";
|
|
138
|
+
const days = Math.floor(ms / (24 * 60 * 60 * 1000));
|
|
139
|
+
if (days > 0)
|
|
140
|
+
return `${days} day${days === 1 ? "" : "s"}`;
|
|
141
|
+
const hours = Math.floor(ms / (60 * 60 * 1000));
|
|
142
|
+
if (hours > 0)
|
|
143
|
+
return `${hours} hour${hours === 1 ? "" : "s"}`;
|
|
144
|
+
const minutes = Math.floor(ms / (60 * 1000));
|
|
145
|
+
return `${minutes} minute${minutes === 1 ? "" : "s"}`;
|
|
146
|
+
}
|
|
147
|
+
const OAUTH_DEVICE_CODE_GRANT = "urn:ietf:params:oauth:grant-type:device_code";
|
|
148
|
+
const DEFAULT_OAUTH_SCOPE = "openid profile offline_access";
|
|
149
|
+
function resolveCredentialExpiry(params) {
|
|
150
|
+
if (params.expiresAt) {
|
|
151
|
+
const parsed = new Date(params.expiresAt);
|
|
152
|
+
if (!Number.isNaN(parsed.getTime())) {
|
|
153
|
+
return parsed.toISOString();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
const expiresIn = params.expiresIn ?? 30 * 24 * 60 * 60;
|
|
157
|
+
return new Date(Date.now() + expiresIn * 1000).toISOString();
|
|
158
|
+
}
|
|
159
|
+
function getAccountUrl() {
|
|
160
|
+
return (process.env.VANA_ACCOUNT_URL?.replace(/\/+$/, "") ??
|
|
161
|
+
"https://account.vana.org");
|
|
162
|
+
}
|
|
163
|
+
export function resolveOAuthClientId(accountUrl = getAccountUrl()) {
|
|
164
|
+
const configured = process.env.VANA_OAUTH_CLIENT_ID ?? process.env.VANA_ACCOUNT_CLIENT_ID;
|
|
165
|
+
if (configured?.trim()) {
|
|
166
|
+
return configured.trim();
|
|
167
|
+
}
|
|
168
|
+
try {
|
|
169
|
+
const hostname = new URL(accountUrl).hostname;
|
|
170
|
+
if (hostname === "localhost" ||
|
|
171
|
+
hostname === "127.0.0.1" ||
|
|
172
|
+
hostname.includes("account-dev")) {
|
|
173
|
+
return "vana-cli-dev";
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
// Fall through to the production client id.
|
|
178
|
+
}
|
|
179
|
+
return "vana-cli";
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Request a device code from the auth server.
|
|
183
|
+
*/
|
|
184
|
+
export async function requestDeviceCode() {
|
|
185
|
+
const url = `${getAccountUrl()}/api/auth/device`;
|
|
186
|
+
const response = await fetch(url, {
|
|
187
|
+
method: "POST",
|
|
188
|
+
headers: { "Content-Type": "application/json" },
|
|
189
|
+
});
|
|
190
|
+
if (!response.ok) {
|
|
191
|
+
const text = await response.text().catch(() => "");
|
|
192
|
+
throw new Error(`Failed to start device code flow: HTTP ${response.status}${text ? ` — ${text}` : ""}`);
|
|
193
|
+
}
|
|
194
|
+
return (await response.json());
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Poll for device code authorization.
|
|
198
|
+
*/
|
|
199
|
+
export async function pollDeviceCode(deviceCode) {
|
|
200
|
+
const url = `${getAccountUrl()}/api/auth/device/poll?device_code=${encodeURIComponent(deviceCode)}`;
|
|
201
|
+
const response = await fetch(url, {
|
|
202
|
+
method: "GET",
|
|
203
|
+
signal: AbortSignal.timeout(10_000),
|
|
204
|
+
});
|
|
205
|
+
if (!response.ok) {
|
|
206
|
+
const text = await response.text().catch(() => "");
|
|
207
|
+
throw new Error(`Poll failed: HTTP ${response.status}${text ? ` — ${text}` : ""}`);
|
|
208
|
+
}
|
|
209
|
+
return (await response.json());
|
|
210
|
+
}
|
|
211
|
+
async function discoverOAuthDeviceEndpoints(accountUrl) {
|
|
212
|
+
try {
|
|
213
|
+
const response = await fetch(`${accountUrl}/.well-known/openid-configuration`, {
|
|
214
|
+
method: "GET",
|
|
215
|
+
headers: { accept: "application/json" },
|
|
216
|
+
signal: AbortSignal.timeout(10_000),
|
|
217
|
+
});
|
|
218
|
+
if (!response.ok) {
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
const doc = (await response.json());
|
|
222
|
+
if (typeof doc.device_authorization_endpoint !== "string" ||
|
|
223
|
+
typeof doc.token_endpoint !== "string") {
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
deviceAuthorizationEndpoint: doc.device_authorization_endpoint,
|
|
228
|
+
tokenEndpoint: doc.token_endpoint,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
catch {
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
async function requestOAuthDeviceCode(endpoint, clientId) {
|
|
236
|
+
const body = new URLSearchParams({
|
|
237
|
+
client_id: clientId,
|
|
238
|
+
scope: process.env.VANA_OAUTH_SCOPE ?? DEFAULT_OAUTH_SCOPE,
|
|
239
|
+
});
|
|
240
|
+
const response = await fetch(endpoint, {
|
|
241
|
+
method: "POST",
|
|
242
|
+
headers: {
|
|
243
|
+
accept: "application/json",
|
|
244
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
245
|
+
},
|
|
246
|
+
body,
|
|
247
|
+
});
|
|
248
|
+
if (!response.ok) {
|
|
249
|
+
const detail = await readOAuthErrorDetail(response);
|
|
250
|
+
throw new Error(`Failed to start OAuth device flow: HTTP ${response.status}${detail ? ` — ${detail}` : ""}`);
|
|
251
|
+
}
|
|
252
|
+
return (await response.json());
|
|
253
|
+
}
|
|
254
|
+
async function pollOAuthDeviceCode(params) {
|
|
255
|
+
const body = new URLSearchParams({
|
|
256
|
+
client_id: params.clientId,
|
|
257
|
+
device_code: params.deviceCode,
|
|
258
|
+
grant_type: OAUTH_DEVICE_CODE_GRANT,
|
|
259
|
+
});
|
|
260
|
+
const response = await fetch(params.tokenEndpoint, {
|
|
261
|
+
method: "POST",
|
|
262
|
+
headers: {
|
|
263
|
+
accept: "application/json",
|
|
264
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
265
|
+
},
|
|
266
|
+
body,
|
|
267
|
+
signal: AbortSignal.timeout(10_000),
|
|
268
|
+
});
|
|
269
|
+
const raw = (await response.json().catch(() => ({})));
|
|
270
|
+
const parsed = raw && typeof raw === "object"
|
|
271
|
+
? raw
|
|
272
|
+
: {};
|
|
273
|
+
if (response.ok && "access_token" in parsed) {
|
|
274
|
+
return oauthTokenToAuthorized(parsed);
|
|
275
|
+
}
|
|
276
|
+
const errorBody = parsed;
|
|
277
|
+
const oauthError = typeof errorBody.error === "string" ? errorBody.error : "unknown_error";
|
|
278
|
+
if (oauthError === "authorization_pending") {
|
|
279
|
+
return { status: "pending" };
|
|
280
|
+
}
|
|
281
|
+
if (oauthError === "slow_down") {
|
|
282
|
+
return { status: "slow_down" };
|
|
283
|
+
}
|
|
284
|
+
if (oauthError === "expired_token") {
|
|
285
|
+
return { status: "expired" };
|
|
286
|
+
}
|
|
287
|
+
const description = typeof errorBody.error_description === "string"
|
|
288
|
+
? errorBody.error_description
|
|
289
|
+
: oauthError;
|
|
290
|
+
throw new Error(`OAuth device authorization failed: ${description}`);
|
|
291
|
+
}
|
|
292
|
+
function oauthTokenToAuthorized(token) {
|
|
293
|
+
return {
|
|
294
|
+
status: "authorized",
|
|
295
|
+
address: resolveOAuthAccountAddress(token),
|
|
296
|
+
session_token: token.access_token,
|
|
297
|
+
expires_at: token.expires_at,
|
|
298
|
+
expires_in: token.expires_in,
|
|
299
|
+
personal_server_url: token.personal_server_url,
|
|
300
|
+
personal_server_session_token: token.personal_server_session_token,
|
|
301
|
+
ps_access_token: token.ps_access_token,
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
async function readOAuthErrorDetail(response) {
|
|
305
|
+
const text = await response.text().catch(() => "");
|
|
306
|
+
if (!text) {
|
|
307
|
+
return "";
|
|
308
|
+
}
|
|
309
|
+
try {
|
|
310
|
+
const parsed = JSON.parse(text);
|
|
311
|
+
return parsed.error_description ?? parsed.error ?? text.slice(0, 500);
|
|
312
|
+
}
|
|
313
|
+
catch {
|
|
314
|
+
return text.slice(0, 500);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
function resolveOAuthAccountAddress(token) {
|
|
318
|
+
if (token.address) {
|
|
319
|
+
return token.address;
|
|
320
|
+
}
|
|
321
|
+
const claims = decodeJwtClaims(token.id_token);
|
|
322
|
+
for (const key of ["wallet_address", "wallet", "eth_address", "address"]) {
|
|
323
|
+
const value = claims?.[key];
|
|
324
|
+
if (typeof value === "string" && value.trim()) {
|
|
325
|
+
return value;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
const sub = claims?.sub;
|
|
329
|
+
if (typeof sub === "string" && isWalletAddress(sub)) {
|
|
330
|
+
return sub;
|
|
331
|
+
}
|
|
332
|
+
return "vana-account";
|
|
333
|
+
}
|
|
334
|
+
function decodeJwtClaims(idToken) {
|
|
335
|
+
if (!idToken) {
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
const [, payload] = idToken.split(".");
|
|
339
|
+
if (!payload) {
|
|
340
|
+
return null;
|
|
341
|
+
}
|
|
342
|
+
try {
|
|
343
|
+
return JSON.parse(Buffer.from(payload, "base64url").toString("utf8"));
|
|
344
|
+
}
|
|
345
|
+
catch {
|
|
346
|
+
return null;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
async function startDeviceCodeFlow(options) {
|
|
350
|
+
const accountUrl = getAccountUrl();
|
|
351
|
+
const endpoints = await discoverOAuthDeviceEndpoints(accountUrl);
|
|
352
|
+
if (endpoints) {
|
|
353
|
+
const clientId = options.clientId ?? resolveOAuthClientId(accountUrl);
|
|
354
|
+
const deviceCode = await requestOAuthDeviceCode(endpoints.deviceAuthorizationEndpoint, clientId);
|
|
355
|
+
return {
|
|
356
|
+
deviceCode,
|
|
357
|
+
kind: "oauth",
|
|
358
|
+
poll: () => pollOAuthDeviceCode({
|
|
359
|
+
clientId,
|
|
360
|
+
deviceCode: deviceCode.device_code,
|
|
361
|
+
tokenEndpoint: endpoints.tokenEndpoint,
|
|
362
|
+
}),
|
|
363
|
+
verificationUri: deviceCode.verification_uri_complete ?? deviceCode.verification_uri,
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
const deviceCode = await requestDeviceCode();
|
|
367
|
+
return {
|
|
368
|
+
deviceCode,
|
|
369
|
+
kind: "legacy",
|
|
370
|
+
poll: () => pollDeviceCode(deviceCode.device_code),
|
|
371
|
+
verificationUri: deviceCode.verification_uri,
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Open a URL in the user's default browser.
|
|
376
|
+
* Best-effort — failures are silently ignored.
|
|
377
|
+
*/
|
|
378
|
+
export function openBrowser(url) {
|
|
379
|
+
// Use spawnSync with args array to prevent shell injection.
|
|
380
|
+
// A malicious server could return a URL with shell metacharacters.
|
|
381
|
+
const platform = process.platform;
|
|
382
|
+
try {
|
|
383
|
+
const opener = platform === "darwin"
|
|
384
|
+
? "open"
|
|
385
|
+
: platform === "win32"
|
|
386
|
+
? "start"
|
|
387
|
+
: "xdg-open";
|
|
388
|
+
spawnSync(opener, [url], { stdio: "ignore" });
|
|
389
|
+
}
|
|
390
|
+
catch {
|
|
391
|
+
// Best-effort — user can open manually
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Run the full device code login flow.
|
|
396
|
+
*
|
|
397
|
+
* Returns credentials on success, or null if the code expired.
|
|
398
|
+
* Calls the provided callbacks for UI updates.
|
|
399
|
+
*/
|
|
400
|
+
export async function runDeviceCodeFlow(callbacks, options = {}) {
|
|
401
|
+
try {
|
|
402
|
+
const flow = await startDeviceCodeFlow(options);
|
|
403
|
+
const { deviceCode } = flow;
|
|
404
|
+
callbacks.onCode(deviceCode.user_code, flow.verificationUri);
|
|
405
|
+
// Try to open browser
|
|
406
|
+
openBrowser(flow.verificationUri);
|
|
407
|
+
callbacks.onWaiting();
|
|
408
|
+
let interval = (deviceCode.interval ?? 5) * 1000;
|
|
409
|
+
const deadline = Date.now() + deviceCode.expires_in * 1000;
|
|
410
|
+
while (Date.now() < deadline) {
|
|
411
|
+
await new Promise((resolve) => setTimeout(resolve, interval));
|
|
412
|
+
try {
|
|
413
|
+
const result = await flow.poll();
|
|
414
|
+
if (result.status === "authorized") {
|
|
415
|
+
const expiresAt = resolveCredentialExpiry({
|
|
416
|
+
expiresAt: result.expires_at,
|
|
417
|
+
expiresIn: result.expires_in,
|
|
418
|
+
});
|
|
419
|
+
const creds = {
|
|
420
|
+
account: {
|
|
421
|
+
address: result.address,
|
|
422
|
+
session_token: result.session_token,
|
|
423
|
+
expires_at: expiresAt,
|
|
424
|
+
},
|
|
425
|
+
personal_server: result.personal_server_url &&
|
|
426
|
+
(result.personal_server_session_token ?? result.ps_access_token)
|
|
427
|
+
? {
|
|
428
|
+
url: result.personal_server_url,
|
|
429
|
+
session_token: result.personal_server_session_token ??
|
|
430
|
+
result.ps_access_token ??
|
|
431
|
+
"",
|
|
432
|
+
expires_at: expiresAt,
|
|
433
|
+
}
|
|
434
|
+
: null,
|
|
435
|
+
};
|
|
436
|
+
await callbacks.onAuthorized(creds);
|
|
437
|
+
return creds;
|
|
438
|
+
}
|
|
439
|
+
if (result.status === "expired") {
|
|
440
|
+
callbacks.onExpired();
|
|
441
|
+
return null;
|
|
442
|
+
}
|
|
443
|
+
if (result.status === "slow_down") {
|
|
444
|
+
interval += 5_000;
|
|
445
|
+
continue;
|
|
446
|
+
}
|
|
447
|
+
// status === "pending" — continue polling
|
|
448
|
+
}
|
|
449
|
+
catch (error) {
|
|
450
|
+
if (flow.kind === "legacy") {
|
|
451
|
+
// Transient legacy poll error — retry on next interval
|
|
452
|
+
continue;
|
|
453
|
+
}
|
|
454
|
+
throw error;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
// Timed out
|
|
458
|
+
callbacks.onExpired();
|
|
459
|
+
return null;
|
|
460
|
+
}
|
|
461
|
+
catch (error) {
|
|
462
|
+
callbacks.onError(error instanceof Error ? error : new Error(String(error)));
|
|
463
|
+
return null;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
export function getAuthTarget(psUrl) {
|
|
467
|
+
if (!psUrl)
|
|
468
|
+
return "cloud";
|
|
469
|
+
if (psUrl.includes(".myvana.app"))
|
|
470
|
+
return "cloud";
|
|
471
|
+
return "self-hosted";
|
|
472
|
+
}
|
|
473
|
+
export function resolvePersonalServerUrl() {
|
|
474
|
+
return (process.env.VANA_PS_URL ||
|
|
475
|
+
process.env.VANA_PERSONAL_SERVER_URL ||
|
|
476
|
+
loadCredentials()?.personal_server?.url);
|
|
477
|
+
}
|
|
478
|
+
const SELF_HOSTED_POLL_INTERVAL_MS = 5_000;
|
|
479
|
+
function resolveLoginV2Url(serverUrl, endpoint) {
|
|
480
|
+
return new URL(endpoint, `${serverUrl.replace(/\/$/, "")}/`).toString();
|
|
481
|
+
}
|
|
482
|
+
export async function runSelfHostedLoginFlow(serverUrl, onLoginUrl) {
|
|
483
|
+
const base = serverUrl.replace(/\/$/, "");
|
|
484
|
+
// 1. Initiate login flow
|
|
485
|
+
const initRes = await fetch(`${base}/auth/device`, { method: "POST" });
|
|
486
|
+
if (!initRes.ok) {
|
|
487
|
+
throw new Error(`Server at ${base} does not support CLI login (${initRes.status})`);
|
|
488
|
+
}
|
|
489
|
+
const init = (await initRes.json());
|
|
490
|
+
// 2. Open browser
|
|
491
|
+
onLoginUrl(resolveLoginV2Url(base, init.login));
|
|
492
|
+
// 3. Poll for completion (5 min timeout)
|
|
493
|
+
const deadline = Date.now() + 5 * 60 * 1000;
|
|
494
|
+
const pollUrl = resolveLoginV2Url(base, init.poll.endpoint);
|
|
495
|
+
while (Date.now() < deadline) {
|
|
496
|
+
await new Promise((r) => setTimeout(r, SELF_HOSTED_POLL_INTERVAL_MS));
|
|
497
|
+
const pollRes = await fetch(`${pollUrl}?token=${encodeURIComponent(init.poll.token)}`);
|
|
498
|
+
if (pollRes.status === 200) {
|
|
499
|
+
const result = (await pollRes.json());
|
|
500
|
+
if (!isWalletAddress(result.address)) {
|
|
501
|
+
throw new Error("Personal Server did not report a valid owner wallet address. Ensure VANA_MASTER_KEY_SIGNATURE is configured.");
|
|
502
|
+
}
|
|
503
|
+
return {
|
|
504
|
+
server: result.server,
|
|
505
|
+
address: result.address,
|
|
506
|
+
session_token: result.access_token,
|
|
507
|
+
expires_at: result.expires_at,
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
if (pollRes.status === 404 || pollRes.status === 202) {
|
|
511
|
+
const result = (await pollRes
|
|
512
|
+
.json()
|
|
513
|
+
.catch(() => null));
|
|
514
|
+
if (result?.status === "expired") {
|
|
515
|
+
throw new Error("Authorization expired. Please try again.");
|
|
516
|
+
}
|
|
517
|
+
continue;
|
|
518
|
+
}
|
|
519
|
+
if (pollRes.status === 429) {
|
|
520
|
+
continue;
|
|
521
|
+
}
|
|
522
|
+
if (!pollRes.ok) {
|
|
523
|
+
throw new Error(`Poll failed: ${pollRes.status}`);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
throw new Error("Authorization timed out. Please try again.");
|
|
527
|
+
}
|
|
528
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/cli/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../../src/cli/bin.ts"],"names":[],"mappings":""}
|
package/dist/cli/bin.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { runCli } from "./index.js";
|
|
3
|
+
for (const stream of [process.stdout, process.stderr]) {
|
|
4
|
+
stream.on("error", (error) => {
|
|
5
|
+
if (error.code === "EPIPE") {
|
|
6
|
+
process.exit(0);
|
|
7
|
+
}
|
|
8
|
+
throw error;
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
const exitCode = await runCli(process.argv);
|
|
12
|
+
if (typeof exitCode === "number") {
|
|
13
|
+
process.exitCode = exitCode;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=bin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../../src/cli/bin.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEpC,KAAK,MAAM,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;IACtD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAA4B,EAAE,EAAE;QAClD,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC3B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAC5C,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;IACjC,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { readCliState } from "../core/index.js";
|
|
2
|
+
import type { CliChannel, CliInstallMethod, CliStatus, SourceStatus } from "../core/cli-types.js";
|
|
3
|
+
import type { AvailableSource } from "../connectors/registry.js";
|
|
4
|
+
interface SourceLabelMap {
|
|
5
|
+
[source: string]: string;
|
|
6
|
+
}
|
|
7
|
+
interface SourceMetadataMap {
|
|
8
|
+
[source: string]: {
|
|
9
|
+
name: string;
|
|
10
|
+
company?: string;
|
|
11
|
+
description?: string;
|
|
12
|
+
authMode?: "automated" | "interactive" | "legacy";
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
type RenderTone = "accent" | "success" | "warning" | "error" | "muted" | "info";
|
|
16
|
+
export declare function runCli(argv?: string[]): Promise<number>;
|
|
17
|
+
export declare function formatUptime(seconds: number): string;
|
|
18
|
+
export declare function displaySource(source: string, labels?: SourceLabelMap): string;
|
|
19
|
+
export declare function humanizeIssue(message: string): string;
|
|
20
|
+
export declare function gatherSourceStatuses(storedSources: Record<string, Awaited<ReturnType<typeof readCliState>>["sources"][string]>, metadata?: SourceMetadataMap): Promise<SourceStatus[]>;
|
|
21
|
+
export declare function listInstalledConnectorFiles(): Promise<Array<{
|
|
22
|
+
source: string;
|
|
23
|
+
path: string;
|
|
24
|
+
}>>;
|
|
25
|
+
export declare function buildStatusNextSteps(sources: SourceStatus[], sourceLabels?: SourceLabelMap, runtime?: CliStatus["runtime"], availableSources?: Array<{
|
|
26
|
+
id: string;
|
|
27
|
+
name: string;
|
|
28
|
+
authMode?: string;
|
|
29
|
+
}>): string[];
|
|
30
|
+
export declare function buildSourcesNextSteps(recommendedSource: {
|
|
31
|
+
id: string;
|
|
32
|
+
name: string;
|
|
33
|
+
authMode?: "automated" | "interactive" | "legacy";
|
|
34
|
+
} | null | undefined, connectedCount: number): string[];
|
|
35
|
+
export declare function buildDataListNextSteps(datasetRecords: Array<{
|
|
36
|
+
source: string;
|
|
37
|
+
name?: string | null;
|
|
38
|
+
}>, registrySources: Array<{
|
|
39
|
+
id: string;
|
|
40
|
+
authMode?: "automated" | "interactive" | "legacy";
|
|
41
|
+
}>): string[];
|
|
42
|
+
export declare function buildDataShowNextSteps(source: string, datasetCount: number, sourceLabels?: SourceLabelMap): string[];
|
|
43
|
+
/** Derive a human-readable message from a stored `connectionHealthReason`. */
|
|
44
|
+
export declare function formatHealthMessage(reason: string | undefined): string | null;
|
|
45
|
+
export declare function getCliVersion(): string;
|
|
46
|
+
export declare function getCliChannel(version?: string): "stable" | "canary";
|
|
47
|
+
export declare function getCliInstallMethod(execPath?: string): CliInstallMethod;
|
|
48
|
+
export declare function getDoctorAppRootPath(installMethod: CliInstallMethod, execPath?: string): string | null;
|
|
49
|
+
export declare function formatInstallMethodLabel(method: CliInstallMethod): string;
|
|
50
|
+
export declare function getLifecycleCommands(installMethod: CliInstallMethod, channel: CliChannel): {
|
|
51
|
+
upgrade: string;
|
|
52
|
+
uninstall: string;
|
|
53
|
+
};
|
|
54
|
+
export declare function createSourceLabelMap(sources: Array<{
|
|
55
|
+
id: string;
|
|
56
|
+
name: string;
|
|
57
|
+
}>): SourceLabelMap;
|
|
58
|
+
export declare function createSourceMetadataMap(sources: Array<{
|
|
59
|
+
id: string;
|
|
60
|
+
name: string;
|
|
61
|
+
company?: string;
|
|
62
|
+
description?: string;
|
|
63
|
+
authMode?: "automated" | "interactive" | "legacy";
|
|
64
|
+
}>): SourceMetadataMap;
|
|
65
|
+
export declare function getSourceStatusPresentation(source: SourceStatus): {
|
|
66
|
+
label: string;
|
|
67
|
+
tone: RenderTone;
|
|
68
|
+
};
|
|
69
|
+
export declare function toneForRuntime(runtime: CliStatus["runtime"]): RenderTone;
|
|
70
|
+
export declare function loadRegistrySources(): Promise<AvailableSource[]>;
|
|
71
|
+
export declare function compareSourceStatusOrder(left: SourceStatus, right: SourceStatus): number;
|
|
72
|
+
export declare function isSourceAttention(source: SourceStatus): boolean;
|
|
73
|
+
export declare function rankSourceStatus(source: SourceStatus): number;
|
|
74
|
+
export declare function readResultSummary(resultPath: string): Promise<{
|
|
75
|
+
lines: string[];
|
|
76
|
+
} | null>;
|
|
77
|
+
export declare function summarizeResultData(data: Record<string, unknown>): {
|
|
78
|
+
lines: string[];
|
|
79
|
+
} | null;
|
|
80
|
+
export declare function formatTimestamp(value: string): string;
|
|
81
|
+
export declare function compareDatasetOrder(left: {
|
|
82
|
+
lastRunAt: string | null;
|
|
83
|
+
name: string | undefined;
|
|
84
|
+
source: string;
|
|
85
|
+
}, right: {
|
|
86
|
+
lastRunAt: string | null;
|
|
87
|
+
name: string | undefined;
|
|
88
|
+
source: string;
|
|
89
|
+
}): number;
|
|
90
|
+
export declare function hasCollectedData(dataState: SourceStatus["dataState"] | null | undefined): boolean;
|
|
91
|
+
export {};
|
|
92
|
+
//# sourceMappingURL=index.d.ts.map
|