@clawmarket.cc/marketcc 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 (55) hide show
  1. package/dist/commands/delete.d.ts +3 -0
  2. package/dist/commands/delete.js +22 -0
  3. package/dist/commands/delete.js.map +1 -0
  4. package/dist/commands/get.d.ts +4 -0
  5. package/dist/commands/get.js +58 -0
  6. package/dist/commands/get.js.map +1 -0
  7. package/dist/commands/info.d.ts +1 -0
  8. package/dist/commands/info.js +37 -0
  9. package/dist/commands/info.js.map +1 -0
  10. package/dist/commands/init.d.ts +3 -0
  11. package/dist/commands/init.js +12 -0
  12. package/dist/commands/init.js.map +1 -0
  13. package/dist/commands/list.d.ts +5 -0
  14. package/dist/commands/list.js +46 -0
  15. package/dist/commands/list.js.map +1 -0
  16. package/dist/commands/login.d.ts +3 -0
  17. package/dist/commands/login.js +37 -0
  18. package/dist/commands/login.js.map +1 -0
  19. package/dist/commands/logout.d.ts +1 -0
  20. package/dist/commands/logout.js +7 -0
  21. package/dist/commands/logout.js.map +1 -0
  22. package/dist/commands/stats.d.ts +1 -0
  23. package/dist/commands/stats.js +24 -0
  24. package/dist/commands/stats.js.map +1 -0
  25. package/dist/commands/update.d.ts +1 -0
  26. package/dist/commands/update.js +34 -0
  27. package/dist/commands/update.js.map +1 -0
  28. package/dist/commands/upload.d.ts +3 -0
  29. package/dist/commands/upload.js +70 -0
  30. package/dist/commands/upload.js.map +1 -0
  31. package/dist/commands/wallet.d.ts +2 -0
  32. package/dist/commands/wallet.js +23 -0
  33. package/dist/commands/wallet.js.map +1 -0
  34. package/dist/commands/whoami.d.ts +1 -0
  35. package/dist/commands/whoami.js +17 -0
  36. package/dist/commands/whoami.js.map +1 -0
  37. package/dist/index.d.ts +2 -0
  38. package/dist/index.js +98 -0
  39. package/dist/index.js.map +1 -0
  40. package/dist/lib/api.d.ts +28 -0
  41. package/dist/lib/api.js +107 -0
  42. package/dist/lib/api.js.map +1 -0
  43. package/dist/lib/config.d.ts +8 -0
  44. package/dist/lib/config.js +45 -0
  45. package/dist/lib/config.js.map +1 -0
  46. package/dist/lib/packager.d.ts +8 -0
  47. package/dist/lib/packager.js +55 -0
  48. package/dist/lib/packager.js.map +1 -0
  49. package/dist/lib/validator.d.ts +5 -0
  50. package/dist/lib/validator.js +67 -0
  51. package/dist/lib/validator.js.map +1 -0
  52. package/dist/types/index.d.ts +113 -0
  53. package/dist/types/index.js +2 -0
  54. package/dist/types/index.js.map +1 -0
  55. package/package.json +40 -0
@@ -0,0 +1,3 @@
1
+ export declare function deleteCommand(botId: string, opts: {
2
+ yes?: boolean;
3
+ }): Promise<void>;
@@ -0,0 +1,22 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { createInterface } from 'node:readline/promises';
4
+ import { stdin, stdout } from 'node:process';
5
+ import { createAuthenticatedClient } from '../lib/api.js';
6
+ export async function deleteCommand(botId, opts) {
7
+ if (!opts.yes) {
8
+ const rl = createInterface({ input: stdin, output: stdout });
9
+ const answer = await rl.question(`Are you sure you want to delete bot ${botId}? (y/N) `);
10
+ rl.close();
11
+ if (answer.toLowerCase() !== 'y') {
12
+ console.log('Cancelled.');
13
+ return;
14
+ }
15
+ }
16
+ const spinner = ora('Deleting bot...').start();
17
+ const client = await createAuthenticatedClient();
18
+ const result = await client.deleteBot(botId);
19
+ spinner.stop();
20
+ console.log(chalk.green(result.message));
21
+ }
22
+ //# sourceMappingURL=delete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete.js","sourceRoot":"","sources":["../../src/commands/delete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAE1D,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,KAAa,EACb,IAAuB;IAEvB,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QACd,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAC7D,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAC9B,uCAAuC,KAAK,UAAU,CACvD,CAAC;QACF,EAAE,CAAC,KAAK,EAAE,CAAC;QACX,IAAI,MAAM,CAAC,WAAW,EAAE,KAAK,GAAG,EAAE,CAAC;YACjC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAC1B,OAAO;QACT,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,iBAAiB,CAAC,CAAC,KAAK,EAAE,CAAC;IAC/C,MAAM,MAAM,GAAG,MAAM,yBAAyB,EAAE,CAAC;IACjD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC7C,OAAO,CAAC,IAAI,EAAE,CAAC;IAEf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function getCommand(slug: string, opts: {
2
+ key: string;
3
+ output?: string;
4
+ }): Promise<void>;
@@ -0,0 +1,58 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { mkdir } from 'node:fs/promises';
4
+ import { existsSync } from 'node:fs';
5
+ import { Readable } from 'node:stream';
6
+ import { pipeline } from 'node:stream/promises';
7
+ import * as tar from 'tar';
8
+ import { createClient, ApiClientError } from '../lib/api.js';
9
+ export async function getCommand(slug, opts) {
10
+ if (!opts.key) {
11
+ console.error(chalk.red('Access token required. Use: marketcc get <slug> --key <token>'));
12
+ process.exit(1);
13
+ }
14
+ const spinner = ora('Verifying access token...').start();
15
+ const client = await createClient();
16
+ let configUrl;
17
+ try {
18
+ const result = await client.verifyToken(opts.key);
19
+ if (!result.valid) {
20
+ spinner.stop();
21
+ console.error(chalk.red(`Token invalid: ${result.error || 'unknown error'}`));
22
+ process.exit(1);
23
+ }
24
+ if (!result.config_url) {
25
+ spinner.stop();
26
+ console.error(chalk.red('No download URL available for this bot.'));
27
+ process.exit(1);
28
+ }
29
+ configUrl = result.config_url;
30
+ }
31
+ catch (e) {
32
+ spinner.stop();
33
+ if (e instanceof ApiClientError) {
34
+ console.error(chalk.red(`Token verification failed: ${e.message}`));
35
+ process.exit(1);
36
+ }
37
+ throw e;
38
+ }
39
+ // Download the archive
40
+ spinner.text = 'Downloading bot...';
41
+ const res = await fetch(configUrl);
42
+ if (!res.ok || !res.body) {
43
+ spinner.stop();
44
+ console.error(chalk.red('Failed to download bot archive.'));
45
+ process.exit(1);
46
+ }
47
+ // Extract to output directory
48
+ const outDir = opts.output || `./${slug}`;
49
+ if (!existsSync(outDir)) {
50
+ await mkdir(outDir, { recursive: true });
51
+ }
52
+ spinner.text = 'Extracting...';
53
+ const nodeStream = Readable.fromWeb(res.body);
54
+ await pipeline(nodeStream, tar.extract({ cwd: outDir, strip: 1 }));
55
+ spinner.stop();
56
+ console.log(chalk.green(`Bot downloaded to ${outDir}/`));
57
+ }
58
+ //# sourceMappingURL=get.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get.js","sourceRoot":"","sources":["../../src/commands/get.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function infoCommand(slug: string): Promise<void>;
@@ -0,0 +1,37 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { createClient, ApiClientError } from '../lib/api.js';
4
+ export async function infoCommand(slug) {
5
+ const spinner = ora('Fetching bot info...').start();
6
+ const client = await createClient();
7
+ try {
8
+ const bot = await client.getBotInfo(slug);
9
+ spinner.stop();
10
+ console.log(chalk.bold(bot.name));
11
+ console.log(` Slug: ${bot.slug}`);
12
+ console.log(` Price: $${bot.price_usd}`);
13
+ console.log(` Category: ${bot.category || 'N/A'}`);
14
+ if (bot.tags?.length) {
15
+ console.log(` Tags: ${bot.tags.join(', ')}`);
16
+ }
17
+ console.log(` Buyers: ${bot.buyer_count}`);
18
+ console.log(` Provider: ${bot.provider_address}`);
19
+ console.log(` Created: ${bot.created_at}`);
20
+ console.log(` Updated: ${bot.updated_at}`);
21
+ console.log('');
22
+ console.log(chalk.dim(bot.description));
23
+ if (bot.long_description) {
24
+ console.log('');
25
+ console.log(bot.long_description);
26
+ }
27
+ }
28
+ catch (e) {
29
+ spinner.stop();
30
+ if (e instanceof ApiClientError && e.statusCode === 404) {
31
+ console.error(chalk.red(`Bot not found: ${slug}`));
32
+ process.exit(1);
33
+ }
34
+ throw e;
35
+ }
36
+ }
37
+ //# sourceMappingURL=info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"info.js","sourceRoot":"","sources":["../../src/commands/info.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE7D,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAY;IAC5C,MAAM,OAAO,GAAG,GAAG,CAAC,sBAAsB,CAAC,CAAC,KAAK,EAAE,CAAC;IACpD,MAAM,MAAM,GAAG,MAAM,YAAY,EAAE,CAAC;IAEpC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC1C,OAAO,CAAC,IAAI,EAAE,CAAC;QAEf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,mBAAmB,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,CAAC,QAAQ,IAAI,KAAK,EAAE,CAAC,CAAC;QACvD,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACvD,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,CAAC,gBAAgB,EAAE,CAAC,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;QACxC,IAAI,GAAG,CAAC,gBAAgB,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,IAAI,CAAC,YAAY,cAAc,IAAI,CAAC,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;YACxD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC,CAAC;YACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,CAAC,CAAC;IACV,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function initCommand(opts: {
2
+ apiUrl?: string;
3
+ }): Promise<void>;
@@ -0,0 +1,12 @@
1
+ import chalk from 'chalk';
2
+ import { ensureConfigDir, saveConfig, getConfigDir } from '../lib/config.js';
3
+ const DEFAULT_API_URL = 'http://100.73.202.72:8000';
4
+ export async function initCommand(opts) {
5
+ const apiUrl = opts.apiUrl || DEFAULT_API_URL;
6
+ await ensureConfigDir();
7
+ await saveConfig({ api_url: apiUrl });
8
+ console.log(chalk.green('Initialized marketcc configuration.'));
9
+ console.log(` Config dir: ${getConfigDir()}`);
10
+ console.log(` API URL: ${apiUrl}`);
11
+ }
12
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAE7E,MAAM,eAAe,GAAG,2BAA2B,CAAC;AAEpD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAyB;IACzD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,eAAe,CAAC;IAE9C,MAAM,eAAe,EAAE,CAAC;IACxB,MAAM,UAAU,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IAEtC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC,CAAC;IAChE,OAAO,CAAC,GAAG,CAAC,iBAAiB,YAAY,EAAE,EAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,iBAAiB,MAAM,EAAE,CAAC,CAAC;AACzC,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare function listCommand(opts: {
2
+ mine?: boolean;
3
+ category?: string;
4
+ search?: string;
5
+ }): Promise<void>;
@@ -0,0 +1,46 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { createClient, createAuthenticatedClient } from '../lib/api.js';
4
+ export async function listCommand(opts) {
5
+ if (opts.mine) {
6
+ const spinner = ora('Fetching your bots...').start();
7
+ const client = await createAuthenticatedClient();
8
+ const data = await client.listMyBots();
9
+ spinner.stop();
10
+ if (data.bots.length === 0) {
11
+ console.log('No bots found. Upload one with: marketcc upload <dir>');
12
+ return;
13
+ }
14
+ console.log(chalk.bold(`Your bots (${data.bots.length}):\n`));
15
+ for (const bot of data.bots) {
16
+ const status = bot.status === 'ACTIVE'
17
+ ? chalk.green(bot.status)
18
+ : chalk.dim(bot.status);
19
+ console.log(` ${chalk.bold(bot.name)} (${bot.slug})`);
20
+ console.log(` ID: ${bot.id} Status: ${status} Price: $${bot.price_usd}`);
21
+ console.log(` Buyers: ${bot.total_buyers}`);
22
+ console.log('');
23
+ }
24
+ }
25
+ else {
26
+ const spinner = ora('Fetching marketplace...').start();
27
+ const client = await createClient();
28
+ const data = await client.listMarketplace({
29
+ category: opts.category,
30
+ search: opts.search,
31
+ });
32
+ spinner.stop();
33
+ if (data.bots.length === 0) {
34
+ console.log('No bots found on the marketplace.');
35
+ return;
36
+ }
37
+ console.log(chalk.bold(`Marketplace (${data.total} bots, showing ${data.bots.length}):\n`));
38
+ for (const bot of data.bots) {
39
+ console.log(` ${chalk.bold(bot.name)} (${bot.slug})`);
40
+ console.log(` $${bot.price_usd} ${bot.category || ''} ${bot.buyer_count} buyers`);
41
+ console.log(` ${chalk.dim(bot.description)}`);
42
+ console.log('');
43
+ }
44
+ }
45
+ }
46
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,YAAY,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAExE,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAIjC;IACC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,OAAO,GAAG,GAAG,CAAC,uBAAuB,CAAC,CAAC,KAAK,EAAE,CAAC;QACrD,MAAM,MAAM,GAAG,MAAM,yBAAyB,EAAE,CAAC;QACjD,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;QACvC,OAAO,CAAC,IAAI,EAAE,CAAC;QAEf,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;YACrE,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC;QAC9D,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,MAAM,MAAM,GACV,GAAG,CAAC,MAAM,KAAK,QAAQ;gBACrB,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;gBACzB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;YACvD,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,CAAC,EAAE,aAAa,MAAM,aAAa,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;YAC9E,OAAO,CAAC,GAAG,CAAC,eAAe,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC;YAC/C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,OAAO,GAAG,GAAG,CAAC,yBAAyB,CAAC,CAAC,KAAK,EAAE,CAAC;QACvD,MAAM,MAAM,GAAG,MAAM,YAAY,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC;YACxC,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,EAAE,CAAC;QAEf,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;YACjD,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,IAAI,CAAC,gBAAgB,IAAI,CAAC,KAAK,kBAAkB,IAAI,CAAC,IAAI,CAAC,MAAM,MAAM,CAAC,CAC/E,CAAC;QACF,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;YACvD,OAAO,CAAC,GAAG,CACT,QAAQ,GAAG,CAAC,SAAS,KAAK,GAAG,CAAC,QAAQ,IAAI,EAAE,KAAK,GAAG,CAAC,WAAW,SAAS,CAC1E,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;YACjD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function loginCommand(opts: {
2
+ key?: string;
3
+ }): Promise<void>;
@@ -0,0 +1,37 @@
1
+ import chalk from 'chalk';
2
+ import { createInterface } from 'node:readline/promises';
3
+ import { stdin, stdout } from 'node:process';
4
+ import { saveConfig, loadConfig, getApiUrl } from '../lib/config.js';
5
+ import { ApiClient, ApiClientError } from '../lib/api.js';
6
+ import ora from 'ora';
7
+ export async function loginCommand(opts) {
8
+ let key = opts.key;
9
+ if (!key) {
10
+ const rl = createInterface({ input: stdin, output: stdout });
11
+ key = await rl.question('Enter your secret key (CLAW-SK-...): ');
12
+ rl.close();
13
+ }
14
+ key = key.trim();
15
+ if (!key.startsWith('CLAW-SK-')) {
16
+ console.error(chalk.red('Invalid key format. Secret keys start with "CLAW-SK-".'));
17
+ process.exit(1);
18
+ }
19
+ const spinner = ora('Validating key...').start();
20
+ try {
21
+ const config = await loadConfig();
22
+ const client = new ApiClient(getApiUrl(config), key);
23
+ await client.listMyBots();
24
+ spinner.stop();
25
+ await saveConfig({ secret_key: key });
26
+ console.log(chalk.green('Logged in successfully.'));
27
+ }
28
+ catch (e) {
29
+ spinner.stop();
30
+ if (e instanceof ApiClientError && e.statusCode === 401) {
31
+ console.error(chalk.red('Invalid secret key.'));
32
+ process.exit(1);
33
+ }
34
+ throw e;
35
+ }
36
+ }
37
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,GAAG,MAAM,KAAK,CAAC;AAEtB,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAsB;IACvD,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;IAEnB,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAC7D,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC,CAAC;QACjE,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;IAED,GAAG,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACjB,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAChC,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CAAC,wDAAwD,CAAC,CACpE,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,mBAAmB,CAAC,CAAC,KAAK,EAAE,CAAC;IAEjD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC;QACrD,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;QAC1B,OAAO,CAAC,IAAI,EAAE,CAAC;QAEf,MAAM,UAAU,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;IACtD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,IAAI,CAAC,YAAY,cAAc,IAAI,CAAC,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;YACxD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC,CAAC;YAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,CAAC,CAAC;IACV,CAAC;AACH,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function logoutCommand(): Promise<void>;
@@ -0,0 +1,7 @@
1
+ import chalk from 'chalk';
2
+ import { clearConfig } from '../lib/config.js';
3
+ export async function logoutCommand() {
4
+ await clearConfig();
5
+ console.log(chalk.green('Logged out. Secret key removed from config.'));
6
+ }
7
+ //# sourceMappingURL=logout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,WAAW,EAAE,CAAC;IACpB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC,CAAC;AAC1E,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function statsCommand(): Promise<void>;
@@ -0,0 +1,24 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { createAuthenticatedClient } from '../lib/api.js';
4
+ export async function statsCommand() {
5
+ const spinner = ora('Fetching stats...').start();
6
+ const client = await createAuthenticatedClient();
7
+ const data = await client.getStats();
8
+ spinner.stop();
9
+ console.log(chalk.bold('Provider Stats'));
10
+ console.log(` Total revenue: $${data.total_revenue_usd.toFixed(2)}`);
11
+ console.log(` Total buyers: ${data.total_buyers}`);
12
+ console.log(` Payout addr: ${data.payout_address}`);
13
+ if (data.bots.length > 0) {
14
+ console.log(chalk.bold('\nPer-bot breakdown:\n'));
15
+ for (const bot of data.bots) {
16
+ const status = bot.status === 'ACTIVE'
17
+ ? chalk.green(bot.status)
18
+ : chalk.dim(bot.status);
19
+ console.log(` ${chalk.bold(bot.name)} (${bot.slug})`);
20
+ console.log(` Revenue: $${bot.revenue_usd.toFixed(2)} Buyers: ${bot.buyer_count} Status: ${status}`);
21
+ }
22
+ }
23
+ }
24
+ //# sourceMappingURL=stats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.js","sourceRoot":"","sources":["../../src/commands/stats.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAE1D,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,OAAO,GAAG,GAAG,CAAC,mBAAmB,CAAC,CAAC,KAAK,EAAE,CAAC;IACjD,MAAM,MAAM,GAAG,MAAM,yBAAyB,EAAE,CAAC;IACjD,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;IACrC,OAAO,CAAC,IAAI,EAAE,CAAC;IAEf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACtE,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;IAEvD,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC;QAClD,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,MAAM,MAAM,GACV,GAAG,CAAC,MAAM,KAAK,QAAQ;gBACrB,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;gBACzB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;YACvD,OAAO,CAAC,GAAG,CACT,iBAAiB,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,GAAG,CAAC,WAAW,aAAa,MAAM,EAAE,CAC7F,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function updateCommand(botId: string, dir: string): Promise<void>;
@@ -0,0 +1,34 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { existsSync } from 'node:fs';
4
+ import { resolve } from 'node:path';
5
+ import { validateSkillMd, ValidationError } from '../lib/validator.js';
6
+ import { packageBot } from '../lib/packager.js';
7
+ import { createAuthenticatedClient } from '../lib/api.js';
8
+ export async function updateCommand(botId, dir) {
9
+ const dirPath = resolve(dir);
10
+ if (!existsSync(dirPath)) {
11
+ console.error(chalk.red(`Directory not found: ${dirPath}`));
12
+ process.exit(1);
13
+ }
14
+ try {
15
+ await validateSkillMd(dirPath);
16
+ }
17
+ catch (e) {
18
+ if (e instanceof ValidationError) {
19
+ console.error(chalk.red(`Validation error: ${e.message}`));
20
+ process.exit(1);
21
+ }
22
+ throw e;
23
+ }
24
+ const spinner = ora('Packaging bot...').start();
25
+ const archive = await packageBot(dirPath);
26
+ spinner.text = 'Updating...';
27
+ const client = await createAuthenticatedClient();
28
+ const result = await client.updateBot(botId, archive);
29
+ spinner.stop();
30
+ console.log(chalk.green('Bot updated successfully.'));
31
+ console.log(` Slug: ${result.slug}`);
32
+ console.log(` Updated: ${result.updated_at}`);
33
+ }
34
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAE1D,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAa,EAAE,GAAW;IAC5D,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAE7B,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,wBAAwB,OAAO,EAAE,CAAC,CAAC,CAAC;QAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,eAAe,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,YAAY,eAAe,EAAE,CAAC;YACjC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,CAAC,CAAC;IACV,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,kBAAkB,CAAC,CAAC,KAAK,EAAE,CAAC;IAChD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC;IAC1C,OAAO,CAAC,IAAI,GAAG,aAAa,CAAC;IAE7B,MAAM,MAAM,GAAG,MAAM,yBAAyB,EAAE,CAAC;IACjD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACtD,OAAO,CAAC,IAAI,EAAE,CAAC;IAEf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function uploadCommand(dir: string, opts: {
2
+ wallet?: string;
3
+ }): Promise<void>;
@@ -0,0 +1,70 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { existsSync } from 'node:fs';
4
+ import { resolve } from 'node:path';
5
+ import { validateSkillMd, ValidationError } from '../lib/validator.js';
6
+ import { packageBot, listBotFiles, formatFileSize } from '../lib/packager.js';
7
+ import { createClient } from '../lib/api.js';
8
+ import { saveConfig, loadConfig, getSecretKey } from '../lib/config.js';
9
+ export async function uploadCommand(dir, opts) {
10
+ const dirPath = resolve(dir);
11
+ if (!existsSync(dirPath)) {
12
+ console.error(chalk.red(`Directory not found: ${dirPath}`));
13
+ process.exit(1);
14
+ }
15
+ // Validate SKILL.md
16
+ let meta;
17
+ try {
18
+ meta = await validateSkillMd(dirPath);
19
+ }
20
+ catch (e) {
21
+ if (e instanceof ValidationError) {
22
+ console.error(chalk.red(`Validation error: ${e.message}`));
23
+ process.exit(1);
24
+ }
25
+ throw e;
26
+ }
27
+ console.log(chalk.bold(`Uploading: ${meta.name}`));
28
+ console.log(` Price: $${meta.priceUsd}`);
29
+ if (meta.category)
30
+ console.log(` Category: ${meta.category}`);
31
+ // Show files
32
+ const files = await listBotFiles(dirPath);
33
+ console.log(` Files: ${files.length}`);
34
+ for (const f of files) {
35
+ console.log(` ${f.name} (${formatFileSize(f.size)})`);
36
+ }
37
+ // Check auth state
38
+ const config = await loadConfig();
39
+ const hasKey = !!getSecretKey(config);
40
+ if (!hasKey && !opts.wallet) {
41
+ console.error(chalk.red('First upload requires a payout wallet address.\n' +
42
+ 'Use: marketcc upload <dir> --wallet <solana_address>'));
43
+ process.exit(1);
44
+ }
45
+ if (opts.wallet && !/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(opts.wallet)) {
46
+ console.error(chalk.red('Invalid Solana address.'));
47
+ process.exit(1);
48
+ }
49
+ // Package
50
+ const spinner = ora('Packaging bot...').start();
51
+ const archive = await packageBot(dirPath);
52
+ spinner.text = 'Uploading...';
53
+ const client = await createClient();
54
+ const result = await client.uploadBot(archive, opts.wallet);
55
+ spinner.stop();
56
+ console.log(chalk.green(`\nBot uploaded successfully!`));
57
+ console.log(` Bot ID: ${result.bot_id}`);
58
+ console.log(` Slug: ${result.slug}`);
59
+ console.log(` URL: ${result.marketplace_url}`);
60
+ // First upload — save secret key
61
+ if (result.secret_key) {
62
+ await saveConfig({ secret_key: result.secret_key });
63
+ console.log('');
64
+ console.log(chalk.yellow.bold('IMPORTANT: Save your secret key! You cannot retrieve it later.'));
65
+ console.log(chalk.yellow(` ${result.secret_key}`));
66
+ console.log('');
67
+ console.log(' Key saved to ~/.marketcc/credentials');
68
+ }
69
+ }
70
+ //# sourceMappingURL=upload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/commands/upload.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function walletCommand(): Promise<void>;
2
+ export declare function walletSetCommand(address: string): Promise<void>;
@@ -0,0 +1,23 @@
1
+ import chalk from 'chalk';
2
+ import { createAuthenticatedClient } from '../lib/api.js';
3
+ import ora from 'ora';
4
+ export async function walletCommand() {
5
+ const spinner = ora('Fetching wallet info...').start();
6
+ const client = await createAuthenticatedClient();
7
+ const data = await client.listMyBots();
8
+ spinner.stop();
9
+ console.log(`Payout address: ${data.payout_address}`);
10
+ }
11
+ export async function walletSetCommand(address) {
12
+ if (!/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(address)) {
13
+ console.error(chalk.red('Invalid Solana address.'));
14
+ process.exit(1);
15
+ }
16
+ const spinner = ora('Updating payout address...').start();
17
+ const client = await createAuthenticatedClient();
18
+ const result = await client.setPayoutAddress(address);
19
+ spinner.stop();
20
+ console.log(chalk.green('Payout address updated.'));
21
+ console.log(` Address: ${result.payout_address}`);
22
+ }
23
+ //# sourceMappingURL=wallet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wallet.js","sourceRoot":"","sources":["../../src/commands/wallet.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,GAAG,MAAM,KAAK,CAAC;AAEtB,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,OAAO,GAAG,GAAG,CAAC,yBAAyB,CAAC,CAAC,KAAK,EAAE,CAAC;IACvD,MAAM,MAAM,GAAG,MAAM,yBAAyB,EAAE,CAAC;IACjD,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;IACvC,OAAO,CAAC,IAAI,EAAE,CAAC;IAEf,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAAe;IACpD,IAAI,CAAC,+BAA+B,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,4BAA4B,CAAC,CAAC,KAAK,EAAE,CAAC;IAC1D,MAAM,MAAM,GAAG,MAAM,yBAAyB,EAAE,CAAC;IACjD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACtD,OAAO,CAAC,IAAI,EAAE,CAAC;IAEf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;AACrD,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function whoamiCommand(): Promise<void>;
@@ -0,0 +1,17 @@
1
+ import chalk from 'chalk';
2
+ import { createAuthenticatedClient } from '../lib/api.js';
3
+ import ora from 'ora';
4
+ export async function whoamiCommand() {
5
+ const spinner = ora('Fetching provider info...').start();
6
+ const client = await createAuthenticatedClient();
7
+ const data = await client.listMyBots();
8
+ spinner.stop();
9
+ console.log(chalk.bold('Provider Info'));
10
+ console.log(` Payout address: ${data.payout_address}`);
11
+ console.log(` Bots: ${data.bots.length}`);
12
+ if (data.bots.length > 0) {
13
+ const active = data.bots.filter((b) => b.status === 'ACTIVE').length;
14
+ console.log(` Active bots: ${active}`);
15
+ }
16
+ }
17
+ //# sourceMappingURL=whoami.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,GAAG,MAAM,KAAK,CAAC;AAEtB,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,OAAO,GAAG,GAAG,CAAC,2BAA2B,CAAC,CAAC,KAAK,EAAE,CAAC;IACzD,MAAM,MAAM,GAAG,MAAM,yBAAyB,EAAE,CAAC;IACjD,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;IACvC,OAAO,CAAC,IAAI,EAAE,CAAC;IAEf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACrD,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,MAAM,CAAC;QACrE,OAAO,CAAC,GAAG,CAAC,qBAAqB,MAAM,EAAE,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import chalk from 'chalk';
4
+ import { initCommand } from './commands/init.js';
5
+ import { loginCommand } from './commands/login.js';
6
+ import { logoutCommand } from './commands/logout.js';
7
+ import { whoamiCommand } from './commands/whoami.js';
8
+ import { walletCommand, walletSetCommand } from './commands/wallet.js';
9
+ import { uploadCommand } from './commands/upload.js';
10
+ import { listCommand } from './commands/list.js';
11
+ import { updateCommand } from './commands/update.js';
12
+ import { deleteCommand } from './commands/delete.js';
13
+ import { infoCommand } from './commands/info.js';
14
+ import { getCommand } from './commands/get.js';
15
+ import { statsCommand } from './commands/stats.js';
16
+ import { ApiClientError } from './lib/api.js';
17
+ const program = new Command();
18
+ program
19
+ .name('marketcc')
20
+ .description('CLI for ClawMarket — upload, manage, and download OpenClaw bots')
21
+ .version('0.1.0');
22
+ program
23
+ .command('init')
24
+ .description('Initialize marketcc configuration')
25
+ .option('--api-url <url>', 'API base URL')
26
+ .action(wrap(initCommand));
27
+ program
28
+ .command('login')
29
+ .description('Authenticate with your secret key')
30
+ .option('--key <key>', 'Secret key (CLAW-SK-...)')
31
+ .action(wrap(loginCommand));
32
+ program
33
+ .command('logout')
34
+ .description('Remove saved secret key')
35
+ .action(wrap(logoutCommand));
36
+ program
37
+ .command('whoami')
38
+ .description('Show current provider info')
39
+ .action(wrap(whoamiCommand));
40
+ const wallet = program
41
+ .command('wallet')
42
+ .description('View or set payout wallet address')
43
+ .action(wrap(walletCommand));
44
+ wallet
45
+ .command('set <address>')
46
+ .description('Set payout wallet address')
47
+ .action(wrap(walletSetCommand));
48
+ program
49
+ .command('upload <dir>')
50
+ .description('Upload a bot from a local directory')
51
+ .option('--wallet <address>', 'Solana payout address (required on first upload)')
52
+ .action(wrap(uploadCommand));
53
+ program
54
+ .command('list')
55
+ .description('List bots on the marketplace or your own bots')
56
+ .option('--mine', 'Show only your bots')
57
+ .option('--category <category>', 'Filter by category')
58
+ .option('--search <query>', 'Search bots')
59
+ .action(wrap(listCommand));
60
+ program
61
+ .command('update <bot-id> <dir>')
62
+ .description('Update an existing bot')
63
+ .action(wrap(updateCommand));
64
+ program
65
+ .command('delete <bot-id>')
66
+ .description('Delete a bot')
67
+ .option('-y, --yes', 'Skip confirmation')
68
+ .action(wrap(deleteCommand));
69
+ program
70
+ .command('info <slug>')
71
+ .description('Show details about a bot on the marketplace')
72
+ .action(wrap(infoCommand));
73
+ program
74
+ .command('get <slug>')
75
+ .description('Download a purchased bot')
76
+ .requiredOption('--key <token>', 'Access token')
77
+ .option('-o, --output <dir>', 'Output directory')
78
+ .action(wrap(getCommand));
79
+ program
80
+ .command('stats')
81
+ .description('Show provider revenue stats')
82
+ .action(wrap(statsCommand));
83
+ function wrap(fn) {
84
+ return (...args) => fn(...args).catch((err) => {
85
+ if (err instanceof ApiClientError) {
86
+ console.error(chalk.red(`API error (${err.statusCode}): ${err.message}`));
87
+ process.exit(1);
88
+ }
89
+ if (err instanceof Error) {
90
+ console.error(chalk.red(err.message));
91
+ process.exit(1);
92
+ }
93
+ console.error(chalk.red('Unknown error'));
94
+ process.exit(1);
95
+ });
96
+ }
97
+ program.parse();
98
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { ProviderBotsResponse, UploadResponse, UpdateResponse, DeleteResponse, MarketplaceListResponse, MarketplaceBotDetail, ProviderStats, VerifyTokenResponse, PayoutResponse } from '../types/index.js';
2
+ export declare class ApiClientError extends Error {
3
+ statusCode: number;
4
+ errorCode: string;
5
+ constructor(statusCode: number, errorCode: string, message: string);
6
+ }
7
+ export declare class ApiClient {
8
+ private baseUrl;
9
+ private secretKey?;
10
+ constructor(baseUrl: string, secretKey?: string | undefined);
11
+ private request;
12
+ listMyBots(): Promise<ProviderBotsResponse>;
13
+ uploadBot(configArchive: string, payoutAddress?: string): Promise<UploadResponse>;
14
+ updateBot(botId: string, configArchive: string): Promise<UpdateResponse>;
15
+ deleteBot(botId: string): Promise<DeleteResponse>;
16
+ getStats(): Promise<ProviderStats>;
17
+ setPayoutAddress(address: string): Promise<PayoutResponse>;
18
+ listMarketplace(opts?: {
19
+ category?: string;
20
+ search?: string;
21
+ limit?: number;
22
+ offset?: number;
23
+ }): Promise<MarketplaceListResponse>;
24
+ getBotInfo(slug: string): Promise<MarketplaceBotDetail>;
25
+ verifyToken(token: string): Promise<VerifyTokenResponse>;
26
+ }
27
+ export declare function createClient(): Promise<ApiClient>;
28
+ export declare function createAuthenticatedClient(): Promise<ApiClient>;
@@ -0,0 +1,107 @@
1
+ import { loadConfig, getApiUrl, getSecretKey } from './config.js';
2
+ export class ApiClientError extends Error {
3
+ statusCode;
4
+ errorCode;
5
+ constructor(statusCode, errorCode, message) {
6
+ super(message);
7
+ this.statusCode = statusCode;
8
+ this.errorCode = errorCode;
9
+ this.name = 'ApiClientError';
10
+ }
11
+ }
12
+ export class ApiClient {
13
+ baseUrl;
14
+ secretKey;
15
+ constructor(baseUrl, secretKey) {
16
+ this.baseUrl = baseUrl;
17
+ this.secretKey = secretKey;
18
+ }
19
+ async request(method, path, body, auth = true) {
20
+ const headers = {
21
+ 'Content-Type': 'application/json',
22
+ };
23
+ if (auth && this.secretKey) {
24
+ headers['Authorization'] = `Bearer ${this.secretKey}`;
25
+ }
26
+ const url = `${this.baseUrl}${path}`;
27
+ const res = await fetch(url, {
28
+ method,
29
+ headers,
30
+ body: body ? JSON.stringify(body) : undefined,
31
+ });
32
+ if (!res.ok) {
33
+ let errBody;
34
+ try {
35
+ errBody = (await res.json());
36
+ }
37
+ catch {
38
+ throw new ApiClientError(res.status, 'UNKNOWN', res.statusText);
39
+ }
40
+ throw new ApiClientError(res.status, errBody.error || 'UNKNOWN', errBody.message || errBody.error || res.statusText);
41
+ }
42
+ return (await res.json());
43
+ }
44
+ // Provider endpoints (auth required)
45
+ async listMyBots() {
46
+ return this.request('GET', '/api/v1/bots');
47
+ }
48
+ async uploadBot(configArchive, payoutAddress) {
49
+ const body = { config_archive: configArchive };
50
+ if (payoutAddress) {
51
+ body.payout_address = payoutAddress;
52
+ }
53
+ // If no secret key, send without auth (first upload creates provider)
54
+ const useAuth = !!this.secretKey;
55
+ return this.request('POST', '/api/v1/bots', body, useAuth);
56
+ }
57
+ async updateBot(botId, configArchive) {
58
+ return this.request('PUT', `/api/v1/bots/${botId}`, {
59
+ config_archive: configArchive,
60
+ });
61
+ }
62
+ async deleteBot(botId) {
63
+ return this.request('DELETE', `/api/v1/bots/${botId}`);
64
+ }
65
+ async getStats() {
66
+ return this.request('GET', '/api/v1/provider/stats');
67
+ }
68
+ async setPayoutAddress(address) {
69
+ return this.request('PUT', '/api/v1/provider/payout', {
70
+ payout_address: address,
71
+ });
72
+ }
73
+ // Public marketplace endpoints
74
+ async listMarketplace(opts) {
75
+ const params = new URLSearchParams();
76
+ if (opts?.category)
77
+ params.set('category', opts.category);
78
+ if (opts?.search)
79
+ params.set('search', opts.search);
80
+ if (opts?.limit)
81
+ params.set('limit', String(opts.limit));
82
+ if (opts?.offset)
83
+ params.set('offset', String(opts.offset));
84
+ const qs = params.toString();
85
+ return this.request('GET', `/api/v1/marketplace/bots${qs ? `?${qs}` : ''}`, undefined, false);
86
+ }
87
+ async getBotInfo(slug) {
88
+ return this.request('GET', `/api/v1/marketplace/bots/${slug}`, undefined, false);
89
+ }
90
+ // Access token verification
91
+ async verifyToken(token) {
92
+ return this.request('GET', `/api/v1/verify/${token}`, undefined, false);
93
+ }
94
+ }
95
+ export async function createClient() {
96
+ const config = await loadConfig();
97
+ return new ApiClient(getApiUrl(config), getSecretKey(config));
98
+ }
99
+ export async function createAuthenticatedClient() {
100
+ const config = await loadConfig();
101
+ const key = getSecretKey(config);
102
+ if (!key) {
103
+ throw new Error('Not logged in. Run `marketcc login` or `marketcc upload` first.');
104
+ }
105
+ return new ApiClient(getApiUrl(config), key);
106
+ }
107
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { CliConfig } from '../types/index.js';
2
+ export declare function ensureConfigDir(): Promise<void>;
3
+ export declare function loadConfig(): Promise<CliConfig>;
4
+ export declare function saveConfig(config: Partial<CliConfig>): Promise<void>;
5
+ export declare function clearConfig(): Promise<void>;
6
+ export declare function getSecretKey(config: CliConfig): string | undefined;
7
+ export declare function getApiUrl(config: CliConfig): string;
8
+ export declare function getConfigDir(): string;
@@ -0,0 +1,45 @@
1
+ import { readFile, writeFile, mkdir, chmod } from 'node:fs/promises';
2
+ import { existsSync } from 'node:fs';
3
+ import { homedir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ const CONFIG_DIR = join(homedir(), '.marketcc');
6
+ const CREDENTIALS_FILE = join(CONFIG_DIR, 'credentials');
7
+ const DEFAULT_API_URL = 'http://100.73.202.72:8000';
8
+ export async function ensureConfigDir() {
9
+ if (!existsSync(CONFIG_DIR)) {
10
+ await mkdir(CONFIG_DIR, { recursive: true });
11
+ await chmod(CONFIG_DIR, 0o700);
12
+ }
13
+ }
14
+ export async function loadConfig() {
15
+ try {
16
+ const raw = await readFile(CREDENTIALS_FILE, 'utf-8');
17
+ return JSON.parse(raw);
18
+ }
19
+ catch {
20
+ return { api_url: DEFAULT_API_URL };
21
+ }
22
+ }
23
+ export async function saveConfig(config) {
24
+ await ensureConfigDir();
25
+ const existing = await loadConfig();
26
+ const merged = { ...existing, ...config };
27
+ await writeFile(CREDENTIALS_FILE, JSON.stringify(merged, null, 2) + '\n', 'utf-8');
28
+ await chmod(CREDENTIALS_FILE, 0o600);
29
+ }
30
+ export async function clearConfig() {
31
+ const existing = await loadConfig();
32
+ delete existing.secret_key;
33
+ await writeFile(CREDENTIALS_FILE, JSON.stringify(existing, null, 2) + '\n', 'utf-8');
34
+ await chmod(CREDENTIALS_FILE, 0o600);
35
+ }
36
+ export function getSecretKey(config) {
37
+ return config.secret_key;
38
+ }
39
+ export function getApiUrl(config) {
40
+ return process.env.MARKETCC_API_URL || config.api_url || DEFAULT_API_URL;
41
+ }
42
+ export function getConfigDir() {
43
+ return CONFIG_DIR;
44
+ }
45
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;AAChD,MAAM,gBAAgB,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AACzD,MAAM,eAAe,GAAG,2BAA2B,CAAC;AAEpD,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,MAAM,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7C,MAAM,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IACjC,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QACtD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAc,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC;IACtC,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAA0B;IACzD,MAAM,eAAe,EAAE,CAAC;IACxB,MAAM,QAAQ,GAAG,MAAM,UAAU,EAAE,CAAC;IACpC,MAAM,MAAM,GAAc,EAAE,GAAG,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC;IACrD,MAAM,SAAS,CAAC,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IACnF,MAAM,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,QAAQ,GAAG,MAAM,UAAU,EAAE,CAAC;IACpC,OAAO,QAAQ,CAAC,UAAU,CAAC;IAC3B,MAAM,SAAS,CAAC,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IACrF,MAAM,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAiB;IAC5C,OAAO,MAAM,CAAC,UAAU,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,MAAiB;IACzC,OAAO,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,MAAM,CAAC,OAAO,IAAI,eAAe,CAAC;AAC3E,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -0,0 +1,8 @@
1
+ interface FileEntry {
2
+ name: string;
3
+ size: number;
4
+ }
5
+ export declare function listBotFiles(dirPath: string): Promise<FileEntry[]>;
6
+ export declare function packageBot(dirPath: string): Promise<string>;
7
+ export declare function formatFileSize(bytes: number): string;
8
+ export {};
@@ -0,0 +1,55 @@
1
+ import { readdir, stat } from 'node:fs/promises';
2
+ import { join, relative } from 'node:path';
3
+ import * as tar from 'tar';
4
+ async function walkDir(dir, base) {
5
+ const entries = [];
6
+ const items = await readdir(dir, { withFileTypes: true });
7
+ for (const item of items) {
8
+ const fullPath = join(dir, item.name);
9
+ if (item.isDirectory()) {
10
+ // Skip common non-essential directories
11
+ if (['node_modules', '.git', '__pycache__', '.venv'].includes(item.name)) {
12
+ continue;
13
+ }
14
+ entries.push(...(await walkDir(fullPath, base)));
15
+ }
16
+ else {
17
+ const info = await stat(fullPath);
18
+ entries.push({
19
+ name: relative(base, fullPath),
20
+ size: info.size,
21
+ });
22
+ }
23
+ }
24
+ return entries;
25
+ }
26
+ export async function listBotFiles(dirPath) {
27
+ return walkDir(dirPath, dirPath);
28
+ }
29
+ export async function packageBot(dirPath) {
30
+ const files = await listBotFiles(dirPath);
31
+ const fileNames = files.map((f) => f.name);
32
+ const chunks = [];
33
+ await new Promise((resolve, reject) => {
34
+ const stream = tar.create({
35
+ gzip: true,
36
+ cwd: dirPath,
37
+ }, fileNames);
38
+ // tar.create returns a ReadableStream
39
+ stream.on('data', (chunk) => {
40
+ chunks.push(chunk);
41
+ });
42
+ stream.on('end', () => resolve());
43
+ stream.on('error', (err) => reject(err));
44
+ });
45
+ const buffer = Buffer.concat(chunks);
46
+ return buffer.toString('base64');
47
+ }
48
+ export function formatFileSize(bytes) {
49
+ if (bytes < 1024)
50
+ return `${bytes} B`;
51
+ if (bytes < 1024 * 1024)
52
+ return `${(bytes / 1024).toFixed(1)} KB`;
53
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
54
+ }
55
+ //# sourceMappingURL=packager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packager.js","sourceRoot":"","sources":["../../src/lib/packager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { SkillMeta } from '../types/index.js';
2
+ export declare class ValidationError extends Error {
3
+ constructor(message: string);
4
+ }
5
+ export declare function validateSkillMd(dirPath: string): Promise<SkillMeta>;
@@ -0,0 +1,67 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { existsSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { parse as parseYaml } from 'yaml';
5
+ export class ValidationError extends Error {
6
+ constructor(message) {
7
+ super(message);
8
+ this.name = 'ValidationError';
9
+ }
10
+ }
11
+ export async function validateSkillMd(dirPath) {
12
+ const skillPath = join(dirPath, 'SKILL.md');
13
+ if (!existsSync(skillPath)) {
14
+ throw new ValidationError(`SKILL.md not found in ${dirPath}`);
15
+ }
16
+ const raw = await readFile(skillPath, 'utf-8');
17
+ // Parse YAML frontmatter
18
+ const frontmatterMatch = raw.match(/^---\s*\n([\s\S]*?)\n---\s*\n?([\s\S]*)$/);
19
+ if (!frontmatterMatch) {
20
+ throw new ValidationError('SKILL.md must have YAML frontmatter between --- delimiters');
21
+ }
22
+ const [, yamlStr, body] = frontmatterMatch;
23
+ let frontmatter;
24
+ try {
25
+ frontmatter = parseYaml(yamlStr);
26
+ }
27
+ catch (e) {
28
+ throw new ValidationError(`Invalid YAML frontmatter: ${e instanceof Error ? e.message : String(e)}`);
29
+ }
30
+ if (!frontmatter || typeof frontmatter !== 'object') {
31
+ throw new ValidationError('SKILL.md frontmatter must be a YAML object');
32
+ }
33
+ // Validate required fields
34
+ const { name, description, category, tags, clawmarket } = frontmatter;
35
+ if (!name || typeof name !== 'string') {
36
+ throw new ValidationError('SKILL.md: "name" is required (string)');
37
+ }
38
+ if (!description || typeof description !== 'string') {
39
+ throw new ValidationError('SKILL.md: "description" is required (string)');
40
+ }
41
+ // Validate clawmarket.price_usd
42
+ const cm = clawmarket;
43
+ if (!cm || typeof cm !== 'object' || !('price_usd' in cm)) {
44
+ throw new ValidationError('SKILL.md: "clawmarket.price_usd" is required');
45
+ }
46
+ const priceUsd = Number(cm.price_usd);
47
+ if (isNaN(priceUsd) || priceUsd <= 0) {
48
+ throw new ValidationError('SKILL.md: "clawmarket.price_usd" must be a positive number');
49
+ }
50
+ // Validate optional fields
51
+ if (category !== undefined && typeof category !== 'string') {
52
+ throw new ValidationError('SKILL.md: "category" must be a string');
53
+ }
54
+ if (tags !== undefined && !Array.isArray(tags)) {
55
+ throw new ValidationError('SKILL.md: "tags" must be an array');
56
+ }
57
+ return {
58
+ name: name,
59
+ description: description,
60
+ category: category,
61
+ tags: tags,
62
+ priceUsd,
63
+ longDescription: body.trim(),
64
+ metadata: frontmatter,
65
+ };
66
+ }
67
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/lib/validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,113 @@
1
+ export interface CliConfig {
2
+ secret_key?: string;
3
+ api_url: string;
4
+ }
5
+ export interface SkillMeta {
6
+ name: string;
7
+ description: string;
8
+ category?: string;
9
+ tags?: string[];
10
+ priceUsd: number;
11
+ longDescription: string;
12
+ metadata?: Record<string, unknown>;
13
+ }
14
+ export interface Bot {
15
+ id: string;
16
+ slug: string;
17
+ name: string;
18
+ description: string;
19
+ category: string;
20
+ tags: string[];
21
+ price_usd: number;
22
+ status: string;
23
+ total_buyers: number;
24
+ created_at: string;
25
+ updated_at: string;
26
+ }
27
+ export interface ProviderBotsResponse {
28
+ bots: Bot[];
29
+ payout_address: string;
30
+ }
31
+ export interface UploadResponse {
32
+ bot_id: string;
33
+ slug: string;
34
+ name: string;
35
+ marketplace_url: string;
36
+ secret_key?: string;
37
+ }
38
+ export interface UpdateResponse {
39
+ bot_id: string;
40
+ slug: string;
41
+ name: string;
42
+ updated_at: string;
43
+ }
44
+ export interface DeleteResponse {
45
+ message: string;
46
+ bot_id: string;
47
+ }
48
+ export interface MarketplaceBot {
49
+ id: string;
50
+ slug: string;
51
+ name: string;
52
+ description: string;
53
+ category: string;
54
+ tags: string[];
55
+ price_usd: number;
56
+ provider_address: string;
57
+ buyer_count: number;
58
+ created_at: string;
59
+ }
60
+ export interface MarketplaceListResponse {
61
+ bots: MarketplaceBot[];
62
+ total: number;
63
+ limit: number;
64
+ offset: number;
65
+ }
66
+ export interface MarketplaceBotDetail {
67
+ id: string;
68
+ slug: string;
69
+ name: string;
70
+ description: string;
71
+ long_description: string;
72
+ category: string;
73
+ tags: string[];
74
+ price_usd: number;
75
+ metadata: Record<string, unknown>;
76
+ provider_address: string;
77
+ buyer_count: number;
78
+ created_at: string;
79
+ updated_at: string;
80
+ }
81
+ export interface ProviderStats {
82
+ total_revenue_usd: number;
83
+ total_buyers: number;
84
+ bots: {
85
+ bot_id: string;
86
+ slug: string;
87
+ name: string;
88
+ status: string;
89
+ revenue_usd: number;
90
+ buyer_count: number;
91
+ }[];
92
+ payout_address: string;
93
+ }
94
+ export interface VerifyTokenResponse {
95
+ valid: boolean;
96
+ bot_id?: string;
97
+ bot_name?: string;
98
+ bot_slug?: string;
99
+ config_url?: string;
100
+ expires_at?: string;
101
+ channel_type?: string | null;
102
+ channel_user_id?: string | null;
103
+ activated_at?: string | null;
104
+ error?: string;
105
+ }
106
+ export interface PayoutResponse {
107
+ message: string;
108
+ payout_address: string;
109
+ }
110
+ export interface ApiError {
111
+ error: string;
112
+ message?: string;
113
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@clawmarket.cc/marketcc",
3
+ "version": "0.1.0",
4
+ "description": "CLI for ClawMarket — upload, manage, and download OpenClaw bots",
5
+ "type": "module",
6
+ "bin": {
7
+ "marketcc": "./dist/index.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "dev": "tsx src/index.ts",
12
+ "prepublishOnly": "npm run build"
13
+ },
14
+ "engines": {
15
+ "node": ">=20.0.0"
16
+ },
17
+ "dependencies": {
18
+ "chalk": "^5.3.0",
19
+ "commander": "^12.0.0",
20
+ "ora": "^8.0.0",
21
+ "tar": "^7.0.0",
22
+ "yaml": "^2.8.0"
23
+ },
24
+ "devDependencies": {
25
+ "@types/node": "^22.0.0",
26
+ "tsx": "^4.19.0",
27
+ "typescript": "^5.7.0"
28
+ },
29
+ "files": [
30
+ "dist"
31
+ ],
32
+ "keywords": [
33
+ "marketcc",
34
+ "openclaw",
35
+ "marketplace",
36
+ "bots",
37
+ "cli"
38
+ ],
39
+ "license": "MIT"
40
+ }