@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
@@ -0,0 +1,72 @@
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.keysCommand = void 0;
7
+ const commander_1 = require("commander");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const client_1 = require("../utils/client");
10
+ const format_1 = require("../utils/format");
11
+ exports.keysCommand = new commander_1.Command('keys').description('API key management');
12
+ exports.keysCommand
13
+ .command('generate')
14
+ .option('--name <name>', 'Human-readable name for the key')
15
+ .description('Generate a new API key')
16
+ .action(async (opts) => {
17
+ try {
18
+ const client = (0, client_1.getClient)();
19
+ const data = await client.post('/keys/generate', { name: opts.name });
20
+ const rec = data.keyRecord;
21
+ (0, format_1.success)('API key generated');
22
+ console.log(` ID: ${rec.id}`);
23
+ console.log(` Name: ${rec.name || chalk_1.default.dim('(none)')}`);
24
+ console.log(` Prefix: ${rec.keyPrefix}`);
25
+ console.log();
26
+ console.log(chalk_1.default.yellow.bold(' Full key (shown once — save it now):'));
27
+ console.log(chalk_1.default.yellow(` ${data.key}`));
28
+ }
29
+ catch (err) {
30
+ (0, format_1.error)(err.message);
31
+ }
32
+ });
33
+ exports.keysCommand
34
+ .command('list')
35
+ .description('List your API keys')
36
+ .action(async () => {
37
+ try {
38
+ const client = (0, client_1.getClient)();
39
+ const data = await client.get('/keys');
40
+ const keys = data.keys || [];
41
+ if (keys.length === 0) {
42
+ console.log(chalk_1.default.dim(' No API keys'));
43
+ return;
44
+ }
45
+ (0, format_1.heading)('API Keys');
46
+ console.log((0, format_1.makeTable)(['ID', 'Name', 'Prefix', 'Permissions', 'Last Used', 'Active'], keys.map((k) => [
47
+ (0, format_1.shorten)(k.id),
48
+ k.name || chalk_1.default.dim('—'),
49
+ k.keyPrefix,
50
+ k.permissions?.length ? k.permissions.join(', ') : chalk_1.default.dim('all'),
51
+ k.lastUsedAt ? (0, format_1.formatTimeAgo)(k.lastUsedAt) : chalk_1.default.dim('never'),
52
+ k.isActive ? chalk_1.default.green('yes') : chalk_1.default.red('no'),
53
+ ])));
54
+ }
55
+ catch (err) {
56
+ (0, format_1.error)(err.message);
57
+ }
58
+ });
59
+ exports.keysCommand
60
+ .command('revoke')
61
+ .argument('<key-id>', 'API key ID to revoke')
62
+ .description('Revoke an API key')
63
+ .action(async (keyId) => {
64
+ try {
65
+ const client = (0, client_1.getClient)();
66
+ await client.del(`/keys/${keyId}`);
67
+ (0, format_1.success)(`API key ${(0, format_1.shorten)(keyId)} revoked`);
68
+ }
69
+ catch (err) {
70
+ (0, format_1.error)(err.message);
71
+ }
72
+ });
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare const promptsCommand: Command;
@@ -0,0 +1,136 @@
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.promptsCommand = void 0;
40
+ const commander_1 = require("commander");
41
+ const chalk_1 = __importDefault(require("chalk"));
42
+ const client_1 = require("../utils/client");
43
+ const format_1 = require("../utils/format");
44
+ exports.promptsCommand = new commander_1.Command('prompts').description('Browse curated prompt templates');
45
+ exports.promptsCommand
46
+ .description('List all curated prompts')
47
+ .option('--category <cat>', 'Filter by category (agent, poster, workspace, workflow)')
48
+ .action(async (opts) => {
49
+ try {
50
+ const client = (0, client_1.getClient)();
51
+ const query = opts.category ? `?category=${opts.category}` : '';
52
+ const data = await client.get(`/prompts${query}`);
53
+ const prompts = data.prompts || [];
54
+ if (prompts.length === 0) {
55
+ console.log('No prompts found.');
56
+ return;
57
+ }
58
+ (0, format_1.heading)('Curated Prompts');
59
+ for (const p of prompts) {
60
+ const badge = chalk_1.default.dim(`[${p.category}]`);
61
+ console.log(` ${chalk_1.default.bold(p.name)} ${badge}`);
62
+ console.log(` ${p.title} — ${chalk_1.default.dim(p.description)}`);
63
+ if (p.tags?.length) {
64
+ console.log(` ${chalk_1.default.cyan(p.tags.join(', '))}`);
65
+ }
66
+ console.log();
67
+ }
68
+ }
69
+ catch (err) {
70
+ (0, format_1.error)(err.message);
71
+ }
72
+ });
73
+ exports.promptsCommand
74
+ .command('show')
75
+ .argument('<name>', 'Prompt name (slug)')
76
+ .description('Show full prompt content')
77
+ .action(async (name) => {
78
+ try {
79
+ const client = (0, client_1.getClient)();
80
+ const data = await client.get(`/prompts/${name}`);
81
+ const p = data.prompt;
82
+ (0, format_1.heading)(p.title);
83
+ console.log(` Category: ${p.category}`);
84
+ console.log(` Description: ${p.description}`);
85
+ if (p.tags?.length) {
86
+ console.log(` Tags: ${p.tags.join(', ')}`);
87
+ }
88
+ if (p.tools?.length) {
89
+ console.log(` Tools: ${p.tools.join(', ')}`);
90
+ }
91
+ if (p.arguments?.length) {
92
+ console.log(` Arguments:`);
93
+ for (const arg of p.arguments) {
94
+ const req = arg.required ? chalk_1.default.red('*') : '';
95
+ console.log(` ${arg.name}${req} — ${arg.description}`);
96
+ }
97
+ }
98
+ console.log();
99
+ console.log(chalk_1.default.dim('─'.repeat(60)));
100
+ console.log();
101
+ console.log(p.content);
102
+ }
103
+ catch (err) {
104
+ (0, format_1.error)(err.message);
105
+ }
106
+ });
107
+ exports.promptsCommand
108
+ .command('copy')
109
+ .argument('<name>', 'Prompt name (slug)')
110
+ .description('Copy prompt content to clipboard')
111
+ .action(async (name) => {
112
+ try {
113
+ const client = (0, client_1.getClient)();
114
+ const data = await client.get(`/prompts/${name}`);
115
+ const p = data.prompt;
116
+ // Use pbcopy on macOS, xclip on Linux
117
+ const { execSync } = await Promise.resolve().then(() => __importStar(require('child_process')));
118
+ try {
119
+ execSync('pbcopy', { input: p.content });
120
+ console.log(chalk_1.default.green(`Copied "${p.title}" to clipboard.`));
121
+ }
122
+ catch {
123
+ try {
124
+ execSync('xclip -selection clipboard', { input: p.content });
125
+ console.log(chalk_1.default.green(`Copied "${p.title}" to clipboard.`));
126
+ }
127
+ catch {
128
+ console.log(p.content);
129
+ console.log(chalk_1.default.yellow('\nCould not copy to clipboard. Content printed above.'));
130
+ }
131
+ }
132
+ }
133
+ catch (err) {
134
+ (0, format_1.error)(err.message);
135
+ }
136
+ });
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare const repoCommand: Command;
@@ -0,0 +1,197 @@
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.repoCommand = void 0;
7
+ const commander_1 = require("commander");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const client_1 = require("../utils/client");
10
+ const format_1 = require("../utils/format");
11
+ exports.repoCommand = new commander_1.Command('repo').description('GitHub repo access management');
12
+ exports.repoCommand
13
+ .command('list')
14
+ .description('List GitHub repos accessible via your GitHub App installation')
15
+ .action(async () => {
16
+ try {
17
+ const client = (0, client_1.getClient)();
18
+ const data = await client.get('/github/repos');
19
+ const repos = data.repos || [];
20
+ if (repos.length === 0) {
21
+ console.log(chalk_1.default.dim(' No repos found. Install the Wenrwa GitHub App first.'));
22
+ return;
23
+ }
24
+ (0, format_1.heading)('Accessible Repos');
25
+ console.log((0, format_1.makeTable)(['Repo', 'Private', 'Branch'], repos.map((r) => [
26
+ r.fullName,
27
+ r.private ? chalk_1.default.yellow('yes') : chalk_1.default.dim('no'),
28
+ r.defaultBranch || 'main',
29
+ ])));
30
+ }
31
+ catch (err) {
32
+ (0, format_1.error)(err.message);
33
+ }
34
+ });
35
+ exports.repoCommand
36
+ .command('browse')
37
+ .argument('<repo>', 'Repository in owner/repo format')
38
+ .argument('[path]', 'Directory path to browse', '')
39
+ .option('--ref <ref>', 'Git ref (branch/tag/SHA)', 'HEAD')
40
+ .description('Browse a repo directory tree')
41
+ .action(async (repo, path, opts) => {
42
+ try {
43
+ const [owner, repoName] = repo.split('/');
44
+ if (!owner || !repoName) {
45
+ (0, format_1.error)('Repo must be in owner/repo format');
46
+ return;
47
+ }
48
+ const client = (0, client_1.getClient)();
49
+ const qs = new URLSearchParams();
50
+ if (path)
51
+ qs.set('path', path);
52
+ if (opts.ref !== 'HEAD')
53
+ qs.set('ref', opts.ref);
54
+ const query = qs.toString();
55
+ const data = await client.get(`/github/repos/${owner}/${repoName}/tree${query ? `?${query}` : ''}`);
56
+ const tree = data.tree || [];
57
+ if (tree.length === 0) {
58
+ console.log(chalk_1.default.dim(' Empty directory'));
59
+ return;
60
+ }
61
+ (0, format_1.heading)(`${repo}${path ? `/${path}` : ''}`);
62
+ for (const entry of tree) {
63
+ const icon = entry.type === 'dir' ? chalk_1.default.blue('📁') : '📄';
64
+ const size = entry.size ? chalk_1.default.dim(` (${formatSize(entry.size)})`) : '';
65
+ console.log(` ${icon} ${entry.name}${size}`);
66
+ }
67
+ }
68
+ catch (err) {
69
+ (0, format_1.error)(err.message);
70
+ }
71
+ });
72
+ exports.repoCommand
73
+ .command('grant')
74
+ .argument('<bountyId>', 'Bounty ID')
75
+ .argument('<repo>', 'Repository in owner/repo format')
76
+ .option('--paths <globs...>', 'Allowed path patterns (e.g. "src/**" "package.json")')
77
+ .option('--blocked <globs...>', 'Additional blocked path patterns')
78
+ .option('--access <level>', 'Access level: read or write', 'read')
79
+ .description('Grant agent access to a repo for a bounty')
80
+ .action(async (bountyId, repo, opts) => {
81
+ try {
82
+ const client = (0, client_1.getClient)();
83
+ const body = {
84
+ repoFullName: repo,
85
+ accessLevel: opts.access,
86
+ };
87
+ if (opts.paths)
88
+ body.allowedPaths = opts.paths;
89
+ if (opts.blocked)
90
+ body.blockedPaths = opts.blocked;
91
+ const data = await client.post(`/bounties/${bountyId}/repo-access`, body);
92
+ const grant = data.grant;
93
+ (0, format_1.success)('Repo access granted');
94
+ console.log(` Bounty: ${(0, format_1.shorten)(bountyId)}`);
95
+ console.log(` Repo: ${grant.repoFullName}`);
96
+ console.log(` Access: ${grant.accessLevel}`);
97
+ console.log(` Private: ${grant.repoPrivate ? chalk_1.default.yellow('yes') : 'no'}`);
98
+ if (grant.allowedPaths.length > 0) {
99
+ console.log(` Allowed: ${grant.allowedPaths.join(', ')}`);
100
+ }
101
+ else {
102
+ console.log(` Allowed: ${chalk_1.default.dim('all files (except blocked)')}`);
103
+ }
104
+ console.log(` Blocked: ${grant.blockedPaths.join(', ')}`);
105
+ }
106
+ catch (err) {
107
+ (0, format_1.error)(err.message);
108
+ }
109
+ });
110
+ exports.repoCommand
111
+ .command('access')
112
+ .argument('<bountyId>', 'Bounty ID')
113
+ .description('View repo access grants for a bounty')
114
+ .action(async (bountyId) => {
115
+ try {
116
+ const client = (0, client_1.getClient)();
117
+ const data = await client.get(`/bounties/${bountyId}/repo-access`);
118
+ const grants = data.grants || [];
119
+ if (grants.length === 0) {
120
+ console.log(chalk_1.default.dim(' No repo access grants for this bounty'));
121
+ return;
122
+ }
123
+ (0, format_1.heading)(`Repo Access — Bounty ${(0, format_1.shorten)(bountyId)}`);
124
+ console.log((0, format_1.makeTable)(['Repo', 'Access', 'Private', 'Allowed Paths', 'Granted By'], grants.map((g) => [
125
+ g.repoFullName,
126
+ g.accessLevel,
127
+ g.repoPrivate ? chalk_1.default.yellow('yes') : 'no',
128
+ g.allowedPaths.length > 0 ? g.allowedPaths.join(', ') : chalk_1.default.dim('all'),
129
+ (0, format_1.shorten)(g.grantedBy),
130
+ ])));
131
+ }
132
+ catch (err) {
133
+ (0, format_1.error)(err.message);
134
+ }
135
+ });
136
+ exports.repoCommand
137
+ .command('revoke')
138
+ .argument('<bountyId>', 'Bounty ID')
139
+ .argument('<repo>', 'Repository in owner/repo format')
140
+ .description('Revoke repo access for a bounty')
141
+ .action(async (bountyId, repo) => {
142
+ try {
143
+ const client = (0, client_1.getClient)();
144
+ await client.del(`/bounties/${bountyId}/repo-access/${repo}`);
145
+ (0, format_1.success)(`Repo access revoked for ${repo}`);
146
+ }
147
+ catch (err) {
148
+ (0, format_1.error)(err.message);
149
+ }
150
+ });
151
+ exports.repoCommand
152
+ .command('files')
153
+ .argument('<bountyId>', 'Bounty ID')
154
+ .argument('[path]', 'File path to read (omit to list all accessible files)')
155
+ .description('List accessible files or read a specific file')
156
+ .action(async (bountyId, path) => {
157
+ try {
158
+ const client = (0, client_1.getClient)();
159
+ if (path) {
160
+ // Read specific file
161
+ const data = await client.get(`/bounties/${bountyId}/files/${path}`);
162
+ const file = data.file;
163
+ (0, format_1.heading)(`${file.path} (${formatSize(file.size)})`);
164
+ console.log(file.content);
165
+ }
166
+ else {
167
+ // List all files
168
+ const data = await client.get(`/bounties/${bountyId}/files`);
169
+ const groups = data.files || [];
170
+ if (groups.length === 0) {
171
+ console.log(chalk_1.default.dim(' No accessible files'));
172
+ return;
173
+ }
174
+ for (const group of groups) {
175
+ (0, format_1.heading)(group.repoFullName);
176
+ if (group.files.length === 0) {
177
+ console.log(chalk_1.default.dim(' No files'));
178
+ continue;
179
+ }
180
+ for (const file of group.files) {
181
+ const size = file.size ? chalk_1.default.dim(` (${formatSize(file.size)})`) : '';
182
+ console.log(` 📄 ${file.path}${size}`);
183
+ }
184
+ }
185
+ }
186
+ }
187
+ catch (err) {
188
+ (0, format_1.error)(err.message);
189
+ }
190
+ });
191
+ function formatSize(bytes) {
192
+ if (bytes < 1024)
193
+ return `${bytes}B`;
194
+ if (bytes < 1024 * 1024)
195
+ return `${(bytes / 1024).toFixed(1)}KB`;
196
+ return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
197
+ }
@@ -1,2 +1,3 @@
1
1
  import { Command } from 'commander';
2
2
  export declare const workspaceCommand: Command;
3
+ export declare const invitesCommand: Command;