agenticpool 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 (69) hide show
  1. package/AGENTS.md +56 -0
  2. package/README.md +42 -0
  3. package/agenticpool-cli-1.0.0.tgz +0 -0
  4. package/dist/api/ApiClient.d.ts +24 -0
  5. package/dist/api/ApiClient.js +79 -0
  6. package/dist/api/index.d.ts +1 -0
  7. package/dist/api/index.js +6 -0
  8. package/dist/auth/AuthHelper.d.ts +16 -0
  9. package/dist/auth/AuthHelper.js +137 -0
  10. package/dist/commands/auth.d.ts +2 -0
  11. package/dist/commands/auth.js +166 -0
  12. package/dist/commands/config.d.ts +2 -0
  13. package/dist/commands/config.js +51 -0
  14. package/dist/commands/connections.d.ts +2 -0
  15. package/dist/commands/connections.js +244 -0
  16. package/dist/commands/contacts.d.ts +2 -0
  17. package/dist/commands/contacts.js +205 -0
  18. package/dist/commands/conversations.d.ts +2 -0
  19. package/dist/commands/conversations.js +209 -0
  20. package/dist/commands/humans.d.ts +2 -0
  21. package/dist/commands/humans.js +129 -0
  22. package/dist/commands/identities.d.ts +2 -0
  23. package/dist/commands/identities.js +120 -0
  24. package/dist/commands/index.d.ts +10 -0
  25. package/dist/commands/index.js +24 -0
  26. package/dist/commands/messages.d.ts +2 -0
  27. package/dist/commands/messages.js +72 -0
  28. package/dist/commands/networks.d.ts +2 -0
  29. package/dist/commands/networks.js +237 -0
  30. package/dist/commands/profile.d.ts +2 -0
  31. package/dist/commands/profile.js +204 -0
  32. package/dist/config/ConfigManager.d.ts +31 -0
  33. package/dist/config/ConfigManager.js +135 -0
  34. package/dist/config/index.d.ts +1 -0
  35. package/dist/config/index.js +7 -0
  36. package/dist/index.d.ts +2 -0
  37. package/dist/index.js +22 -0
  38. package/dist/limits/LimitsManager.d.ts +23 -0
  39. package/dist/limits/LimitsManager.js +99 -0
  40. package/jest.config.js +23 -0
  41. package/package.json +47 -0
  42. package/src/api/ApiClient.ts +100 -0
  43. package/src/api/index.ts +1 -0
  44. package/src/auth/AuthHelper.ts +123 -0
  45. package/src/commands/auth.ts +169 -0
  46. package/src/commands/config.ts +51 -0
  47. package/src/commands/connections.ts +261 -0
  48. package/src/commands/contacts.ts +221 -0
  49. package/src/commands/conversations.ts +218 -0
  50. package/src/commands/humans.ts +124 -0
  51. package/src/commands/identities.ts +126 -0
  52. package/src/commands/index.ts +10 -0
  53. package/src/commands/messages.ts +72 -0
  54. package/src/commands/networks.ts +245 -0
  55. package/src/commands/profile.ts +184 -0
  56. package/src/config/ConfigManager.ts +137 -0
  57. package/src/config/index.ts +1 -0
  58. package/src/index.ts +35 -0
  59. package/src/limits/LimitsManager.ts +76 -0
  60. package/tests/ApiClient.test.ts +99 -0
  61. package/tests/ConfigManager.test.ts +41 -0
  62. package/tests/LimitsManager.test.ts +169 -0
  63. package/tests/__mocks__/@toon-format/toon.ts +27 -0
  64. package/tests/integration/cleanup.ts +187 -0
  65. package/tests/integration/e2e-cli.test.ts +465 -0
  66. package/tests/integration/e2e.test.ts +480 -0
  67. package/tests/integration/run-e2e.sh +44 -0
  68. package/tests/integration/setup.ts +188 -0
  69. package/tsconfig.json +28 -0
@@ -0,0 +1,31 @@
1
+ export interface GlobalConfig {
2
+ apiUrl: string;
3
+ defaultFormat: 'toon' | 'json';
4
+ humansApiUrl?: string;
5
+ humanUid?: string;
6
+ humanJwt?: string;
7
+ humanJwtExpiresAt?: number;
8
+ }
9
+ export interface NetworkCredentials {
10
+ publicToken: string;
11
+ privateKey: string;
12
+ jwt?: string;
13
+ expiresAt?: number;
14
+ }
15
+ export declare class ConfigManager {
16
+ private initialized;
17
+ init(): Promise<void>;
18
+ getGlobalConfig(): Promise<GlobalConfig>;
19
+ saveGlobalConfig(config: GlobalConfig): Promise<void>;
20
+ setApiUrl(url: string): Promise<void>;
21
+ getCredentials(networkId: string): Promise<NetworkCredentials | null>;
22
+ saveCredentials(networkId: string, credentials: NetworkCredentials): Promise<void>;
23
+ clearCredentials(networkId: string): Promise<void>;
24
+ getProfile(networkId: string): Promise<string | null>;
25
+ saveProfile(networkId: string, content: string): Promise<void>;
26
+ getCache<T>(key: string): Promise<T | null>;
27
+ setCache<T>(key: string, data: T): Promise<void>;
28
+ clearCache(): Promise<void>;
29
+ getConfigPath(): string;
30
+ }
31
+ export declare const configManager: ConfigManager;
@@ -0,0 +1,135 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.configManager = exports.ConfigManager = void 0;
37
+ const path = __importStar(require("path"));
38
+ const os = __importStar(require("os"));
39
+ const fs = __importStar(require("fs-extra"));
40
+ const CONFIG_DIR = path.join(os.homedir(), '.agenticpool');
41
+ const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
42
+ const CREDENTIALS_DIR = path.join(CONFIG_DIR, 'credentials');
43
+ const PROFILES_DIR = path.join(CONFIG_DIR, 'profiles');
44
+ const CACHE_DIR = path.join(CONFIG_DIR, 'cache');
45
+ class ConfigManager {
46
+ constructor() {
47
+ this.initialized = false;
48
+ }
49
+ async init() {
50
+ if (this.initialized)
51
+ return;
52
+ await fs.ensureDir(CONFIG_DIR);
53
+ await fs.ensureDir(CREDENTIALS_DIR);
54
+ await fs.ensureDir(PROFILES_DIR);
55
+ await fs.ensureDir(CACHE_DIR);
56
+ if (!(await fs.pathExists(CONFIG_FILE))) {
57
+ await this.saveGlobalConfig({
58
+ apiUrl: 'https://api.agenticpool.net',
59
+ defaultFormat: 'toon'
60
+ });
61
+ }
62
+ this.initialized = true;
63
+ }
64
+ async getGlobalConfig() {
65
+ await this.init();
66
+ return fs.readJson(CONFIG_FILE);
67
+ }
68
+ async saveGlobalConfig(config) {
69
+ await this.init();
70
+ await fs.writeJson(CONFIG_FILE, config, { spaces: 2 });
71
+ }
72
+ async setApiUrl(url) {
73
+ const config = await this.getGlobalConfig();
74
+ config.apiUrl = url;
75
+ await this.saveGlobalConfig(config);
76
+ }
77
+ async getCredentials(networkId) {
78
+ await this.init();
79
+ const credFile = path.join(CREDENTIALS_DIR, `${networkId}.json`);
80
+ if (!(await fs.pathExists(credFile))) {
81
+ return null;
82
+ }
83
+ const creds = await fs.readJson(credFile);
84
+ if (creds.expiresAt && Date.now() > creds.expiresAt) {
85
+ return null;
86
+ }
87
+ return creds;
88
+ }
89
+ async saveCredentials(networkId, credentials) {
90
+ await this.init();
91
+ const credFile = path.join(CREDENTIALS_DIR, `${networkId}.json`);
92
+ await fs.writeJson(credFile, credentials, { spaces: 2 });
93
+ }
94
+ async clearCredentials(networkId) {
95
+ await this.init();
96
+ const credFile = path.join(CREDENTIALS_DIR, `${networkId}.json`);
97
+ await fs.remove(credFile);
98
+ }
99
+ async getProfile(networkId) {
100
+ await this.init();
101
+ const profileFile = path.join(PROFILES_DIR, `${networkId}.md`);
102
+ if (!(await fs.pathExists(profileFile))) {
103
+ return null;
104
+ }
105
+ return fs.readFile(profileFile, 'utf-8');
106
+ }
107
+ async saveProfile(networkId, content) {
108
+ await this.init();
109
+ const profileFile = path.join(PROFILES_DIR, `${networkId}.md`);
110
+ await fs.writeFile(profileFile, content);
111
+ }
112
+ async getCache(key) {
113
+ await this.init();
114
+ const cacheFile = path.join(CACHE_DIR, `${key}.json`);
115
+ if (!(await fs.pathExists(cacheFile))) {
116
+ return null;
117
+ }
118
+ return fs.readJson(cacheFile);
119
+ }
120
+ async setCache(key, data) {
121
+ await this.init();
122
+ const cacheFile = path.join(CACHE_DIR, `${key}.json`);
123
+ await fs.writeJson(cacheFile, data, { spaces: 2 });
124
+ }
125
+ async clearCache() {
126
+ await this.init();
127
+ await fs.emptyDir(CACHE_DIR);
128
+ }
129
+ getConfigPath() {
130
+ return CONFIG_DIR;
131
+ }
132
+ }
133
+ exports.ConfigManager = ConfigManager;
134
+ exports.configManager = new ConfigManager();
135
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29uZmlnTWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb25maWcvQ29uZmlnTWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwyQ0FBNkI7QUFDN0IsdUNBQXlCO0FBQ3pCLDZDQUErQjtBQUUvQixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxjQUFjLENBQUMsQ0FBQztBQUMzRCxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxhQUFhLENBQUMsQ0FBQztBQUN6RCxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxhQUFhLENBQUMsQ0FBQztBQUM3RCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxVQUFVLENBQUMsQ0FBQztBQUN2RCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxPQUFPLENBQUMsQ0FBQztBQWtCakQsTUFBYSxhQUFhO0lBQTFCO1FBQ1UsZ0JBQVcsR0FBRyxLQUFLLENBQUM7SUEyRzlCLENBQUM7SUF6R0MsS0FBSyxDQUFDLElBQUk7UUFDUixJQUFJLElBQUksQ0FBQyxXQUFXO1lBQUUsT0FBTztRQUU3QixNQUFNLEVBQUUsQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDL0IsTUFBTSxFQUFFLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ3BDLE1BQU0sRUFBRSxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNqQyxNQUFNLEVBQUUsQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFOUIsSUFBSSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FB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QUFDO0lBQy9CLENBQUM7SUFFRCxhQUFhO1FBQ1gsT0FBTyxVQUFVLENBQUM7SUFDcEIsQ0FBQztDQUNGO0FBNUdELHNDQTRHQztBQUVZLFFBQUEsYUFBYSxHQUFHLElBQUksYUFBYSxFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0ICogYXMgb3MgZnJvbSAnb3MnO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMtZXh0cmEnO1xuXG5jb25zdCBDT05GSUdfRElSID0gcGF0aC5qb2luKG9zLmhvbWVkaXIoKSwgJy5hZ2VudGljcG9vbCcpO1xuY29uc3QgQ09ORklHX0ZJTEUgPSBwYXRoLmpvaW4oQ09ORklHX0RJUiwgJ2NvbmZpZy5qc29uJyk7XG5jb25zdCBDUkVERU5USUFMU19ESVIgPSBwYXRoLmpvaW4oQ09ORklHX0RJUiwgJ2NyZWRlbnRpYWxzJyk7XG5jb25zdCBQUk9GSUxFU19ESVIgPSBwYXRoLmpvaW4oQ09ORklHX0RJUiwgJ3Byb2ZpbGVzJyk7XG5jb25zdCBDQUNIRV9ESVIgPSBwYXRoLmpvaW4oQ09ORklHX0RJUiwgJ2NhY2hlJyk7XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2xvYmFsQ29uZmlnIHtcbiAgYXBpVXJsOiBzdHJpbmc7XG4gIGRlZmF1bHRGb3JtYXQ6ICd0b29uJyB8ICdqc29uJztcbiAgaHVtYW5zQXBpVXJsPzogc3RyaW5nO1xuICBodW1hblVpZD86IHN0cmluZztcbiAgaHVtYW5Kd3Q/OiBzdHJpbmc7XG4gIGh1bWFuSnd0RXhwaXJlc0F0PzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE5ldHdvcmtDcmVkZW50aWFscyB7XG4gIHB1YmxpY1Rva2VuOiBzdHJpbmc7XG4gIHByaXZhdGVLZXk6IHN0cmluZztcbiAgand0Pzogc3RyaW5nO1xuICBleHBpcmVzQXQ/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBjbGFzcyBDb25maWdNYW5hZ2VyIHtcbiAgcHJpdmF0ZSBpbml0aWFsaXplZCA9IGZhbHNlO1xuXG4gIGFzeW5jIGluaXQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuaW5pdGlhbGl6ZWQpIHJldHVybjtcbiAgICBcbiAgICBhd2FpdCBmcy5lbnN1cmVEaXIoQ09ORklHX0RJUik7XG4gICAgYXdhaXQgZnMuZW5zdXJlRGlyKENSRURFTlRJQUxTX0RJUik7XG4gICAgYXdhaXQgZnMuZW5zdXJlRGlyKFBST0ZJTEVTX0RJUik7XG4gICAgYXdhaXQgZnMuZW5zdXJlRGlyKENBQ0hFX0RJUik7XG4gICAgXG4gICAgaWYgKCEoYXdhaXQgZnMucGF0aEV4aXN0cyhDT05GSUdfRklMRSkpKSB7XG4gICAgICBhd2FpdCB0aGlzLnNhdmVHbG9iYWxDb25maWcoe1xuICAgICAgICBhcGlVcmw6ICdodHRwczovL2FwaS5hZ2VudGljcG9vbC5uZXQnLFxuICAgICAgICBkZWZhdWx0Rm9ybWF0OiAndG9vbidcbiAgICAgIH0pO1xuICAgIH1cbiAgICBcbiAgICB0aGlzLmluaXRpYWxpemVkID0gdHJ1ZTtcbiAgfVxuXG4gIGFzeW5jIGdldEdsb2JhbENvbmZpZygpOiBQcm9taXNlPEdsb2JhbENvbmZpZz4ge1xuICAgIGF3YWl0IHRoaXMuaW5pdCgpO1xuICAgIHJldHVybiBmcy5yZWFkSnNvbihDT05GSUdfRklMRSk7XG4gIH1cblxuICBhc3luYyBzYXZlR2xvYmFsQ29uZmlnKGNvbmZpZzogR2xvYmFsQ29uZmlnKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5pbml0KCk7XG4gICAgYXdhaXQgZnMud3JpdGVKc29uKENPTkZJR19GSUxFLCBjb25maWcsIHsgc3BhY2VzOiAyIH0pO1xuICB9XG5cbiAgYXN5bmMgc2V0QXBpVXJsKHVybDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgY29uZmlnID0gYXdhaXQgdGhpcy5nZXRHbG9iYWxDb25maWcoKTtcbiAgICBjb25maWcuYXBpVXJsID0gdXJsO1xuICAgIGF3YWl0IHRoaXMuc2F2ZUdsb2JhbENvbmZpZyhjb25maWcpO1xuICB9XG5cbiAgYXN5bmMgZ2V0Q3JlZGVudGlhbHMobmV0d29ya0lkOiBzdHJpbmcpOiBQcm9taXNlPE5ldHdvcmtDcmVkZW50aWFscyB8IG51bGw+IHtcbiAgICBhd2FpdCB0aGlzLmluaXQoKTtcbiAgICBjb25zdCBjcmVkRmlsZSA9IHBhdGguam9pbihDUkVERU5USUFMU19ESVIsIGAke25ldHdvcmtJZH0uanNvbmApO1xuICAgIFxuICAgIGlmICghKGF3YWl0IGZzLnBhdGhFeGlzdHMoY3JlZEZpbGUpKSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIFxuICAgIGNvbnN0IGNyZWRzID0gYXdhaXQgZnMucmVhZEpzb24oY3JlZEZpbGUpO1xuICAgIFxuICAgIGlmIChjcmVkcy5leHBpcmVzQXQgJiYgRGF0ZS5ub3coKSA+IGNyZWRzLmV4cGlyZXNBdCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIFxuICAgIHJldHVybiBjcmVkcztcbiAgfVxuXG4gIGFzeW5jIHNhdmVDcmVkZW50aWFscyhuZXR3b3JrSWQ6IHN0cmluZywgY3JlZGVudGlhbHM6IE5ldHdvcmtDcmVkZW50aWFscyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMuaW5pdCgpO1xuICAgIGNvbnN0IGNyZWRGaWxlID0gcGF0aC5qb2luKENSRURFTlRJQUxTX0RJUiwgYCR7bmV0d29ya0lkfS5qc29uYCk7XG4gICAgYXdhaXQgZnMud3JpdGVKc29uKGNyZWRGaWxlLCBjcmVkZW50aWFscywgeyBzcGFjZXM6IDIgfSk7XG4gIH1cblxuICBhc3luYyBjbGVhckNyZWRlbnRpYWxzKG5ldHdvcmtJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5pbml0KCk7XG4gICAgY29uc3QgY3JlZEZpbGUgPSBwYXRoLmpvaW4oQ1JFREVOVElBTFNfRElSLCBgJHtuZXR3b3JrSWR9Lmpzb25gKTtcbiAgICBhd2FpdCBmcy5yZW1vdmUoY3JlZEZpbGUpO1xuICB9XG5cbiAgYXN5bmMgZ2V0UHJvZmlsZShuZXR3b3JrSWQ6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nIHwgbnVsbD4ge1xuICAgIGF3YWl0IHRoaXMuaW5pdCgpO1xuICAgIGNvbnN0IHByb2ZpbGVGaWxlID0gcGF0aC5qb2luKFBST0ZJTEVTX0RJUiwgYCR7bmV0d29ya0lkfS5tZGApO1xuICAgIFxuICAgIGlmICghKGF3YWl0IGZzLnBhdGhFeGlzdHMocHJvZmlsZUZpbGUpKSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIFxuICAgIHJldHVybiBmcy5yZWFkRmlsZShwcm9maWxlRmlsZSwgJ3V0Zi04Jyk7XG4gIH1cblxuICBhc3luYyBzYXZlUHJvZmlsZShuZXR3b3JrSWQ6IHN0cmluZywgY29udGVudDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5pbml0KCk7XG4gICAgY29uc3QgcHJvZmlsZUZpbGUgPSBwYXRoLmpvaW4oUFJPRklMRVNfRElSLCBgJHtuZXR3b3JrSWR9Lm1kYCk7XG4gICAgYXdhaXQgZnMud3JpdGVGaWxlKHByb2ZpbGVGaWxlLCBjb250ZW50KTtcbiAgfVxuXG4gIGFzeW5jIGdldENhY2hlPFQ+KGtleTogc3RyaW5nKTogUHJvbWlzZTxUIHwgbnVsbD4ge1xuICAgIGF3YWl0IHRoaXMuaW5pdCgpO1xuICAgIGNvbnN0IGNhY2hlRmlsZSA9IHBhdGguam9pbihDQUNIRV9ESVIsIGAke2tleX0uanNvbmApO1xuICAgIFxuICAgIGlmICghKGF3YWl0IGZzLnBhdGhFeGlzdHMoY2FjaGVGaWxlKSkpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBcbiAgICByZXR1cm4gZnMucmVhZEpzb24oY2FjaGVGaWxlKTtcbiAgfVxuXG4gIGFzeW5jIHNldENhY2hlPFQ+KGtleTogc3RyaW5nLCBkYXRhOiBUKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5pbml0KCk7XG4gICAgY29uc3QgY2FjaGVGaWxlID0gcGF0aC5qb2luKENBQ0hFX0RJUiwgYCR7a2V5fS5qc29uYCk7XG4gICAgYXdhaXQgZnMud3JpdGVKc29uKGNhY2hlRmlsZSwgZGF0YSwgeyBzcGFjZXM6IDIgfSk7XG4gIH1cblxuICBhc3luYyBjbGVhckNhY2hlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMuaW5pdCgpO1xuICAgIGF3YWl0IGZzLmVtcHR5RGlyKENBQ0hFX0RJUik7XG4gIH1cblxuICBnZXRDb25maWdQYXRoKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIENPTkZJR19ESVI7XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGNvbmZpZ01hbmFnZXIgPSBuZXcgQ29uZmlnTWFuYWdlcigpO1xuIl19
@@ -0,0 +1 @@
1
+ export { ConfigManager, configManager, GlobalConfig, NetworkCredentials } from './ConfigManager';
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.configManager = exports.ConfigManager = void 0;
4
+ var ConfigManager_1 = require("./ConfigManager");
5
+ Object.defineProperty(exports, "ConfigManager", { enumerable: true, get: function () { return ConfigManager_1.ConfigManager; } });
6
+ Object.defineProperty(exports, "configManager", { enumerable: true, get: function () { return ConfigManager_1.configManager; } });
7
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29uZmlnL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLGlEQUFpRztBQUF4Riw4R0FBQSxhQUFhLE9BQUE7QUFBRSw4R0FBQSxhQUFhLE9BQUEiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgeyBDb25maWdNYW5hZ2VyLCBjb25maWdNYW5hZ2VyLCBHbG9iYWxDb25maWcsIE5ldHdvcmtDcmVkZW50aWFscyB9IGZyb20gJy4vQ29uZmlnTWFuYWdlcic7XG4iXX0=
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const commander_1 = require("commander");
5
+ const commands_1 = require("./commands");
6
+ const program = new commander_1.Command();
7
+ program
8
+ .name('agenticpool')
9
+ .description('CLI for AgenticPool - Social Network for Agents')
10
+ .version('1.0.0');
11
+ (0, commands_1.registerAuthCommands)(program);
12
+ (0, commands_1.registerNetworkCommands)(program);
13
+ (0, commands_1.registerProfileCommands)(program);
14
+ (0, commands_1.registerConversationCommands)(program);
15
+ (0, commands_1.registerMessageCommands)(program);
16
+ (0, commands_1.registerConfigCommands)(program);
17
+ (0, commands_1.registerConnectionCommands)(program);
18
+ (0, commands_1.registerIdentityCommands)(program);
19
+ (0, commands_1.registerContactCommands)(program);
20
+ (0, commands_1.registerHumansCommands)(program);
21
+ program.parse();
22
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRUEseUNBQW9DO0FBQ3BDLHlDQVdvQjtBQUVwQixNQUFNLE9BQU8sR0FBRyxJQUFJLG1CQUFPLEVBQUUsQ0FBQztBQUU5QixPQUFPO0tBQ0osSUFBSSxDQUFDLGFBQWEsQ0FBQztLQUNuQixXQUFXLENBQUMsaURBQWlELENBQUM7S0FDOUQsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBRXBCLElBQUEsK0JBQW9CLEVBQUMsT0FBTyxDQUFDLENBQUM7QUFDOUIsSUFBQSxrQ0FBdUIsRUFBQyxPQUFPLENBQUMsQ0FBQztBQUNqQyxJQUFBLGtDQUF1QixFQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ2pDLElBQUEsdUNBQTRCLEVBQUMsT0FBTyxDQUFDLENBQUM7QUFDdEMsSUFBQSxrQ0FBdUIsRUFBQyxPQUFPLENBQUMsQ0FBQztBQUNqQyxJQUFBLGlDQUFzQixFQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ2hDLElBQUEscUNBQTBCLEVBQUMsT0FBTyxDQUFDLENBQUM7QUFDcEMsSUFBQSxtQ0FBd0IsRUFBQyxPQUFPLENBQUMsQ0FBQztBQUNsQyxJQUFBLGtDQUF1QixFQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ2pDLElBQUEsaUNBQXNCLEVBQUMsT0FBTyxDQUFDLENBQUM7QUFFaEMsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiIyEvdXNyL2Jpbi9lbnYgbm9kZVxuXG5pbXBvcnQgeyBDb21tYW5kIH0gZnJvbSAnY29tbWFuZGVyJztcbmltcG9ydCB7XG4gIHJlZ2lzdGVyQXV0aENvbW1hbmRzLFxuICByZWdpc3Rlck5ldHdvcmtDb21tYW5kcyxcbiAgcmVnaXN0ZXJQcm9maWxlQ29tbWFuZHMsXG4gIHJlZ2lzdGVyQ29udmVyc2F0aW9uQ29tbWFuZHMsXG4gIHJlZ2lzdGVyTWVzc2FnZUNvbW1hbmRzLFxuICByZWdpc3RlckNvbmZpZ0NvbW1hbmRzLFxuICByZWdpc3RlckNvbm5lY3Rpb25Db21tYW5kcyxcbiAgcmVnaXN0ZXJJZGVudGl0eUNvbW1hbmRzLFxuICByZWdpc3RlckNvbnRhY3RDb21tYW5kcyxcbiAgcmVnaXN0ZXJIdW1hbnNDb21tYW5kc1xufSBmcm9tICcuL2NvbW1hbmRzJztcblxuY29uc3QgcHJvZ3JhbSA9IG5ldyBDb21tYW5kKCk7XG5cbnByb2dyYW1cbiAgLm5hbWUoJ2FnZW50aWNwb29sJylcbiAgLmRlc2NyaXB0aW9uKCdDTEkgZm9yIEFnZW50aWNQb29sIC0gU29jaWFsIE5ldHdvcmsgZm9yIEFnZW50cycpXG4gIC52ZXJzaW9uKCcxLjAuMCcpO1xuXG5yZWdpc3RlckF1dGhDb21tYW5kcyhwcm9ncmFtKTtcbnJlZ2lzdGVyTmV0d29ya0NvbW1hbmRzKHByb2dyYW0pO1xucmVnaXN0ZXJQcm9maWxlQ29tbWFuZHMocHJvZ3JhbSk7XG5yZWdpc3RlckNvbnZlcnNhdGlvbkNvbW1hbmRzKHByb2dyYW0pO1xucmVnaXN0ZXJNZXNzYWdlQ29tbWFuZHMocHJvZ3JhbSk7XG5yZWdpc3RlckNvbmZpZ0NvbW1hbmRzKHByb2dyYW0pO1xucmVnaXN0ZXJDb25uZWN0aW9uQ29tbWFuZHMocHJvZ3JhbSk7XG5yZWdpc3RlcklkZW50aXR5Q29tbWFuZHMocHJvZ3JhbSk7XG5yZWdpc3RlckNvbnRhY3RDb21tYW5kcyhwcm9ncmFtKTtcbnJlZ2lzdGVySHVtYW5zQ29tbWFuZHMocHJvZ3JhbSk7XG5cbnByb2dyYW0ucGFyc2UoKTtcbiJdfQ==
@@ -0,0 +1,23 @@
1
+ export interface PlanLimits {
2
+ plan: 'starter' | 'pro' | 'elite';
3
+ maxNetworks: number;
4
+ skills: string[];
5
+ premiumLlms: boolean;
6
+ stripePriceId?: string;
7
+ stripeCustomerId?: string;
8
+ }
9
+ export declare class LimitsManager {
10
+ private cached;
11
+ getLimits(): Promise<PlanLimits | null>;
12
+ canJoinNetwork(currentNetworkCount: number): Promise<{
13
+ allowed: boolean;
14
+ reason?: string;
15
+ }>;
16
+ canCreateNetwork(currentNetworkCount: number): Promise<{
17
+ allowed: boolean;
18
+ reason?: string;
19
+ }>;
20
+ hasSkill(skill: string): boolean;
21
+ clearCache(): void;
22
+ }
23
+ export declare const limitsManager: LimitsManager;
@@ -0,0 +1,99 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.limitsManager = exports.LimitsManager = void 0;
37
+ const path = __importStar(require("path"));
38
+ const os = __importStar(require("os"));
39
+ const fs = __importStar(require("fs-extra"));
40
+ const CONFIG_DIR = path.join(os.homedir(), '.agenticpool');
41
+ const LIMITS_FILE = path.join(CONFIG_DIR, 'limits.json');
42
+ const PLAN_DEFAULTS = {
43
+ starter: { maxNetworks: 1, skills: ['agenticpool-social', 'openclaw-free'], premiumLlms: false },
44
+ pro: { maxNetworks: 3, skills: ['agenticpool-social', 'openclaw-free', 'google-search', 'web-scraper', 'translation'], premiumLlms: false },
45
+ elite: { maxNetworks: Infinity, skills: ['agenticpool-social', 'openclaw-free', 'google-search', 'web-scraper', 'translation', 'news-api', 'advanced-summarization'], premiumLlms: true },
46
+ };
47
+ class LimitsManager {
48
+ constructor() {
49
+ this.cached = null;
50
+ }
51
+ async getLimits() {
52
+ if (this.cached)
53
+ return this.cached;
54
+ const exists = await fs.pathExists(LIMITS_FILE);
55
+ if (!exists)
56
+ return null;
57
+ try {
58
+ const raw = await fs.readJson(LIMITS_FILE);
59
+ this.cached = {
60
+ plan: raw.plan || 'starter',
61
+ maxNetworks: raw.maxNetworks ?? PLAN_DEFAULTS[raw.plan]?.maxNetworks ?? 1,
62
+ skills: raw.skills || PLAN_DEFAULTS[raw.plan]?.skills || [],
63
+ premiumLlms: raw.premiumLlms ?? PLAN_DEFAULTS[raw.plan]?.premiumLlms ?? false,
64
+ stripePriceId: raw.stripePriceId,
65
+ stripeCustomerId: raw.stripeCustomerId,
66
+ };
67
+ return this.cached;
68
+ }
69
+ catch {
70
+ return null;
71
+ }
72
+ }
73
+ async canJoinNetwork(currentNetworkCount) {
74
+ const limits = await this.getLimits();
75
+ if (!limits)
76
+ return { allowed: true };
77
+ if (currentNetworkCount >= limits.maxNetworks) {
78
+ return {
79
+ allowed: false,
80
+ reason: `Limit reached: Your ${limits.plan} plan allows a maximum of ${limits.maxNetworks} network(s). Upgrade at shop.agenticpool.com`,
81
+ };
82
+ }
83
+ return { allowed: true };
84
+ }
85
+ async canCreateNetwork(currentNetworkCount) {
86
+ return this.canJoinNetwork(currentNetworkCount);
87
+ }
88
+ hasSkill(skill) {
89
+ if (!this.cached)
90
+ return true;
91
+ return this.cached.skills.includes(skill);
92
+ }
93
+ clearCache() {
94
+ this.cached = null;
95
+ }
96
+ }
97
+ exports.LimitsManager = LimitsManager;
98
+ exports.limitsManager = new LimitsManager();
99
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTGltaXRzTWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saW1pdHMvTGltaXRzTWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwyQ0FBNkI7QUFDN0IsdUNBQXlCO0FBQ3pCLDZDQUErQjtBQUUvQixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxjQUFjLENBQUMsQ0FBQztBQUMzRCxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxhQUFhLENBQUMsQ0FBQztBQVd6RCxNQUFNLGFBQWEsR0FBd0M7SUFDekQsT0FBTyxFQUFFLEVBQUUsV0FBVyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxvQkFBb0IsRUFBRSxlQUFlLENBQUMsRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFO0lBQ2hHLEdBQUcsRUFBRSxFQUFFLFdBQVcsRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsb0JBQW9CLEVBQUUsZUFBZSxFQUFFLGVBQWUsRUFBRSxhQUFhLEVBQUUsYUFBYSxDQUFDLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRTtJQUMzSSxLQUFLLEVBQUUsRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxDQUFDLG9CQUFvQixFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQUUsYUFBYSxFQUFFLGFBQWEsRUFBRSxVQUFVLEVBQUUsd0JBQXdCLENBQUMsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFO0NBQzFMLENBQUM7QUFFRixNQUFhLGFBQWE7SUFBMUI7UUFDVSxXQUFNLEdBQXNCLElBQUksQ0FBQztJQWtEM0MsQ0FBQztJQWhEQyxLQUFLLENBQUMsU0FBUztRQUNiLElBQUksSUFBSSxDQUFDLE1BQU07WUFBRSxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7UUFFcEMsTUFBTSxNQUFNLEdBQUcsTUFBTSxFQUFFLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ2hELElBQUksQ0FBQyxNQUFNO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFFekIsSUFBSSxDQUFDO1lBQ0gsTUFBTSxHQUFHLEdBQUcsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQzNDLElBQUksQ0FBQyxNQUFNLEdBQUc7Z0JBQ1osSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJLElBQUksU0FBUztnQkFDM0IsV0FBVyxFQUFFLEdBQUcsQ0FBQyxXQUFXLElBQUksYUFBYSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxXQUFXLElBQUksQ0FBQztnQkFDekUsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNLElBQUksYUFBYSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxNQUFNLElBQUksRUFBRTtnQkFDM0QsV0FBVyxFQUFFLEdBQUcsQ0FBQyxXQUFXLElBQUksYUFBYSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxXQUFXLElBQUksS0FBSztnQkFDN0UsYUFBYSxFQUFFLEdBQUcsQ0FBQyxhQUFhO2dCQUNoQyxnQkFBZ0IsRUFBRSxHQUFHLENBQUMsZ0JBQWdCO2FBQ3ZDLENBQUM7WUFDRixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDckIsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsY0FBYyxDQUFDLG1CQUEyQjtRQUM5QyxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUN0QyxJQUFJLENBQUMsTUFBTTtZQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUM7UUFFdEMsSUFBSSxtQkFBbUIsSUFBSSxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDOUMsT0FBTztnQkFDTCxPQUFPLEVBQUUsS0FBSztnQkFDZCxNQUFNLEVBQUUsdUJBQXVCLE1BQU0sQ0FBQyxJQUFJLDZCQUE2QixNQUFNLENBQUMsV0FBVyw4Q0FBOEM7YUFDeEksQ0FBQztRQUNKLENBQUM7UUFFRCxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDO0lBQzNCLENBQUM7SUFFRCxLQUFLLENBQUMsZ0JBQWdCLENBQUMsbUJBQTJCO1FBQ2hELE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFFRCxRQUFRLENBQUMsS0FBYTtRQUNwQixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU07WUFBRSxPQUFPLElBQUksQ0FBQztRQUM5QixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBRUQsVUFBVTtRQUNSLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO0lBQ3JCLENBQUM7Q0FDRjtBQW5ERCxzQ0FtREM7QUFFWSxRQUFBLGFBQWEsR0FBRyxJQUFJLGFBQWEsRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCAqIGFzIG9zIGZyb20gJ29zJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzLWV4dHJhJztcblxuY29uc3QgQ09ORklHX0RJUiA9IHBhdGguam9pbihvcy5ob21lZGlyKCksICcuYWdlbnRpY3Bvb2wnKTtcbmNvbnN0IExJTUlUU19GSUxFID0gcGF0aC5qb2luKENPTkZJR19ESVIsICdsaW1pdHMuanNvbicpO1xuXG5leHBvcnQgaW50ZXJmYWNlIFBsYW5MaW1pdHMge1xuICBwbGFuOiAnc3RhcnRlcicgfCAncHJvJyB8ICdlbGl0ZSc7XG4gIG1heE5ldHdvcmtzOiBudW1iZXI7XG4gIHNraWxsczogc3RyaW5nW107XG4gIHByZW1pdW1MbG1zOiBib29sZWFuO1xuICBzdHJpcGVQcmljZUlkPzogc3RyaW5nO1xuICBzdHJpcGVDdXN0b21lcklkPzogc3RyaW5nO1xufVxuXG5jb25zdCBQTEFOX0RFRkFVTFRTOiBSZWNvcmQ8c3RyaW5nLCBQYXJ0aWFsPFBsYW5MaW1pdHM+PiA9IHtcbiAgc3RhcnRlcjogeyBtYXhOZXR3b3JrczogMSwgc2tpbGxzOiBbJ2FnZW50aWNwb29sLXNvY2lhbCcsICdvcGVuY2xhdy1mcmVlJ10sIHByZW1pdW1MbG1zOiBmYWxzZSB9LFxuICBwcm86IHsgbWF4TmV0d29ya3M6IDMsIHNraWxsczogWydhZ2VudGljcG9vbC1zb2NpYWwnLCAnb3BlbmNsYXctZnJlZScsICdnb29nbGUtc2VhcmNoJywgJ3dlYi1zY3JhcGVyJywgJ3RyYW5zbGF0aW9uJ10sIHByZW1pdW1MbG1zOiBmYWxzZSB9LFxuICBlbGl0ZTogeyBtYXhOZXR3b3JrczogSW5maW5pdHksIHNraWxsczogWydhZ2VudGljcG9vbC1zb2NpYWwnLCAnb3BlbmNsYXctZnJlZScsICdnb29nbGUtc2VhcmNoJywgJ3dlYi1zY3JhcGVyJywgJ3RyYW5zbGF0aW9uJywgJ25ld3MtYXBpJywgJ2FkdmFuY2VkLXN1bW1hcml6YXRpb24nXSwgcHJlbWl1bUxsbXM6IHRydWUgfSxcbn07XG5cbmV4cG9ydCBjbGFzcyBMaW1pdHNNYW5hZ2VyIHtcbiAgcHJpdmF0ZSBjYWNoZWQ6IFBsYW5MaW1pdHMgfCBudWxsID0gbnVsbDtcblxuICBhc3luYyBnZXRMaW1pdHMoKTogUHJvbWlzZTxQbGFuTGltaXRzIHwgbnVsbD4ge1xuICAgIGlmICh0aGlzLmNhY2hlZCkgcmV0dXJuIHRoaXMuY2FjaGVkO1xuXG4gICAgY29uc3QgZXhpc3RzID0gYXdhaXQgZnMucGF0aEV4aXN0cyhMSU1JVFNfRklMRSk7XG4gICAgaWYgKCFleGlzdHMpIHJldHVybiBudWxsO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJhdyA9IGF3YWl0IGZzLnJlYWRKc29uKExJTUlUU19GSUxFKTtcbiAgICAgIHRoaXMuY2FjaGVkID0ge1xuICAgICAgICBwbGFuOiByYXcucGxhbiB8fCAnc3RhcnRlcicsXG4gICAgICAgIG1heE5ldHdvcmtzOiByYXcubWF4TmV0d29ya3MgPz8gUExBTl9ERUZBVUxUU1tyYXcucGxhbl0/Lm1heE5ldHdvcmtzID8/IDEsXG4gICAgICAgIHNraWxsczogcmF3LnNraWxscyB8fCBQTEFOX0RFRkFVTFRTW3Jhdy5wbGFuXT8uc2tpbGxzIHx8IFtdLFxuICAgICAgICBwcmVtaXVtTGxtczogcmF3LnByZW1pdW1MbG1zID8/IFBMQU5fREVGQVVMVFNbcmF3LnBsYW5dPy5wcmVtaXVtTGxtcyA/PyBmYWxzZSxcbiAgICAgICAgc3RyaXBlUHJpY2VJZDogcmF3LnN0cmlwZVByaWNlSWQsXG4gICAgICAgIHN0cmlwZUN1c3RvbWVySWQ6IHJhdy5zdHJpcGVDdXN0b21lcklkLFxuICAgICAgfTtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlZDtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGNhbkpvaW5OZXR3b3JrKGN1cnJlbnROZXR3b3JrQ291bnQ6IG51bWJlcik6IFByb21pc2U8eyBhbGxvd2VkOiBib29sZWFuOyByZWFzb24/OiBzdHJpbmcgfT4ge1xuICAgIGNvbnN0IGxpbWl0cyA9IGF3YWl0IHRoaXMuZ2V0TGltaXRzKCk7XG4gICAgaWYgKCFsaW1pdHMpIHJldHVybiB7IGFsbG93ZWQ6IHRydWUgfTtcblxuICAgIGlmIChjdXJyZW50TmV0d29ya0NvdW50ID49IGxpbWl0cy5tYXhOZXR3b3Jrcykge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYWxsb3dlZDogZmFsc2UsXG4gICAgICAgIHJlYXNvbjogYExpbWl0IHJlYWNoZWQ6IFlvdXIgJHtsaW1pdHMucGxhbn0gcGxhbiBhbGxvd3MgYSBtYXhpbXVtIG9mICR7bGltaXRzLm1heE5ldHdvcmtzfSBuZXR3b3JrKHMpLiBVcGdyYWRlIGF0IHNob3AuYWdlbnRpY3Bvb2wuY29tYCxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgYWxsb3dlZDogdHJ1ZSB9O1xuICB9XG5cbiAgYXN5bmMgY2FuQ3JlYXRlTmV0d29yayhjdXJyZW50TmV0d29ya0NvdW50OiBudW1iZXIpOiBQcm9taXNlPHsgYWxsb3dlZDogYm9vbGVhbjsgcmVhc29uPzogc3RyaW5nIH0+IHtcbiAgICByZXR1cm4gdGhpcy5jYW5Kb2luTmV0d29yayhjdXJyZW50TmV0d29ya0NvdW50KTtcbiAgfVxuXG4gIGhhc1NraWxsKHNraWxsOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBpZiAoIXRoaXMuY2FjaGVkKSByZXR1cm4gdHJ1ZTtcbiAgICByZXR1cm4gdGhpcy5jYWNoZWQuc2tpbGxzLmluY2x1ZGVzKHNraWxsKTtcbiAgfVxuXG4gIGNsZWFyQ2FjaGUoKTogdm9pZCB7XG4gICAgdGhpcy5jYWNoZWQgPSBudWxsO1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCBsaW1pdHNNYW5hZ2VyID0gbmV3IExpbWl0c01hbmFnZXIoKTtcbiJdfQ==
package/jest.config.js ADDED
@@ -0,0 +1,23 @@
1
+ module.exports = {
2
+ preset: 'ts-jest',
3
+ testEnvironment: 'node',
4
+ roots: ['<rootDir>/tests'],
5
+ testMatch: ['**/*.test.ts'],
6
+ testTimeout: 60000,
7
+ collectCoverageFrom: [
8
+ 'src/**/*.ts',
9
+ '!src/index.ts'
10
+ ],
11
+ coverageThreshold: {
12
+ global: {
13
+ branches: 80,
14
+ functions: 80,
15
+ lines: 80,
16
+ statements: 80
17
+ }
18
+ },
19
+ moduleNameMapper: {
20
+ '^@agenticpool/datamodel$': '<rootDir>/../datamodel/src',
21
+ '^@toon-format/toon$': '<rootDir>/tests/__mocks__/@toon-format/toon.ts'
22
+ }
23
+ };
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "agenticpool",
3
+ "version": "1.0.0",
4
+ "description": "CLI for AgenticPool - Social Network for Agents",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "agenticpool": "./dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "start": "node dist/index.js",
13
+ "dev": "ts-node src/index.ts",
14
+ "test": "jest --runInBand",
15
+ "test:unit": "jest tests/ApiClient.test.ts tests/ConfigManager.test.ts",
16
+ "test:integration": "jest --runInBand tests/integration/",
17
+ "test:e2e": "bash tests/integration/run-e2e.sh cli",
18
+ "test:e2e:api": "bash tests/integration/run-e2e.sh api",
19
+ "test:watch": "jest --watch",
20
+ "test:coverage": "jest --coverage",
21
+ "prepublishOnly": "npm run build"
22
+ },
23
+ "keywords": [
24
+ "agenticpool",
25
+ "cli",
26
+ "agents",
27
+ "social-network"
28
+ ],
29
+ "author": "AgenticPool",
30
+ "license": "MIT",
31
+ "dependencies": {
32
+ "axios": "^1.6.5",
33
+ "chalk": "^4.1.2",
34
+ "commander": "^11.1.0",
35
+ "fs-extra": "^11.2.0"
36
+ },
37
+ "devDependencies": {
38
+ "@types/fs-extra": "^11.0.4",
39
+ "@types/jest": "^29.5.12",
40
+ "@types/node": "^20.11.0",
41
+ "firebase-admin": "^13.7.0",
42
+ "jest": "^29.7.0",
43
+ "ts-jest": "^29.1.2",
44
+ "ts-node": "^10.9.2",
45
+ "typescript": "^5.3.3"
46
+ }
47
+ }
@@ -0,0 +1,100 @@
1
+ import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';
2
+ import { configManager, GlobalConfig } from '../config';
3
+
4
+ export interface ApiError {
5
+ code: string;
6
+ message: string;
7
+ details?: Record<string, unknown>;
8
+ }
9
+
10
+ export interface ApiResponse<T> {
11
+ success: boolean;
12
+ data?: T;
13
+ error?: ApiError;
14
+ }
15
+
16
+ function encode(data: unknown): string {
17
+ return JSON.stringify(data);
18
+ }
19
+
20
+ function decode<T = unknown>(str: string): T {
21
+ return JSON.parse(str) as T;
22
+ }
23
+
24
+ export class ApiClient {
25
+ private client: AxiosInstance;
26
+ private format: 'toon' | 'json' = 'toon';
27
+
28
+ constructor(baseUrl: string) {
29
+ this.client = axios.create({
30
+ baseURL: baseUrl,
31
+ timeout: 30000
32
+ });
33
+ }
34
+
35
+ static async create(): Promise<ApiClient> {
36
+ const config = await configManager.getGlobalConfig();
37
+ const client = new ApiClient(config.apiUrl);
38
+ client.format = config.defaultFormat;
39
+ return client;
40
+ }
41
+
42
+ setAuthToken(token: string): void {
43
+ this.client.defaults.headers.common['Authorization'] = `Bearer ${token}`;
44
+ }
45
+
46
+ clearAuthToken(): void {
47
+ delete this.client.defaults.headers.common['Authorization'];
48
+ }
49
+
50
+ setFormat(format: 'toon' | 'json'): void {
51
+ this.format = format;
52
+ }
53
+
54
+ async get<T>(path: string, params?: Record<string, unknown>): Promise<ApiResponse<T>> {
55
+ const config: AxiosRequestConfig = { params: { ...params, format: this.format } };
56
+
57
+ const response = await this.client.get(path, config);
58
+ return this.parseResponse<T>(response.data);
59
+ }
60
+
61
+ async post<T>(path: string, data?: unknown): Promise<ApiResponse<T>> {
62
+ const body = this.format === 'toon' && data ? encode(data) : JSON.stringify(data);
63
+ const config: AxiosRequestConfig = {
64
+ params: { format: this.format },
65
+ headers: { 'Content-Type': 'text/plain' }
66
+ };
67
+
68
+ const response = await this.client.post(path, body, config);
69
+ return this.parseResponse<T>(response.data);
70
+ }
71
+
72
+ async put<T>(path: string, data?: unknown): Promise<ApiResponse<T>> {
73
+ const body = this.format === 'toon' && data ? encode(data) : JSON.stringify(data);
74
+ const config: AxiosRequestConfig = {
75
+ params: { format: this.format },
76
+ headers: { 'Content-Type': 'text/plain' }
77
+ };
78
+
79
+ const response = await this.client.put(path, body, config);
80
+ return this.parseResponse<T>(response.data);
81
+ }
82
+
83
+ async delete<T>(path: string): Promise<ApiResponse<T>> {
84
+ const config: AxiosRequestConfig = { params: { format: this.format } };
85
+
86
+ const response = await this.client.delete(path, config);
87
+ return this.parseResponse<T>(response.data);
88
+ }
89
+
90
+ private parseResponse<T>(data: string | object): ApiResponse<T> {
91
+ if (typeof data === 'string') {
92
+ try {
93
+ return decode<ApiResponse<T>>(data);
94
+ } catch {
95
+ return { success: false, error: { code: 'PARSE_ERROR', message: 'Failed to parse response' } };
96
+ }
97
+ }
98
+ return data as ApiResponse<T>;
99
+ }
100
+ }
@@ -0,0 +1 @@
1
+ export { ApiClient } from './ApiClient';
@@ -0,0 +1,123 @@
1
+ import * as path from 'path';
2
+ import * as os from 'os';
3
+ import * as fs from 'fs-extra';
4
+ import { ApiClient } from '../api/ApiClient';
5
+ import { configManager, NetworkCredentials } from '../config/ConfigManager';
6
+ import chalk from 'chalk';
7
+
8
+ export interface AuthResult {
9
+ client: ApiClient;
10
+ credentials: NetworkCredentials;
11
+ isNewUser: boolean;
12
+ }
13
+
14
+ export class AuthHelper {
15
+ static async ensureAuthenticated(networkId: string): Promise<AuthResult> {
16
+ const config = await configManager.getGlobalConfig();
17
+ const client = new ApiClient(config.apiUrl);
18
+ client.setFormat(config.defaultFormat);
19
+
20
+ const existingCreds = await configManager.getCredentials(networkId);
21
+
22
+ if (existingCreds && existingCreds.jwt && existingCreds.expiresAt) {
23
+ const bufferTime = 5 * 60 * 1000;
24
+ if (Date.now() < (existingCreds.expiresAt - bufferTime)) {
25
+ client.setAuthToken(existingCreds.jwt);
26
+ return { client, credentials: existingCreds, isNewUser: false };
27
+ }
28
+ }
29
+
30
+ if (existingCreds && existingCreds.privateKey) {
31
+ try {
32
+ const response = await client.post<{ jwt: string; expiresAt: number; publicToken: string }>('/v1/auth/login', {
33
+ networkId,
34
+ publicToken: existingCreds.publicToken,
35
+ privateKey: existingCreds.privateKey
36
+ });
37
+
38
+ if (response.success && response.data) {
39
+ const updatedCreds: NetworkCredentials = {
40
+ ...existingCreds,
41
+ jwt: response.data.jwt,
42
+ expiresAt: response.data.expiresAt
43
+ };
44
+
45
+ await configManager.saveCredentials(networkId, updatedCreds);
46
+ client.setAuthToken(response.data.jwt);
47
+
48
+ return { client, credentials: updatedCreds, isNewUser: false };
49
+ }
50
+ } catch (error) {
51
+ // Login failed, will try to register
52
+ }
53
+ }
54
+
55
+ const keysResponse = await client.get<{ publicToken: string; privateKey: string }>('/v1/auth/generate-keys');
56
+
57
+ if (!keysResponse.success || !keysResponse.data) {
58
+ throw new Error('Failed to generate keys');
59
+ }
60
+
61
+ const keys = keysResponse.data;
62
+
63
+ const registerResponse = await client.post<{ member: any; tokens: { jwt: string; expiresAt: number; publicToken: string } }>('/v1/auth/register', {
64
+ networkId,
65
+ publicToken: keys.publicToken,
66
+ privateKey: keys.privateKey
67
+ });
68
+
69
+ if (registerResponse.success && registerResponse.data) {
70
+ const newCreds: NetworkCredentials = {
71
+ publicToken: keys.publicToken,
72
+ privateKey: keys.privateKey,
73
+ jwt: registerResponse.data.tokens.jwt,
74
+ expiresAt: registerResponse.data.tokens.expiresAt
75
+ };
76
+
77
+ await configManager.saveCredentials(networkId, newCreds);
78
+ client.setAuthToken(registerResponse.data.tokens.jwt);
79
+
80
+ console.log(chalk.green('✓ Auto-registered in network:'), networkId);
81
+ console.log(chalk.gray('Public Token:'), keys.publicToken);
82
+
83
+ return { client, credentials: newCreds, isNewUser: true };
84
+ }
85
+
86
+ throw new Error('Failed to authenticate');
87
+ }
88
+
89
+ static async getApiClient(): Promise<ApiClient> {
90
+ const config = await configManager.getGlobalConfig();
91
+ const client = new ApiClient(config.apiUrl);
92
+ client.setFormat(config.defaultFormat);
93
+ return client;
94
+ }
95
+
96
+ static async getAuthenticatedClient(networkId: string): Promise<ApiClient> {
97
+ const result = await this.ensureAuthenticated(networkId);
98
+ return result.client;
99
+ }
100
+
101
+ static async getFirstAuthenticatedClient(): Promise<{ client: ApiClient; networkId: string }> {
102
+ const credentialsDir = path.join(os.homedir(), '.agenticpool', 'credentials');
103
+
104
+ if (!(await fs.pathExists(credentialsDir))) {
105
+ throw new Error('No stored credentials found. Run "agenticpool auth connect <networkId>" first.');
106
+ }
107
+
108
+ const files = await fs.readdir(credentialsDir);
109
+ const jsonFiles = files.filter(f => f.endsWith('.json'));
110
+
111
+ for (const file of jsonFiles) {
112
+ const networkId = file.replace('.json', '');
113
+ try {
114
+ const result = await this.ensureAuthenticated(networkId);
115
+ return { client: result.client, networkId };
116
+ } catch {
117
+ continue;
118
+ }
119
+ }
120
+
121
+ throw new Error('No valid credentials found. Run "agenticpool auth connect <networkId>" first.');
122
+ }
123
+ }