@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.
Files changed (43) hide show
  1. package/dist/commands/login.d.ts +4 -0
  2. package/dist/commands/login.js +123 -0
  3. package/dist/commands/login.js.map +1 -0
  4. package/dist/commands/logout.d.ts +4 -0
  5. package/dist/commands/logout.js +14 -0
  6. package/dist/commands/logout.js.map +1 -0
  7. package/dist/commands/pull.d.ts +4 -0
  8. package/dist/commands/pull.js +73 -0
  9. package/dist/commands/pull.js.map +1 -0
  10. package/dist/commands/push.d.ts +4 -0
  11. package/dist/commands/push.js +90 -0
  12. package/dist/commands/push.js.map +1 -0
  13. package/dist/commands/status.d.ts +4 -0
  14. package/dist/commands/status.js +26 -0
  15. package/dist/commands/status.js.map +1 -0
  16. package/dist/index.d.ts +13 -0
  17. package/dist/index.js +90 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/lib/api-client.d.ts +18 -0
  20. package/dist/lib/api-client.js +50 -0
  21. package/dist/lib/api-client.js.map +1 -0
  22. package/dist/lib/auth.d.ts +59 -0
  23. package/dist/lib/auth.js +191 -0
  24. package/dist/lib/auth.js.map +1 -0
  25. package/dist/lib/config.d.ts +14 -0
  26. package/dist/lib/config.js +37 -0
  27. package/dist/lib/config.js.map +1 -0
  28. package/dist/lib/diff-display.d.ts +8 -0
  29. package/dist/lib/diff-display.js +37 -0
  30. package/dist/lib/diff-display.js.map +1 -0
  31. package/dist/lib/parser.d.ts +11 -0
  32. package/dist/lib/parser.js +64 -0
  33. package/dist/lib/parser.js.map +1 -0
  34. package/dist/lib/types.d.ts +106 -0
  35. package/dist/lib/types.js +5 -0
  36. package/dist/lib/types.js.map +1 -0
  37. package/dist/lib/utils.d.ts +16 -0
  38. package/dist/lib/utils.js +38 -0
  39. package/dist/lib/utils.js.map +1 -0
  40. package/dist/lib/yaml-writer.d.ts +13 -0
  41. package/dist/lib/yaml-writer.js +101 -0
  42. package/dist/lib/yaml-writer.js.map +1 -0
  43. package/package.json +41 -0
@@ -0,0 +1,4 @@
1
+ /**
2
+ * wayai login — OAuth browser flow (default) or --token fallback
3
+ */
4
+ export declare function loginCommand(args: string[]): Promise<void>;
@@ -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,4 @@
1
+ /**
2
+ * wayai logout — clear stored credentials
3
+ */
4
+ export declare function logoutCommand(): Promise<void>;
@@ -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,4 @@
1
+ /**
2
+ * wayai pull [hub-path] — fetch hub config from platform and write to local files
3
+ */
4
+ export declare function pullCommand(args: string[]): Promise<void>;
@@ -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,4 @@
1
+ /**
2
+ * wayai push [hub-path] — parse local files, diff remote, sync to preview
3
+ */
4
+ export declare function pushCommand(args: string[]): Promise<void>;
@@ -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,4 @@
1
+ /**
2
+ * wayai status — show current auth/config status
3
+ */
4
+ export declare function statusCommand(): Promise<void>;
@@ -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"}
@@ -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
+ }>;