@porchestra/cli 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +625 -0
  2. package/bin/porchestra.js +2 -0
  3. package/package.json +51 -0
  4. package/src/agents/testPrompt/ast.json +71 -0
  5. package/src/agents/testPrompt/config.ts +18 -0
  6. package/src/agents/testPrompt/index.ts +64 -0
  7. package/src/agents/testPrompt/schemas.ts +45 -0
  8. package/src/agents/testPrompt/tools.ts +88 -0
  9. package/src/commands/agents.ts +173 -0
  10. package/src/commands/config.ts +97 -0
  11. package/src/commands/explore.ts +160 -0
  12. package/src/commands/login.ts +101 -0
  13. package/src/commands/logout.ts +52 -0
  14. package/src/commands/pull.ts +220 -0
  15. package/src/commands/status.ts +78 -0
  16. package/src/commands/whoami.ts +56 -0
  17. package/src/core/api/client.ts +133 -0
  18. package/src/core/auth/auth-service.ts +176 -0
  19. package/src/core/auth/token-manager.ts +47 -0
  20. package/src/core/config/config-manager.ts +107 -0
  21. package/src/core/config/config-schema.ts +56 -0
  22. package/src/core/config/project-tracker.ts +158 -0
  23. package/src/core/generators/code-generator.ts +329 -0
  24. package/src/core/generators/schema-generator.ts +59 -0
  25. package/src/index.ts +85 -0
  26. package/src/types/index.ts +214 -0
  27. package/src/utils/date.ts +23 -0
  28. package/src/utils/errors.ts +38 -0
  29. package/src/utils/logger.ts +11 -0
  30. package/src/utils/path-utils.ts +47 -0
  31. package/tests/unit/config-manager.test.ts +74 -0
  32. package/tests/unit/config-schema.test.ts +61 -0
  33. package/tests/unit/path-utils.test.ts +53 -0
  34. package/tests/unit/schema-generator.test.ts +82 -0
  35. package/tsconfig.json +30 -0
  36. package/tsup.config.ts +19 -0
  37. package/vitest.config.ts +20 -0
package/README.md ADDED
@@ -0,0 +1,625 @@
1
+ # Porchestra CLI
2
+
3
+ A powerful CLI tool for generating type-safe LLM tool handlers from Porchestra agents.
4
+
5
+ ## Overview
6
+
7
+ Porchestra CLI enables developers to:
8
+ - Authenticate and manage CLI sessions with 90-day tokens
9
+ - Browse and select agents from Porchestra projects
10
+ - Generate TypeScript code with Zod schemas for tool validation
11
+ - Maintain multi-agent projects with automatic code generation
12
+ - Support on-premise deployments with custom API URLs
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ # Install globally
18
+ npm install -g @porchestra/cli
19
+
20
+ # Or use with npx (no installation)
21
+ npx @porchestra/cli <command>
22
+ ```
23
+
24
+ **Requirements:**
25
+ - Node.js 22+
26
+ - TypeScript 5.x project (for generated code)
27
+
28
+ ## Quick Start
29
+
30
+ ```bash
31
+ # 1. Login with your Porchestra account
32
+ porchestra login
33
+
34
+ # 2. Explore and select agents to track
35
+ porchestra explore
36
+
37
+ # 3. Generate tool code
38
+ porchestra pull
39
+ ```
40
+
41
+ ## Commands
42
+
43
+ ### `login`
44
+
45
+ Authenticate with your Porchestra account and generate a CLI token (90-day expiry).
46
+
47
+ ```bash
48
+ porchestra login [options]
49
+ ```
50
+
51
+ **Options:**
52
+ - `--api-url <url>` - Custom API URL for on-premise deployments
53
+ - `--device-name <name>` - Name for this device (defaults to hostname + OS)
54
+ - `--skip-tls-verify` - Skip TLS certificate verification (development only)
55
+
56
+ **Interactive Prompts:**
57
+ - Email address
58
+ - Password (hidden input)
59
+ - On-premise deployment (yes/no)
60
+ - API URL (if on-premise)
61
+
62
+ **Example:**
63
+ ```bash
64
+ # Standard login
65
+ porchestra login
66
+
67
+ # On-premise deployment
68
+ porchestra login --api-url https://porchestra.company.com/api/v1
69
+
70
+ # With custom device name
71
+ porchestra login --device-name "CI/CD Pipeline"
72
+ ```
73
+
74
+ **Output:**
75
+ ```
76
+ 🔐 Porchestra CLI Login
77
+
78
+ ✔ Email: user@example.com
79
+ ✔ Password: ••••••••
80
+ ✔ Are you using an on-premise deployment? No
81
+
82
+ ✓ Authentication successful
83
+ ✓ Logged in as user@example.com
84
+ Token expires in 90 days (2025-04-30T12:00:00Z)
85
+ Device: MacBook-Pro - darwin
86
+ Auto-refresh: 7 days before expiry
87
+ ```
88
+
89
+ ---
90
+
91
+ ### `logout`
92
+
93
+ Logout and revoke the CLI token.
94
+
95
+ ```bash
96
+ porchestra logout [options]
97
+ ```
98
+
99
+ **Options:**
100
+ - `--all` - Revoke all CLI tokens across all devices
101
+
102
+ **Example:**
103
+ ```bash
104
+ # Logout current device
105
+ porchestra logout
106
+
107
+ # Logout all devices
108
+ porchestra logout --all
109
+ ```
110
+
111
+ **Output:**
112
+ ```
113
+ ✓ Logged out successfully
114
+ ```
115
+
116
+ ---
117
+
118
+ ### `whoami`
119
+
120
+ Display current user information and token status.
121
+
122
+ ```bash
123
+ porchestra whoami
124
+ ```
125
+
126
+ **Example Output:**
127
+ ```
128
+ 👤 User Information
129
+
130
+ Email: user@example.com
131
+ Name: John Doe
132
+ Org: Acme Corp
133
+
134
+ 🔑 Token Information
135
+
136
+ Device: MacBook-Pro - darwin
137
+ Expires: 83 days (2025-04-30T12:00:00Z)
138
+
139
+ 📁 Tracked Projects
140
+
141
+ Projects: 2
142
+ Agents: 5
143
+ ```
144
+
145
+ ---
146
+
147
+ ### `explore`
148
+
149
+ Interactive project and agent browser. Select which agents to track for code generation.
150
+
151
+ ```bash
152
+ porchestra explore [options]
153
+ ```
154
+
155
+ **Options:**
156
+ - `-p, --project <id>` - Start with specific project (skip project selection)
157
+
158
+ **Interactive Features:**
159
+ - Project list with agent counts
160
+ - Agent browser with folder paths
161
+ - Checkbox selection for agents
162
+ - Version resolution display (PRODUCTION/STAGING/DEVELOPMENT)
163
+
164
+ **Example:**
165
+ ```bash
166
+ # Full explore mode
167
+ porchestra explore
168
+
169
+ # Start with specific project
170
+ porchestra explore --project customer-support
171
+ ```
172
+
173
+ **Output Example:**
174
+ ```
175
+ 📦 Customer Support Bot
176
+
177
+ ● Ticket Classifier
178
+ Path: main/ticket-classifier
179
+ Version: v2.3.1 (PRODUCTION)
180
+ Tools: 5
181
+
182
+ ● Response Generator
183
+ Path: main/response-generator
184
+ Version: v1.5.0 (PRODUCTION)
185
+ Tools: 3
186
+
187
+ ✓ Tracking 2 agents from Customer Support Bot
188
+
189
+ 📊 Tracking Summary
190
+
191
+ Projects: 2
192
+ Agents: 5
193
+
194
+ Run `porchestra pull` to generate code for tracked agents
195
+ ```
196
+
197
+ ---
198
+
199
+ ### `pull`
200
+
201
+ Generate TypeScript tool code for all tracked agents.
202
+
203
+ ```bash
204
+ porchestra pull [options]
205
+ ```
206
+
207
+ **Options:**
208
+ - `-p, --project <id>` - Pull specific project only
209
+ - `-a, --agent <id>` - Pull specific agent only
210
+ - `-e, --env <environment>` - Target environment: `production`, `staging`, or `development`
211
+ - `-o, --output <path>` - Override output directory
212
+ - `--force` - Overwrite implementation files (⚠️ may lose code)
213
+
214
+ **Environment Priority:**
215
+ If no environment specified, uses priority: PRODUCTION → STAGING → DEVELOPMENT
216
+
217
+ **Generated Files:**
218
+ For each agent, creates:
219
+ - `tool-schemas.ts` - Zod schemas (always overwritten)
220
+ - `tool-dispatcher.ts` - Switch/case dispatcher (always overwritten)
221
+ - `tool-impl.ts` - Implementation stubs (created once, never overwritten)
222
+
223
+ **Example:**
224
+ ```bash
225
+ # Pull all tracked agents
226
+ porchestra pull
227
+
228
+ # Pull specific project
229
+ porchestra pull --project customer-support
230
+
231
+ # Pull specific agent
232
+ porchestra pull --agent ticket-classifier
233
+
234
+ # Use staging environment
235
+ porchestra pull --env staging
236
+
237
+ # Custom output directory
238
+ porchestra pull --output ./src/my-agents
239
+
240
+ # Force overwrite implementation files
241
+ porchestra pull --force
242
+ ```
243
+
244
+ **Output Example:**
245
+ ```
246
+ 📦 Customer Support Bot
247
+
248
+ [1/2] ✓ Ticket Classifier → ./src/agents/main/ticket-classifier
249
+ [2/2] ✓ Response Generator → ./src/agents/main/response-generator
250
+
251
+ 📦 Sales Assistant
252
+
253
+ [1/1] ✓ Lead Scorer → ./src/agents/sales/lead-scorer
254
+
255
+ ✨ Pull Complete
256
+
257
+ Generated: 3 / 3 agents
258
+ Output: ./src/agents
259
+
260
+ Next steps:
261
+ 1. Implement tool functions in tool-impl.ts files
262
+ 2. Import and use the tool dispatcher in your code
263
+ ```
264
+
265
+ **Auto-Trigger Explore:**
266
+ If no projects are tracked, `pull` automatically launches `explore` first.
267
+
268
+ ---
269
+
270
+ ### `config`
271
+
272
+ Manage CLI configuration.
273
+
274
+ ```bash
275
+ porchestra config <subcommand>
276
+ ```
277
+
278
+ **Subcommands:**
279
+
280
+ #### `config get <key>`
281
+ Get a configuration value.
282
+
283
+ ```bash
284
+ porchestra config get api.baseUrl
285
+ porchestra config get output.baseDir
286
+ ```
287
+
288
+ #### `config set <key> <value>`
289
+ Set a configuration value.
290
+
291
+ ```bash
292
+ porchestra config set api.baseUrl https://api.porchestra.io/v1
293
+ porchestra config set output.baseDir ./src/agents
294
+ porchestra config set output.createIndexFiles true
295
+ ```
296
+
297
+ #### `config list`
298
+ List all configuration values.
299
+
300
+ ```bash
301
+ porchestra config list
302
+ ```
303
+
304
+ #### `config reset`
305
+ Reset all configuration (⚠️ clears auth and tracking).
306
+
307
+ ```bash
308
+ porchestra config reset
309
+ porchestra config reset --force # Skip confirmation
310
+ ```
311
+
312
+ ---
313
+
314
+ ### `status`
315
+
316
+ Show CLI status and tracked projects summary.
317
+
318
+ ```bash
319
+ porchestra status
320
+ ```
321
+
322
+ **Output Example:**
323
+ ```
324
+ 📊 Porchestra CLI Status
325
+
326
+ 🔑 Authentication
327
+ Status: ✓ Logged in
328
+ Device: MacBook-Pro - darwin
329
+ Expires: 83 days (2025-04-30T12:00:00Z)
330
+
331
+ 🔗 API Configuration
332
+ URL: https://api.porchestra.io/v1
333
+
334
+ 📁 Tracked Projects
335
+ Projects: 2
336
+ Agents: 5
337
+
338
+ Customer Support Bot
339
+ └─ Ticket Classifier main/ticket-classifier (2 days ago)
340
+ └─ Response Generator main/response-generator (2 days ago)
341
+ Last pulled: 2 days ago
342
+
343
+ Sales Assistant
344
+ └─ Lead Scorer sales/lead-scorer (never)
345
+
346
+ 📂 Output Configuration
347
+ Base dir: ./src/agents
348
+ Index files: yes
349
+ ```
350
+
351
+ ---
352
+
353
+ ### `agents`
354
+
355
+ List or remove tracked agents without running the explorer.
356
+
357
+ ```bash
358
+ # List all tracked agents (default)
359
+ porchestra agents
360
+ porchestra agents list
361
+
362
+ # Filter by project id/slug
363
+ porchestra agents list --project customer-support
364
+
365
+ # Remove a tracked agent by id/slug (will prompt when ambiguous)
366
+ porchestra agents remove ticket-classifier
367
+ porchestra agents remove ticket-classifier --project customer-support
368
+
369
+ # Skip confirmation
370
+ porchestra agents remove ticket-classifier --project customer-support --force
371
+ ```
372
+
373
+ **Behavior:**
374
+ - `agents` defaults to `agents list` for convenience.
375
+ - `remove` drops the agent from tracking and deletes the project entry if it was the last tracked agent.
376
+ - Use `--json` on `agents list` for scripting.
377
+
378
+ ---
379
+
380
+ ## Configuration
381
+
382
+ Configuration is stored in `~/.porchestra/config.json`.
383
+
384
+ ### Configuration Options
385
+
386
+ | Key | Type | Default | Description |
387
+ |-----|------|---------|-------------|
388
+ | `api.baseUrl` | string | `https://api.porchestra.io/v1` | API endpoint URL |
389
+ | `api.skipTlsVerify` | boolean | `false` | Skip TLS verification (dev only) |
390
+ | `output.baseDir` | string | `./src/agents` | Base directory for generated files |
391
+ | `output.createIndexFiles` | boolean | `true` | Create index.ts files for exports |
392
+
393
+ ### Environment Variables
394
+
395
+ | Variable | Description | Example |
396
+ |----------|-------------|---------|
397
+ | `PORCHESTRA_API_URL` | Override API URL | `https://porchestra.internal.company.com` |
398
+ | `PORCHESTRA_CONFIG_DIR` | Custom config directory | `/etc/porchestra` |
399
+ | `PORCHESTRA_SKIP_TLS_VERIFY` | Skip TLS verification | `true` |
400
+
401
+ ---
402
+
403
+ ## Multi-Agent Support
404
+
405
+ Porchestra CLI supports multiple agents organized by folder paths from your Porchestra project.
406
+
407
+ ### Folder Path Resolution
408
+
409
+ Agents are organized based on their `folderPath` from the database:
410
+
411
+ | folderPath (DB) | Generated Directory |
412
+ |-----------------|---------------------|
413
+ | `/main/x-agent/` | `{baseDir}/main/x-agent/` |
414
+ | `y-agent` | `{baseDir}/y-agent/` |
415
+ | `/api/v2/customer-support` | `{baseDir}/api/v2/customer-support/` |
416
+ | `//legacy//agents//` | `{baseDir}/legacy/agents/` |
417
+
418
+ ### Example Project Structure
419
+
420
+ ```
421
+ ./src/agents/
422
+ ├── main/
423
+ │ ├── ticket-classifier/
424
+ │ │ ├── tool-schemas.ts # Zod schemas
425
+ │ │ ├── tool-dispatcher.ts # Switch/case dispatcher
426
+ │ │ └── tool-impl.ts # Your implementation
427
+ │ └── response-generator/
428
+ │ ├── tool-schemas.ts
429
+ │ ├── tool-dispatcher.ts
430
+ │ └── tool-impl.ts
431
+ └── sales/
432
+ └── lead-scorer/
433
+ ├── tool-schemas.ts
434
+ ├── tool-dispatcher.ts
435
+ └── tool-impl.ts
436
+ ```
437
+
438
+ ---
439
+
440
+ ## Environment-Based Version Resolution
441
+
442
+ The CLI automatically resolves which agent version to use based on environment:
443
+
444
+ ### Priority Order
445
+
446
+ 1. **PRODUCTION** - Used if available
447
+ 2. **STAGING** - Fallback if no production version
448
+ 3. **DEVELOPMENT** - Fallback if no staging version
449
+
450
+ ### Command Examples
451
+
452
+ ```bash
453
+ # Use production (default priority)
454
+ porchestra pull
455
+
456
+ # Force staging environment
457
+ porchestra pull --env staging
458
+
459
+ # Force development environment
460
+ porchestra pull --env development
461
+ ```
462
+
463
+ **Note:** You cannot pin to specific versions. The CLI always fetches the latest version from the requested environment (or falls back through the priority chain).
464
+
465
+ ---
466
+
467
+ ## Generated Code
468
+
469
+ ### tool-schemas.ts
470
+
471
+ Auto-generated Zod schemas for runtime validation:
472
+
473
+ ```typescript
474
+ import { z } from 'zod';
475
+
476
+ export const GetUserParamsSchema = z.object({
477
+ id: z.string().uuid()
478
+ });
479
+
480
+ export type GetUserParams = z.infer<typeof GetUserParamsSchema>;
481
+
482
+ export type ToolName = 'getUser' | 'sendEmail';
483
+ ```
484
+
485
+ ### tool-dispatcher.ts
486
+
487
+ Auto-generated switch/case dispatcher:
488
+
489
+ ```typescript
490
+ import { GetUserParams, getUser } from './tool-impl.js';
491
+
492
+ export async function dispatchTool(
493
+ toolName: string,
494
+ params: unknown
495
+ ): Promise<ToolResult> {
496
+ switch (toolName) {
497
+ case 'getUser': {
498
+ const result = await getUser(params as GetUserParams);
499
+ return { success: true, data: result };
500
+ }
501
+ default:
502
+ return { success: false, error: `Unknown tool: ${toolName}` };
503
+ }
504
+ }
505
+ ```
506
+
507
+ ### tool-impl.ts
508
+
509
+ User implementation file (created once, never overwritten):
510
+
511
+ ```typescript
512
+ import { GetUserParams } from './tool-schemas.js';
513
+
514
+ export async function getUser(params: GetUserParams): Promise<any> {
515
+ // TODO: Implement getUser
516
+ console.log('Called getUser with:', params);
517
+ throw new Error('getUser not implemented');
518
+ }
519
+ ```
520
+
521
+ **Important:** Never modify `tool-schemas.ts` or `tool-dispatcher.ts` manually - they are auto-generated. Only edit `tool-impl.ts` files.
522
+
523
+ ---
524
+
525
+ ## Usage in Your Application
526
+
527
+ ```typescript
528
+ import { dispatchTool } from './src/agents/main/ticket-classifier/tool-dispatcher.js';
529
+ import { myToolLogic } from './src/agents/main/ticket-classifier/tool-impl.js';
530
+
531
+ // In your LLM loop
532
+ const toolCall = llmResponse.tool_calls[0];
533
+
534
+ try {
535
+ const result = await dispatchTool(
536
+ toolCall.name,
537
+ JSON.parse(toolCall.arguments)
538
+ );
539
+
540
+ if (result.success) {
541
+ // Send result back to LLM
542
+ } else {
543
+ console.error('Tool failed:', result.error);
544
+ }
545
+ } catch (error) {
546
+ console.error('Tool execution failed:', error);
547
+ }
548
+ ```
549
+
550
+ ---
551
+
552
+ ## Troubleshooting
553
+
554
+ ### Authentication Issues
555
+
556
+ **Problem:** "Invalid email or password"
557
+ - Ensure you're using the same credentials as the web app
558
+ - Check API URL if using on-premise deployment
559
+
560
+ **Problem:** "Token expired"
561
+ - Run `porchestra login` to generate a new token
562
+ - Tokens auto-refresh 7 days before expiry
563
+
564
+ ### Connection Issues
565
+
566
+ **Problem:** "ECONNREFUSED" or "ENOTFOUND"
567
+ - Check if API server is running
568
+ - Verify API URL in config: `porchestra config get api.baseUrl`
569
+ - For on-premise: ensure correct URL format
570
+
571
+ ### Code Generation Issues
572
+
573
+ **Problem:** "No projects selected for tracking"
574
+ - Run `porchestra explore` first to select agents
575
+ - Or run `porchestra pull` which auto-triggers explore
576
+
577
+ **Problem:** "tool-impl.ts already exists"
578
+ - This is expected - implementation files are created once
579
+ - Use `--force` flag to overwrite (⚠️ will lose your code)
580
+
581
+ ### Version Issues
582
+
583
+ **Problem:** "Agent has no published versions"
584
+ - Agent must be published to at least one environment
585
+ - Check in Porchestra web app if agent is published
586
+
587
+ ---
588
+
589
+ ## API Endpoints
590
+
591
+ The CLI communicates with these API endpoints:
592
+
593
+ | Endpoint | Description | Auth |
594
+ |----------|-------------|------|
595
+ | `POST /cli/login` | Authenticate and generate CLI token | None |
596
+ | `POST /cli/token/refresh` | Refresh expiring token | CLI Token |
597
+ | `DELETE /cli/token` | Revoke token | CLI Token |
598
+ | `GET /cli/tokens` | List active tokens | CLI Token |
599
+ | `GET /cli/config` | Get CLI configuration | None |
600
+ | `GET /projects/:id/agents` | List agents | CLI Token |
601
+ | `POST /projects/:id/agents/:id/tools/export` | Export tools | CLI Token |
602
+
603
+ ---
604
+
605
+ ## Development
606
+
607
+ ```bash
608
+ # Install dependencies
609
+ pnpm install
610
+
611
+ # Build
612
+ pnpm run build
613
+
614
+ # Run tests
615
+ pnpm run test
616
+
617
+ # Watch mode
618
+ pnpm run dev
619
+ ```
620
+
621
+ ---
622
+
623
+ ## License
624
+
625
+ MIT
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import('../dist/index.js');
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@porchestra/cli",
3
+ "version": "1.0.0",
4
+ "description": "CLI for Porchestra - Generate LLM tool handlers",
5
+ "type": "module",
6
+ "engines": {
7
+ "node": ">=22.0.0"
8
+ },
9
+ "bin": {
10
+ "porchestra": "./bin/porchestra.js"
11
+ },
12
+ "scripts": {
13
+ "build": "tsup",
14
+ "dev": "tsup --watch",
15
+ "test": "vitest",
16
+ "test:ci": "vitest run",
17
+ "lint": "eslint src/**/*.ts",
18
+ "typecheck": "tsc --noEmit",
19
+ "prepublishOnly": "pnpm run build"
20
+ },
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "dependencies": {
25
+ "@porchestra/core": "^1.0.0",
26
+ "@inquirer/prompts": "^7.0.0",
27
+ "commander": "^12.0.0",
28
+ "conf": "^13.0.0",
29
+ "fs-extra": "^11.2.0",
30
+ "got": "^14.4.0",
31
+ "handlebars": "^4.7.8",
32
+ "ora": "^8.0.0",
33
+ "passport-http-bearer": "^1.0.1",
34
+ "picocolors": "^1.1.0",
35
+ "zod": "^3.23.0"
36
+ },
37
+ "devDependencies": {
38
+ "@types/fs-extra": "^11.0.4",
39
+ "@types/node": "^22.0.0",
40
+ "@types/passport-http-bearer": "^1.0.42",
41
+ "@typescript-eslint/eslint-plugin": "^8.0.0",
42
+ "@typescript-eslint/parser": "^8.0.0",
43
+ "@vitest/coverage-v8": "^2.1.0",
44
+ "eslint": "^9.0.0",
45
+ "nock": "^13.5.0",
46
+ "tmp": "^0.2.3",
47
+ "tsup": "^8.3.0",
48
+ "typescript": "^5.6.0",
49
+ "vitest": "^2.1.0"
50
+ }
51
+ }