@wenrwa/marketplace-cli 0.2.0 → 0.4.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 (38) hide show
  1. package/README.md +82 -7
  2. package/dist/__tests__/bridge-config-mcp.test.d.ts +1 -0
  3. package/dist/__tests__/bridge-config-mcp.test.js +117 -0
  4. package/dist/__tests__/bridge-server.test.d.ts +1 -0
  5. package/dist/__tests__/bridge-server.test.js +137 -0
  6. package/dist/__tests__/bridge-session-manager.test.d.ts +1 -0
  7. package/dist/__tests__/bridge-session-manager.test.js +104 -0
  8. package/dist/__tests__/config.test.js +3 -3
  9. package/dist/bridge/config.d.ts +11 -0
  10. package/dist/bridge/config.js +79 -0
  11. package/dist/bridge/mcpRegister.d.ts +28 -0
  12. package/dist/bridge/mcpRegister.js +35 -0
  13. package/dist/bridge/realPty.d.ts +2 -0
  14. package/dist/bridge/realPty.js +88 -0
  15. package/dist/bridge/server.d.ts +14 -0
  16. package/dist/bridge/server.js +182 -0
  17. package/dist/bridge/sessionManager.d.ts +42 -0
  18. package/dist/bridge/sessionManager.js +79 -0
  19. package/dist/commands/agent.js +98 -1
  20. package/dist/commands/apps.js +79 -0
  21. package/dist/commands/bounty.js +374 -7
  22. package/dist/commands/bridge.d.ts +3 -0
  23. package/dist/commands/bridge.js +122 -0
  24. package/dist/commands/credits.d.ts +2 -0
  25. package/dist/commands/credits.js +128 -0
  26. package/dist/commands/keys.d.ts +2 -0
  27. package/dist/commands/keys.js +72 -0
  28. package/dist/commands/prompts.d.ts +2 -0
  29. package/dist/commands/prompts.js +136 -0
  30. package/dist/commands/repo.d.ts +2 -0
  31. package/dist/commands/repo.js +197 -0
  32. package/dist/commands/workspace.d.ts +1 -0
  33. package/dist/commands/workspace.js +294 -12
  34. package/dist/index.js +12 -1
  35. package/dist/utils/client.d.ts +1 -0
  36. package/dist/utils/client.js +3 -0
  37. package/dist/utils/config.js +3 -3
  38. package/package.json +10 -15
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.workspaceCommand = void 0;
6
+ exports.invitesCommand = exports.workspaceCommand = void 0;
7
7
  const commander_1 = require("commander");
8
8
  const chalk_1 = __importDefault(require("chalk"));
9
9
  const client_1 = require("../utils/client");
@@ -125,22 +125,47 @@ exports.workspaceCommand
125
125
  }
126
126
  });
127
127
  exports.workspaceCommand
128
- .command('invite-create')
128
+ .command('invite-agent')
129
+ .argument('<workspace-id>', 'Workspace ID')
130
+ .argument('<wallet>', 'Wallet address of the agent to invite')
131
+ .option('--role <role>', 'Role to assign: manager, reviewer, or member', 'member')
132
+ .option('--expires <date>', 'Expiration date (ISO 8601)')
133
+ .description('Invite a specific agent to a workspace by wallet address')
134
+ .action(async (workspaceId, wallet, opts) => {
135
+ try {
136
+ const client = (0, client_1.getClient)();
137
+ const body = { targetWallet: wallet };
138
+ if (opts.role && opts.role !== 'member')
139
+ body.role = opts.role;
140
+ if (opts.expires)
141
+ body.expiresAt = opts.expires;
142
+ await client.post(`/workspaces/${workspaceId}/invites`, body);
143
+ console.log(chalk_1.default.green(`Invite sent to ${(0, format_1.shorten)(wallet)} (role: ${opts.role || 'member'})`));
144
+ }
145
+ catch (err) {
146
+ (0, format_1.error)(err.message);
147
+ }
148
+ });
149
+ exports.workspaceCommand
150
+ .command('invite-link')
129
151
  .argument('<workspace-id>', 'Workspace ID')
130
152
  .option('--max-uses <n>', 'Maximum number of uses')
153
+ .option('--role <role>', 'Role to assign: manager, reviewer, or member', 'member')
131
154
  .option('--expires <date>', 'Expiration date (ISO 8601)')
132
- .description('Create an invite link for a workspace')
155
+ .description('Generate a shareable invite link for a workspace')
133
156
  .action(async (workspaceId, opts) => {
134
157
  try {
135
158
  const client = (0, client_1.getClient)();
136
159
  const body = {};
137
160
  if (opts.maxUses)
138
161
  body.maxUses = parseInt(opts.maxUses, 10);
162
+ if (opts.role && opts.role !== 'member')
163
+ body.role = opts.role;
139
164
  if (opts.expires)
140
165
  body.expiresAt = opts.expires;
141
166
  const data = await client.post(`/workspaces/${workspaceId}/invites`, body);
142
167
  const invite = data.invite;
143
- (0, format_1.heading)('Invite Created');
168
+ (0, format_1.heading)('Invite Link Created');
144
169
  console.log(` Token: ${invite.token}`);
145
170
  console.log(` Max Uses: ${invite.maxUses ?? 'unlimited'}`);
146
171
  console.log(` Expires: ${invite.expiresAt ?? 'never'}`);
@@ -164,19 +189,121 @@ exports.workspaceCommand
164
189
  console.log('No invites found.');
165
190
  return;
166
191
  }
167
- console.log((0, format_1.makeTable)(['ID', 'Token', 'Uses', 'Max Uses', 'Expires', 'Created'], invites.map((inv) => [
168
- (0, format_1.shorten)(inv.id),
169
- inv.token.slice(0, 12) + '...',
170
- String(inv.useCount),
171
- inv.maxUses != null ? String(inv.maxUses) : 'unlimited',
172
- inv.expiresAt ? new Date(inv.expiresAt).toLocaleDateString() : 'never',
173
- new Date(inv.createdAt).toLocaleDateString(),
192
+ console.log((0, format_1.makeTable)(['ID', 'Token', 'Type', 'Target/Max', 'Uses', 'Expires', 'Created'], invites.map((inv) => {
193
+ const isTargeted = !!inv.targetWallet;
194
+ return [
195
+ (0, format_1.shorten)(inv.id),
196
+ inv.token.slice(0, 12) + '...',
197
+ isTargeted ? 'targeted' : 'open',
198
+ isTargeted ? (0, format_1.shorten)(inv.targetWallet) : (inv.maxUses != null ? String(inv.maxUses) : 'unlimited'),
199
+ String(inv.useCount),
200
+ inv.expiresAt ? new Date(inv.expiresAt).toLocaleDateString() : 'never',
201
+ new Date(inv.createdAt).toLocaleDateString(),
202
+ ];
203
+ })));
204
+ }
205
+ catch (err) {
206
+ (0, format_1.error)(err.message);
207
+ }
208
+ });
209
+ exports.workspaceCommand
210
+ .command('invite-revoke')
211
+ .argument('<workspace-id>', 'Workspace ID')
212
+ .argument('<invite-id>', 'Invite ID to revoke')
213
+ .description('Revoke an invite for a workspace')
214
+ .action(async (workspaceId, inviteId) => {
215
+ try {
216
+ const client = (0, client_1.getClient)();
217
+ await client.del(`/workspaces/${workspaceId}/invites/${inviteId}`);
218
+ console.log(chalk_1.default.green('Invite revoked.'));
219
+ }
220
+ catch (err) {
221
+ (0, format_1.error)(err.message);
222
+ }
223
+ });
224
+ exports.workspaceCommand
225
+ .command('members')
226
+ .argument('<workspace-id>', 'Workspace ID')
227
+ .description('List members and their roles')
228
+ .action(async (workspaceId) => {
229
+ try {
230
+ const client = (0, client_1.getClient)();
231
+ const data = await client.get(`/workspaces/${workspaceId}/members`);
232
+ const members = data.members || [];
233
+ if (members.length === 0) {
234
+ console.log('No members found.');
235
+ return;
236
+ }
237
+ console.log((0, format_1.makeTable)(['Wallet', 'Role', 'Joined'], members.map((m) => [
238
+ (0, format_1.shorten)(m.walletPubkey),
239
+ m.role,
240
+ m.joinedAt ? new Date(m.joinedAt).toLocaleDateString() : '',
174
241
  ])));
175
242
  }
176
243
  catch (err) {
177
244
  (0, format_1.error)(err.message);
178
245
  }
179
246
  });
247
+ exports.workspaceCommand
248
+ .command('kick')
249
+ .argument('<workspace-id>', 'Workspace ID')
250
+ .argument('<wallet>', 'Wallet to kick')
251
+ .description('Remove a member from the workspace')
252
+ .action(async (workspaceId, wallet) => {
253
+ try {
254
+ const client = (0, client_1.getClient)();
255
+ await client.del(`/workspaces/${workspaceId}/members/${wallet}`);
256
+ console.log(chalk_1.default.green(`Kicked ${(0, format_1.shorten)(wallet)} from workspace.`));
257
+ }
258
+ catch (err) {
259
+ (0, format_1.error)(err.message);
260
+ }
261
+ });
262
+ exports.workspaceCommand
263
+ .command('leave')
264
+ .argument('<workspace-id>', 'Workspace ID')
265
+ .description('Leave a workspace')
266
+ .action(async (workspaceId) => {
267
+ try {
268
+ const client = (0, client_1.getClient)();
269
+ await client.post(`/workspaces/${workspaceId}/leave`, {});
270
+ console.log(chalk_1.default.green('Left workspace.'));
271
+ }
272
+ catch (err) {
273
+ (0, format_1.error)(err.message);
274
+ }
275
+ });
276
+ exports.workspaceCommand
277
+ .command('set-role')
278
+ .argument('<workspace-id>', 'Workspace ID')
279
+ .argument('<wallet>', 'Member wallet')
280
+ .argument('<role>', 'New role: manager, reviewer, or member')
281
+ .description('Set a member\'s role (owner only)')
282
+ .action(async (workspaceId, wallet, role) => {
283
+ try {
284
+ const client = (0, client_1.getClient)();
285
+ await client.put(`/workspaces/${workspaceId}/members/${wallet}/role`, { role });
286
+ console.log(chalk_1.default.green(`Set ${(0, format_1.shorten)(wallet)} role to ${role}.`));
287
+ }
288
+ catch (err) {
289
+ (0, format_1.error)(err.message);
290
+ }
291
+ });
292
+ exports.workspaceCommand
293
+ .command('transfer')
294
+ .argument('<workspace-id>', 'Workspace ID')
295
+ .argument('<wallet>', 'New owner wallet')
296
+ .description('Transfer workspace ownership')
297
+ .action(async (workspaceId, wallet) => {
298
+ try {
299
+ const client = (0, client_1.getClient)();
300
+ await client.post(`/workspaces/${workspaceId}/transfer`, { targetWallet: wallet });
301
+ console.log(chalk_1.default.green(`Ownership transferred to ${(0, format_1.shorten)(wallet)}.`));
302
+ }
303
+ catch (err) {
304
+ (0, format_1.error)(err.message);
305
+ }
306
+ });
180
307
  exports.workspaceCommand
181
308
  .command('status')
182
309
  .argument('<workspace-id>', 'Workspace ID')
@@ -190,7 +317,6 @@ exports.workspaceCommand
190
317
  console.log(` ID: ${ws.id}`);
191
318
  console.log(` Mode: ${ws.mode}`);
192
319
  console.log(` Visibility: ${ws.visibility || 'private'}`);
193
- console.log(` Escrow: ${ws.use_escrow || ws.useEscrow ? 'Yes' : 'No'}`);
194
320
  if (ws.description)
195
321
  console.log(` Description: ${ws.description}`);
196
322
  if (ws.tags?.length)
@@ -241,3 +367,159 @@ exports.workspaceCommand
241
367
  process.exit(0);
242
368
  });
243
369
  });
370
+ exports.workspaceCommand
371
+ .command('chat')
372
+ .argument('<workspace-id>', 'Workspace ID')
373
+ .option('--limit <n>', 'Max messages to display', '50')
374
+ .option('--before <timestamp>', 'Show messages before this ISO timestamp')
375
+ .description('Display recent chat messages in a workspace')
376
+ .action(async (workspaceId, opts) => {
377
+ try {
378
+ const client = (0, client_1.getClient)();
379
+ const params = new URLSearchParams();
380
+ params.set('limit', opts.limit);
381
+ if (opts.before)
382
+ params.set('before', opts.before);
383
+ const query = params.toString();
384
+ const data = await client.get(`/workspaces/${workspaceId}/chat${query ? `?${query}` : ''}`);
385
+ const messages = data.messages || [];
386
+ if (messages.length === 0) {
387
+ console.log('No messages yet.');
388
+ return;
389
+ }
390
+ for (const msg of messages) {
391
+ const time = new Date(msg.createdAt).toLocaleTimeString();
392
+ const sender = (0, format_1.shorten)(msg.senderWallet);
393
+ const reply = msg.replyTo ? chalk_1.default.dim(` (reply to ${(0, format_1.shorten)(msg.replyTo)})`) : '';
394
+ console.log(`${chalk_1.default.dim(time)} ${chalk_1.default.cyan(sender)}${reply}: ${msg.content}`);
395
+ }
396
+ }
397
+ catch (err) {
398
+ (0, format_1.error)(err.message);
399
+ }
400
+ });
401
+ exports.workspaceCommand
402
+ .command('say')
403
+ .argument('<workspace-id>', 'Workspace ID')
404
+ .argument('<message>', 'Message to send')
405
+ .option('--reply-to <id>', 'Reply to a specific message UUID')
406
+ .description('Send a chat message to a workspace')
407
+ .action(async (workspaceId, message, opts) => {
408
+ try {
409
+ const client = (0, client_1.getClient)();
410
+ const body = { content: message };
411
+ if (opts.replyTo)
412
+ body.replyTo = opts.replyTo;
413
+ await client.post(`/workspaces/${workspaceId}/chat`, body);
414
+ console.log(chalk_1.default.green('Message sent.'));
415
+ }
416
+ catch (err) {
417
+ (0, format_1.error)(err.message);
418
+ }
419
+ });
420
+ exports.workspaceCommand
421
+ .command('context')
422
+ .argument('<workspace-id>', 'Workspace ID')
423
+ .description('List shared context keys in a workspace')
424
+ .action(async (workspaceId) => {
425
+ try {
426
+ const client = (0, client_1.getClient)();
427
+ const data = await client.get(`/workspaces/${workspaceId}/context`);
428
+ const contexts = data.contexts || [];
429
+ if (contexts.length === 0) {
430
+ console.log('No context keys found.');
431
+ return;
432
+ }
433
+ (0, format_1.heading)('Shared Context Keys');
434
+ console.log((0, format_1.makeTable)(['Key', 'Producer', 'Updated'], contexts.map((c) => [
435
+ c.key,
436
+ (0, format_1.shorten)(c.producerWallet || c.producer_wallet || '—'),
437
+ c.updatedAt || c.updated_at ? new Date(c.updatedAt || c.updated_at).toLocaleString() : '—',
438
+ ])));
439
+ }
440
+ catch (err) {
441
+ (0, format_1.error)(err.message);
442
+ }
443
+ });
444
+ exports.workspaceCommand
445
+ .command('context-get')
446
+ .argument('<workspace-id>', 'Workspace ID')
447
+ .argument('<key>', 'Context key')
448
+ .description('Read a shared context value')
449
+ .action(async (workspaceId, key) => {
450
+ try {
451
+ const client = (0, client_1.getClient)();
452
+ const data = await client.get(`/workspaces/${workspaceId}/context/${key}`);
453
+ (0, format_1.heading)(`Context: ${key}`);
454
+ console.log(JSON.stringify(data.context?.content ?? data.context, null, 2));
455
+ }
456
+ catch (err) {
457
+ (0, format_1.error)(err.message);
458
+ }
459
+ });
460
+ exports.workspaceCommand
461
+ .command('context-set')
462
+ .argument('<workspace-id>', 'Workspace ID')
463
+ .requiredOption('--key <key>', 'Context key')
464
+ .requiredOption('--value <value>', 'Context value (JSON string)')
465
+ .description('Set a shared context value')
466
+ .action(async (workspaceId, opts) => {
467
+ try {
468
+ const client = (0, client_1.getClient)();
469
+ let content;
470
+ try {
471
+ content = JSON.parse(opts.value);
472
+ }
473
+ catch {
474
+ content = opts.value;
475
+ }
476
+ await client.put(`/workspaces/${workspaceId}/context`, { key: opts.key, content });
477
+ console.log(chalk_1.default.green(`Context key '${opts.key}' set.`));
478
+ }
479
+ catch (err) {
480
+ (0, format_1.error)(err.message);
481
+ }
482
+ });
483
+ exports.invitesCommand = new commander_1.Command('invites')
484
+ .description('List pending invites for your wallet')
485
+ .action(async () => {
486
+ try {
487
+ const client = (0, client_1.getClient)();
488
+ const data = await client.get('/me/invites');
489
+ const invites = data.invites || [];
490
+ if (invites.length === 0) {
491
+ console.log('No pending invites.');
492
+ return;
493
+ }
494
+ (0, format_1.heading)('Pending Invites');
495
+ for (const item of invites) {
496
+ const inv = item.invite;
497
+ const ws = item.workspace;
498
+ console.log(` ${chalk_1.default.cyan(ws.name)} (${(0, format_1.shorten)(ws.id)})`);
499
+ if (ws.description)
500
+ console.log(` ${ws.description.slice(0, 60)}`);
501
+ console.log(` Role: ${chalk_1.default.yellow(inv.role || 'member')} Members: ${ws.memberCount ?? '?'} Visibility: ${ws.visibility}`);
502
+ console.log(` Token: ${inv.token.slice(0, 12)}...`);
503
+ console.log(` Accept: ${chalk_1.default.dim('wenrwa workspace join ' + inv.token + ' --invite')}`);
504
+ console.log(` Decline: ${chalk_1.default.dim('wenrwa invites decline ' + inv.id)}`);
505
+ console.log('');
506
+ }
507
+ }
508
+ catch (err) {
509
+ (0, format_1.error)(err.message);
510
+ }
511
+ });
512
+ exports.invitesCommand
513
+ .command('decline')
514
+ .argument('<invite-id>', 'Invite ID to decline')
515
+ .description('Decline a pending workspace invite')
516
+ .action(async (inviteId) => {
517
+ try {
518
+ const client = (0, client_1.getClient)();
519
+ await client.post('/me/invites/decline', { inviteId });
520
+ console.log(chalk_1.default.green('Invite declined.'));
521
+ }
522
+ catch (err) {
523
+ (0, format_1.error)(err.message);
524
+ }
525
+ });
package/dist/index.js CHANGED
@@ -10,11 +10,16 @@ const treasury_1 = require("./commands/treasury");
10
10
  const dashboard_1 = require("./commands/dashboard");
11
11
  const webhook_1 = require("./commands/webhook");
12
12
  const apps_1 = require("./commands/apps");
13
+ const keys_1 = require("./commands/keys");
14
+ const repo_1 = require("./commands/repo");
15
+ const prompts_1 = require("./commands/prompts");
16
+ const credits_1 = require("./commands/credits");
17
+ const bridge_1 = require("./commands/bridge");
13
18
  const program = new commander_1.Command();
14
19
  program
15
20
  .name('wen-market')
16
21
  .description('Wenrwa Agent Marketplace CLI')
17
- .version('0.1.0');
22
+ .version('0.3.0');
18
23
  program.addCommand(auth_1.authCommand);
19
24
  program.addCommand(workspace_1.workspaceCommand);
20
25
  program.addCommand(bounty_1.bountyCommand);
@@ -23,4 +28,10 @@ program.addCommand(treasury_1.treasuryCommand);
23
28
  program.addCommand(dashboard_1.dashboardCommand);
24
29
  program.addCommand(webhook_1.webhookCommand);
25
30
  program.addCommand(apps_1.appsCommand);
31
+ program.addCommand(keys_1.keysCommand);
32
+ program.addCommand(workspace_1.invitesCommand);
33
+ program.addCommand(repo_1.repoCommand);
34
+ program.addCommand(prompts_1.promptsCommand);
35
+ program.addCommand(credits_1.creditsCommand);
36
+ program.addCommand(bridge_1.bridgeCommand);
26
37
  program.parse();
@@ -6,6 +6,7 @@ export declare class ApiClient {
6
6
  get<T>(path: string): Promise<T>;
7
7
  post<T>(path: string, body?: any): Promise<T>;
8
8
  put<T>(path: string, body?: any): Promise<T>;
9
+ patch<T>(path: string, body?: any): Promise<T>;
9
10
  del<T>(path: string): Promise<T>;
10
11
  getApiUrl(): string;
11
12
  getApiKey(): string;
@@ -38,6 +38,9 @@ class ApiClient {
38
38
  put(path, body) {
39
39
  return this.request('PUT', path, body);
40
40
  }
41
+ patch(path, body) {
42
+ return this.request('PATCH', path, body);
43
+ }
41
44
  del(path) {
42
45
  return this.request('DELETE', path);
43
46
  }
@@ -42,7 +42,7 @@ const path = __importStar(require("path"));
42
42
  const os = __importStar(require("os"));
43
43
  const CONFIG_DIR = path.join(os.homedir(), '.wen-market');
44
44
  const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
45
- const DEFAULT_API_URL = 'http://localhost:3001/api/marketplace';
45
+ const DEFAULT_API_URL = 'http://localhost:3002/api/v1';
46
46
  function loadConfig() {
47
47
  try {
48
48
  const raw = fs.readFileSync(CONFIG_FILE, 'utf-8');
@@ -53,8 +53,8 @@ function loadConfig() {
53
53
  }
54
54
  }
55
55
  function saveConfig(config) {
56
- fs.mkdirSync(CONFIG_DIR, { recursive: true });
57
- fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + '\n');
56
+ fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
57
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + '\n', { mode: 0o600 });
58
58
  }
59
59
  function requireConfig() {
60
60
  const config = loadConfig();
package/package.json CHANGED
@@ -1,18 +1,10 @@
1
1
  {
2
2
  "name": "@wenrwa/marketplace-cli",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "CLI tool for the Wenrwa Agent Marketplace — monitor bounties, agents, workspaces, and treasury from your terminal",
5
5
  "author": "Wenrwa <dev@wenrwa.com>",
6
6
  "license": "MIT",
7
- "homepage": "https://github.com/BunnyDAO/wenrwa-marketplace#readme",
8
- "repository": {
9
- "type": "git",
10
- "url": "https://github.com/BunnyDAO/wenrwa-marketplace.git",
11
- "directory": "cli"
12
- },
13
- "bugs": {
14
- "url": "https://github.com/BunnyDAO/wenrwa-marketplace/issues"
15
- },
7
+ "homepage": "https://marketplace.wenrwa.com",
16
8
  "keywords": [
17
9
  "solana",
18
10
  "ai-agent",
@@ -37,17 +29,20 @@
37
29
  "test": "jest"
38
30
  },
39
31
  "dependencies": {
40
- "commander": "^12.0.0",
41
32
  "chalk": "^4.1.2",
42
33
  "cli-table3": "^0.6.0",
43
- "socket.io-client": "^4.7.0"
34
+ "commander": "^12.0.0",
35
+ "node-pty": "^1.1.0",
36
+ "socket.io-client": "^4.7.0",
37
+ "ws": "^8.21.1"
44
38
  },
45
39
  "devDependencies": {
46
- "typescript": "^5.5.0",
47
- "@types/node": "^20.0.0",
48
40
  "@types/jest": "^29.5.0",
41
+ "@types/node": "^20.0.0",
42
+ "@types/ws": "^8.18.1",
49
43
  "jest": "^29.7.0",
50
44
  "ts-jest": "^29.2.0",
51
- "ts-node": "^10.9.0"
45
+ "ts-node": "^10.9.0",
46
+ "typescript": "^5.5.0"
52
47
  }
53
48
  }