@wayai/cli 0.1.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/dist/commands/login.d.ts +4 -0
- package/dist/commands/login.js +123 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +4 -0
- package/dist/commands/logout.js +14 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/pull.d.ts +4 -0
- package/dist/commands/pull.js +73 -0
- package/dist/commands/pull.js.map +1 -0
- package/dist/commands/push.d.ts +4 -0
- package/dist/commands/push.js +90 -0
- package/dist/commands/push.js.map +1 -0
- package/dist/commands/status.d.ts +4 -0
- package/dist/commands/status.js +26 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +90 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api-client.d.ts +18 -0
- package/dist/lib/api-client.js +50 -0
- package/dist/lib/api-client.js.map +1 -0
- package/dist/lib/auth.d.ts +59 -0
- package/dist/lib/auth.js +191 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/config.d.ts +14 -0
- package/dist/lib/config.js +37 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/diff-display.d.ts +8 -0
- package/dist/lib/diff-display.js +37 -0
- package/dist/lib/diff-display.js.map +1 -0
- package/dist/lib/parser.d.ts +11 -0
- package/dist/lib/parser.js +64 -0
- package/dist/lib/parser.js.map +1 -0
- package/dist/lib/types.d.ts +106 -0
- package/dist/lib/types.js +5 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/utils.d.ts +16 -0
- package/dist/lib/utils.js +38 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/lib/yaml-writer.d.ts +13 -0
- package/dist/lib/yaml-writer.js +101 -0
- package/dist/lib/yaml-writer.js.map +1 -0
- package/package.json +41 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* wayai login — OAuth browser flow (default) or --token fallback
|
|
3
|
+
*/
|
|
4
|
+
import * as readline from 'node:readline';
|
|
5
|
+
import { generatePKCE, findAvailablePort, startCallbackServer, exchangeCodeForTokens, exchangeMcpToken, fetchAuthConfig, } from '../lib/auth.js';
|
|
6
|
+
import { writeConfig } from '../lib/config.js';
|
|
7
|
+
function prompt(question, defaultValue) {
|
|
8
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
9
|
+
const display = defaultValue ? `${question} [${defaultValue}]: ` : `${question}: `;
|
|
10
|
+
return new Promise((resolve) => {
|
|
11
|
+
rl.question(display, (answer) => {
|
|
12
|
+
rl.close();
|
|
13
|
+
resolve(answer.trim() || defaultValue || '');
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
export async function loginCommand(args) {
|
|
18
|
+
const useToken = args.includes('--token');
|
|
19
|
+
if (useToken) {
|
|
20
|
+
await loginWithToken();
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
await loginWithOAuth();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async function loginWithOAuth() {
|
|
27
|
+
const apiUrl = await prompt('API URL', 'https://api.wayai.pro');
|
|
28
|
+
console.log('\nConnecting to WayAI...');
|
|
29
|
+
let supabaseUrl;
|
|
30
|
+
try {
|
|
31
|
+
const authConfig = await fetchAuthConfig(apiUrl);
|
|
32
|
+
supabaseUrl = authConfig.supabase_url;
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
console.error(`Failed to connect to ${apiUrl}: ${err instanceof Error ? err.message : String(err)}`);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
console.log('Starting OAuth login...');
|
|
39
|
+
const { codeVerifier, codeChallenge } = generatePKCE();
|
|
40
|
+
const port = await findAvailablePort();
|
|
41
|
+
const redirectUri = `http://127.0.0.1:${port}/callback`;
|
|
42
|
+
const authUrl = `${supabaseUrl}/auth/v1/authorize?provider=email&redirect_to=${encodeURIComponent(redirectUri)}&code_challenge=${codeChallenge}&code_challenge_method=S256`;
|
|
43
|
+
// Try to open browser
|
|
44
|
+
const openBrowser = await tryOpenBrowser(authUrl);
|
|
45
|
+
if (!openBrowser) {
|
|
46
|
+
console.log(`\nOpen this URL in your browser to log in:\n\n ${authUrl}\n`);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
console.log('Opening browser for login...');
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
const callbackPromise = startCallbackServer(port);
|
|
53
|
+
const { code } = await callbackPromise;
|
|
54
|
+
console.log('Exchanging authorization code for tokens...');
|
|
55
|
+
const { accessToken, refreshToken } = await exchangeCodeForTokens(supabaseUrl, code, codeVerifier);
|
|
56
|
+
writeConfig({
|
|
57
|
+
api_url: apiUrl,
|
|
58
|
+
supabase_url: supabaseUrl,
|
|
59
|
+
refresh_token: refreshToken,
|
|
60
|
+
auth_method: 'oauth',
|
|
61
|
+
});
|
|
62
|
+
// Suppress unused variable — token is validated by exchange
|
|
63
|
+
void accessToken;
|
|
64
|
+
console.log('\nLogin successful! Configuration saved to ~/.wayai/config.json');
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
console.error(`\nLogin failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async function loginWithToken() {
|
|
72
|
+
const apiUrl = await prompt('API URL', 'https://api.wayai.pro');
|
|
73
|
+
const mcpToken = await prompt('MCP Token (way_...)');
|
|
74
|
+
if (!mcpToken) {
|
|
75
|
+
console.error('MCP token is required.');
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
if (!mcpToken.startsWith('way_')) {
|
|
79
|
+
console.error('Invalid token format. MCP tokens start with "way_".');
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
console.log('\nValidating token...');
|
|
83
|
+
try {
|
|
84
|
+
await exchangeMcpToken(apiUrl, mcpToken);
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
console.error(`Token validation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
writeConfig({
|
|
91
|
+
api_url: apiUrl,
|
|
92
|
+
mcp_token: mcpToken,
|
|
93
|
+
auth_method: 'token',
|
|
94
|
+
});
|
|
95
|
+
console.log('\nLogin successful! Configuration saved to ~/.wayai/config.json');
|
|
96
|
+
}
|
|
97
|
+
async function tryOpenBrowser(url) {
|
|
98
|
+
// Skip in headless environments
|
|
99
|
+
if (process.env.SSH_CONNECTION || process.env.SSH_TTY) {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
const { exec } = await import('node:child_process');
|
|
104
|
+
const platform = process.platform;
|
|
105
|
+
let cmd;
|
|
106
|
+
if (platform === 'darwin') {
|
|
107
|
+
cmd = `open "${url}"`;
|
|
108
|
+
}
|
|
109
|
+
else if (platform === 'win32') {
|
|
110
|
+
cmd = `start "" "${url}"`;
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
cmd = `xdg-open "${url}"`;
|
|
114
|
+
}
|
|
115
|
+
return new Promise((resolve) => {
|
|
116
|
+
exec(cmd, (err) => resolve(!err));
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* wayai logout — clear stored credentials
|
|
3
|
+
*/
|
|
4
|
+
import { deleteConfig, readConfig } from '../lib/config.js';
|
|
5
|
+
export async function logoutCommand() {
|
|
6
|
+
const config = readConfig();
|
|
7
|
+
if (!config) {
|
|
8
|
+
console.log('Not logged in.');
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
deleteConfig();
|
|
12
|
+
console.log('Logged out. Configuration removed from ~/.wayai/config.json');
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=logout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE5D,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAC9B,OAAO;IACT,CAAC;IAED,YAAY,EAAE,CAAC;IACf,OAAO,CAAC,GAAG,CAAC,6DAA6D,CAAC,CAAC;AAC7E,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* wayai pull [hub-path] — fetch hub config from platform and write to local files
|
|
3
|
+
*/
|
|
4
|
+
import * as readline from 'node:readline';
|
|
5
|
+
import { requireAuth } from '../lib/auth.js';
|
|
6
|
+
import { ApiClient } from '../lib/api-client.js';
|
|
7
|
+
import { writeHubFolder } from '../lib/yaml-writer.js';
|
|
8
|
+
import { parseHubFolder } from '../lib/parser.js';
|
|
9
|
+
import { printDiff } from '../lib/diff-display.js';
|
|
10
|
+
import { detectHubFromCwd } from '../lib/utils.js';
|
|
11
|
+
function confirm(question) {
|
|
12
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
13
|
+
return new Promise((resolve) => {
|
|
14
|
+
rl.question(`${question} [y/N]: `, (answer) => {
|
|
15
|
+
rl.close();
|
|
16
|
+
resolve(answer.trim().toLowerCase() === 'y');
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
export async function pullCommand(args) {
|
|
21
|
+
const { config, accessToken } = await requireAuth();
|
|
22
|
+
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
23
|
+
const hubPath = args[0];
|
|
24
|
+
let hubId;
|
|
25
|
+
let hubFolder;
|
|
26
|
+
if (hubPath) {
|
|
27
|
+
// Resolve hub-path (org/project/hub) → hub_id
|
|
28
|
+
console.log(`Looking up ${hubPath}...`);
|
|
29
|
+
const lookup = await client.lookup(hubPath);
|
|
30
|
+
hubId = lookup.hub_id;
|
|
31
|
+
hubFolder = process.cwd();
|
|
32
|
+
console.log(`Found hub: ${lookup.hub_name} (${lookup.hub_environment}) in ${lookup.organization_name}/${lookup.project_name}`);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
// Try to detect from wayai.yaml in cwd
|
|
36
|
+
const detected = await detectHubFromCwd();
|
|
37
|
+
if (!detected) {
|
|
38
|
+
console.error('No hub path provided and no wayai.yaml found in current directory.');
|
|
39
|
+
console.error('Usage: wayai pull <org/project/hub>');
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
hubId = detected.hubId;
|
|
43
|
+
hubFolder = detected.hubFolder;
|
|
44
|
+
console.log(`Using hub from wayai.yaml: ${hubId}`);
|
|
45
|
+
}
|
|
46
|
+
// Fetch remote config
|
|
47
|
+
console.log('Fetching hub configuration...');
|
|
48
|
+
const payload = await client.pull(hubId);
|
|
49
|
+
// If local files exist, show diff before overwriting
|
|
50
|
+
try {
|
|
51
|
+
const localPayload = parseHubFolder(hubFolder);
|
|
52
|
+
// Use the diff endpoint to compare remote vs local
|
|
53
|
+
const diffResult = await client.diff(hubId, localPayload, 'pull');
|
|
54
|
+
if (!diffResult.has_changes) {
|
|
55
|
+
console.log('No changes — local files are up to date.');
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
console.log('\nChanges to apply locally:');
|
|
59
|
+
printDiff(diffResult.summary);
|
|
60
|
+
const ok = await confirm('Apply these changes?');
|
|
61
|
+
if (!ok) {
|
|
62
|
+
console.log('Cancelled.');
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
// No local files exist or they can't be parsed — first pull
|
|
68
|
+
console.log('Writing hub configuration...');
|
|
69
|
+
}
|
|
70
|
+
writeHubFolder(hubFolder, payload);
|
|
71
|
+
console.log(`Hub configuration written to ${hubFolder}`);
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=pull.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pull.js","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* wayai push [hub-path] — parse local files, diff remote, sync to preview
|
|
3
|
+
*/
|
|
4
|
+
import * as readline from 'node:readline';
|
|
5
|
+
import { requireAuth } from '../lib/auth.js';
|
|
6
|
+
import { ApiClient } from '../lib/api-client.js';
|
|
7
|
+
import { parseHubFolder } from '../lib/parser.js';
|
|
8
|
+
import { printDiff } from '../lib/diff-display.js';
|
|
9
|
+
import { detectHubFromCwd } from '../lib/utils.js';
|
|
10
|
+
function confirm(question) {
|
|
11
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
12
|
+
return new Promise((resolve) => {
|
|
13
|
+
rl.question(`${question} [y/N]: `, (answer) => {
|
|
14
|
+
rl.close();
|
|
15
|
+
resolve(answer.trim().toLowerCase() === 'y');
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
export async function pushCommand(args) {
|
|
20
|
+
const { config, accessToken } = await requireAuth();
|
|
21
|
+
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
22
|
+
const hubPath = args[0];
|
|
23
|
+
let hubId;
|
|
24
|
+
let hubFolder;
|
|
25
|
+
if (hubPath) {
|
|
26
|
+
console.log(`Looking up ${hubPath}...`);
|
|
27
|
+
const lookup = await client.lookup(hubPath);
|
|
28
|
+
hubId = lookup.hub_id;
|
|
29
|
+
hubFolder = process.cwd();
|
|
30
|
+
console.log(`Found hub: ${lookup.hub_name} (${lookup.hub_environment}) in ${lookup.organization_name}/${lookup.project_name}`);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
const detected = await detectHubFromCwd();
|
|
34
|
+
if (!detected) {
|
|
35
|
+
console.error('No hub path provided and no wayai.yaml found in current directory.');
|
|
36
|
+
console.error('Usage: wayai push <org/project/hub>');
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
hubId = detected.hubId;
|
|
40
|
+
hubFolder = detected.hubFolder;
|
|
41
|
+
console.log(`Using hub from wayai.yaml: ${hubId}`);
|
|
42
|
+
}
|
|
43
|
+
// Parse local files
|
|
44
|
+
console.log('Parsing local configuration...');
|
|
45
|
+
const localConfig = parseHubFolder(hubFolder);
|
|
46
|
+
// Get diff preview
|
|
47
|
+
console.log('Computing diff...');
|
|
48
|
+
const diffResult = await client.diff(hubId, localConfig, 'push');
|
|
49
|
+
if (!diffResult.has_changes) {
|
|
50
|
+
console.log('No changes to push.');
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
console.log('\nChanges to push:');
|
|
54
|
+
printDiff(diffResult.summary);
|
|
55
|
+
const ok = await confirm('Push these changes?');
|
|
56
|
+
if (!ok) {
|
|
57
|
+
console.log('Cancelled.');
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
// Sync to a CLI branch preview
|
|
61
|
+
console.log('Syncing changes...');
|
|
62
|
+
const result = await client.sync(hubId, 'cli', localConfig);
|
|
63
|
+
console.log(`\nSync complete. Preview hub: ${result.preview_hub_id}`);
|
|
64
|
+
const c = result.changes;
|
|
65
|
+
const parts = [];
|
|
66
|
+
if (c.hub_updated)
|
|
67
|
+
parts.push('hub updated');
|
|
68
|
+
if (c.agents_created > 0)
|
|
69
|
+
parts.push(`${c.agents_created} agent(s) created`);
|
|
70
|
+
if (c.agents_updated > 0)
|
|
71
|
+
parts.push(`${c.agents_updated} agent(s) updated`);
|
|
72
|
+
if (c.agents_deleted > 0)
|
|
73
|
+
parts.push(`${c.agents_deleted} agent(s) deleted`);
|
|
74
|
+
if (c.tools_created > 0)
|
|
75
|
+
parts.push(`${c.tools_created} tool(s) created`);
|
|
76
|
+
if (c.tools_updated > 0)
|
|
77
|
+
parts.push(`${c.tools_updated} tool(s) updated`);
|
|
78
|
+
if (c.tools_deleted > 0)
|
|
79
|
+
parts.push(`${c.tools_deleted} tool(s) deleted`);
|
|
80
|
+
if (c.states_created > 0)
|
|
81
|
+
parts.push(`${c.states_created} state(s) created`);
|
|
82
|
+
if (c.states_updated > 0)
|
|
83
|
+
parts.push(`${c.states_updated} state(s) updated`);
|
|
84
|
+
if (c.states_deleted > 0)
|
|
85
|
+
parts.push(`${c.states_deleted} state(s) deleted`);
|
|
86
|
+
if (parts.length > 0) {
|
|
87
|
+
console.log(`Changes: ${parts.join(', ')}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=push.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* wayai status — show current auth/config status
|
|
3
|
+
*/
|
|
4
|
+
import { readConfig } from '../lib/config.js';
|
|
5
|
+
import { getAccessToken } from '../lib/auth.js';
|
|
6
|
+
export async function statusCommand() {
|
|
7
|
+
const config = readConfig();
|
|
8
|
+
if (!config) {
|
|
9
|
+
console.log('Not logged in. Run `wayai login`.');
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
console.log(`Auth method: ${config.auth_method}`);
|
|
13
|
+
console.log(`API URL: ${config.api_url}`);
|
|
14
|
+
if (config.supabase_url) {
|
|
15
|
+
console.log(`Supabase URL: ${config.supabase_url}`);
|
|
16
|
+
}
|
|
17
|
+
// Test token validity
|
|
18
|
+
try {
|
|
19
|
+
await getAccessToken(config);
|
|
20
|
+
console.log(`Token: valid`);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
console.log(`Token: expired (run \`wayai login\` to re-authenticate)`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAE5B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;QACjD,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,iBAAiB,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,iBAAiB,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAC/C,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,iBAAiB,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,sBAAsB;IACtB,IAAI,CAAC;QACH,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,gEAAgE,CAAC,CAAC;IAChF,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @wayai/cli — sync hub configuration between local files and the platform
|
|
4
|
+
*
|
|
5
|
+
* Commands:
|
|
6
|
+
* wayai login — authenticate via OAuth (browser)
|
|
7
|
+
* wayai login --token — authenticate via MCP token (headless)
|
|
8
|
+
* wayai logout — clear stored credentials
|
|
9
|
+
* wayai status — show current auth/config status
|
|
10
|
+
* wayai pull [path] — fetch hub config and write local files
|
|
11
|
+
* wayai push [path] — parse local files, diff, and sync to preview
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @wayai/cli — sync hub configuration between local files and the platform
|
|
4
|
+
*
|
|
5
|
+
* Commands:
|
|
6
|
+
* wayai login — authenticate via OAuth (browser)
|
|
7
|
+
* wayai login --token — authenticate via MCP token (headless)
|
|
8
|
+
* wayai logout — clear stored credentials
|
|
9
|
+
* wayai status — show current auth/config status
|
|
10
|
+
* wayai pull [path] — fetch hub config and write local files
|
|
11
|
+
* wayai push [path] — parse local files, diff, and sync to preview
|
|
12
|
+
*/
|
|
13
|
+
import { readFileSync } from 'node:fs';
|
|
14
|
+
import { fileURLToPath } from 'node:url';
|
|
15
|
+
import { dirname, join } from 'node:path';
|
|
16
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
17
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));
|
|
18
|
+
const [, , command, ...args] = process.argv;
|
|
19
|
+
async function main() {
|
|
20
|
+
switch (command) {
|
|
21
|
+
case 'login': {
|
|
22
|
+
const { loginCommand } = await import('./commands/login.js');
|
|
23
|
+
await loginCommand(args);
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
case 'logout': {
|
|
27
|
+
const { logoutCommand } = await import('./commands/logout.js');
|
|
28
|
+
await logoutCommand();
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
case 'status': {
|
|
32
|
+
const { statusCommand } = await import('./commands/status.js');
|
|
33
|
+
await statusCommand();
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
case 'pull': {
|
|
37
|
+
const { pullCommand } = await import('./commands/pull.js');
|
|
38
|
+
await pullCommand(args);
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
case 'push': {
|
|
42
|
+
const { pushCommand } = await import('./commands/push.js');
|
|
43
|
+
await pushCommand(args);
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
case 'help':
|
|
47
|
+
case '--help':
|
|
48
|
+
case '-h':
|
|
49
|
+
case undefined:
|
|
50
|
+
printHelp();
|
|
51
|
+
break;
|
|
52
|
+
case '--version':
|
|
53
|
+
case '-v':
|
|
54
|
+
console.log(pkg.version);
|
|
55
|
+
break;
|
|
56
|
+
default:
|
|
57
|
+
console.error(`Unknown command: ${command}`);
|
|
58
|
+
printHelp();
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function printHelp() {
|
|
63
|
+
console.log(`
|
|
64
|
+
wayai — WayAI CLI
|
|
65
|
+
|
|
66
|
+
Usage:
|
|
67
|
+
wayai <command> [options]
|
|
68
|
+
|
|
69
|
+
Commands:
|
|
70
|
+
login Authenticate via OAuth (opens browser)
|
|
71
|
+
login --token Authenticate via MCP token (for headless/CI)
|
|
72
|
+
logout Clear stored credentials
|
|
73
|
+
status Show current auth and config status
|
|
74
|
+
pull [path] Fetch hub config and write local files
|
|
75
|
+
push [path] Parse local files, show diff, sync to preview
|
|
76
|
+
|
|
77
|
+
Arguments:
|
|
78
|
+
path Hub path as org/project/hub (optional if wayai.yaml exists in cwd)
|
|
79
|
+
|
|
80
|
+
Examples:
|
|
81
|
+
wayai login
|
|
82
|
+
wayai pull acme/support/customer-hub
|
|
83
|
+
wayai push
|
|
84
|
+
`.trim());
|
|
85
|
+
}
|
|
86
|
+
main().catch((err) => {
|
|
87
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
88
|
+
process.exit(1);
|
|
89
|
+
});
|
|
90
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AAErF,MAAM,CAAC,EAAC,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;AAE3C,KAAK,UAAU,IAAI;IACjB,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;YAC7D,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;YACzB,MAAM;QACR,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;YAC/D,MAAM,aAAa,EAAE,CAAC;YACtB,MAAM;QACR,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;YAC/D,MAAM,aAAa,EAAE,CAAC;YACtB,MAAM;QACR,CAAC;QACD,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;YAC3D,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;YACxB,MAAM;QACR,CAAC;QACD,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;YAC3D,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;YACxB,MAAM;QACR,CAAC;QACD,KAAK,MAAM,CAAC;QACZ,KAAK,QAAQ,CAAC;QACd,KAAK,IAAI,CAAC;QACV,KAAK,SAAS;YACZ,SAAS,EAAE,CAAC;YACZ,MAAM;QACR,KAAK,WAAW,CAAC;QACjB,KAAK,IAAI;YACP,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACzB,MAAM;QACR;YACE,OAAO,CAAC,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;YAC7C,SAAS,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACH,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;GAqBX,CAAC,IAAI,EAAE,CAAC,CAAC;AACZ,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API client — authenticated requests to the WayAI backend
|
|
3
|
+
*/
|
|
4
|
+
import type { HubAsCodePayload, CiDiffResponse, CiLookupResponse, CiSyncResponse } from './types.js';
|
|
5
|
+
export interface ApiClientOptions {
|
|
6
|
+
apiUrl: string;
|
|
7
|
+
accessToken: string;
|
|
8
|
+
}
|
|
9
|
+
export declare class ApiClient {
|
|
10
|
+
private apiUrl;
|
|
11
|
+
private accessToken;
|
|
12
|
+
constructor(options: ApiClientOptions);
|
|
13
|
+
pull(hubId: string): Promise<HubAsCodePayload>;
|
|
14
|
+
diff(hubId: string, config: HubAsCodePayload, direction?: 'push' | 'pull'): Promise<CiDiffResponse>;
|
|
15
|
+
sync(hubId: string, branchName: string, config: HubAsCodePayload, commitSha?: string): Promise<CiSyncResponse>;
|
|
16
|
+
lookup(path: string): Promise<CiLookupResponse>;
|
|
17
|
+
private request;
|
|
18
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API client — authenticated requests to the WayAI backend
|
|
3
|
+
*/
|
|
4
|
+
export class ApiClient {
|
|
5
|
+
apiUrl;
|
|
6
|
+
accessToken;
|
|
7
|
+
constructor(options) {
|
|
8
|
+
this.apiUrl = options.apiUrl;
|
|
9
|
+
this.accessToken = options.accessToken;
|
|
10
|
+
}
|
|
11
|
+
async pull(hubId) {
|
|
12
|
+
return this.request('GET', `/api/ci/pull/${hubId}`);
|
|
13
|
+
}
|
|
14
|
+
async diff(hubId, config, direction = 'push') {
|
|
15
|
+
return this.request('POST', '/api/ci/diff', {
|
|
16
|
+
hub_id: hubId,
|
|
17
|
+
config,
|
|
18
|
+
direction,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
async sync(hubId, branchName, config, commitSha) {
|
|
22
|
+
return this.request('POST', '/api/ci/sync', {
|
|
23
|
+
hub_id: hubId,
|
|
24
|
+
branch_name: branchName,
|
|
25
|
+
config,
|
|
26
|
+
commit_sha: commitSha,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
async lookup(path) {
|
|
30
|
+
return this.request('GET', `/api/ci/lookup?path=${encodeURIComponent(path)}`);
|
|
31
|
+
}
|
|
32
|
+
async request(method, path, body) {
|
|
33
|
+
const url = `${this.apiUrl}${path}`;
|
|
34
|
+
const headers = {
|
|
35
|
+
Authorization: `Bearer ${this.accessToken}`,
|
|
36
|
+
'Content-Type': 'application/json',
|
|
37
|
+
};
|
|
38
|
+
const response = await fetch(url, {
|
|
39
|
+
method,
|
|
40
|
+
headers,
|
|
41
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
42
|
+
});
|
|
43
|
+
if (!response.ok) {
|
|
44
|
+
const errorBody = await response.text();
|
|
45
|
+
throw new Error(`API request failed: ${method} ${path} (${response.status}): ${errorBody}`);
|
|
46
|
+
}
|
|
47
|
+
return response.json();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/lib/api-client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH,MAAM,OAAO,SAAS;IACZ,MAAM,CAAS;IACf,WAAW,CAAS;IAE5B,YAAY,OAAyB;QACnC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAa;QACtB,OAAO,IAAI,CAAC,OAAO,CAAmB,KAAK,EAAE,gBAAgB,KAAK,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAa,EAAE,MAAwB,EAAE,YAA6B,MAAM;QACrF,OAAO,IAAI,CAAC,OAAO,CAAiB,MAAM,EAAE,cAAc,EAAE;YAC1D,MAAM,EAAE,KAAK;YACb,MAAM;YACN,SAAS;SACV,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAa,EAAE,UAAkB,EAAE,MAAwB,EAAE,SAAkB;QACxF,OAAO,IAAI,CAAC,OAAO,CAAiB,MAAM,EAAE,cAAc,EAAE;YAC1D,MAAM,EAAE,KAAK;YACb,WAAW,EAAE,UAAU;YACvB,MAAM;YACN,UAAU,EAAE,SAAS;SACtB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,OAAO,IAAI,CAAC,OAAO,CAAmB,KAAK,EAAE,uBAAuB,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAClG,CAAC;IAEO,KAAK,CAAC,OAAO,CAAI,MAAc,EAAE,IAAY,EAAE,IAAc;QACnE,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,EAAE,CAAC;QACpC,MAAM,OAAO,GAA2B;YACtC,aAAa,EAAE,UAAU,IAAI,CAAC,WAAW,EAAE;YAC3C,cAAc,EAAE,kBAAkB;SACnC,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM;YACN,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;SAC9C,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,uBAAuB,MAAM,IAAI,IAAI,KAAK,QAAQ,CAAC,MAAM,MAAM,SAAS,EAAE,CAAC,CAAC;QAC9F,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,EAAgB,CAAC;IACvC,CAAC;CACF"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication — OAuth PKCE flow + MCP token fallback
|
|
3
|
+
*/
|
|
4
|
+
import type { CliConfig } from './config.js';
|
|
5
|
+
/**
|
|
6
|
+
* Fetch auth configuration from the backend (Supabase URL, etc.)
|
|
7
|
+
*/
|
|
8
|
+
export declare function fetchAuthConfig(apiUrl: string): Promise<{
|
|
9
|
+
supabase_url: string;
|
|
10
|
+
}>;
|
|
11
|
+
/**
|
|
12
|
+
* Generate PKCE code_verifier and code_challenge for OAuth
|
|
13
|
+
*/
|
|
14
|
+
export declare function generatePKCE(): {
|
|
15
|
+
codeVerifier: string;
|
|
16
|
+
codeChallenge: string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Start a local HTTP server that waits for the OAuth callback.
|
|
20
|
+
* Returns the authorization code received.
|
|
21
|
+
*/
|
|
22
|
+
export declare function startCallbackServer(port: number, timeoutMs?: number): Promise<{
|
|
23
|
+
code: string;
|
|
24
|
+
port: number;
|
|
25
|
+
}>;
|
|
26
|
+
/**
|
|
27
|
+
* Find an available port by trying to listen on port 0
|
|
28
|
+
*/
|
|
29
|
+
export declare function findAvailablePort(): Promise<number>;
|
|
30
|
+
/**
|
|
31
|
+
* Exchange PKCE authorization code for tokens
|
|
32
|
+
*/
|
|
33
|
+
export declare function exchangeCodeForTokens(supabaseUrl: string, code: string, codeVerifier: string): Promise<{
|
|
34
|
+
accessToken: string;
|
|
35
|
+
refreshToken: string;
|
|
36
|
+
}>;
|
|
37
|
+
/**
|
|
38
|
+
* Refresh an OAuth access token using a refresh token
|
|
39
|
+
*/
|
|
40
|
+
export declare function refreshAccessToken(supabaseUrl: string, refreshToken: string): Promise<{
|
|
41
|
+
accessToken: string;
|
|
42
|
+
refreshToken: string;
|
|
43
|
+
}>;
|
|
44
|
+
/**
|
|
45
|
+
* Exchange MCP token for a JWT via the backend
|
|
46
|
+
*/
|
|
47
|
+
export declare function exchangeMcpToken(apiUrl: string, mcpToken: string): Promise<string>;
|
|
48
|
+
/**
|
|
49
|
+
* Get a valid access token from the current config.
|
|
50
|
+
* Handles refresh for both OAuth and token auth methods.
|
|
51
|
+
*/
|
|
52
|
+
export declare function getAccessToken(config: CliConfig): Promise<string>;
|
|
53
|
+
/**
|
|
54
|
+
* Read config and get access token, or exit with error.
|
|
55
|
+
*/
|
|
56
|
+
export declare function requireAuth(): Promise<{
|
|
57
|
+
config: CliConfig;
|
|
58
|
+
accessToken: string;
|
|
59
|
+
}>;
|