@clawapps/cli 0.5.0 → 0.6.1

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 (97) hide show
  1. package/README.md +86 -123
  2. package/dist/commands/balance.d.ts +3 -0
  3. package/dist/commands/balance.js +31 -0
  4. package/dist/commands/balance.js.map +1 -0
  5. package/dist/commands/connect.d.ts +7 -0
  6. package/dist/commands/connect.js +143 -0
  7. package/dist/commands/connect.js.map +1 -0
  8. package/dist/commands/helpers/resolve-credentials.d.ts +12 -0
  9. package/dist/commands/helpers/resolve-credentials.js +29 -0
  10. package/dist/commands/helpers/resolve-credentials.js.map +1 -0
  11. package/dist/commands/login-code.d.ts +5 -0
  12. package/dist/commands/login-code.js +25 -0
  13. package/dist/commands/login-code.js.map +1 -0
  14. package/dist/commands/login-poll.d.ts +5 -0
  15. package/dist/commands/login-poll.js +30 -0
  16. package/dist/commands/login-poll.js.map +1 -0
  17. package/dist/commands/login.d.ts +3 -1
  18. package/dist/commands/login.js +72 -49
  19. package/dist/commands/login.js.map +1 -1
  20. package/dist/commands/logout.js +3 -18
  21. package/dist/commands/logout.js.map +1 -1
  22. package/dist/commands/send.d.ts +8 -0
  23. package/dist/commands/send.js +112 -0
  24. package/dist/commands/send.js.map +1 -0
  25. package/dist/commands/sessions.d.ts +6 -0
  26. package/dist/commands/sessions.js +36 -0
  27. package/dist/commands/sessions.js.map +1 -0
  28. package/dist/index.js +49 -30
  29. package/dist/index.js.map +1 -1
  30. package/dist/lib/config.d.ts +4 -15
  31. package/dist/lib/config.js +6 -21
  32. package/dist/lib/config.js.map +1 -1
  33. package/dist/lib/login-service.d.ts +23 -0
  34. package/dist/lib/login-service.js +68 -0
  35. package/dist/lib/login-service.js.map +1 -0
  36. package/dist/lib/relay-client.d.ts +25 -0
  37. package/dist/lib/relay-client.js +113 -0
  38. package/dist/lib/relay-client.js.map +1 -0
  39. package/dist/lib/sse-parser.d.ts +12 -0
  40. package/dist/lib/sse-parser.js +61 -0
  41. package/dist/lib/sse-parser.js.map +1 -0
  42. package/dist/lib/types.d.ts +17 -27
  43. package/package.json +3 -2
  44. package/dist/auth/apple.d.ts +0 -5
  45. package/dist/auth/apple.js +0 -15
  46. package/dist/auth/apple.js.map +0 -1
  47. package/dist/auth/exchange.d.ts +0 -6
  48. package/dist/auth/exchange.js +0 -25
  49. package/dist/auth/exchange.js.map +0 -1
  50. package/dist/auth/google.d.ts +0 -5
  51. package/dist/auth/google.js +0 -16
  52. package/dist/auth/google.js.map +0 -1
  53. package/dist/auth/login-server.d.ts +0 -10
  54. package/dist/auth/login-server.js +0 -62
  55. package/dist/auth/login-server.js.map +0 -1
  56. package/dist/auth/payment-server.d.ts +0 -10
  57. package/dist/auth/payment-server.js +0 -66
  58. package/dist/auth/payment-server.js.map +0 -1
  59. package/dist/auth/qr-poll.d.ts +0 -32
  60. package/dist/auth/qr-poll.js +0 -72
  61. package/dist/auth/qr-poll.js.map +0 -1
  62. package/dist/auth/server.d.ts +0 -17
  63. package/dist/auth/server.js +0 -102
  64. package/dist/auth/server.js.map +0 -1
  65. package/dist/commands/credit.d.ts +0 -1
  66. package/dist/commands/credit.js +0 -28
  67. package/dist/commands/credit.js.map +0 -1
  68. package/dist/commands/helpers/ensure-token.d.ts +0 -6
  69. package/dist/commands/helpers/ensure-token.js +0 -29
  70. package/dist/commands/helpers/ensure-token.js.map +0 -1
  71. package/dist/commands/membership.d.ts +0 -1
  72. package/dist/commands/membership.js +0 -28
  73. package/dist/commands/membership.js.map +0 -1
  74. package/dist/commands/payment-grant.d.ts +0 -1
  75. package/dist/commands/payment-grant.js +0 -56
  76. package/dist/commands/payment-grant.js.map +0 -1
  77. package/dist/commands/recharge-credits.d.ts +0 -1
  78. package/dist/commands/recharge-credits.js +0 -10
  79. package/dist/commands/recharge-credits.js.map +0 -1
  80. package/dist/commands/subscribe.d.ts +0 -1
  81. package/dist/commands/subscribe.js +0 -10
  82. package/dist/commands/subscribe.js.map +0 -1
  83. package/dist/commands/token.d.ts +0 -1
  84. package/dist/commands/token.js +0 -17
  85. package/dist/commands/token.js.map +0 -1
  86. package/dist/commands/whoami.d.ts +0 -1
  87. package/dist/commands/whoami.js +0 -59
  88. package/dist/commands/whoami.js.map +0 -1
  89. package/dist/html/callback.d.ts +0 -12
  90. package/dist/html/callback.js +0 -246
  91. package/dist/html/callback.js.map +0 -1
  92. package/dist/html/logo-data.d.ts +0 -1
  93. package/dist/html/logo-data.js +0 -2
  94. package/dist/html/logo-data.js.map +0 -1
  95. package/dist/lib/api.d.ts +0 -13
  96. package/dist/lib/api.js +0 -26
  97. package/dist/lib/api.js.map +0 -1
@@ -1,73 +1,96 @@
1
1
  import chalk from 'chalk';
2
2
  import ora from 'ora';
3
- import { loadCredentials, saveCredentials } from '../lib/credentials.js';
4
- import { apiGet } from '../lib/api.js';
5
- import { CONFIG } from '../lib/config.js';
6
- import { ensureValidToken } from './helpers/ensure-token.js';
7
- import { createLoginCode, displayQRCode, pollAuthCode } from '../auth/qr-poll.js';
8
- export async function loginCommand() {
9
- // Check if already logged in, refresh token if needed
3
+ import qrcode from 'qrcode-terminal';
4
+ import { loadCredentials } from '../lib/credentials.js';
5
+ import { getBalance } from '../lib/relay-client.js';
6
+ import { createLoginCode, pollLoginCode } from '../lib/login-service.js';
7
+ function jsonOut(obj) {
8
+ process.stdout.write(JSON.stringify(obj) + '\n');
9
+ }
10
+ export async function loginCommand(options) {
11
+ const isJson = !!options.json;
12
+ // Check if already logged in
10
13
  const existing = await loadCredentials();
11
14
  if (existing) {
12
15
  try {
13
- const validated = await ensureValidToken(existing);
14
- if (validated) {
15
- const res = await apiGet(CONFIG.CLAW_ME, validated.access_token);
16
- if (res.ok) {
17
- const user = res.data.data;
18
- console.log(chalk.green(`Already logged in as ${chalk.bold(user.email || user.name || 'user')}.`));
19
- console.log(chalk.gray('Session refreshed. Run `clawapps logout` first to switch accounts.'));
20
- return;
21
- }
16
+ const balance = await getBalance(existing.access_token);
17
+ if (isJson) {
18
+ jsonOut({ event: 'already_logged_in', display_name: balance.display_name });
19
+ }
20
+ else {
21
+ console.log(chalk.green(`Already logged in as ${chalk.bold(balance.display_name || 'user')}.`));
22
+ console.log(chalk.gray('Run `clawapps logout` first to switch accounts.'));
22
23
  }
24
+ return;
23
25
  }
24
26
  catch {
25
- // Token validation/refresh failed, continue with login
27
+ // Token invalid, continue with login
26
28
  }
27
29
  }
28
- // Create login code via API and display QR code
30
+ // Create login code
29
31
  let loginCode;
30
32
  try {
31
33
  loginCode = await createLoginCode();
32
34
  }
33
35
  catch (err) {
34
- const message = err instanceof Error ? err.message : 'Unknown error';
35
- console.error(chalk.red(`\nFailed to create login code: ${message}`));
36
+ const msg = err instanceof Error ? err.message : String(err);
37
+ if (isJson) {
38
+ jsonOut({ event: 'error', code: 'LOGIN_CODE_FAILED', message: msg });
39
+ }
40
+ else {
41
+ console.error(chalk.red(`Failed to create login code: ${msg}`));
42
+ }
36
43
  process.exit(1);
37
44
  }
38
- console.log(chalk.gray('\nScan the QR code to login:\n'));
39
- displayQRCode(loginCode.qr_url);
40
- console.log(chalk.gray(`\nOr visit: ${loginCode.qr_url}\n`));
41
- console.log(chalk.yellow('Waiting for QR code verification (valid for 3 minutes)...\n'));
42
- const spinner = ora('Waiting for authentication...').start();
43
- try {
44
- const result = await pollAuthCode(loginCode.code, 'login');
45
- // Save credentials
46
- await saveCredentials({
47
- provider: 'google', // web login handles provider selection
48
- access_token: result.access_token,
49
- refresh_token: result.refresh_token,
50
- logged_in_at: new Date().toISOString(),
45
+ // Display login info
46
+ if (isJson) {
47
+ jsonOut({
48
+ event: 'login_url',
49
+ url: loginCode.qr_url,
50
+ qr_image: loginCode.qr_image,
51
+ expires_at: loginCode.expires_at,
52
+ instructions: 'Show the URL and QR image to the user. They need to open the link or scan the QR code with WeChat to authenticate.',
51
53
  });
52
- spinner.text = 'Fetching user info...';
53
- const userRes = await apiGet(CONFIG.CLAW_ME, result.access_token);
54
- spinner.stop();
55
- console.log(chalk.green('\nLogin successful!'));
56
- console.log(chalk.gray(`Access Token: ${result.access_token}`));
57
- if (userRes.ok) {
58
- const user = userRes.data.data;
59
- const name = user.name || user.email || 'user';
60
- console.log(chalk.gray(`User: ${name}`));
61
- if (user.email) {
62
- console.log(chalk.gray(`Email: ${user.email}`));
54
+ }
55
+ else {
56
+ console.log(chalk.bold('\nLogin URL:'));
57
+ console.log(chalk.cyan(loginCode.qr_url));
58
+ console.log();
59
+ qrcode.generate(loginCode.qr_url, { small: true });
60
+ console.log(chalk.gray('\nOpen the link or scan QR code with WeChat to authenticate.'));
61
+ console.log(chalk.yellow('Waiting for verification (valid for 3 minutes)...\n'));
62
+ }
63
+ // Poll for verification
64
+ const spinner = isJson ? null : ora('Waiting for authentication...').start();
65
+ const result = await pollLoginCode(loginCode.code, (remaining) => {
66
+ if (spinner) {
67
+ const min = Math.floor(remaining / 60);
68
+ const sec = remaining % 60;
69
+ spinner.text = `Waiting for authentication... ${min}:${sec.toString().padStart(2, '0')}`;
70
+ }
71
+ else if (remaining % 30 === 0) {
72
+ jsonOut({ event: 'waiting', remaining });
73
+ }
74
+ });
75
+ spinner?.stop();
76
+ if (result.success) {
77
+ if (isJson) {
78
+ jsonOut({ event: 'login_success', display_name: result.display_name || null });
79
+ }
80
+ else {
81
+ console.log(chalk.green('\nLogin successful!'));
82
+ if (result.display_name) {
83
+ console.log(chalk.gray(`User: ${result.display_name}`));
63
84
  }
64
85
  }
65
86
  }
66
- catch (err) {
67
- spinner.stop();
68
- const message = err instanceof Error ? err.message : 'Unknown error';
69
- console.error(chalk.red(`\nLogin failed: ${message}`));
70
- console.error(chalk.yellow('QR code has expired. Please run `clawapps login` to generate a new one.'));
87
+ else {
88
+ if (isJson) {
89
+ jsonOut({ event: 'error', code: 'LOGIN_FAILED', message: result.error });
90
+ }
91
+ else {
92
+ console.error(chalk.red(`\n${result.error}. Run \`clawapps login\` to try again.`));
93
+ }
71
94
  process.exit(1);
72
95
  }
73
96
  }
@@ -1 +1 @@
1
- {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
@@ -1,24 +1,9 @@
1
1
  import chalk from 'chalk';
2
- import ora from 'ora';
3
- import { loadCredentials, clearCredentials } from '../lib/credentials.js';
4
- import { apiPost } from '../lib/api.js';
5
- import { CONFIG } from '../lib/config.js';
2
+ import { clearCredentials } from '../lib/credentials.js';
3
+ import { clearSessions } from '../lib/relay-client.js';
6
4
  export async function logoutCommand() {
7
- const credentials = await loadCredentials();
8
- if (!credentials) {
9
- console.log(chalk.yellow('Not logged in.'));
10
- return;
11
- }
12
- const spinner = ora('Logging out...').start();
13
- try {
14
- // Call server-side logout
15
- await apiPost(CONFIG.CLAW_LOGOUT, { refresh_token: credentials.refresh_token }, credentials.access_token);
16
- }
17
- catch {
18
- // Ignore API errors — we still clear local credentials
19
- }
20
5
  await clearCredentials();
21
- spinner.stop();
6
+ await clearSessions();
22
7
  console.log(chalk.green('Logged out successfully.'));
23
8
  }
24
9
  //# sourceMappingURL=logout.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,WAAW,GAAG,MAAM,eAAe,EAAE,CAAC;IAE5C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC;QAC5C,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,gBAAgB,CAAC,CAAC,KAAK,EAAE,CAAC;IAE9C,IAAI,CAAC;QACH,0BAA0B;QAC1B,MAAM,OAAO,CACX,MAAM,CAAC,WAAW,EAClB,EAAE,aAAa,EAAE,WAAW,CAAC,aAAa,EAAE,EAC5C,WAAW,CAAC,YAAY,CACzB,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,uDAAuD;IACzD,CAAC;IAED,MAAM,gBAAgB,EAAE,CAAC;IACzB,OAAO,CAAC,IAAI,EAAE,CAAC;IAEf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC,CAAC;AACvD,CAAC"}
1
+ {"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,gBAAgB,EAAE,CAAC;IACzB,MAAM,aAAa,EAAE,CAAC;IACtB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC,CAAC;AACvD,CAAC"}
@@ -0,0 +1,8 @@
1
+ interface SendOptions {
2
+ sessionId?: string;
3
+ newSession?: boolean;
4
+ json?: boolean;
5
+ timeout?: string;
6
+ }
7
+ export declare function sendCommand(message: string, options: SendOptions): Promise<void>;
8
+ export {};
@@ -0,0 +1,112 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { resolveCredentials } from './helpers/resolve-credentials.js';
4
+ import { createSession, sendMessage, saveSession, getLastSessionId, } from '../lib/relay-client.js';
5
+ export async function sendCommand(message, options) {
6
+ const isJson = !!options.json;
7
+ try {
8
+ const creds = await resolveCredentials();
9
+ const token = creds.access_token;
10
+ // Resolve session
11
+ let sessionId;
12
+ if (options.sessionId) {
13
+ sessionId = options.sessionId;
14
+ }
15
+ else if (options.newSession) {
16
+ const session = await createSession(token);
17
+ sessionId = session.session_id;
18
+ await saveSession({ session_id: sessionId, created_at: new Date().toISOString() });
19
+ }
20
+ else {
21
+ // Try to reuse last session, fall back to new
22
+ const lastId = await getLastSessionId();
23
+ if (lastId) {
24
+ sessionId = lastId;
25
+ }
26
+ else {
27
+ const session = await createSession(token);
28
+ sessionId = session.session_id;
29
+ await saveSession({ session_id: sessionId, created_at: new Date().toISOString() });
30
+ }
31
+ }
32
+ if (isJson) {
33
+ process.stdout.write(JSON.stringify({ event: 'session_created', session_id: sessionId }) + '\n');
34
+ }
35
+ // Send message and collect response
36
+ const spinner = isJson ? null : ora('Thinking...').start();
37
+ let fullResponse = '';
38
+ let usage = null;
39
+ let creditsUsed = 0;
40
+ let balanceAfter = 0;
41
+ for await (const evt of sendMessage(token, sessionId, message)) {
42
+ switch (evt.event) {
43
+ case 'text':
44
+ fullResponse += evt.data.content || '';
45
+ if (isJson) {
46
+ process.stdout.write(JSON.stringify({ event: 'text', content: evt.data.content }) + '\n');
47
+ }
48
+ else if (spinner?.isSpinning) {
49
+ spinner.stop();
50
+ }
51
+ break;
52
+ case 'status':
53
+ case 'log':
54
+ if (spinner?.isSpinning) {
55
+ const state = (evt.data.state || evt.data.level || 'processing');
56
+ spinner.text = state;
57
+ }
58
+ if (isJson) {
59
+ process.stdout.write(JSON.stringify({ event: evt.event, ...evt.data }) + '\n');
60
+ }
61
+ break;
62
+ case 'mode_change':
63
+ if (isJson) {
64
+ process.stdout.write(JSON.stringify({ event: 'mode_change', ...evt.data }) + '\n');
65
+ }
66
+ break;
67
+ case 'complete':
68
+ usage = evt.data.usage || null;
69
+ if (isJson) {
70
+ process.stdout.write(JSON.stringify({ event: 'complete', ...evt.data }) + '\n');
71
+ }
72
+ break;
73
+ case 'cost':
74
+ creditsUsed = evt.data.credits_used || 0;
75
+ balanceAfter = evt.data.balance_after || 0;
76
+ if (isJson) {
77
+ process.stdout.write(JSON.stringify({ event: 'cost', ...evt.data }) + '\n');
78
+ }
79
+ break;
80
+ case 'error':
81
+ if (spinner?.isSpinning)
82
+ spinner.fail(evt.data.message);
83
+ if (isJson) {
84
+ process.stdout.write(JSON.stringify({ event: 'error', ...evt.data }) + '\n');
85
+ }
86
+ else {
87
+ console.error(chalk.red(`Error: ${evt.data.message}`));
88
+ }
89
+ break;
90
+ }
91
+ }
92
+ if (spinner?.isSpinning)
93
+ spinner.stop();
94
+ if (!isJson && fullResponse) {
95
+ console.log(fullResponse);
96
+ if (creditsUsed > 0) {
97
+ console.log(chalk.gray(`\n[Credits used: ${creditsUsed} | Balance: ${balanceAfter}]`));
98
+ }
99
+ }
100
+ }
101
+ catch (err) {
102
+ const msg = err instanceof Error ? err.message : String(err);
103
+ if (isJson) {
104
+ process.stdout.write(JSON.stringify({ event: 'error', code: 'CLI_ERROR', message: msg }) + '\n');
105
+ }
106
+ else {
107
+ console.error(chalk.red(msg));
108
+ }
109
+ process.exit(msg.includes('authenticated') || msg.includes('expired') ? 2 : 1);
110
+ }
111
+ }
112
+ //# sourceMappingURL=send.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send.js","sourceRoot":"","sources":["../../src/commands/send.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ interface SessionsOptions {
2
+ clear?: boolean;
3
+ json?: boolean;
4
+ }
5
+ export declare function sessionsCommand(options: SessionsOptions): Promise<void>;
6
+ export {};
@@ -0,0 +1,36 @@
1
+ import chalk from 'chalk';
2
+ import { loadSessions, clearSessions } from '../lib/relay-client.js';
3
+ export async function sessionsCommand(options) {
4
+ if (options.clear) {
5
+ await clearSessions();
6
+ if (options.json) {
7
+ process.stdout.write(JSON.stringify({ cleared: true }) + '\n');
8
+ }
9
+ else {
10
+ console.log(chalk.green('Session history cleared.'));
11
+ }
12
+ return;
13
+ }
14
+ const store = await loadSessions();
15
+ const entries = Object.values(store.sessions);
16
+ if (options.json) {
17
+ process.stdout.write(JSON.stringify({
18
+ last_session_id: store.last_session_id || null,
19
+ sessions: entries,
20
+ }) + '\n');
21
+ return;
22
+ }
23
+ if (entries.length === 0) {
24
+ console.log(chalk.gray('No sessions found.'));
25
+ return;
26
+ }
27
+ console.log(chalk.bold('Recent Sessions'));
28
+ console.log();
29
+ for (const s of entries) {
30
+ const isCurrent = s.session_id === store.last_session_id;
31
+ const marker = isCurrent ? chalk.green(' (current)') : '';
32
+ console.log(` ${s.session_id}${marker}`);
33
+ console.log(` Created: ${s.created_at}`);
34
+ }
35
+ }
36
+ //# sourceMappingURL=sessions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/commands/sessions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAOrE,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAwB;IAC5D,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,aAAa,EAAE,CAAC;QACtB,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QACjE,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC,CAAC;QACvD,CAAC;QACD,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,YAAY,EAAE,CAAC;IACnC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAE9C,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;YAClC,eAAe,EAAE,KAAK,CAAC,eAAe,IAAI,IAAI;YAC9C,QAAQ,EAAE,OAAO;SAClB,CAAC,GAAG,IAAI,CAAC,CAAC;QACX,OAAO;IACT,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAC;QAC9C,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,SAAS,GAAG,CAAC,CAAC,UAAU,KAAK,KAAK,CAAC,eAAe,CAAC;QACzD,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,UAAU,GAAG,MAAM,EAAE,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC"}
package/dist/index.js CHANGED
@@ -1,44 +1,63 @@
1
1
  import { Command } from 'commander';
2
2
  import { loginCommand } from './commands/login.js';
3
+ import { loginCodeCommand } from './commands/login-code.js';
4
+ import { loginPollCommand } from './commands/login-poll.js';
3
5
  import { logoutCommand } from './commands/logout.js';
4
- import { whoamiCommand } from './commands/whoami.js';
5
- import { tokenCommand } from './commands/token.js';
6
- import { paymentGrantCommand } from './commands/payment-grant.js';
7
- import { rechargeCreditsCommand } from './commands/recharge-credits.js';
8
- import { subscribeCommand } from './commands/subscribe.js';
6
+ import { connectCommand } from './commands/connect.js';
7
+ import { sendCommand } from './commands/send.js';
8
+ import { sessionsCommand } from './commands/sessions.js';
9
+ import { balanceCommand } from './commands/balance.js';
9
10
  const program = new Command();
10
11
  program
11
12
  .name('clawapps')
12
- .description('ClawApps CLI - Authenticate, manage payments, and recharge credits via QR code')
13
- .version('0.5.0');
13
+ .description('ClawApps CLI - AI agent platform client')
14
+ .version('0.6.0');
15
+ // Auth
14
16
  program
15
17
  .command('login')
16
- .description('Log in via QR code (scan to authenticate, valid for 3 minutes)')
18
+ .description('Log in via WeChat QR code (interactive)')
19
+ .option('--json', 'Output as JSON')
17
20
  .action(loginCommand);
18
21
  program
19
- .command('logout')
20
- .description('Log out of your ClawApps account')
21
- .action(logoutCommand);
22
- program
23
- .command('whoami')
24
- .description('Show your ClawApps account info')
25
- .action(whoamiCommand);
26
- program
27
- .command('token')
28
- .description('Print valid access token (auto-refreshes if expired)')
29
- .action(tokenCommand);
22
+ .command('login-code')
23
+ .description('Create login code and QR image (non-blocking, for AI agents)')
24
+ .action(loginCodeCommand);
30
25
  program
31
- .command('payment-grant')
32
- .description('Authorize skill payment via QR code (valid for 3 minutes)')
33
- .argument('<skill_id>', 'The skill ID to grant payment for')
34
- .action(paymentGrantCommand);
26
+ .command('login-poll')
27
+ .description('Poll for login verification (for AI agents)')
28
+ .argument('<code>', 'Login code from login-code command')
29
+ .action(loginPollCommand);
35
30
  program
36
- .command('recharge-credits')
37
- .description('Display QR code to recharge credits')
38
- .action(rechargeCreditsCommand);
39
- program
40
- .command('subscribe')
41
- .description('Display QR code to subscribe membership')
42
- .action(subscribeCommand);
31
+ .command('logout')
32
+ .description('Log out and clear local credentials')
33
+ .action(logoutCommand);
34
+ // Agent workspace
35
+ program
36
+ .command('connect')
37
+ .description('Connect to agent workspace (persistent session)')
38
+ .option('--session-id <id>', 'Resume a specific session')
39
+ .option('--json', 'JSON I/O mode (NDJSON stdin/stdout)')
40
+ .option('--timeout <ms>', 'Connection timeout in milliseconds')
41
+ .action(connectCommand);
42
+ program
43
+ .command('send')
44
+ .description('Send a message to agent workspace')
45
+ .argument('<message>', 'Message to send')
46
+ .option('--session-id <id>', 'Use a specific session')
47
+ .option('--new-session', 'Force create a new session')
48
+ .option('--json', 'Output as JSON')
49
+ .option('--timeout <ms>', 'Response timeout in milliseconds')
50
+ .action(sendCommand);
51
+ program
52
+ .command('sessions')
53
+ .description('List or manage workspace sessions')
54
+ .option('--clear', 'Clear session history')
55
+ .option('--json', 'Output as JSON')
56
+ .action(sessionsCommand);
57
+ program
58
+ .command('balance')
59
+ .description('Check credit balance')
60
+ .option('--json', 'Output as JSON')
61
+ .action(balanceCommand);
43
62
  program.parse();
44
63
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,gFAAgF,CAAC;KAC7F,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,gEAAgE,CAAC;KAC7E,MAAM,CAAC,YAAY,CAAC,CAAC;AAExB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,kCAAkC,CAAC;KAC/C,MAAM,CAAC,aAAa,CAAC,CAAC;AAEzB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,iCAAiC,CAAC;KAC9C,MAAM,CAAC,aAAa,CAAC,CAAC;AAEzB,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,sDAAsD,CAAC;KACnE,MAAM,CAAC,YAAY,CAAC,CAAC;AAExB,OAAO;KACJ,OAAO,CAAC,eAAe,CAAC;KACxB,WAAW,CAAC,2DAA2D,CAAC;KACxE,QAAQ,CAAC,YAAY,EAAE,mCAAmC,CAAC;KAC3D,MAAM,CAAC,mBAAmB,CAAC,CAAC;AAE/B,OAAO;KACJ,OAAO,CAAC,kBAAkB,CAAC;KAC3B,WAAW,CAAC,qCAAqC,CAAC;KAClD,MAAM,CAAC,sBAAsB,CAAC,CAAC;AAElC,OAAO;KACJ,OAAO,CAAC,WAAW,CAAC;KACpB,WAAW,CAAC,yCAAyC,CAAC;KACtD,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAE5B,OAAO,CAAC,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,yCAAyC,CAAC;KACtD,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;AACP,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,yCAAyC,CAAC;KACtD,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC;KAClC,MAAM,CAAC,YAAY,CAAC,CAAC;AAExB,OAAO;KACJ,OAAO,CAAC,YAAY,CAAC;KACrB,WAAW,CAAC,8DAA8D,CAAC;KAC3E,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAE5B,OAAO;KACJ,OAAO,CAAC,YAAY,CAAC;KACrB,WAAW,CAAC,6CAA6C,CAAC;KAC1D,QAAQ,CAAC,QAAQ,EAAE,oCAAoC,CAAC;KACxD,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAE5B,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,qCAAqC,CAAC;KAClD,MAAM,CAAC,aAAa,CAAC,CAAC;AAEzB,kBAAkB;AAClB,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,iDAAiD,CAAC;KAC9D,MAAM,CAAC,mBAAmB,EAAE,2BAA2B,CAAC;KACxD,MAAM,CAAC,QAAQ,EAAE,qCAAqC,CAAC;KACvD,MAAM,CAAC,gBAAgB,EAAE,oCAAoC,CAAC;KAC9D,MAAM,CAAC,cAAc,CAAC,CAAC;AAE1B,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,mCAAmC,CAAC;KAChD,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAC;KACxC,MAAM,CAAC,mBAAmB,EAAE,wBAAwB,CAAC;KACrD,MAAM,CAAC,eAAe,EAAE,4BAA4B,CAAC;KACrD,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC;KAClC,MAAM,CAAC,gBAAgB,EAAE,kCAAkC,CAAC;KAC5D,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO;KACJ,OAAO,CAAC,UAAU,CAAC;KACnB,WAAW,CAAC,mCAAmC,CAAC;KAChD,MAAM,CAAC,SAAS,EAAE,uBAAuB,CAAC;KAC1C,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC;KAClC,MAAM,CAAC,eAAe,CAAC,CAAC;AAE3B,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,sBAAsB,CAAC;KACnC,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC;KAClC,MAAM,CAAC,cAAc,CAAC,CAAC;AAE1B,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -1,19 +1,8 @@
1
1
  export declare const CONFIG: {
2
- readonly GOOGLE_CLIENT_ID: "89883978473-52rsbijnbti2lr3imsg9odjc04ulq1ds.apps.googleusercontent.com";
3
- readonly OD_API_BASE: "https://api.opendigits.ai/api/v1";
4
- readonly CLAW_API_BASE: "https://api.clawapps.ai/api/v1";
5
- readonly OD_GOOGLE_AUTH: "https://api.opendigits.ai/api/v1/auth/oauth/google";
6
- readonly OD_APPLE_AUTHORIZE: "https://api.opendigits.ai/api/v1/auth/oauth/apple/authorize";
7
- readonly CLAW_EXCHANGE: "https://api.clawapps.ai/api/v1/auth/exchange";
8
- readonly CLAW_ME: "https://api.clawapps.ai/api/v1/auth/me";
9
- readonly CLAW_REFRESH: "https://api.clawapps.ai/api/v1/auth/refresh";
10
- readonly CLAW_LOGOUT: "https://api.clawapps.ai/api/v1/auth/logout";
11
- readonly CLAW_WEB_BASE: "https://clawapps.ai";
12
- readonly AGENT_CREATE_LOGIN_CODE: "https://api.clawapps.ai/api/v1/agent/create-login-code";
13
- readonly AGENT_CREATE_PAYMENT_CODE: "https://api.clawapps.ai/api/v1/agent/create-payment-code";
14
- readonly AGENT_AUTH_CODE: "https://api.clawapps.ai/api/v1/agent/auth-code";
15
- readonly AUTH_POLL_INTERVAL_MS: number;
16
- readonly AUTH_TIMEOUT_MS: number;
2
+ readonly CLI_RELAY_BASE: "https://api.clawapps.ai/cli/v1";
3
+ readonly CLI_CONNECT_TIMEOUT_MS: number;
4
+ readonly CLI_MESSAGE_TIMEOUT_MS: number;
17
5
  readonly CREDENTIALS_DIR: ".clawapps";
18
6
  readonly CREDENTIALS_FILE: "credentials.json";
7
+ readonly SESSIONS_FILE: "sessions.json";
19
8
  };
@@ -1,26 +1,11 @@
1
1
  export const CONFIG = {
2
- GOOGLE_CLIENT_ID: '89883978473-52rsbijnbti2lr3imsg9odjc04ulq1ds.apps.googleusercontent.com',
3
- OD_API_BASE: 'https://api.opendigits.ai/api/v1',
4
- CLAW_API_BASE: 'https://api.clawapps.ai/api/v1',
5
- // OD endpoints
6
- OD_GOOGLE_AUTH: 'https://api.opendigits.ai/api/v1/auth/oauth/google',
7
- OD_APPLE_AUTHORIZE: 'https://api.opendigits.ai/api/v1/auth/oauth/apple/authorize',
8
- // ClawApps endpoints
9
- CLAW_EXCHANGE: 'https://api.clawapps.ai/api/v1/auth/exchange',
10
- CLAW_ME: 'https://api.clawapps.ai/api/v1/auth/me',
11
- CLAW_REFRESH: 'https://api.clawapps.ai/api/v1/auth/refresh',
12
- CLAW_LOGOUT: 'https://api.clawapps.ai/api/v1/auth/logout',
13
- // Web
14
- CLAW_WEB_BASE: 'https://clawapps.ai',
15
- // Agent code endpoints
16
- AGENT_CREATE_LOGIN_CODE: 'https://api.clawapps.ai/api/v1/agent/create-login-code',
17
- AGENT_CREATE_PAYMENT_CODE: 'https://api.clawapps.ai/api/v1/agent/create-payment-code',
18
- AGENT_AUTH_CODE: 'https://api.clawapps.ai/api/v1/agent/auth-code',
19
- AUTH_POLL_INTERVAL_MS: 3 * 1000, // 3 seconds
20
- // Timeouts
21
- AUTH_TIMEOUT_MS: 3 * 60 * 1000, // 3 minutes
22
- // Credentials
2
+ // CLI Relay
3
+ CLI_RELAY_BASE: 'https://api.clawapps.ai/cli/v1',
4
+ CLI_CONNECT_TIMEOUT_MS: 30 * 1000,
5
+ CLI_MESSAGE_TIMEOUT_MS: 5 * 60 * 1000,
6
+ // Local storage
23
7
  CREDENTIALS_DIR: '.clawapps',
24
8
  CREDENTIALS_FILE: 'credentials.json',
9
+ SESSIONS_FILE: 'sessions.json',
25
10
  };
26
11
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,gBAAgB,EAAE,yEAAyE;IAE3F,WAAW,EAAE,kCAAkC;IAC/C,aAAa,EAAE,gCAAgC;IAE/C,eAAe;IACf,cAAc,EAAE,oDAAoD;IACpE,kBAAkB,EAAE,6DAA6D;IAEjF,qBAAqB;IACrB,aAAa,EAAE,8CAA8C;IAC7D,OAAO,EAAE,wCAAwC;IACjD,YAAY,EAAE,6CAA6C;IAC3D,WAAW,EAAE,4CAA4C;IAEzD,MAAM;IACN,aAAa,EAAE,qBAAqB;IAEpC,uBAAuB;IACvB,uBAAuB,EAAE,wDAAwD;IACjF,yBAAyB,EAAE,0DAA0D;IACrF,eAAe,EAAE,gDAAgD;IACjE,qBAAqB,EAAE,CAAC,GAAG,IAAI,EAAE,YAAY;IAE7C,WAAW;IACX,eAAe,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,YAAY;IAE5C,cAAc;IACd,eAAe,EAAE,WAAW;IAC5B,gBAAgB,EAAE,kBAAkB;CAC5B,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,YAAY;IACZ,cAAc,EAAE,gCAAgC;IAChD,sBAAsB,EAAE,EAAE,GAAG,IAAI;IACjC,sBAAsB,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI;IAErC,gBAAgB;IAChB,eAAe,EAAE,WAAW;IAC5B,gBAAgB,EAAE,kBAAkB;IACpC,aAAa,EAAE,eAAe;CACtB,CAAC"}
@@ -0,0 +1,23 @@
1
+ export interface LoginCodeResult {
2
+ code: string;
3
+ qr_url: string;
4
+ qr_image: string;
5
+ qr_text: string;
6
+ expires_at: string;
7
+ }
8
+ export interface LoginPollResult {
9
+ success: boolean;
10
+ display_name?: string;
11
+ error?: string;
12
+ }
13
+ /**
14
+ * Create a login code and generate QR image.
15
+ * Returns immediately (non-blocking).
16
+ */
17
+ export declare function createLoginCode(): Promise<LoginCodeResult>;
18
+ /**
19
+ * Poll for login verification.
20
+ * Calls onStatus every poll interval.
21
+ * Returns when verified, expired, or timed out.
22
+ */
23
+ export declare function pollLoginCode(code: string, onStatus?: (remaining: number) => void, timeoutMs?: number): Promise<LoginPollResult>;