upclaw-cli 1.0.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 (53) hide show
  1. package/README.md +188 -0
  2. package/dist/commands/info.d.ts +2 -0
  3. package/dist/commands/info.d.ts.map +1 -0
  4. package/dist/commands/info.js +44 -0
  5. package/dist/commands/info.js.map +1 -0
  6. package/dist/commands/install.d.ts +4 -0
  7. package/dist/commands/install.d.ts.map +1 -0
  8. package/dist/commands/install.js +100 -0
  9. package/dist/commands/install.js.map +1 -0
  10. package/dist/commands/list.d.ts +4 -0
  11. package/dist/commands/list.d.ts.map +1 -0
  12. package/dist/commands/list.js +43 -0
  13. package/dist/commands/list.js.map +1 -0
  14. package/dist/commands/login.d.ts +5 -0
  15. package/dist/commands/login.d.ts.map +1 -0
  16. package/dist/commands/login.js +111 -0
  17. package/dist/commands/login.js.map +1 -0
  18. package/dist/commands/publish.d.ts +10 -0
  19. package/dist/commands/publish.d.ts.map +1 -0
  20. package/dist/commands/publish.js +163 -0
  21. package/dist/commands/publish.js.map +1 -0
  22. package/dist/commands/search.d.ts +9 -0
  23. package/dist/commands/search.d.ts.map +1 -0
  24. package/dist/commands/search.js +47 -0
  25. package/dist/commands/search.js.map +1 -0
  26. package/dist/commands/whoami.d.ts +2 -0
  27. package/dist/commands/whoami.d.ts.map +1 -0
  28. package/dist/commands/whoami.js +22 -0
  29. package/dist/commands/whoami.js.map +1 -0
  30. package/dist/config.d.ts +10 -0
  31. package/dist/config.d.ts.map +1 -0
  32. package/dist/config.js +13 -0
  33. package/dist/config.js.map +1 -0
  34. package/dist/index.d.ts +3 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +59 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/utils/api.d.ts +5 -0
  39. package/dist/utils/api.d.ts.map +1 -0
  40. package/dist/utils/api.js +31 -0
  41. package/dist/utils/api.js.map +1 -0
  42. package/package.json +49 -0
  43. package/src/commands/info.ts +42 -0
  44. package/src/commands/install.ts +73 -0
  45. package/src/commands/list.ts +47 -0
  46. package/src/commands/login.ts +80 -0
  47. package/src/commands/publish.ts +152 -0
  48. package/src/commands/search.ts +56 -0
  49. package/src/commands/whoami.ts +18 -0
  50. package/src/config.ts +14 -0
  51. package/src/index.ts +67 -0
  52. package/src/utils/api.ts +26 -0
  53. package/tsconfig.json +21 -0
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.publishCommand = publishCommand;
40
+ const chalk_1 = __importDefault(require("chalk"));
41
+ const ora_1 = __importDefault(require("ora"));
42
+ const inquirer_1 = __importDefault(require("inquirer"));
43
+ const fs = __importStar(require("fs-extra"));
44
+ const path = __importStar(require("path"));
45
+ const archiver_1 = __importDefault(require("archiver"));
46
+ const form_data_1 = __importDefault(require("form-data"));
47
+ const api_1 = require("../utils/api");
48
+ async function publishCommand(options) {
49
+ (0, api_1.requireAuth)();
50
+ console.log(chalk_1.default.bold.cyan("\n📤 Publishing Skill to UpClaw\n"));
51
+ // Check for required files
52
+ const requiredFiles = ["SKILL.md", "package.json"];
53
+ const missingFiles = requiredFiles.filter((file) => !fs.existsSync(file));
54
+ if (missingFiles.length > 0) {
55
+ console.error(chalk_1.default.red(`❌ Missing required files: ${missingFiles.join(", ")}\n`));
56
+ console.log(chalk_1.default.gray("Your skill must include:"));
57
+ console.log(chalk_1.default.gray(" - SKILL.md (documentation)"));
58
+ console.log(chalk_1.default.gray(" - package.json (dependencies)\n"));
59
+ process.exit(1);
60
+ }
61
+ // Get metadata from user if not provided
62
+ let metadata = options;
63
+ if (!metadata.name || !metadata.description || !metadata.category || !metadata.price) {
64
+ const packageJson = await fs.readJSON("package.json");
65
+ const answers = await inquirer_1.default.prompt([
66
+ {
67
+ type: "input",
68
+ name: "name",
69
+ message: "Skill name:",
70
+ default: metadata.name || packageJson.name,
71
+ when: !metadata.name,
72
+ },
73
+ {
74
+ type: "input",
75
+ name: "description",
76
+ message: "Description:",
77
+ default: metadata.description || packageJson.description,
78
+ when: !metadata.description,
79
+ },
80
+ {
81
+ type: "list",
82
+ name: "category",
83
+ message: "Category:",
84
+ choices: ["automation", "data", "communication", "web", "ai", "utility", "other"],
85
+ when: !metadata.category,
86
+ },
87
+ {
88
+ type: "input",
89
+ name: "price",
90
+ message: "Price in USDC:",
91
+ validate: (input) => {
92
+ const num = parseFloat(input);
93
+ if (isNaN(num) || num < 0) {
94
+ return "Please enter a valid price (e.g., 25.00)";
95
+ }
96
+ return true;
97
+ },
98
+ when: !metadata.price,
99
+ },
100
+ {
101
+ type: "input",
102
+ name: "version",
103
+ message: "Version:",
104
+ default: metadata.version || packageJson.version || "1.0.0",
105
+ when: !metadata.version,
106
+ },
107
+ ]);
108
+ metadata = { ...metadata, ...answers };
109
+ }
110
+ const spinner = (0, ora_1.default)("Creating skill bundle...").start();
111
+ try {
112
+ // Create a zip of the current directory
113
+ const zipPath = path.join(process.cwd(), "skill-bundle.zip");
114
+ const output = fs.createWriteStream(zipPath);
115
+ const archive = (0, archiver_1.default)("zip", { zlib: { level: 9 } });
116
+ archive.pipe(output);
117
+ archive.glob("**/*", {
118
+ ignore: ["node_modules/**", "*.zip", ".git/**", "dist/**", ".env*"],
119
+ });
120
+ await archive.finalize();
121
+ await new Promise((resolve) => output.on("close", () => resolve(undefined)));
122
+ spinner.text = "Uploading to IPFS...";
123
+ // Upload to marketplace API
124
+ const api = (0, api_1.createAPIClient)();
125
+ const formData = new form_data_1.default();
126
+ formData.append("name", metadata.name);
127
+ formData.append("description", metadata.description);
128
+ formData.append("category", metadata.category);
129
+ formData.append("price", metadata.price);
130
+ formData.append("version", metadata.version);
131
+ formData.append("files", fs.createReadStream(zipPath));
132
+ const response = await api.post("/cli/skills/publish", formData, {
133
+ headers: formData.getHeaders(),
134
+ maxContentLength: Infinity,
135
+ maxBodyLength: Infinity,
136
+ });
137
+ // Clean up
138
+ await fs.remove(zipPath);
139
+ spinner.succeed(chalk_1.default.green("✓ Skill uploaded successfully!"));
140
+ const { skill, message, next_steps } = response.data;
141
+ console.log(chalk_1.default.bold(`\n✨ ${metadata.name} is ready!\n`));
142
+ console.log(`${chalk_1.default.gray("Skill ID:")} ${skill.id}`);
143
+ console.log(`${chalk_1.default.gray("IPFS CID:")} ${skill.ipfs_cid}`);
144
+ console.log(`${chalk_1.default.gray("Price:")} ${chalk_1.default.green("$" + skill.price + " USDC")}\n`);
145
+ console.log(chalk_1.default.yellow(message + "\n"));
146
+ console.log(chalk_1.default.bold("⚡ Next Steps:\n"));
147
+ next_steps.forEach((step, i) => {
148
+ console.log(` ${i + 1}. ${step}`);
149
+ });
150
+ console.log();
151
+ }
152
+ catch (error) {
153
+ spinner.fail(chalk_1.default.red("Publication failed"));
154
+ if (error.response?.data?.error) {
155
+ console.error(chalk_1.default.red(`\nError: ${error.response.data.error}\n`));
156
+ }
157
+ else {
158
+ console.error(chalk_1.default.red(`\nError: ${error.message}\n`));
159
+ }
160
+ process.exit(1);
161
+ }
162
+ }
163
+ //# sourceMappingURL=publish.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/commands/publish.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ interface SearchOptions {
2
+ category?: string;
3
+ minPrice?: string;
4
+ maxPrice?: string;
5
+ limit?: string;
6
+ }
7
+ export declare function searchCommand(query: string, options: SearchOptions): Promise<void>;
8
+ export {};
9
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"AAIA,UAAU,aAAa;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,iBA4CxE"}
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.searchCommand = searchCommand;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const ora_1 = __importDefault(require("ora"));
9
+ const api_1 = require("../utils/api");
10
+ async function searchCommand(query, options) {
11
+ const spinner = (0, ora_1.default)("Searching marketplace...").start();
12
+ try {
13
+ const api = (0, api_1.createAPIClient)();
14
+ const params = new URLSearchParams({
15
+ q: query,
16
+ limit: options.limit || "20",
17
+ });
18
+ if (options.category)
19
+ params.append("category", options.category);
20
+ if (options.minPrice)
21
+ params.append("minPrice", options.minPrice);
22
+ if (options.maxPrice)
23
+ params.append("maxPrice", options.maxPrice);
24
+ const response = await api.get(`/cli/skills/search?${params.toString()}`);
25
+ const { skills, count } = response.data;
26
+ spinner.stop();
27
+ if (skills.length === 0) {
28
+ console.log(chalk_1.default.yellow("\n⚠️ No skills found matching your query.\n"));
29
+ return;
30
+ }
31
+ console.log(chalk_1.default.bold(`\n🔍 Found ${count} skill${count !== 1 ? "s" : ""}\n`));
32
+ skills.forEach((skill) => {
33
+ console.log(chalk_1.default.bold.cyan(`• ${skill.name}`));
34
+ console.log(` ${skill.description}`);
35
+ console.log(` ${chalk_1.default.gray("Category:")} ${skill.category} ${chalk_1.default.gray("Price:")} ${chalk_1.default.green("$" + skill.price_usdc)} ${chalk_1.default.gray("⬇")} ${skill.downloads}`);
36
+ console.log(` ${chalk_1.default.gray("ID:")} ${skill.id}\n`);
37
+ });
38
+ console.log(chalk_1.default.gray(`Run 'upclaw info <skill-name>' to see more details`));
39
+ console.log(chalk_1.default.gray(`Run 'upclaw install <skill-name>' to purchase and install\n`));
40
+ }
41
+ catch (error) {
42
+ spinner.fail(chalk_1.default.red("Search failed"));
43
+ console.error(chalk_1.default.red(`Error: ${error.message}\n`));
44
+ process.exit(1);
45
+ }
46
+ }
47
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":";;;;;AAWA,sCA4CC;AAvDD,kDAA0B;AAC1B,8CAAsB;AACtB,sCAA+C;AASxC,KAAK,UAAU,aAAa,CAAC,KAAa,EAAE,OAAsB;IACvE,MAAM,OAAO,GAAG,IAAA,aAAG,EAAC,0BAA0B,CAAC,CAAC,KAAK,EAAE,CAAC;IAExD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAA,qBAAe,GAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;YACjC,CAAC,EAAE,KAAK;YACR,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,IAAI;SAC7B,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,QAAQ;YAAE,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QAClE,IAAI,OAAO,CAAC,QAAQ;YAAE,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QAClE,IAAI,OAAO,CAAC,QAAQ;YAAE,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QAElE,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,sBAAsB,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC1E,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC;QAExC,OAAO,CAAC,IAAI,EAAE,CAAC;QAEf,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,MAAM,CAAC,8CAA8C,CAAC,CAAC,CAAC;YAC1E,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,cAAc,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;QAEhF,MAAM,CAAC,OAAO,CAAC,CAAC,KAAU,EAAE,EAAE;YAC5B,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YAChD,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;YACtC,OAAO,CAAC,GAAG,CACT,KAAK,eAAK,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,QAAQ,KAAK,eAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,eAAK,CAAC,KAAK,CACpF,GAAG,GAAG,KAAK,CAAC,UAAU,CACvB,KAAK,eAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,SAAS,EAAE,CAC3C,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,KAAK,eAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC,CAAC;QAC9E,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC,CAAC;IACzF,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,eAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC;QACzC,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function whoamiCommand(): Promise<void>;
2
+ //# sourceMappingURL=whoami.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAGA,wBAAsB,aAAa,kBAclC"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.whoamiCommand = whoamiCommand;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const config_1 = require("../config");
9
+ async function whoamiCommand() {
10
+ const token = config_1.config.get("token");
11
+ const address = config_1.config.get("address");
12
+ const username = config_1.config.get("username");
13
+ if (!token) {
14
+ console.log(chalk_1.default.yellow("Not authenticated. Run 'upclaw login' to sign in."));
15
+ return;
16
+ }
17
+ console.log(chalk_1.default.bold("\n🔐 Authentication Status\n"));
18
+ console.log(`Username: ${chalk_1.default.cyan(username)}`);
19
+ console.log(`Address: ${chalk_1.default.cyan(address)}`);
20
+ console.log(`Status: ${chalk_1.default.green("✓ Authenticated")}\n`);
21
+ }
22
+ //# sourceMappingURL=whoami.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":";;;;;AAGA,sCAcC;AAjBD,kDAA0B;AAC1B,sCAAmC;AAE5B,KAAK,UAAU,aAAa;IACjC,MAAM,KAAK,GAAG,eAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,eAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACtC,MAAM,QAAQ,GAAG,eAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAExC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,MAAM,CAAC,mDAAmD,CAAC,CAAC,CAAC;QAC/E,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,aAAa,eAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,aAAa,eAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,aAAa,eAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;AAC/D,CAAC"}
@@ -0,0 +1,10 @@
1
+ import Conf from "conf";
2
+ interface UpClawConfig {
3
+ token?: string;
4
+ address?: string;
5
+ username?: string;
6
+ }
7
+ export declare const config: Conf<UpClawConfig>;
8
+ export declare const API_BASE_URL: string;
9
+ export {};
10
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,UAAU,YAAY;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,MAAM,oBAGjB,CAAC;AAEH,eAAO,MAAM,YAAY,QAAwD,CAAC"}
package/dist/config.js ADDED
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.API_BASE_URL = exports.config = void 0;
7
+ const conf_1 = __importDefault(require("conf"));
8
+ exports.config = new conf_1.default({
9
+ projectName: "upclaw-cli",
10
+ defaults: {},
11
+ });
12
+ exports.API_BASE_URL = process.env.UPCLAW_API_URL || "https://upclaw.ai/api";
13
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAwB;AAQX,QAAA,MAAM,GAAG,IAAI,cAAI,CAAe;IAC3C,WAAW,EAAE,YAAY;IACzB,QAAQ,EAAE,EAAE;CACb,CAAC,CAAC;AAEU,QAAA,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,uBAAuB,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const commander_1 = require("commander");
5
+ const search_1 = require("./commands/search");
6
+ const install_1 = require("./commands/install");
7
+ const publish_1 = require("./commands/publish");
8
+ const login_1 = require("./commands/login");
9
+ const whoami_1 = require("./commands/whoami");
10
+ const list_1 = require("./commands/list");
11
+ const info_1 = require("./commands/info");
12
+ const program = new commander_1.Command();
13
+ program
14
+ .name("upclaw")
15
+ .description("CLI tool for UpClaw marketplace - buy and sell OpenClaw agent skills")
16
+ .version("1.0.0");
17
+ program
18
+ .command("login")
19
+ .description("Authenticate with your wallet")
20
+ .option("-p, --private-key <key>", "Wallet private key (0x...)")
21
+ .option("-k, --keystore <file>", "Path to keystore JSON file")
22
+ .action(login_1.loginCommand);
23
+ program
24
+ .command("whoami")
25
+ .description("Show current authentication status")
26
+ .action(whoami_1.whoamiCommand);
27
+ program
28
+ .command("search <query>")
29
+ .description("Search for skills in the marketplace")
30
+ .option("-c, --category <category>", "Filter by category")
31
+ .option("--min-price <price>", "Minimum price in USDC")
32
+ .option("--max-price <price>", "Maximum price in USDC")
33
+ .option("-l, --limit <number>", "Number of results to show", "20")
34
+ .action(search_1.searchCommand);
35
+ program
36
+ .command("info <skill-name>")
37
+ .description("View detailed information about a skill")
38
+ .action(info_1.infoCommand);
39
+ program
40
+ .command("install <skill-name>")
41
+ .description("Purchase and install a skill")
42
+ .option("-o, --output <directory>", "Installation directory", process.env.HOME + "/.upclaw/skills")
43
+ .action(install_1.installCommand);
44
+ program
45
+ .command("list")
46
+ .description("List your owned skills")
47
+ .option("-f, --format <format>", "Output format (table|json)", "table")
48
+ .action(list_1.listCommand);
49
+ program
50
+ .command("publish")
51
+ .description("Publish current directory as a skill")
52
+ .option("-n, --name <name>", "Skill name")
53
+ .option("-d, --description <description>", "Skill description")
54
+ .option("-c, --category <category>", "Category (automation|data|communication|etc)")
55
+ .option("-p, --price <price>", "Price in USDC")
56
+ .option("-v, --version <version>", "Version number", "1.0.0")
57
+ .action(publish_1.publishCommand);
58
+ program.parse();
59
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,8CAAkD;AAClD,gDAAoD;AACpD,gDAAoD;AACpD,4CAAgD;AAChD,8CAAkD;AAClD,0CAA8C;AAC9C,0CAA8C;AAE9C,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CAAC,sEAAsE,CAAC;KACnF,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,+BAA+B,CAAC;KAC5C,MAAM,CAAC,yBAAyB,EAAE,4BAA4B,CAAC;KAC/D,MAAM,CAAC,uBAAuB,EAAE,4BAA4B,CAAC;KAC7D,MAAM,CAAC,oBAAY,CAAC,CAAC;AAExB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,oCAAoC,CAAC;KACjD,MAAM,CAAC,sBAAa,CAAC,CAAC;AAEzB,OAAO;KACJ,OAAO,CAAC,gBAAgB,CAAC;KACzB,WAAW,CAAC,sCAAsC,CAAC;KACnD,MAAM,CAAC,2BAA2B,EAAE,oBAAoB,CAAC;KACzD,MAAM,CAAC,qBAAqB,EAAE,uBAAuB,CAAC;KACtD,MAAM,CAAC,qBAAqB,EAAE,uBAAuB,CAAC;KACtD,MAAM,CAAC,sBAAsB,EAAE,2BAA2B,EAAE,IAAI,CAAC;KACjE,MAAM,CAAC,sBAAa,CAAC,CAAC;AAEzB,OAAO;KACJ,OAAO,CAAC,mBAAmB,CAAC;KAC5B,WAAW,CAAC,yCAAyC,CAAC;KACtD,MAAM,CAAC,kBAAW,CAAC,CAAC;AAEvB,OAAO;KACJ,OAAO,CAAC,sBAAsB,CAAC;KAC/B,WAAW,CAAC,8BAA8B,CAAC;KAC3C,MAAM,CAAC,0BAA0B,EAAE,wBAAwB,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,iBAAiB,CAAC;KAClG,MAAM,CAAC,wBAAc,CAAC,CAAC;AAE1B,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,wBAAwB,CAAC;KACrC,MAAM,CAAC,uBAAuB,EAAE,4BAA4B,EAAE,OAAO,CAAC;KACtE,MAAM,CAAC,kBAAW,CAAC,CAAC;AAEvB,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,sCAAsC,CAAC;KACnD,MAAM,CAAC,mBAAmB,EAAE,YAAY,CAAC;KACzC,MAAM,CAAC,iCAAiC,EAAE,mBAAmB,CAAC;KAC9D,MAAM,CAAC,2BAA2B,EAAE,8CAA8C,CAAC;KACnF,MAAM,CAAC,qBAAqB,EAAE,eAAe,CAAC;KAC9C,MAAM,CAAC,yBAAyB,EAAE,gBAAgB,EAAE,OAAO,CAAC;KAC5D,MAAM,CAAC,wBAAc,CAAC,CAAC;AAE1B,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { AxiosInstance } from "axios";
2
+ export declare function createAPIClient(): AxiosInstance;
3
+ export declare function isAuthenticated(): boolean;
4
+ export declare function requireAuth(): void;
5
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/utils/api.ts"],"names":[],"mappings":"AAAA,OAAc,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAG7C,wBAAgB,eAAe,IAAI,aAAa,CAW/C;AAED,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED,wBAAgB,WAAW,SAK1B"}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createAPIClient = createAPIClient;
7
+ exports.isAuthenticated = isAuthenticated;
8
+ exports.requireAuth = requireAuth;
9
+ const axios_1 = __importDefault(require("axios"));
10
+ const config_1 = require("../config");
11
+ function createAPIClient() {
12
+ const token = config_1.config.get("token");
13
+ return axios_1.default.create({
14
+ baseURL: config_1.API_BASE_URL,
15
+ headers: token
16
+ ? {
17
+ Authorization: `Bearer ${token}`,
18
+ }
19
+ : {},
20
+ });
21
+ }
22
+ function isAuthenticated() {
23
+ return !!config_1.config.get("token");
24
+ }
25
+ function requireAuth() {
26
+ if (!isAuthenticated()) {
27
+ console.error("❌ Not authenticated. Please run 'upclaw login' first.");
28
+ process.exit(1);
29
+ }
30
+ }
31
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/utils/api.ts"],"names":[],"mappings":";;;;;AAGA,0CAWC;AAED,0CAEC;AAED,kCAKC;AAzBD,kDAA6C;AAC7C,sCAAiD;AAEjD,SAAgB,eAAe;IAC7B,MAAM,KAAK,GAAG,eAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAElC,OAAO,eAAK,CAAC,MAAM,CAAC;QAClB,OAAO,EAAE,qBAAY;QACrB,OAAO,EAAE,KAAK;YACZ,CAAC,CAAC;gBACE,aAAa,EAAE,UAAU,KAAK,EAAE;aACjC;YACH,CAAC,CAAC,EAAE;KACP,CAAC,CAAC;AACL,CAAC;AAED,SAAgB,eAAe;IAC7B,OAAO,CAAC,CAAC,eAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAC/B,CAAC;AAED,SAAgB,WAAW;IACzB,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;QACvB,OAAO,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;QACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "upclaw-cli",
3
+ "version": "1.0.0",
4
+ "description": "CLI tool for UpClaw marketplace - buy and sell OpenClaw agent skills",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "upclaw": "./dist/index.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc --noEmitOnError false || true",
11
+ "dev": "tsx src/index.ts"
12
+ },
13
+ "keywords": [
14
+ "openclaw",
15
+ "skills",
16
+ "marketplace",
17
+ "blockchain",
18
+ "base",
19
+ "ipfs",
20
+ "agents"
21
+ ],
22
+ "author": "UpClaw",
23
+ "license": "MIT",
24
+ "dependencies": {
25
+ "archiver": "^6.0.1",
26
+ "axios": "^1.6.0",
27
+ "chalk": "^5.3.0",
28
+ "commander": "^11.1.0",
29
+ "conf": "^12.0.0",
30
+ "extract-zip": "^2.0.1",
31
+ "form-data": "^4.0.0",
32
+ "fs-extra": "^11.2.0",
33
+ "inquirer": "^9.2.12",
34
+ "ora": "^8.0.1"
35
+ },
36
+ "devDependencies": {
37
+ "@types/archiver": "^6.0.4",
38
+ "@types/conf": "^2.1.0",
39
+ "@types/extract-zip": "^2.0.0",
40
+ "@types/fs-extra": "^11.0.4",
41
+ "@types/inquirer": "^9.0.7",
42
+ "@types/node": "^20.10.0",
43
+ "tsx": "^4.7.0",
44
+ "typescript": "^5.3.0"
45
+ },
46
+ "engines": {
47
+ "node": ">=18.0.0"
48
+ }
49
+ }
@@ -0,0 +1,42 @@
1
+ import chalk from "chalk";
2
+ import ora from "ora";
3
+ import { createAPIClient } from "../utils/api";
4
+
5
+ export async function infoCommand(skillName: string) {
6
+ const spinner = ora("Fetching skill details...").start();
7
+
8
+ try {
9
+ const api = createAPIClient();
10
+
11
+ // First search for the skill by name
12
+ const searchResponse = await api.get(`/cli/skills/search?q=${encodeURIComponent(skillName)}&limit=1`);
13
+ const skills = searchResponse.data.skills;
14
+
15
+ if (skills.length === 0) {
16
+ spinner.fail(chalk.red(`Skill "${skillName}" not found`));
17
+ return;
18
+ }
19
+
20
+ const skill = skills[0];
21
+ spinner.stop();
22
+
23
+ console.log(chalk.bold.cyan(`\n📦 ${skill.name}\n`));
24
+ console.log(skill.description);
25
+ console.log();
26
+ console.log(`${chalk.gray("Category:")} ${skill.category}`);
27
+ console.log(`${chalk.gray("Version:")} ${skill.version}`);
28
+ console.log(`${chalk.gray("Price:")} ${chalk.green("$" + skill.price_usdc + " USDC")}`);
29
+ console.log(`${chalk.gray("Downloads:")} ${skill.downloads}`);
30
+ console.log(`${chalk.gray("Stars:")} ${"⭐".repeat(Math.min(skill.stars || 0, 5))}`);
31
+ console.log(`${chalk.gray("Seller:")} ${skill.seller_address}`);
32
+ console.log(`${chalk.gray("IPFS CID:")} ${skill.ipfs_cid}`);
33
+ console.log();
34
+ console.log(chalk.bold("Installation:"));
35
+ console.log(` ${chalk.cyan(`upclaw install ${skill.id}`)}`);
36
+ console.log();
37
+ } catch (error: any) {
38
+ spinner.fail(chalk.red("Failed to fetch skill details"));
39
+ console.error(chalk.red(`Error: ${error.message}\n`));
40
+ process.exit(1);
41
+ }
42
+ }
@@ -0,0 +1,73 @@
1
+ import chalk from "chalk";
2
+ import ora from "ora";
3
+ import * as fs from "fs-extra";
4
+ import * as path from "path";
5
+ import axios from "axios";
6
+ import extract from "extract-zip";
7
+ import { createAPIClient, requireAuth } from "../utils/api";
8
+
9
+ export async function installCommand(skillId: string, options: { output: string }) {
10
+ requireAuth();
11
+
12
+ const spinner = ora("Installing skill...").start();
13
+
14
+ try {
15
+ const api = createAPIClient();
16
+
17
+ // Request download
18
+ spinner.text = "Verifying access...";
19
+ const response = await api.post("/cli/skills/install", { skillId });
20
+ const { skill } = response.data;
21
+
22
+ spinner.text = "Downloading from IPFS...";
23
+
24
+ // Download the skill bundle
25
+ const downloadResponse = await axios.get(skill.download_url, {
26
+ responseType: "arraybuffer",
27
+ });
28
+
29
+ // Create installation directory
30
+ const installDir = path.join(options.output, skill.name);
31
+ await fs.ensureDir(installDir);
32
+
33
+ // Save downloaded file
34
+ const tempFile = path.join(installDir, "download.zip");
35
+ await fs.writeFile(tempFile, downloadResponse.data);
36
+
37
+ spinner.text = "Extracting files...";
38
+
39
+ // Extract if it's a zip
40
+ try {
41
+ await extract(tempFile, { dir: installDir });
42
+ await fs.remove(tempFile); // Clean up zip file
43
+ } catch {
44
+ // If not a zip, just rename the file
45
+ const targetFile = path.join(installDir, "skill.tar.gz");
46
+ await fs.move(tempFile, targetFile);
47
+ }
48
+
49
+ spinner.succeed(
50
+ chalk.green(
51
+ `✓ Successfully installed ${chalk.bold(skill.name)} v${skill.version} to ${installDir}`
52
+ )
53
+ );
54
+
55
+ // Show next steps
56
+ console.log(chalk.bold("\n📚 Next Steps:\n"));
57
+ console.log(` 1. Navigate to: ${chalk.cyan(installDir)}`);
58
+ console.log(` 2. Read SKILL.md for usage instructions`);
59
+ console.log(` 3. Install dependencies: ${chalk.cyan("npm install")}`);
60
+ console.log(` 4. Integrate into your agent\n`);
61
+ } catch (error: any) {
62
+ spinner.fail(chalk.red("Installation failed"));
63
+
64
+ if (error.response?.status === 403) {
65
+ console.error(chalk.yellow("\n⚠️ You don't own this skill. Purchase it first at https://upclaw.ai\n"));
66
+ } else if (error.response?.data?.error) {
67
+ console.error(chalk.red(`\nError: ${error.response.data.error}\n`));
68
+ } else {
69
+ console.error(chalk.red(`\nError: ${error.message}\n`));
70
+ }
71
+ process.exit(1);
72
+ }
73
+ }
@@ -0,0 +1,47 @@
1
+ import chalk from "chalk";
2
+ import ora from "ora";
3
+ import { createAPIClient, requireAuth } from "../utils/api";
4
+
5
+ export async function listCommand(options: { format: string }) {
6
+ requireAuth();
7
+
8
+ const spinner = ora("Fetching your skills...").start();
9
+
10
+ try {
11
+ const api = createAPIClient();
12
+ const response = await api.get("/cli/skills/owned");
13
+ const { skills, count } = response.data;
14
+
15
+ spinner.stop();
16
+
17
+ if (skills.length === 0) {
18
+ console.log(chalk.yellow("\n⚠️ You don't own any skills yet.\n"));
19
+ console.log(chalk.gray("Browse the marketplace: upclaw search <query>\n"));
20
+ return;
21
+ }
22
+
23
+ if (options.format === "json") {
24
+ console.log(JSON.stringify(skills, null, 2));
25
+ return;
26
+ }
27
+
28
+ // Table format
29
+ console.log(chalk.bold(`\n📚 Your Skills (${count} total)\n`));
30
+
31
+ skills.forEach((skill: any) => {
32
+ console.log(chalk.bold.cyan(`• ${skill.name} v${skill.version}`));
33
+ console.log(` ${skill.description}`);
34
+ console.log(
35
+ ` ${chalk.gray("Category:")} ${skill.category} ${chalk.gray("Price:")} ${chalk.green(
36
+ "$" + skill.price_usdc
37
+ )}`
38
+ );
39
+ console.log(` ${chalk.gray("Purchased:")} ${new Date(skill.purchased_at).toLocaleDateString()}`);
40
+ console.log(` ${chalk.gray("Install:")} upclaw install ${skill.id}\n`);
41
+ });
42
+ } catch (error: any) {
43
+ spinner.fail(chalk.red("Failed to fetch skills"));
44
+ console.error(chalk.red(`Error: ${error.message}\n`));
45
+ process.exit(1);
46
+ }
47
+ }