@paperpod/cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +245 -0
- package/dist/cli.d.ts +22 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +812 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands.d.ts +106 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +1053 -0
- package/dist/commands.js.map +1 -0
- package/dist/config.d.ts +47 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +117 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/transport.d.ts +347 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +684 -0
- package/dist/transport.js.map +1 -0
- package/package.json +39 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,812 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* PaperPod CLI
|
|
4
|
+
*
|
|
5
|
+
* Agent-native sandbox execution from your terminal.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* ppod exec "ls -la" # Execute a command
|
|
9
|
+
* ppod exec "npm test" --timeout 120000
|
|
10
|
+
* ppod write /app/script.py ./local.py
|
|
11
|
+
* cat file.txt | ppod write /app/file.txt
|
|
12
|
+
* ppod read /app/output.txt
|
|
13
|
+
* ppod ls /app
|
|
14
|
+
* ppod login # Save token
|
|
15
|
+
* ppod status # Check connection
|
|
16
|
+
*
|
|
17
|
+
* Environment:
|
|
18
|
+
* PAPERPOD_TOKEN - Authentication token (overrides config file)
|
|
19
|
+
* PAPERPOD_API_URL - API URL (default: wss://paperpod.dev/ws)
|
|
20
|
+
*/
|
|
21
|
+
import { execCommand, writeCommand, readCommand, listCommand, loginCommand, logoutCommand, statusCommand, helpCommand, versionCommand,
|
|
22
|
+
// Process & Ports
|
|
23
|
+
exposeCommand, processStartCommand, processListCommand, processKillCommand,
|
|
24
|
+
// Browser
|
|
25
|
+
screenshotCommand, pdfCommand, scrapeCommand, markdownCommand, contentCommand, traceCommand, testCommand, browserSessionsCommand, browserLimitsCommand,
|
|
26
|
+
// AI
|
|
27
|
+
aiGenerateCommand, aiEmbedCommand, aiImageCommand, aiTranscribeCommand,
|
|
28
|
+
// Code
|
|
29
|
+
interpretCommand,
|
|
30
|
+
// Memory
|
|
31
|
+
memoryWriteCommand, memoryReadCommand, memoryListCommand, memoryDeleteCommand, memoryUsageCommand,
|
|
32
|
+
// Account
|
|
33
|
+
balanceCommand, } from "./commands.js";
|
|
34
|
+
function parseArgs(argv) {
|
|
35
|
+
const args = argv.slice(2);
|
|
36
|
+
const command = args[0] || "help";
|
|
37
|
+
const rest = [];
|
|
38
|
+
const options = {};
|
|
39
|
+
let i = 1;
|
|
40
|
+
while (i < args.length) {
|
|
41
|
+
const arg = args[i];
|
|
42
|
+
if (arg === "--timeout" && args[i + 1]) {
|
|
43
|
+
options.timeout = parseInt(args[i + 1], 10);
|
|
44
|
+
i += 2;
|
|
45
|
+
}
|
|
46
|
+
else if (arg === "--json") {
|
|
47
|
+
options.json = true;
|
|
48
|
+
i++;
|
|
49
|
+
}
|
|
50
|
+
else if (arg === "--no-stream") {
|
|
51
|
+
options.stream = false;
|
|
52
|
+
i++;
|
|
53
|
+
}
|
|
54
|
+
else if ((arg === "-o" || arg === "--output") && args[i + 1]) {
|
|
55
|
+
options.output = args[i + 1];
|
|
56
|
+
i += 2;
|
|
57
|
+
}
|
|
58
|
+
else if (arg === "-h" || arg === "--help") {
|
|
59
|
+
options.help = true;
|
|
60
|
+
i++;
|
|
61
|
+
}
|
|
62
|
+
else if (arg === "--full-page") {
|
|
63
|
+
options.fullPage = true;
|
|
64
|
+
i++;
|
|
65
|
+
}
|
|
66
|
+
else if (arg === "--width" && args[i + 1]) {
|
|
67
|
+
options.width = parseInt(args[i + 1], 10);
|
|
68
|
+
i += 2;
|
|
69
|
+
}
|
|
70
|
+
else if (arg === "--height" && args[i + 1]) {
|
|
71
|
+
options.height = parseInt(args[i + 1], 10);
|
|
72
|
+
i += 2;
|
|
73
|
+
}
|
|
74
|
+
else if (arg === "--format" && args[i + 1]) {
|
|
75
|
+
options.format = args[i + 1];
|
|
76
|
+
i += 2;
|
|
77
|
+
}
|
|
78
|
+
else if (arg === "--landscape") {
|
|
79
|
+
options.landscape = true;
|
|
80
|
+
i++;
|
|
81
|
+
}
|
|
82
|
+
else if (arg === "--limit" && args[i + 1]) {
|
|
83
|
+
options.limit = parseInt(args[i + 1], 10);
|
|
84
|
+
i += 2;
|
|
85
|
+
}
|
|
86
|
+
else if (arg === "--model" && args[i + 1]) {
|
|
87
|
+
options.model = args[i + 1];
|
|
88
|
+
i += 2;
|
|
89
|
+
}
|
|
90
|
+
else if (arg === "--system" && args[i + 1]) {
|
|
91
|
+
options.systemPrompt = args[i + 1];
|
|
92
|
+
i += 2;
|
|
93
|
+
}
|
|
94
|
+
else if (arg === "--max-tokens" && args[i + 1]) {
|
|
95
|
+
options.maxTokens = parseInt(args[i + 1], 10);
|
|
96
|
+
i += 2;
|
|
97
|
+
}
|
|
98
|
+
else if (arg === "--temperature" && args[i + 1]) {
|
|
99
|
+
options.temperature = parseFloat(args[i + 1]);
|
|
100
|
+
i += 2;
|
|
101
|
+
}
|
|
102
|
+
else if (arg === "--language" && args[i + 1]) {
|
|
103
|
+
options.language = args[i + 1];
|
|
104
|
+
i += 2;
|
|
105
|
+
}
|
|
106
|
+
else if (arg === "--id" && args[i + 1]) {
|
|
107
|
+
options.processId = args[i + 1];
|
|
108
|
+
i += 2;
|
|
109
|
+
}
|
|
110
|
+
else if (arg === "--trace" && args[i + 1]) {
|
|
111
|
+
options.trace = args[i + 1];
|
|
112
|
+
i += 2;
|
|
113
|
+
}
|
|
114
|
+
else if (arg.startsWith("-")) {
|
|
115
|
+
// Unknown option, skip
|
|
116
|
+
i++;
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
rest.push(arg);
|
|
120
|
+
i++;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return { command, args: rest, options };
|
|
124
|
+
}
|
|
125
|
+
// ============================================================================
|
|
126
|
+
// Per-Command Help
|
|
127
|
+
// ============================================================================
|
|
128
|
+
const COMMAND_HELP = {
|
|
129
|
+
exec: `
|
|
130
|
+
ppod exec <command> [options]
|
|
131
|
+
|
|
132
|
+
Execute a shell command in your sandbox.
|
|
133
|
+
|
|
134
|
+
OPTIONS:
|
|
135
|
+
--timeout <ms> Command timeout (default: 60000)
|
|
136
|
+
--json Output as JSON
|
|
137
|
+
--no-stream Disable streaming output
|
|
138
|
+
|
|
139
|
+
EXAMPLES:
|
|
140
|
+
ppod exec "ls -la"
|
|
141
|
+
ppod exec "python train.py" --timeout 120000
|
|
142
|
+
ppod exec "npm test" --json
|
|
143
|
+
`,
|
|
144
|
+
write: `
|
|
145
|
+
ppod write <remote-path> [local-file]
|
|
146
|
+
|
|
147
|
+
Write a file to your sandbox. If no local file is specified, reads from stdin.
|
|
148
|
+
|
|
149
|
+
EXAMPLES:
|
|
150
|
+
ppod write /app/script.py ./local.py
|
|
151
|
+
echo "hello" | ppod write /app/hello.txt
|
|
152
|
+
cat config.json | ppod write /app/config.json
|
|
153
|
+
`,
|
|
154
|
+
read: `
|
|
155
|
+
ppod read <remote-path> [-o output-file]
|
|
156
|
+
|
|
157
|
+
Read a file from your sandbox.
|
|
158
|
+
|
|
159
|
+
OPTIONS:
|
|
160
|
+
-o, --output <file> Save to local file instead of stdout
|
|
161
|
+
|
|
162
|
+
EXAMPLES:
|
|
163
|
+
ppod read /app/output.txt
|
|
164
|
+
ppod read /app/data.json -o local.json
|
|
165
|
+
`,
|
|
166
|
+
ls: `
|
|
167
|
+
ppod ls [path] [options]
|
|
168
|
+
|
|
169
|
+
List directory contents in your sandbox.
|
|
170
|
+
|
|
171
|
+
OPTIONS:
|
|
172
|
+
--json Output as JSON
|
|
173
|
+
|
|
174
|
+
EXAMPLES:
|
|
175
|
+
ppod ls
|
|
176
|
+
ppod ls /app --json
|
|
177
|
+
`,
|
|
178
|
+
"browser:screenshot": `
|
|
179
|
+
ppod browser:screenshot <url> [options]
|
|
180
|
+
|
|
181
|
+
Take a screenshot of a web page.
|
|
182
|
+
|
|
183
|
+
OPTIONS:
|
|
184
|
+
-o, --output <file> Save to file (default: prints base64)
|
|
185
|
+
--full-page Capture entire page
|
|
186
|
+
--width <px> Viewport width (default: 1280)
|
|
187
|
+
--height <px> Viewport height (default: 720)
|
|
188
|
+
--format <fmt> png, jpeg, or webp (default: png)
|
|
189
|
+
--trace <file> Capture Playwright trace for debugging
|
|
190
|
+
--json Output as JSON
|
|
191
|
+
|
|
192
|
+
EXAMPLES:
|
|
193
|
+
ppod browser:screenshot https://example.com -o shot.png
|
|
194
|
+
ppod browser:screenshot https://example.com --full-page
|
|
195
|
+
ppod browser:screenshot https://example.com --trace debug.zip
|
|
196
|
+
`,
|
|
197
|
+
"browser:pdf": `
|
|
198
|
+
ppod browser:pdf <url> [options]
|
|
199
|
+
|
|
200
|
+
Generate a PDF from a web page.
|
|
201
|
+
|
|
202
|
+
OPTIONS:
|
|
203
|
+
-o, --output <file> Save to file (default: prints base64)
|
|
204
|
+
--landscape Use landscape orientation
|
|
205
|
+
--format <size> a4, letter, legal (default: a4)
|
|
206
|
+
--json Output as JSON
|
|
207
|
+
|
|
208
|
+
EXAMPLES:
|
|
209
|
+
ppod browser:pdf https://example.com -o doc.pdf
|
|
210
|
+
ppod browser:pdf https://example.com --landscape
|
|
211
|
+
`,
|
|
212
|
+
"browser:scrape": `
|
|
213
|
+
ppod browser:scrape <url> [selector] [options]
|
|
214
|
+
|
|
215
|
+
Scrape elements from a web page.
|
|
216
|
+
|
|
217
|
+
ARGUMENTS:
|
|
218
|
+
url The page URL
|
|
219
|
+
selector CSS selector (default: "body")
|
|
220
|
+
|
|
221
|
+
OPTIONS:
|
|
222
|
+
--limit <n> Max elements to return
|
|
223
|
+
--json Output as JSON
|
|
224
|
+
|
|
225
|
+
EXAMPLES:
|
|
226
|
+
ppod browser:scrape https://example.com
|
|
227
|
+
ppod browser:scrape https://example.com "h1, h2"
|
|
228
|
+
ppod browser:scrape https://news.ycombinator.com ".titleline" --limit 10
|
|
229
|
+
`,
|
|
230
|
+
"browser:markdown": `
|
|
231
|
+
ppod browser:markdown <url> [options]
|
|
232
|
+
|
|
233
|
+
Extract markdown from a rendered web page.
|
|
234
|
+
|
|
235
|
+
OPTIONS:
|
|
236
|
+
-o, --output <file> Save to file
|
|
237
|
+
--json Output as JSON
|
|
238
|
+
|
|
239
|
+
EXAMPLES:
|
|
240
|
+
ppod browser:markdown https://example.com
|
|
241
|
+
ppod browser:markdown https://example.com -o page.md
|
|
242
|
+
`,
|
|
243
|
+
"browser:content": `
|
|
244
|
+
ppod browser:content <url> [options]
|
|
245
|
+
|
|
246
|
+
Get the rendered HTML of a web page.
|
|
247
|
+
|
|
248
|
+
OPTIONS:
|
|
249
|
+
-o, --output <file> Save to file
|
|
250
|
+
--json Output as JSON
|
|
251
|
+
|
|
252
|
+
EXAMPLES:
|
|
253
|
+
ppod browser:content https://example.com
|
|
254
|
+
ppod browser:content https://example.com -o page.html
|
|
255
|
+
`,
|
|
256
|
+
"browser:trace": `
|
|
257
|
+
ppod browser:trace start|stop [options]
|
|
258
|
+
|
|
259
|
+
Start or stop browser tracing for debugging.
|
|
260
|
+
|
|
261
|
+
NOTE: Tracing captures all browser operations within the same connection.
|
|
262
|
+
Use with ppod browser:* commands in sequence.
|
|
263
|
+
|
|
264
|
+
OPTIONS:
|
|
265
|
+
-o, --output <file> Save trace to file (for stop)
|
|
266
|
+
--json Output as JSON
|
|
267
|
+
|
|
268
|
+
EXAMPLES:
|
|
269
|
+
ppod browser:trace start
|
|
270
|
+
ppod browser:screenshot https://example.com
|
|
271
|
+
ppod browser:trace stop -o trace.zip
|
|
272
|
+
`,
|
|
273
|
+
"browser:test": `
|
|
274
|
+
ppod browser:test <url> '<assertions-json>' [options]
|
|
275
|
+
|
|
276
|
+
Run Playwright-style assertions against a web page.
|
|
277
|
+
|
|
278
|
+
ASSERTION TYPES:
|
|
279
|
+
visible Element is visible: {"type":"visible","selector":"h1"}
|
|
280
|
+
hidden Element is hidden: {"type":"hidden","selector":".modal"}
|
|
281
|
+
text Element has text: {"type":"text","selector":"h1","expected":"Hello"}
|
|
282
|
+
count Element count: {"type":"count","selector":"li","expected":5}
|
|
283
|
+
title Page title contains: {"type":"title","expected":"Example"}
|
|
284
|
+
url URL contains: {"type":"url","expected":"example.com"}
|
|
285
|
+
|
|
286
|
+
OPTIONS:
|
|
287
|
+
--json Output as JSON
|
|
288
|
+
|
|
289
|
+
EXAMPLES:
|
|
290
|
+
ppod browser:test https://example.com '[{"type":"visible","selector":"h1"}]'
|
|
291
|
+
ppod browser:test https://example.com '[{"type":"text","selector":"h1","expected":"Example Domain"}]'
|
|
292
|
+
`,
|
|
293
|
+
ai: `
|
|
294
|
+
ppod ai <prompt> [options]
|
|
295
|
+
|
|
296
|
+
Generate text using a large language model.
|
|
297
|
+
|
|
298
|
+
OPTIONS:
|
|
299
|
+
--model <name> Model to use (default: llama-3.2-1b-instruct)
|
|
300
|
+
--system <prompt> System prompt
|
|
301
|
+
--max-tokens <n> Max output tokens
|
|
302
|
+
--temperature <f> Sampling temperature (0-2)
|
|
303
|
+
--json Output as JSON
|
|
304
|
+
|
|
305
|
+
EXAMPLES:
|
|
306
|
+
ppod ai "Write a haiku about coding"
|
|
307
|
+
ppod ai "Explain quantum computing" --model "@cf/meta/llama-3.1-8b-instruct"
|
|
308
|
+
ppod ai "Summarize this" --json
|
|
309
|
+
`,
|
|
310
|
+
"ai:image": `
|
|
311
|
+
ppod ai:image <prompt> [options]
|
|
312
|
+
|
|
313
|
+
Generate an image from a text prompt.
|
|
314
|
+
|
|
315
|
+
OPTIONS:
|
|
316
|
+
-o, --output <file> Save to file (default: prints base64)
|
|
317
|
+
--width <px> Image width (default: 1024)
|
|
318
|
+
--height <px> Image height (default: 1024)
|
|
319
|
+
--model <name> Model to use
|
|
320
|
+
--json Output as JSON
|
|
321
|
+
|
|
322
|
+
EXAMPLES:
|
|
323
|
+
ppod ai:image "A sunset over mountains" -o sunset.png
|
|
324
|
+
ppod ai:image "A happy robot" --width 512 --height 512
|
|
325
|
+
`,
|
|
326
|
+
"ai:embed": `
|
|
327
|
+
ppod ai:embed <text> [options]
|
|
328
|
+
|
|
329
|
+
Generate embeddings for text.
|
|
330
|
+
|
|
331
|
+
OPTIONS:
|
|
332
|
+
--model <name> Model to use
|
|
333
|
+
--json Output as JSON
|
|
334
|
+
|
|
335
|
+
EXAMPLES:
|
|
336
|
+
ppod ai:embed "Hello world"
|
|
337
|
+
ppod ai:embed "Search query" --json
|
|
338
|
+
`,
|
|
339
|
+
expose: `
|
|
340
|
+
ppod expose <port> [options]
|
|
341
|
+
|
|
342
|
+
Expose a port from your sandbox and get a public URL.
|
|
343
|
+
|
|
344
|
+
OPTIONS:
|
|
345
|
+
--json Output as JSON
|
|
346
|
+
|
|
347
|
+
EXAMPLES:
|
|
348
|
+
ppod start "python -m http.server 8080"
|
|
349
|
+
ppod expose 8080
|
|
350
|
+
`,
|
|
351
|
+
start: `
|
|
352
|
+
ppod start <command> [options]
|
|
353
|
+
|
|
354
|
+
Start a background process in your sandbox.
|
|
355
|
+
|
|
356
|
+
OPTIONS:
|
|
357
|
+
--json Output as JSON
|
|
358
|
+
|
|
359
|
+
EXAMPLES:
|
|
360
|
+
ppod start "node server.js"
|
|
361
|
+
ppod start "python -m http.server 8080"
|
|
362
|
+
ppod ps # Check running processes
|
|
363
|
+
ppod expose 8080 # Expose the port
|
|
364
|
+
`,
|
|
365
|
+
ps: `
|
|
366
|
+
ppod ps [options]
|
|
367
|
+
|
|
368
|
+
List running processes in your sandbox.
|
|
369
|
+
|
|
370
|
+
OPTIONS:
|
|
371
|
+
--json Output as JSON
|
|
372
|
+
|
|
373
|
+
EXAMPLES:
|
|
374
|
+
ppod ps
|
|
375
|
+
ppod ps --json
|
|
376
|
+
`,
|
|
377
|
+
kill: `
|
|
378
|
+
ppod kill <process-id>
|
|
379
|
+
|
|
380
|
+
Kill a running process.
|
|
381
|
+
|
|
382
|
+
EXAMPLES:
|
|
383
|
+
ppod ps # Get process IDs
|
|
384
|
+
ppod kill proc-123
|
|
385
|
+
`,
|
|
386
|
+
"mem:write": `
|
|
387
|
+
ppod mem:write <path> [local-file]
|
|
388
|
+
|
|
389
|
+
Write to persistent memory (survives sandbox restarts).
|
|
390
|
+
|
|
391
|
+
EXAMPLES:
|
|
392
|
+
ppod mem:write state.json ./local.json
|
|
393
|
+
echo '{"step":1}' | ppod mem:write progress.json
|
|
394
|
+
`,
|
|
395
|
+
"mem:read": `
|
|
396
|
+
ppod mem:read <path>
|
|
397
|
+
|
|
398
|
+
Read from persistent memory.
|
|
399
|
+
|
|
400
|
+
EXAMPLES:
|
|
401
|
+
ppod mem:read state.json
|
|
402
|
+
ppod mem:read progress.json --json
|
|
403
|
+
`,
|
|
404
|
+
"mem:ls": `
|
|
405
|
+
ppod mem:ls [prefix] [options]
|
|
406
|
+
|
|
407
|
+
List files in persistent memory.
|
|
408
|
+
|
|
409
|
+
OPTIONS:
|
|
410
|
+
--json Output as JSON
|
|
411
|
+
|
|
412
|
+
EXAMPLES:
|
|
413
|
+
ppod mem:ls
|
|
414
|
+
ppod mem:ls research/
|
|
415
|
+
`,
|
|
416
|
+
"mem:rm": `
|
|
417
|
+
ppod mem:rm <path>
|
|
418
|
+
|
|
419
|
+
Delete a file from persistent memory.
|
|
420
|
+
|
|
421
|
+
EXAMPLES:
|
|
422
|
+
ppod mem:rm old-state.json
|
|
423
|
+
`,
|
|
424
|
+
interpret: `
|
|
425
|
+
ppod interpret <code> [options]
|
|
426
|
+
|
|
427
|
+
Execute code with rich output (images, charts, dataframes).
|
|
428
|
+
|
|
429
|
+
OPTIONS:
|
|
430
|
+
--language <lang> python, javascript, r (default: python)
|
|
431
|
+
--json Output as JSON
|
|
432
|
+
|
|
433
|
+
EXAMPLES:
|
|
434
|
+
ppod interpret "import matplotlib.pyplot as plt; plt.plot([1,2,3]); plt.show()"
|
|
435
|
+
ppod interpret "console.log('hello')" --language javascript
|
|
436
|
+
`,
|
|
437
|
+
};
|
|
438
|
+
function showCommandHelp(command) {
|
|
439
|
+
// Normalize command (handle aliases)
|
|
440
|
+
const normalized = command
|
|
441
|
+
.replace(/^screenshot$/, "browser:screenshot")
|
|
442
|
+
.replace(/^pdf$/, "browser:pdf")
|
|
443
|
+
.replace(/^scrape$/, "browser:scrape")
|
|
444
|
+
.replace(/^markdown$/, "browser:markdown")
|
|
445
|
+
.replace(/^content$/, "browser:content")
|
|
446
|
+
.replace(/^trace$/, "browser:trace")
|
|
447
|
+
.replace(/^test$/, "browser:test");
|
|
448
|
+
if (COMMAND_HELP[normalized]) {
|
|
449
|
+
console.log(COMMAND_HELP[normalized]);
|
|
450
|
+
}
|
|
451
|
+
else if (COMMAND_HELP[command]) {
|
|
452
|
+
console.log(COMMAND_HELP[command]);
|
|
453
|
+
}
|
|
454
|
+
else {
|
|
455
|
+
// Fall back to general help
|
|
456
|
+
helpCommand();
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
// ============================================================================
|
|
460
|
+
// Main
|
|
461
|
+
// ============================================================================
|
|
462
|
+
async function main() {
|
|
463
|
+
const { command, args, options } = parseArgs(process.argv);
|
|
464
|
+
// Handle per-command help
|
|
465
|
+
if (options.help) {
|
|
466
|
+
showCommandHelp(command);
|
|
467
|
+
process.exit(0);
|
|
468
|
+
}
|
|
469
|
+
let exitCode = 0;
|
|
470
|
+
try {
|
|
471
|
+
switch (command) {
|
|
472
|
+
case "exec":
|
|
473
|
+
if (args.length === 0) {
|
|
474
|
+
console.error("Usage: ppod exec <command>");
|
|
475
|
+
process.exit(1);
|
|
476
|
+
}
|
|
477
|
+
exitCode = await execCommand(args.join(" "), {
|
|
478
|
+
timeout: options.timeout,
|
|
479
|
+
json: options.json,
|
|
480
|
+
stream: options.stream,
|
|
481
|
+
});
|
|
482
|
+
break;
|
|
483
|
+
case "write":
|
|
484
|
+
if (args.length === 0) {
|
|
485
|
+
console.error("Usage: ppod write <remote-path> [local-file]");
|
|
486
|
+
process.exit(1);
|
|
487
|
+
}
|
|
488
|
+
exitCode = await writeCommand(args[0], args[1] || null, {
|
|
489
|
+
timeout: options.timeout,
|
|
490
|
+
});
|
|
491
|
+
break;
|
|
492
|
+
case "read":
|
|
493
|
+
if (args.length === 0) {
|
|
494
|
+
console.error("Usage: ppod read <remote-path>");
|
|
495
|
+
process.exit(1);
|
|
496
|
+
}
|
|
497
|
+
exitCode = await readCommand(args[0], {
|
|
498
|
+
timeout: options.timeout,
|
|
499
|
+
output: options.output,
|
|
500
|
+
});
|
|
501
|
+
break;
|
|
502
|
+
case "ls":
|
|
503
|
+
case "list":
|
|
504
|
+
exitCode = await listCommand(args[0] || ".", {
|
|
505
|
+
timeout: options.timeout,
|
|
506
|
+
json: options.json,
|
|
507
|
+
});
|
|
508
|
+
break;
|
|
509
|
+
case "login":
|
|
510
|
+
exitCode = await loginCommand(args[0]);
|
|
511
|
+
break;
|
|
512
|
+
case "logout":
|
|
513
|
+
exitCode = await logoutCommand();
|
|
514
|
+
break;
|
|
515
|
+
case "status":
|
|
516
|
+
exitCode = await statusCommand();
|
|
517
|
+
break;
|
|
518
|
+
// ====== Port Exposure ======
|
|
519
|
+
case "expose":
|
|
520
|
+
if (args.length === 0) {
|
|
521
|
+
console.error("Usage: ppod expose <port>");
|
|
522
|
+
process.exit(1);
|
|
523
|
+
}
|
|
524
|
+
exitCode = await exposeCommand(parseInt(args[0], 10), {
|
|
525
|
+
timeout: options.timeout,
|
|
526
|
+
json: options.json,
|
|
527
|
+
});
|
|
528
|
+
break;
|
|
529
|
+
// ====== Browser Commands ======
|
|
530
|
+
// Support both "screenshot" and "browser:screenshot" for consistency
|
|
531
|
+
case "screenshot":
|
|
532
|
+
case "browser:screenshot":
|
|
533
|
+
if (args.length === 0) {
|
|
534
|
+
console.error("Usage: ppod browser:screenshot <url> [-o file.png]");
|
|
535
|
+
console.error(" ppod screenshot <url> [-o file.png]");
|
|
536
|
+
process.exit(1);
|
|
537
|
+
}
|
|
538
|
+
exitCode = await screenshotCommand(args[0], {
|
|
539
|
+
timeout: options.timeout,
|
|
540
|
+
output: options.output,
|
|
541
|
+
fullPage: options.fullPage,
|
|
542
|
+
width: options.width,
|
|
543
|
+
height: options.height,
|
|
544
|
+
format: options.format,
|
|
545
|
+
json: options.json,
|
|
546
|
+
trace: options.trace,
|
|
547
|
+
});
|
|
548
|
+
break;
|
|
549
|
+
case "pdf":
|
|
550
|
+
case "browser:pdf":
|
|
551
|
+
if (args.length === 0) {
|
|
552
|
+
console.error("Usage: ppod browser:pdf <url> [-o file.pdf]");
|
|
553
|
+
console.error(" ppod pdf <url> [-o file.pdf]");
|
|
554
|
+
process.exit(1);
|
|
555
|
+
}
|
|
556
|
+
exitCode = await pdfCommand(args[0], {
|
|
557
|
+
timeout: options.timeout,
|
|
558
|
+
output: options.output,
|
|
559
|
+
landscape: options.landscape,
|
|
560
|
+
paperFormat: options.format,
|
|
561
|
+
json: options.json,
|
|
562
|
+
trace: options.trace,
|
|
563
|
+
});
|
|
564
|
+
break;
|
|
565
|
+
case "scrape":
|
|
566
|
+
case "browser:scrape":
|
|
567
|
+
if (args.length === 0) {
|
|
568
|
+
console.error("Usage: ppod browser:scrape <url> [selector]");
|
|
569
|
+
console.error(" ppod scrape <url> [selector]");
|
|
570
|
+
console.error("\nSelector defaults to 'body' if not specified.");
|
|
571
|
+
process.exit(1);
|
|
572
|
+
}
|
|
573
|
+
// Default selector to "body" if not provided
|
|
574
|
+
exitCode = await scrapeCommand(args[0], args[1] || "body", {
|
|
575
|
+
timeout: options.timeout,
|
|
576
|
+
limit: options.limit,
|
|
577
|
+
json: options.json,
|
|
578
|
+
trace: options.trace,
|
|
579
|
+
});
|
|
580
|
+
break;
|
|
581
|
+
case "markdown":
|
|
582
|
+
case "browser:markdown":
|
|
583
|
+
if (args.length === 0) {
|
|
584
|
+
console.error("Usage: ppod browser:markdown <url> [-o file.md]");
|
|
585
|
+
console.error(" ppod markdown <url> [-o file.md]");
|
|
586
|
+
process.exit(1);
|
|
587
|
+
}
|
|
588
|
+
exitCode = await markdownCommand(args[0], {
|
|
589
|
+
timeout: options.timeout,
|
|
590
|
+
output: options.output,
|
|
591
|
+
json: options.json,
|
|
592
|
+
trace: options.trace,
|
|
593
|
+
});
|
|
594
|
+
break;
|
|
595
|
+
case "content":
|
|
596
|
+
case "browser:content":
|
|
597
|
+
if (args.length === 0) {
|
|
598
|
+
console.error("Usage: ppod browser:content <url> [-o file.html]");
|
|
599
|
+
console.error(" ppod content <url> [-o file.html]");
|
|
600
|
+
process.exit(1);
|
|
601
|
+
}
|
|
602
|
+
exitCode = await contentCommand(args[0], {
|
|
603
|
+
timeout: options.timeout,
|
|
604
|
+
output: options.output,
|
|
605
|
+
json: options.json,
|
|
606
|
+
trace: options.trace,
|
|
607
|
+
});
|
|
608
|
+
break;
|
|
609
|
+
case "trace":
|
|
610
|
+
case "browser:trace":
|
|
611
|
+
if (args.length === 0 || !["start", "stop"].includes(args[0])) {
|
|
612
|
+
console.error("Usage: ppod browser:trace start|stop [-o trace.zip]");
|
|
613
|
+
console.error(" ppod trace start|stop [-o trace.zip]");
|
|
614
|
+
console.error("\nNote: Tracing captures operations within the same WebSocket connection.");
|
|
615
|
+
console.error(" For cross-request tracing, browser operations should share a session.");
|
|
616
|
+
process.exit(1);
|
|
617
|
+
}
|
|
618
|
+
exitCode = await traceCommand(args[0], {
|
|
619
|
+
timeout: options.timeout,
|
|
620
|
+
output: options.output,
|
|
621
|
+
json: options.json,
|
|
622
|
+
});
|
|
623
|
+
break;
|
|
624
|
+
case "test":
|
|
625
|
+
case "browser:test":
|
|
626
|
+
if (args.length < 2) {
|
|
627
|
+
console.error("Usage: ppod browser:test <url> '<assertions-json>'");
|
|
628
|
+
console.error(" ppod test <url> '<assertions-json>'");
|
|
629
|
+
console.error("\nAssertion format: JSON array of assertion objects");
|
|
630
|
+
console.error(" Types: visible, hidden, text, count, title, url\n");
|
|
631
|
+
console.error("Examples:");
|
|
632
|
+
console.error(' ppod browser:test https://example.com \'[{"type":"visible","selector":"h1"}]\'');
|
|
633
|
+
console.error(' ppod browser:test https://example.com \'[{"type":"text","selector":"h1","expected":"Hello"}]\'');
|
|
634
|
+
console.error(' ppod browser:test https://example.com \'[{"type":"title","expected":"Example"}]\'');
|
|
635
|
+
process.exit(1);
|
|
636
|
+
}
|
|
637
|
+
exitCode = await testCommand(args[0], args[1], {
|
|
638
|
+
timeout: options.timeout,
|
|
639
|
+
json: options.json,
|
|
640
|
+
});
|
|
641
|
+
break;
|
|
642
|
+
case "browser:sessions":
|
|
643
|
+
exitCode = await browserSessionsCommand({
|
|
644
|
+
timeout: options.timeout,
|
|
645
|
+
json: options.json,
|
|
646
|
+
});
|
|
647
|
+
break;
|
|
648
|
+
case "browser:limits":
|
|
649
|
+
exitCode = await browserLimitsCommand({
|
|
650
|
+
timeout: options.timeout,
|
|
651
|
+
json: options.json,
|
|
652
|
+
});
|
|
653
|
+
break;
|
|
654
|
+
// ====== AI Commands ======
|
|
655
|
+
case "ai":
|
|
656
|
+
if (args.length === 0) {
|
|
657
|
+
console.error("Usage: ppod ai <prompt>");
|
|
658
|
+
process.exit(1);
|
|
659
|
+
}
|
|
660
|
+
exitCode = await aiGenerateCommand(args.join(" "), {
|
|
661
|
+
timeout: options.timeout,
|
|
662
|
+
model: options.model,
|
|
663
|
+
systemPrompt: options.systemPrompt,
|
|
664
|
+
maxTokens: options.maxTokens,
|
|
665
|
+
temperature: options.temperature,
|
|
666
|
+
json: options.json,
|
|
667
|
+
});
|
|
668
|
+
break;
|
|
669
|
+
case "ai:embed":
|
|
670
|
+
if (args.length === 0) {
|
|
671
|
+
console.error("Usage: ppod ai:embed <text>");
|
|
672
|
+
process.exit(1);
|
|
673
|
+
}
|
|
674
|
+
exitCode = await aiEmbedCommand(args.join(" "), {
|
|
675
|
+
timeout: options.timeout,
|
|
676
|
+
model: options.model,
|
|
677
|
+
json: options.json,
|
|
678
|
+
});
|
|
679
|
+
break;
|
|
680
|
+
case "ai:image":
|
|
681
|
+
if (args.length === 0) {
|
|
682
|
+
console.error("Usage: ppod ai:image <prompt> [-o file.png]");
|
|
683
|
+
process.exit(1);
|
|
684
|
+
}
|
|
685
|
+
exitCode = await aiImageCommand(args.join(" "), {
|
|
686
|
+
timeout: options.timeout,
|
|
687
|
+
model: options.model,
|
|
688
|
+
output: options.output,
|
|
689
|
+
width: options.width,
|
|
690
|
+
height: options.height,
|
|
691
|
+
json: options.json,
|
|
692
|
+
});
|
|
693
|
+
break;
|
|
694
|
+
case "ai:transcribe":
|
|
695
|
+
if (args.length === 0) {
|
|
696
|
+
console.error("Usage: ppod ai:transcribe <audio-file>");
|
|
697
|
+
process.exit(1);
|
|
698
|
+
}
|
|
699
|
+
exitCode = await aiTranscribeCommand(args[0], {
|
|
700
|
+
timeout: options.timeout,
|
|
701
|
+
model: options.model,
|
|
702
|
+
json: options.json,
|
|
703
|
+
});
|
|
704
|
+
break;
|
|
705
|
+
// ====== Code Interpreter ======
|
|
706
|
+
case "interpret":
|
|
707
|
+
if (args.length === 0) {
|
|
708
|
+
console.error("Usage: ppod interpret '<code>' [--language python|javascript]");
|
|
709
|
+
process.exit(1);
|
|
710
|
+
}
|
|
711
|
+
exitCode = await interpretCommand(args.join(" "), {
|
|
712
|
+
timeout: options.timeout,
|
|
713
|
+
language: options.language,
|
|
714
|
+
json: options.json,
|
|
715
|
+
});
|
|
716
|
+
break;
|
|
717
|
+
// ====== Memory Commands ======
|
|
718
|
+
case "mem:write":
|
|
719
|
+
if (args.length === 0) {
|
|
720
|
+
console.error("Usage: ppod mem:write <path> [local-file]");
|
|
721
|
+
process.exit(1);
|
|
722
|
+
}
|
|
723
|
+
exitCode = await memoryWriteCommand(args[0], args[1] || null, {
|
|
724
|
+
timeout: options.timeout,
|
|
725
|
+
});
|
|
726
|
+
break;
|
|
727
|
+
case "mem:read":
|
|
728
|
+
if (args.length === 0) {
|
|
729
|
+
console.error("Usage: ppod mem:read <path>");
|
|
730
|
+
process.exit(1);
|
|
731
|
+
}
|
|
732
|
+
exitCode = await memoryReadCommand(args[0], {
|
|
733
|
+
timeout: options.timeout,
|
|
734
|
+
output: options.output,
|
|
735
|
+
});
|
|
736
|
+
break;
|
|
737
|
+
case "mem:ls":
|
|
738
|
+
exitCode = await memoryListCommand(args[0], {
|
|
739
|
+
timeout: options.timeout,
|
|
740
|
+
json: options.json,
|
|
741
|
+
});
|
|
742
|
+
break;
|
|
743
|
+
case "mem:rm":
|
|
744
|
+
if (args.length === 0) {
|
|
745
|
+
console.error("Usage: ppod mem:rm <path>");
|
|
746
|
+
process.exit(1);
|
|
747
|
+
}
|
|
748
|
+
exitCode = await memoryDeleteCommand(args[0], {
|
|
749
|
+
timeout: options.timeout,
|
|
750
|
+
});
|
|
751
|
+
break;
|
|
752
|
+
case "mem:usage":
|
|
753
|
+
exitCode = await memoryUsageCommand({
|
|
754
|
+
timeout: options.timeout,
|
|
755
|
+
json: options.json,
|
|
756
|
+
});
|
|
757
|
+
break;
|
|
758
|
+
// ====== Process Commands ======
|
|
759
|
+
case "ps":
|
|
760
|
+
exitCode = await processListCommand({
|
|
761
|
+
timeout: options.timeout,
|
|
762
|
+
json: options.json,
|
|
763
|
+
});
|
|
764
|
+
break;
|
|
765
|
+
case "start":
|
|
766
|
+
if (args.length === 0) {
|
|
767
|
+
console.error("Usage: ppod start <command>");
|
|
768
|
+
process.exit(1);
|
|
769
|
+
}
|
|
770
|
+
exitCode = await processStartCommand(args.join(" "), {
|
|
771
|
+
timeout: options.timeout,
|
|
772
|
+
processId: options.processId,
|
|
773
|
+
json: options.json,
|
|
774
|
+
});
|
|
775
|
+
break;
|
|
776
|
+
case "kill":
|
|
777
|
+
if (args.length === 0) {
|
|
778
|
+
console.error("Usage: ppod kill <process-id>");
|
|
779
|
+
process.exit(1);
|
|
780
|
+
}
|
|
781
|
+
exitCode = await processKillCommand(args[0], {
|
|
782
|
+
timeout: options.timeout,
|
|
783
|
+
});
|
|
784
|
+
break;
|
|
785
|
+
// ====== Account Commands ======
|
|
786
|
+
case "balance":
|
|
787
|
+
exitCode = await balanceCommand({
|
|
788
|
+
timeout: options.timeout,
|
|
789
|
+
json: options.json,
|
|
790
|
+
});
|
|
791
|
+
break;
|
|
792
|
+
case "version":
|
|
793
|
+
case "-v":
|
|
794
|
+
case "--version":
|
|
795
|
+
versionCommand();
|
|
796
|
+
break;
|
|
797
|
+
case "help":
|
|
798
|
+
case "-h":
|
|
799
|
+
case "--help":
|
|
800
|
+
default:
|
|
801
|
+
helpCommand();
|
|
802
|
+
break;
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
catch (err) {
|
|
806
|
+
console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
807
|
+
exitCode = 1;
|
|
808
|
+
}
|
|
809
|
+
process.exit(exitCode);
|
|
810
|
+
}
|
|
811
|
+
main();
|
|
812
|
+
//# sourceMappingURL=cli.js.map
|