@wayai/cli 0.2.45 → 0.2.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/eval-results.js +3 -3
- package/dist/commands/login.d.ts +4 -1
- package/dist/commands/login.js +27 -19
- package/dist/commands/login.js.map +1 -1
- package/dist/lib/api-client.d.ts +11 -11
- package/dist/lib/api-client.js +4 -4
- package/dist/lib/auth.d.ts +34 -23
- package/dist/lib/auth.js +127 -48
- package/dist/lib/auth.js.map +1 -1
- package/dist/lib/config.d.ts +13 -2
- package/dist/lib/config.js +4 -7
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/eval-format.d.ts +1 -1
- package/dist/lib/eval-format.js +1 -1
- package/package.json +1 -1
|
@@ -82,7 +82,7 @@ async function findLatestSessionForEval(client, hubId, evalName) {
|
|
|
82
82
|
// Sessions are ordered by created_at desc, so first match is the latest
|
|
83
83
|
for (const session of completedSessions) {
|
|
84
84
|
const details = await client.getEvalSessionDetails(session.eval_session_id);
|
|
85
|
-
const hasEval = details.data.results.some((r) => r.
|
|
85
|
+
const hasEval = details.data.results.some((r) => r.eval_id === matchingEval.eval_id);
|
|
86
86
|
if (hasEval) {
|
|
87
87
|
return session.eval_session_id;
|
|
88
88
|
}
|
|
@@ -117,7 +117,7 @@ async function showRunDetails(client, sessionId, evalNameFilter, jsonOutput) {
|
|
|
117
117
|
if (evalNameFilter) {
|
|
118
118
|
const matchingResult = details.data.results.find((r) => r.eval?.eval_name?.toLowerCase() === evalNameFilter.toLowerCase());
|
|
119
119
|
if (matchingResult) {
|
|
120
|
-
evalId = matchingResult.
|
|
120
|
+
evalId = matchingResult.eval_id;
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
const runsResult = await client.getEvalSessionRuns(sessionId, { evalId });
|
|
@@ -131,7 +131,7 @@ async function showRunDetails(client, sessionId, evalNameFilter, jsonOutput) {
|
|
|
131
131
|
return;
|
|
132
132
|
}
|
|
133
133
|
for (const run of runsResult.data.runs) {
|
|
134
|
-
const evalName = run.eval?.eval_name || run.
|
|
134
|
+
const evalName = run.eval?.eval_name || run.eval_id.slice(0, 8);
|
|
135
135
|
const status = run.response_match === true ? 'PASS' : run.response_match === false ? 'FAIL' : 'PENDING';
|
|
136
136
|
const time = run.execution_time_ms != null ? `(${(run.execution_time_ms / 1000).toFixed(1)}s)` : '';
|
|
137
137
|
console.log(`${evalName} — Run #${run.run_number} [${status}] ${time}`);
|
package/dist/commands/login.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* wayai login —
|
|
2
|
+
* wayai login — OAuth 2.1 + PKCE browser flow (default) or --token fallback
|
|
3
|
+
*
|
|
4
|
+
* Browser login: Opens AuthKit authorize → PKCE flow → JWT + refresh token
|
|
5
|
+
* Token login: User pastes a way_ scoped token directly
|
|
3
6
|
*/
|
|
4
7
|
export declare function parseApiUrl(args: string[]): string;
|
|
5
8
|
export declare function loginCommand(args: string[]): Promise<void>;
|
package/dist/commands/login.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* wayai login —
|
|
2
|
+
* wayai login — OAuth 2.1 + PKCE browser flow (default) or --token fallback
|
|
3
|
+
*
|
|
4
|
+
* Browser login: Opens AuthKit authorize → PKCE flow → JWT + refresh token
|
|
5
|
+
* Token login: User pastes a way_ scoped token directly
|
|
3
6
|
*/
|
|
4
7
|
import * as readline from 'node:readline';
|
|
5
|
-
import { generateState, findAvailablePort, startCallbackServer,
|
|
8
|
+
import { generateState, generateCodeVerifier, generateCodeChallenge, findAvailablePort, startCallbackServer, exchangeCodeForTokens, validateToken, getAuthKitDomain, getAuthKitClientId, } from '../lib/auth.js';
|
|
6
9
|
import { writeConfig } from '../lib/config.js';
|
|
7
10
|
function prompt(question, defaultValue) {
|
|
8
11
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
@@ -34,25 +37,29 @@ export async function loginCommand(args) {
|
|
|
34
37
|
}
|
|
35
38
|
async function loginWithBrowser(apiUrl) {
|
|
36
39
|
console.log('\nConnecting to WayAI...');
|
|
40
|
+
const authkitDomain = getAuthKitDomain();
|
|
41
|
+
const clientId = getAuthKitClientId();
|
|
42
|
+
// Generate PKCE parameters
|
|
43
|
+
const codeVerifier = generateCodeVerifier();
|
|
44
|
+
const codeChallenge = await generateCodeChallenge(codeVerifier);
|
|
45
|
+
const state = generateState();
|
|
37
46
|
// Find an available port for the callback server
|
|
38
47
|
const port = await findAvailablePort();
|
|
39
48
|
const redirectUri = `http://127.0.0.1:${port}/callback`;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
process.exit(1);
|
|
49
|
-
}
|
|
49
|
+
// Build AuthKit authorization URL with PKCE
|
|
50
|
+
const authorizeUrl = new URL(`${authkitDomain}/oauth2/authorize`);
|
|
51
|
+
authorizeUrl.searchParams.set('client_id', clientId);
|
|
52
|
+
authorizeUrl.searchParams.set('redirect_uri', redirectUri);
|
|
53
|
+
authorizeUrl.searchParams.set('response_type', 'code');
|
|
54
|
+
authorizeUrl.searchParams.set('code_challenge', codeChallenge);
|
|
55
|
+
authorizeUrl.searchParams.set('code_challenge_method', 'S256');
|
|
56
|
+
authorizeUrl.searchParams.set('state', state);
|
|
50
57
|
// Start callback server before opening browser
|
|
51
58
|
const callbackPromise = startCallbackServer(port, state);
|
|
52
59
|
// Try to open browser
|
|
53
|
-
const openedBrowser = await tryOpenBrowser(
|
|
60
|
+
const openedBrowser = await tryOpenBrowser(authorizeUrl.toString());
|
|
54
61
|
if (!openedBrowser) {
|
|
55
|
-
console.log(`\nOpen this URL in your browser to log in:\n\n ${
|
|
62
|
+
console.log(`\nOpen this URL in your browser to log in:\n\n ${authorizeUrl.toString()}\n`);
|
|
56
63
|
}
|
|
57
64
|
else {
|
|
58
65
|
console.log('Opening browser for login...');
|
|
@@ -60,12 +67,14 @@ async function loginWithBrowser(apiUrl) {
|
|
|
60
67
|
try {
|
|
61
68
|
const { code } = await callbackPromise;
|
|
62
69
|
console.log('Exchanging authorization code...');
|
|
63
|
-
const
|
|
70
|
+
const tokens = await exchangeCodeForTokens(authkitDomain, clientId, code, codeVerifier, redirectUri);
|
|
64
71
|
writeConfig({
|
|
65
72
|
api_url: apiUrl,
|
|
66
|
-
|
|
73
|
+
access_token: tokens.access_token,
|
|
74
|
+
refresh_token: tokens.refresh_token,
|
|
75
|
+
token_expires_at: new Date(Date.now() + tokens.expires_in * 1000).toISOString(),
|
|
67
76
|
});
|
|
68
|
-
console.log(
|
|
77
|
+
console.log('\nLogin successful!');
|
|
69
78
|
console.log('Configuration saved to ~/.wayai/config.json');
|
|
70
79
|
}
|
|
71
80
|
catch (err) {
|
|
@@ -74,7 +83,7 @@ async function loginWithBrowser(apiUrl) {
|
|
|
74
83
|
}
|
|
75
84
|
}
|
|
76
85
|
async function loginWithToken(apiUrl) {
|
|
77
|
-
const token = await prompt('
|
|
86
|
+
const token = await prompt('API Token (way_...)');
|
|
78
87
|
if (!token) {
|
|
79
88
|
console.error('Token is required.');
|
|
80
89
|
process.exit(1);
|
|
@@ -98,7 +107,6 @@ async function loginWithToken(apiUrl) {
|
|
|
98
107
|
console.log('\nLogin successful! Configuration saved to ~/.wayai/config.json');
|
|
99
108
|
}
|
|
100
109
|
async function tryOpenBrowser(url) {
|
|
101
|
-
// Skip in headless environments
|
|
102
110
|
if (process.env.SSH_CONNECTION || process.env.SSH_TTY) {
|
|
103
111
|
return false;
|
|
104
112
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/api-client.d.ts
CHANGED
|
@@ -75,8 +75,8 @@ export declare class ApiClient {
|
|
|
75
75
|
eval_name: string;
|
|
76
76
|
enabled: boolean;
|
|
77
77
|
number_of_runs: number;
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
responder_agent_id: string;
|
|
79
|
+
hub_id: string;
|
|
80
80
|
agent?: {
|
|
81
81
|
agent_id: string;
|
|
82
82
|
agent_name: string;
|
|
@@ -95,7 +95,7 @@ export declare class ApiClient {
|
|
|
95
95
|
eval_session_id: string;
|
|
96
96
|
session_name: string;
|
|
97
97
|
session_status: string;
|
|
98
|
-
|
|
98
|
+
hub_id: string;
|
|
99
99
|
total_evals: number;
|
|
100
100
|
total_runs: number;
|
|
101
101
|
successful_runs: number;
|
|
@@ -114,7 +114,7 @@ export declare class ApiClient {
|
|
|
114
114
|
eval_session_id: string;
|
|
115
115
|
session_name: string;
|
|
116
116
|
session_status: string;
|
|
117
|
-
|
|
117
|
+
hub_id: string;
|
|
118
118
|
};
|
|
119
119
|
};
|
|
120
120
|
message: string;
|
|
@@ -141,7 +141,7 @@ export declare class ApiClient {
|
|
|
141
141
|
};
|
|
142
142
|
results: Array<{
|
|
143
143
|
eval_session_result_id: string;
|
|
144
|
-
|
|
144
|
+
eval_id: string;
|
|
145
145
|
total_runs: number;
|
|
146
146
|
successful_runs: number;
|
|
147
147
|
failed_runs: number;
|
|
@@ -158,7 +158,7 @@ export declare class ApiClient {
|
|
|
158
158
|
eval?: {
|
|
159
159
|
eval_id: string;
|
|
160
160
|
eval_name: string;
|
|
161
|
-
|
|
161
|
+
responder_agent_id: string;
|
|
162
162
|
} | null;
|
|
163
163
|
}>;
|
|
164
164
|
};
|
|
@@ -171,7 +171,7 @@ export declare class ApiClient {
|
|
|
171
171
|
data: {
|
|
172
172
|
runs: Array<{
|
|
173
173
|
eval_session_run_id: string;
|
|
174
|
-
|
|
174
|
+
eval_id: string;
|
|
175
175
|
run_number: number;
|
|
176
176
|
eval_response: {
|
|
177
177
|
role: string;
|
|
@@ -185,7 +185,7 @@ export declare class ApiClient {
|
|
|
185
185
|
eval?: {
|
|
186
186
|
eval_id: string;
|
|
187
187
|
eval_name: string;
|
|
188
|
-
|
|
188
|
+
responder_agent_id: string;
|
|
189
189
|
} | null;
|
|
190
190
|
}>;
|
|
191
191
|
total_count: number;
|
|
@@ -333,7 +333,7 @@ export declare class ApiClient {
|
|
|
333
333
|
data: Array<{
|
|
334
334
|
project_id: string;
|
|
335
335
|
project_name: string;
|
|
336
|
-
|
|
336
|
+
organization_id: string;
|
|
337
337
|
created_at: string;
|
|
338
338
|
}>;
|
|
339
339
|
}>;
|
|
@@ -342,7 +342,7 @@ export declare class ApiClient {
|
|
|
342
342
|
hub_id: string;
|
|
343
343
|
hub_name: string;
|
|
344
344
|
hub_environment: string;
|
|
345
|
-
|
|
345
|
+
project_id: string;
|
|
346
346
|
hub_type: string;
|
|
347
347
|
[key: string]: unknown;
|
|
348
348
|
}>;
|
|
@@ -351,7 +351,7 @@ export declare class ApiClient {
|
|
|
351
351
|
data: Array<{
|
|
352
352
|
project_id: string;
|
|
353
353
|
project_name: string;
|
|
354
|
-
|
|
354
|
+
organization_id: string;
|
|
355
355
|
created_at: string;
|
|
356
356
|
}>;
|
|
357
357
|
}>;
|
package/dist/lib/api-client.js
CHANGED
|
@@ -63,7 +63,7 @@ export class ApiClient {
|
|
|
63
63
|
}
|
|
64
64
|
async syncSkills(hubId, connectionId) {
|
|
65
65
|
return this.request('POST', '/api/setup/resources/sync-skills', {
|
|
66
|
-
|
|
66
|
+
hub_id: hubId,
|
|
67
67
|
...(connectionId && { connection_id: connectionId }),
|
|
68
68
|
});
|
|
69
69
|
}
|
|
@@ -113,7 +113,7 @@ export class ApiClient {
|
|
|
113
113
|
}
|
|
114
114
|
async createEvalSession(hubId, sessionName) {
|
|
115
115
|
return this.request('POST', '/api/evals/sessions', {
|
|
116
|
-
session: {
|
|
116
|
+
session: { hub_id: hubId, session_name: sessionName },
|
|
117
117
|
});
|
|
118
118
|
}
|
|
119
119
|
async runEvalSession(sessionId) {
|
|
@@ -159,13 +159,13 @@ export class ApiClient {
|
|
|
159
159
|
}
|
|
160
160
|
async createProject(organizationId, projectName) {
|
|
161
161
|
return this.request('POST', '/api/setup/projects', {
|
|
162
|
-
|
|
162
|
+
organization_id: organizationId,
|
|
163
163
|
project_name: projectName,
|
|
164
164
|
});
|
|
165
165
|
}
|
|
166
166
|
async createHub(projectId, hubName, hubType, hubDescription) {
|
|
167
167
|
return this.request('POST', '/api/setup/hubs', {
|
|
168
|
-
|
|
168
|
+
project_id: projectId,
|
|
169
169
|
hub_name: hubName,
|
|
170
170
|
...(hubType && { hub_type: hubType }),
|
|
171
171
|
...(hubDescription && { hub_description: hubDescription }),
|
package/dist/lib/auth.d.ts
CHANGED
|
@@ -1,51 +1,62 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Authentication —
|
|
2
|
+
* Authentication — OAuth 2.1 + PKCE browser login + way_ token fallback
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* 1. Browser login (default):
|
|
6
|
-
* 2. Token login (--token): User pastes a way_ token directly
|
|
4
|
+
* Two login paths:
|
|
5
|
+
* 1. Browser login (default): OAuth 2.1 with PKCE → JWT + refresh token
|
|
6
|
+
* 2. Token login (--token): User pastes a way_ scoped token directly
|
|
7
|
+
*
|
|
8
|
+
* The CLI exchanges codes directly with AuthKit's token endpoint.
|
|
9
|
+
* No backend involvement in the auth flow (unlike the old /auth/cli/* endpoints).
|
|
7
10
|
*/
|
|
8
11
|
import type { CliConfig } from './config.js';
|
|
9
12
|
/**
|
|
10
|
-
* Generate a random
|
|
13
|
+
* Generate a cryptographically random PKCE code verifier (43-128 chars, base64url).
|
|
14
|
+
*/
|
|
15
|
+
export declare function generateCodeVerifier(): string;
|
|
16
|
+
/**
|
|
17
|
+
* Generate the S256 code challenge from a code verifier.
|
|
18
|
+
*/
|
|
19
|
+
export declare function generateCodeChallenge(verifier: string): Promise<string>;
|
|
20
|
+
/**
|
|
21
|
+
* Generate a random state parameter for CSRF protection.
|
|
11
22
|
*/
|
|
12
23
|
export declare function generateState(): string;
|
|
13
24
|
/**
|
|
14
|
-
*
|
|
25
|
+
* Exchange an authorization code for JWT + refresh token at AuthKit's token endpoint.
|
|
15
26
|
*/
|
|
16
|
-
export declare function
|
|
27
|
+
export declare function exchangeCodeForTokens(authkitDomain: string, clientId: string, code: string, codeVerifier: string, redirectUri: string): Promise<{
|
|
28
|
+
access_token: string;
|
|
29
|
+
refresh_token: string;
|
|
30
|
+
expires_in: number;
|
|
31
|
+
}>;
|
|
17
32
|
/**
|
|
18
|
-
*
|
|
33
|
+
* Refresh an expired access token using the refresh token.
|
|
34
|
+
* Returns new tokens. If the server rotates refresh tokens,
|
|
35
|
+
* the new refresh_token is included in the response.
|
|
19
36
|
*/
|
|
20
|
-
export declare function
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
email: string;
|
|
37
|
+
export declare function refreshAccessToken(authkitDomain: string, clientId: string, refreshToken: string): Promise<{
|
|
38
|
+
access_token: string;
|
|
39
|
+
refresh_token?: string;
|
|
40
|
+
expires_in: number;
|
|
25
41
|
}>;
|
|
26
42
|
/**
|
|
27
|
-
* Validate a way_ token by making a lightweight API call
|
|
43
|
+
* Validate a way_ token by making a lightweight API call.
|
|
28
44
|
*/
|
|
29
45
|
export declare function validateToken(apiUrl: string, token: string): Promise<void>;
|
|
30
46
|
/**
|
|
31
47
|
* Start a local HTTP server that waits for the OAuth callback.
|
|
32
|
-
* Returns the authorization code and state received.
|
|
33
48
|
*/
|
|
34
49
|
export declare function startCallbackServer(port: number, expectedState: string, timeoutMs?: number): Promise<{
|
|
35
50
|
code: string;
|
|
36
51
|
port: number;
|
|
37
52
|
}>;
|
|
38
|
-
/**
|
|
39
|
-
* Check if a specific port is available by trying to bind then immediately closing.
|
|
40
|
-
*/
|
|
41
|
-
export declare function isPortAvailable(port: number): Promise<boolean>;
|
|
42
|
-
/**
|
|
43
|
-
* Find an available port by trying to listen on port 0
|
|
44
|
-
*/
|
|
45
53
|
export declare function findAvailablePort(): Promise<number>;
|
|
54
|
+
export declare function getAuthKitDomain(): string;
|
|
55
|
+
export declare function getAuthKitClientId(): string;
|
|
46
56
|
/**
|
|
47
57
|
* Get a valid access token from the current config.
|
|
48
|
-
*
|
|
58
|
+
* - For way_ tokens: returns directly (no refresh needed)
|
|
59
|
+
* - For OAuth JWT: checks expiry, refreshes if needed, updates config
|
|
49
60
|
*/
|
|
50
61
|
export declare function getAccessToken(config: CliConfig): Promise<string>;
|
|
51
62
|
/**
|
package/dist/lib/auth.js
CHANGED
|
@@ -1,68 +1,113 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Authentication —
|
|
2
|
+
* Authentication — OAuth 2.1 + PKCE browser login + way_ token fallback
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* 1. Browser login (default):
|
|
6
|
-
* 2. Token login (--token): User pastes a way_ token directly
|
|
4
|
+
* Two login paths:
|
|
5
|
+
* 1. Browser login (default): OAuth 2.1 with PKCE → JWT + refresh token
|
|
6
|
+
* 2. Token login (--token): User pastes a way_ scoped token directly
|
|
7
|
+
*
|
|
8
|
+
* The CLI exchanges codes directly with AuthKit's token endpoint.
|
|
9
|
+
* No backend involvement in the auth flow (unlike the old /auth/cli/* endpoints).
|
|
7
10
|
*/
|
|
8
11
|
import * as crypto from 'node:crypto';
|
|
9
12
|
import * as http from 'node:http';
|
|
10
|
-
import { readConfig } from './config.js';
|
|
13
|
+
import { readConfig, writeConfig } from './config.js';
|
|
11
14
|
import { setSentryUser } from './sentry.js';
|
|
15
|
+
// =============================================================================
|
|
16
|
+
// PKCE Utilities
|
|
17
|
+
// =============================================================================
|
|
18
|
+
/**
|
|
19
|
+
* Generate a cryptographically random PKCE code verifier (43-128 chars, base64url).
|
|
20
|
+
*/
|
|
21
|
+
export function generateCodeVerifier() {
|
|
22
|
+
return crypto.randomBytes(32).toString('base64url');
|
|
23
|
+
}
|
|
12
24
|
/**
|
|
13
|
-
* Generate
|
|
25
|
+
* Generate the S256 code challenge from a code verifier.
|
|
26
|
+
*/
|
|
27
|
+
export async function generateCodeChallenge(verifier) {
|
|
28
|
+
const hash = crypto.createHash('sha256').update(verifier).digest();
|
|
29
|
+
return hash.toString('base64url');
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Generate a random state parameter for CSRF protection.
|
|
14
33
|
*/
|
|
15
34
|
export function generateState() {
|
|
16
35
|
return crypto.randomBytes(16).toString('base64url');
|
|
17
36
|
}
|
|
37
|
+
// =============================================================================
|
|
38
|
+
// AuthKit Token Exchange
|
|
39
|
+
// =============================================================================
|
|
18
40
|
/**
|
|
19
|
-
*
|
|
41
|
+
* Exchange an authorization code for JWT + refresh token at AuthKit's token endpoint.
|
|
20
42
|
*/
|
|
21
|
-
export async function
|
|
22
|
-
const
|
|
23
|
-
|
|
43
|
+
export async function exchangeCodeForTokens(authkitDomain, clientId, code, codeVerifier, redirectUri) {
|
|
44
|
+
const response = await fetch(`${authkitDomain}/oauth2/token`, {
|
|
45
|
+
method: 'POST',
|
|
46
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
47
|
+
body: new URLSearchParams({
|
|
48
|
+
grant_type: 'authorization_code',
|
|
49
|
+
code,
|
|
50
|
+
code_verifier: codeVerifier,
|
|
51
|
+
redirect_uri: redirectUri,
|
|
52
|
+
client_id: clientId,
|
|
53
|
+
}).toString(),
|
|
54
|
+
});
|
|
24
55
|
if (!response.ok) {
|
|
25
56
|
const body = await response.text();
|
|
26
|
-
throw new Error(`
|
|
57
|
+
throw new Error(`Token exchange failed (${response.status}): ${body}`);
|
|
27
58
|
}
|
|
28
|
-
|
|
29
|
-
return data.url;
|
|
59
|
+
return response.json();
|
|
30
60
|
}
|
|
31
61
|
/**
|
|
32
|
-
*
|
|
62
|
+
* Refresh an expired access token using the refresh token.
|
|
63
|
+
* Returns new tokens. If the server rotates refresh tokens,
|
|
64
|
+
* the new refresh_token is included in the response.
|
|
33
65
|
*/
|
|
34
|
-
export async function
|
|
35
|
-
const response = await fetch(`${
|
|
66
|
+
export async function refreshAccessToken(authkitDomain, clientId, refreshToken) {
|
|
67
|
+
const response = await fetch(`${authkitDomain}/oauth2/token`, {
|
|
36
68
|
method: 'POST',
|
|
37
|
-
headers: { 'Content-Type': 'application/
|
|
38
|
-
body:
|
|
69
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
70
|
+
body: new URLSearchParams({
|
|
71
|
+
grant_type: 'refresh_token',
|
|
72
|
+
refresh_token: refreshToken,
|
|
73
|
+
client_id: clientId,
|
|
74
|
+
}).toString(),
|
|
39
75
|
});
|
|
40
76
|
if (!response.ok) {
|
|
77
|
+
const status = response.status;
|
|
41
78
|
const body = await response.text();
|
|
42
|
-
|
|
79
|
+
// Only clear tokens on invalid_grant (expired/revoked refresh token)
|
|
80
|
+
if (status === 400 || status === 401) {
|
|
81
|
+
let isInvalidGrant = false;
|
|
82
|
+
try {
|
|
83
|
+
const parsed = JSON.parse(body);
|
|
84
|
+
if (parsed.error === 'invalid_grant')
|
|
85
|
+
isInvalidGrant = true;
|
|
86
|
+
}
|
|
87
|
+
catch { /* non-JSON body */ }
|
|
88
|
+
if (isInvalidGrant)
|
|
89
|
+
throw new Error('SESSION_EXPIRED');
|
|
90
|
+
}
|
|
91
|
+
throw new Error(`Token refresh failed (${status}): ${body}`);
|
|
43
92
|
}
|
|
44
|
-
|
|
45
|
-
return {
|
|
46
|
-
token: data.data.token,
|
|
47
|
-
orgId: data.data.org_id,
|
|
48
|
-
userId: data.data.user_id,
|
|
49
|
-
email: data.data.email,
|
|
50
|
-
};
|
|
93
|
+
return response.json();
|
|
51
94
|
}
|
|
52
95
|
/**
|
|
53
|
-
* Validate a way_ token by making a lightweight API call
|
|
96
|
+
* Validate a way_ token by making a lightweight API call.
|
|
54
97
|
*/
|
|
55
98
|
export async function validateToken(apiUrl, token) {
|
|
56
|
-
const response = await fetch(`${apiUrl}/api/
|
|
99
|
+
const response = await fetch(`${apiUrl}/api/auth/me`, {
|
|
57
100
|
headers: { Authorization: `Bearer ${token}` },
|
|
58
101
|
});
|
|
59
102
|
if (!response.ok) {
|
|
60
103
|
throw new Error(`Token validation failed (${response.status})`);
|
|
61
104
|
}
|
|
62
105
|
}
|
|
106
|
+
// =============================================================================
|
|
107
|
+
// Callback Server
|
|
108
|
+
// =============================================================================
|
|
63
109
|
/**
|
|
64
110
|
* Start a local HTTP server that waits for the OAuth callback.
|
|
65
|
-
* Returns the authorization code and state received.
|
|
66
111
|
*/
|
|
67
112
|
export function startCallbackServer(port, expectedState, timeoutMs = 120_000) {
|
|
68
113
|
return new Promise((resolve, reject) => {
|
|
@@ -80,7 +125,6 @@ export function startCallbackServer(port, expectedState, timeoutMs = 120_000) {
|
|
|
80
125
|
reject(new Error(`OAuth callback error: ${errorDescription || error}`));
|
|
81
126
|
return;
|
|
82
127
|
}
|
|
83
|
-
// Validate state to prevent CSRF
|
|
84
128
|
if (state !== expectedState) {
|
|
85
129
|
res.writeHead(400, { 'Content-Type': 'text/html' });
|
|
86
130
|
res.end('<html><body><h2>Login failed</h2><p>Invalid state parameter</p></body></html>');
|
|
@@ -122,21 +166,6 @@ export function startCallbackServer(port, expectedState, timeoutMs = 120_000) {
|
|
|
122
166
|
});
|
|
123
167
|
});
|
|
124
168
|
}
|
|
125
|
-
/**
|
|
126
|
-
* Check if a specific port is available by trying to bind then immediately closing.
|
|
127
|
-
*/
|
|
128
|
-
export async function isPortAvailable(port) {
|
|
129
|
-
return new Promise((resolve) => {
|
|
130
|
-
const server = http.createServer();
|
|
131
|
-
server.listen(port, '127.0.0.1', () => {
|
|
132
|
-
server.close(() => resolve(true));
|
|
133
|
-
});
|
|
134
|
-
server.on('error', () => resolve(false));
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Find an available port by trying to listen on port 0
|
|
139
|
-
*/
|
|
140
169
|
export async function findAvailablePort() {
|
|
141
170
|
return new Promise((resolve, reject) => {
|
|
142
171
|
const server = http.createServer();
|
|
@@ -153,15 +182,65 @@ export async function findAvailablePort() {
|
|
|
153
182
|
server.on('error', reject);
|
|
154
183
|
});
|
|
155
184
|
}
|
|
185
|
+
// =============================================================================
|
|
186
|
+
// Token Resolution (for API calls)
|
|
187
|
+
// =============================================================================
|
|
188
|
+
/** Default AuthKit configuration for WayAI */
|
|
189
|
+
const AUTHKIT_DOMAIN = 'https://sprightly-comic-51.authkit.app';
|
|
190
|
+
const AUTHKIT_CLIENT_ID = 'client_01KMZHB50KENM5SV90ZA80VXK4'; // WayAI CLI (public client, PKCE)
|
|
191
|
+
export function getAuthKitDomain() {
|
|
192
|
+
return process.env.WAYAI_AUTHKIT_DOMAIN || AUTHKIT_DOMAIN;
|
|
193
|
+
}
|
|
194
|
+
export function getAuthKitClientId() {
|
|
195
|
+
return process.env.WAYAI_AUTHKIT_CLIENT_ID || AUTHKIT_CLIENT_ID;
|
|
196
|
+
}
|
|
156
197
|
/**
|
|
157
198
|
* Get a valid access token from the current config.
|
|
158
|
-
*
|
|
199
|
+
* - For way_ tokens: returns directly (no refresh needed)
|
|
200
|
+
* - For OAuth JWT: checks expiry, refreshes if needed, updates config
|
|
159
201
|
*/
|
|
160
202
|
export async function getAccessToken(config) {
|
|
161
|
-
|
|
203
|
+
// way_ token path — no refresh needed
|
|
204
|
+
if (config.token) {
|
|
205
|
+
return config.token;
|
|
206
|
+
}
|
|
207
|
+
// OAuth JWT path — check expiry and refresh if needed
|
|
208
|
+
if (!config.access_token || !config.refresh_token) {
|
|
162
209
|
throw new Error('No token found. Run `wayai login` to authenticate.');
|
|
163
210
|
}
|
|
164
|
-
|
|
211
|
+
// Check if JWT is still valid (with 60s buffer)
|
|
212
|
+
if (!config.token_expires_at) {
|
|
213
|
+
// No expiry recorded — use the token as-is (don't unnecessarily refresh)
|
|
214
|
+
return config.access_token;
|
|
215
|
+
}
|
|
216
|
+
const expiresAt = new Date(config.token_expires_at).getTime();
|
|
217
|
+
if (expiresAt > Date.now() + 60_000) {
|
|
218
|
+
return config.access_token;
|
|
219
|
+
}
|
|
220
|
+
// Token expired — refresh
|
|
221
|
+
try {
|
|
222
|
+
const result = await refreshAccessToken(getAuthKitDomain(), getAuthKitClientId(), config.refresh_token);
|
|
223
|
+
// Atomically update config with new tokens
|
|
224
|
+
const updatedConfig = {
|
|
225
|
+
...config,
|
|
226
|
+
access_token: result.access_token,
|
|
227
|
+
token_expires_at: new Date(Date.now() + result.expires_in * 1000).toISOString(),
|
|
228
|
+
};
|
|
229
|
+
// Handle refresh token rotation
|
|
230
|
+
if (result.refresh_token) {
|
|
231
|
+
updatedConfig.refresh_token = result.refresh_token;
|
|
232
|
+
}
|
|
233
|
+
writeConfig(updatedConfig);
|
|
234
|
+
return result.access_token;
|
|
235
|
+
}
|
|
236
|
+
catch (err) {
|
|
237
|
+
if (err instanceof Error && err.message === 'SESSION_EXPIRED') {
|
|
238
|
+
// Clear stored tokens — user must re-login
|
|
239
|
+
writeConfig({ api_url: config.api_url });
|
|
240
|
+
throw new Error('Session expired. Please run `wayai login` again.');
|
|
241
|
+
}
|
|
242
|
+
throw err;
|
|
243
|
+
}
|
|
165
244
|
}
|
|
166
245
|
/**
|
|
167
246
|
* Read config and get access token, or exit with error.
|
package/dist/lib/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* CLI configuration management — reads/writes ~/.wayai/config.json
|
|
3
3
|
*/
|
|
4
|
+
/**
|
|
5
|
+
* CLI config supports two auth modes:
|
|
6
|
+
* - OAuth (browser login): access_token (JWT) + refresh_token + token_expires_at
|
|
7
|
+
* - Token (--token flag): token (way_ scoped token)
|
|
8
|
+
*/
|
|
4
9
|
export interface CliConfig {
|
|
5
10
|
api_url: string;
|
|
6
|
-
/**
|
|
7
|
-
token
|
|
11
|
+
/** way_ scoped token (from --token login) */
|
|
12
|
+
token?: string;
|
|
13
|
+
/** JWT access token (from OAuth browser login) */
|
|
14
|
+
access_token?: string;
|
|
15
|
+
/** OAuth refresh token */
|
|
16
|
+
refresh_token?: string;
|
|
17
|
+
/** ISO 8601 expiry of the access token */
|
|
18
|
+
token_expires_at?: string;
|
|
8
19
|
}
|
|
9
20
|
export declare function getConfigPath(): string;
|
|
10
21
|
export declare function readConfig(): CliConfig | null;
|
package/dist/lib/config.js
CHANGED
|
@@ -16,14 +16,11 @@ export function readConfig() {
|
|
|
16
16
|
try {
|
|
17
17
|
const content = fs.readFileSync(CONFIG_PATH, 'utf-8');
|
|
18
18
|
const parsed = JSON.parse(content);
|
|
19
|
-
//
|
|
20
|
-
if (
|
|
21
|
-
return
|
|
22
|
-
|
|
23
|
-
if (parsed.auth_method === 'oauth' && !parsed.token) {
|
|
24
|
-
// Legacy OAuth config — user needs to re-login
|
|
19
|
+
// Greenfield: reject old config formats — user must re-login
|
|
20
|
+
if (!parsed.api_url)
|
|
21
|
+
return null;
|
|
22
|
+
if (!parsed.token && !parsed.access_token)
|
|
25
23
|
return null;
|
|
26
|
-
}
|
|
27
24
|
return parsed;
|
|
28
25
|
}
|
|
29
26
|
catch {
|
package/dist/lib/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAmB9B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;AACrD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAEzD,MAAM,UAAU,aAAa;IAC3B,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAEnC,6DAA6D;QAC7D,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,YAAY;YAAE,OAAO,IAAI,CAAC;QAEvD,OAAO,MAAmB,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAiB;IAC3C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE;QACpE,IAAI,EAAE,KAAK,EAAE,wBAAwB;KACtC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/B,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC"}
|
package/dist/lib/eval-format.js
CHANGED
|
@@ -11,7 +11,7 @@ export function printResultsTable(results, mode) {
|
|
|
11
11
|
let totalPassed = 0;
|
|
12
12
|
let totalRuns = 0;
|
|
13
13
|
for (const r of results) {
|
|
14
|
-
const evalName = r.eval?.eval_name || r.
|
|
14
|
+
const evalName = r.eval?.eval_name || r.eval_id.slice(0, 8);
|
|
15
15
|
const passed = `${r.successful_runs}/${r.total_runs} passed`;
|
|
16
16
|
const avgTime = r.avg_execution_time_ms != null ? `avg ${(r.avg_execution_time_ms / 1000).toFixed(1)}s` : '';
|
|
17
17
|
let scoresStr = '';
|