propr-cli 0.8.3

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 (64) hide show
  1. package/README.md +549 -0
  2. package/dist/api/agentTank.js +27 -0
  3. package/dist/api/agents.js +201 -0
  4. package/dist/api/client.js +284 -0
  5. package/dist/api/errors.js +145 -0
  6. package/dist/api/implement.js +147 -0
  7. package/dist/api/index.js +26 -0
  8. package/dist/api/logs.js +59 -0
  9. package/dist/api/plans.js +160 -0
  10. package/dist/api/relay.js +73 -0
  11. package/dist/api/repos.js +243 -0
  12. package/dist/api/settings.js +219 -0
  13. package/dist/api/system.js +53 -0
  14. package/dist/api/tasks.js +140 -0
  15. package/dist/api/todos.js +77 -0
  16. package/dist/api/types.js +6 -0
  17. package/dist/assets/.env.example +183 -0
  18. package/dist/assets/env.example.txt +198 -0
  19. package/dist/commands/agentCommands.js +405 -0
  20. package/dist/commands/checkCommands.js +384 -0
  21. package/dist/commands/implementCommands.js +178 -0
  22. package/dist/commands/index.js +22 -0
  23. package/dist/commands/initCommands.js +167 -0
  24. package/dist/commands/initStack.js +193 -0
  25. package/dist/commands/logCommands.js +170 -0
  26. package/dist/commands/planCommands.js +552 -0
  27. package/dist/commands/relayCommands.js +149 -0
  28. package/dist/commands/repoCommands.js +526 -0
  29. package/dist/commands/settingCommands.js +237 -0
  30. package/dist/commands/stackCommands.js +86 -0
  31. package/dist/commands/startCommand.js +36 -0
  32. package/dist/commands/systemCommands.js +221 -0
  33. package/dist/commands/tankCommands.js +55 -0
  34. package/dist/commands/taskCommands.js +554 -0
  35. package/dist/commands/todoCommands.js +620 -0
  36. package/dist/commands/uiDocsCommands.js +69 -0
  37. package/dist/config/ConfigManager.js +360 -0
  38. package/dist/config/index.js +8 -0
  39. package/dist/config/types.js +16 -0
  40. package/dist/index.js +276 -0
  41. package/dist/orchestrator/format.js +31 -0
  42. package/dist/orchestrator/index.js +102 -0
  43. package/dist/orchestrator/manifest.json +16 -0
  44. package/dist/orchestrator/orchestrator.mjs +798 -0
  45. package/dist/orchestrator/types.js +10 -0
  46. package/dist/tui/StartApp.js +175 -0
  47. package/dist/tui/app.js +9 -0
  48. package/dist/tui/render.js +87 -0
  49. package/dist/utils/envFile.js +65 -0
  50. package/dist/utils/index.js +8 -0
  51. package/dist/utils/io.js +186 -0
  52. package/dist/utils/parseState.js +14 -0
  53. package/dist/utils/resolveProject.js +50 -0
  54. package/dist/vendor/shared/demoMode.js +6 -0
  55. package/dist/vendor/shared/events.js +30 -0
  56. package/dist/vendor/shared/githubAuthMode.js +35 -0
  57. package/dist/vendor/shared/index.js +15 -0
  58. package/dist/vendor/shared/labelUtils.js +32 -0
  59. package/dist/vendor/shared/modelDefinitions.js +146 -0
  60. package/dist/vendor/shared/reviewPrompt.js +18 -0
  61. package/dist/vendor/shared/usageTypes.js +13 -0
  62. package/dist/vendor/shared/userWhitelist.js +30 -0
  63. package/dist/vendor/shared/validateRelayUrl.js +21 -0
  64. package/package.json +31 -0
package/README.md ADDED
@@ -0,0 +1,549 @@
1
+ # ProPR CLI
2
+
3
+ Command-line interface for interacting with the ProPR backend. ProPR enables AI-powered automated implementation of GitHub issues and pull requests.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -g @propr/cli
9
+ ```
10
+
11
+ The host CLI requires Node.js 22 or newer. The Docker launcher image is separate
12
+ and remains dependency-free on Node 20 because it does not load the Ink-based
13
+ interactive CLI.
14
+
15
+ ## Quick Start
16
+
17
+ ```bash
18
+ # 1. Configure the backend URL
19
+ propr remote https://api.propr.example.com
20
+
21
+ # 2. Authenticate with GitHub (interactive via gh CLI)
22
+ propr login
23
+
24
+ # Or use a Personal Access Token directly
25
+ propr login ghp_xxxxxxxxxxxx
26
+
27
+ # 3. Set a default project
28
+ propr use owner/repo
29
+
30
+ # 4. Scaffold repo-local ProPR setup files
31
+ propr init
32
+
33
+ # 5. List available plans
34
+ propr plan list
35
+
36
+ # 6. Implement an issue
37
+ propr issue implement <draft-id>/<issue-number> --wait
38
+ ```
39
+
40
+ ## Configuration
41
+
42
+ ProPR CLI stores configuration in `~/.propr/config.json`.
43
+
44
+ ```bash
45
+ propr remote <url> # Set backend API URL
46
+ propr use <owner/repo> # Set default project
47
+ propr login [token] # Authenticate (interactive or PAT)
48
+ propr logout # Clear stored token
49
+ ```
50
+
51
+ ## Compatibility Notes
52
+
53
+ In the control-plane CLI, `propr status` reports the local Docker stack. Use
54
+ `propr remote-status` for the backend health/queue status JSON that older
55
+ scripts may have read from `propr status --json`.
56
+
57
+ **Breaking:** running bare `propr` now performs the same environment checks as
58
+ `propr check` — including a Docker daemon probe that can take a few seconds —
59
+ and exits nonzero when required local stack prerequisites are missing. Scripts
60
+ or shell integrations that invoked bare `propr` to print help text should call
61
+ `propr --help` instead.
62
+
63
+ ## Repository Setup
64
+
65
+ Use `propr init` from a repository root to scaffold `.propr` setup files used by agent execution containers.
66
+
67
+ ```bash
68
+ propr init
69
+ cd .propr && npm install <package>
70
+ ```
71
+
72
+ The generated `.propr/setup.sh` runs before each implementation execution. Edit it to install system tools with commands such as `sudo apk add --no-cache jq`.
73
+
74
+ ### Authentication
75
+
76
+ When no token is provided, `propr login` uses the GitHub CLI (`gh`) for interactive authentication:
77
+ - If you're already logged in to `gh`, your token is used automatically
78
+ - If not, `gh auth login` is launched interactively
79
+
80
+ To use a Personal Access Token instead:
81
+ 1. Go to https://github.com/settings/tokens
82
+ 2. Click "Generate new token (classic)"
83
+ 3. Select scopes: `repo`, `read:org`
84
+ 4. Run: `propr login <your-token>`
85
+
86
+ ## Commands Reference
87
+
88
+ ### Global Options
89
+
90
+ | Option | Description |
91
+ |--------|-------------|
92
+ | `-p, --project <project>` | Specify the target project (owner/repo) |
93
+ | `-V, --version` | Output the version number |
94
+ | `-h, --help` | Display help information |
95
+
96
+ Most commands support `--json` (`-j`) for machine-readable output.
97
+
98
+ ---
99
+
100
+ ### Plans
101
+
102
+ Manage implementation plans for AI-powered issue resolution.
103
+
104
+ ```bash
105
+ propr plan list # List plans for default project
106
+ propr plan list -p owner/repo # List plans for specific project
107
+ propr plan create "Add dark mode" --wait # Create plan and wait for generation
108
+ propr plan create "Fix bug" -b develop # Target a specific branch
109
+ propr plan get <draft-id> # View plan details
110
+ propr plan get <draft-id> --json # View as JSON
111
+ propr plan generate <draft-id> --wait # Trigger generation for existing draft
112
+ propr plan finalize <draft-id> # Create GitHub issues from plan items
113
+ propr plan issues <draft-id> # List plan issues
114
+ propr plan issues <draft-id> --json # List issues as JSON
115
+ propr plan delete <draft-id> # Delete a plan (with confirmation)
116
+ propr plan delete <draft-id> --force # Delete without confirmation
117
+ propr plan abort <draft-id> # Abort ongoing generation
118
+ ```
119
+
120
+ | Option | Command | Description |
121
+ |--------|---------|-------------|
122
+ | `-p, --project` | `list`, `create` | Target project (owner/repo) |
123
+ | `-b, --branch` | `create` | Target branch (default: main) |
124
+ | `-w, --wait` | `create`, `generate` | Wait for plan generation to complete |
125
+ | `-j, --json` | `get`, `finalize`, `issues` | Output as JSON |
126
+ | `-f, --force` | `delete` | Skip confirmation prompt |
127
+
128
+ ---
129
+
130
+ ### Issue Implementation
131
+
132
+ Implement GitHub issues from plans using AI agents.
133
+
134
+ ```bash
135
+ propr issue implement <draft-id>/<issue-number> # Trigger implementation
136
+ propr issue implement <draft-id>/1 --wait # Wait for completion
137
+ propr issue implement <draft-id>/1 -a claude -m model-name # Use specific agent/model
138
+ propr issue implement <draft-id>/1 -a opencode -m opencode-minimax-m3-free
139
+ propr issue implement <draft-id>/1 --epic --auto-merge # Epic PR + auto-merge
140
+ ```
141
+
142
+ | Option | Description |
143
+ |--------|-------------|
144
+ | `-p, --project` | Target project (owner/repo) |
145
+ | `-w, --wait` | Wait for the implementation to complete |
146
+ | `-a, --agent` | Agent alias to use for implementation |
147
+ | `-m, --model` | Model name to use for implementation |
148
+ | `--epic` | Create an Epic PR to collect all related PRs |
149
+ | `--auto-merge` | Enable auto-merge when CI checks pass |
150
+
151
+ The issue ID format is `<draft-id>/<issue-number>` or `<draft-id>:<issue-number>`.
152
+
153
+ ---
154
+
155
+ ### Tasks
156
+
157
+ View and manage implementation tasks.
158
+
159
+ ```bash
160
+ propr task list # List all tasks
161
+ propr task list -s processing # Filter by status
162
+ propr task list -p owner/repo # Filter by project
163
+ propr task list --search "auth" -l 100 # Search with limit
164
+ propr task get <task-id> # View task details with history
165
+ propr task stop <task-id> # Stop a running task
166
+ propr task delete <task-id> # Delete a task (with confirmation)
167
+ propr task delete <task-id> --force # Force delete active task
168
+ propr task revert owner/repo 123 abc 456 # Revert a commit from a PR
169
+ ```
170
+
171
+ | Option | Command | Description |
172
+ |--------|---------|-------------|
173
+ | `-p, --project` | `list` | Filter by project (owner/repo) |
174
+ | `-s, --status` | `list` | Filter by status (see below) |
175
+ | `-l, --limit` | `list` | Max results (default: 50) |
176
+ | `--search` | `list` | Search by term |
177
+ | `-f, --force` | `delete` | Force deletion of active tasks |
178
+ | `-o, --owner` | `revert` | Repo owner if not in owner/repo format |
179
+
180
+ **Status values:** `pending`, `queued`, `processing`, `completed`, `failed`, `cancelled`, `all`
181
+
182
+ ---
183
+
184
+ ### Repositories
185
+
186
+ Manage monitored repositories and their indexing.
187
+
188
+ ```bash
189
+ propr repo list # List monitored repositories
190
+ propr repo add owner/repo # Add a repository
191
+ propr repo add owner/repo -a "Alias" -b dev # With alias and branch
192
+ propr repo remove owner/repo # Remove a repository
193
+ propr repo toggle owner/repo --enable # Enable monitoring
194
+ propr repo toggle owner/repo --disable # Disable monitoring
195
+ propr repo index owner/repo # Trigger full indexing
196
+ propr repo index owner/repo --incremental # Incremental indexing
197
+ propr repo index owner/repo -b feature # Index specific branch
198
+ propr repo status # View all indexing status
199
+ propr repo status owner/repo # View specific repo status
200
+ ```
201
+
202
+ ---
203
+
204
+ ### Agents
205
+
206
+ Manage AI agent configurations for code implementation.
207
+
208
+ ```bash
209
+ propr agent list # List configured agents
210
+ propr agent add my-claude -t claude -m model1,model2 # Add an agent
211
+ propr agent add my-agent -t claude -m model -d model # With default model
212
+ propr agent add test -t antigravity -m antigravity-gemini-3-pro-preview --disabled # Add in disabled state
213
+ propr agent add opencode -t opencode -m opencode-minimax-m3-free -d opencode-minimax-m3-free --config-path /home/your-user/.config/opencode
214
+ propr agent add --file agent-config.json # From JSON file
215
+ cat config.json | propr agent add --file - # From stdin
216
+ propr agent delete my-agent # Delete (with confirmation)
217
+ propr agent delete my-agent --force # Delete without confirmation
218
+ ```
219
+
220
+ **Agent types:** `claude`, `codex`, `antigravity`, `opencode`
221
+
222
+ For OpenCode agents, install and authenticate OpenCode on the host before adding the agent:
223
+
224
+ ```bash
225
+ curl -fsSL https://opencode.ai/install | bash
226
+ mkdir -p ~/.config/opencode ~/.opencode
227
+ opencode auth login
228
+ mkdir -p ~/.config/opencode/xdg-data/opencode && cp ~/.local/share/opencode/auth.json ~/.config/opencode/xdg-data/opencode/auth.json
229
+ ```
230
+
231
+ OpenCode stores `auth.json` under `~/.local/share/opencode`, but ProPR mounts the configured OpenCode config directory into the agent container. When using copied file-based auth, set `XDG_DATA_HOME=/home/node/.config/opencode/xdg-data` on the OpenCode agent. Legacy agents can keep `~/.opencode` as their `configPath`; new agents should use `~/.config/opencode`.
232
+
233
+ The example model `opencode-minimax-m3-free` is a built-in free OpenCode model. OpenCode's model list changes with auth providers; run `opencode models` after logging in and register any desired provider/model IDs with ProPR's `opencode-` prefix, such as `opencode-openai/gpt-5.5`. ProPR converts these IDs back to OpenCode's native `provider/model` syntax at execution time and does not add authenticated provider models by default.
234
+ Dynamic OpenCode GitHub labels use the format `llm-<agent-alias>~<propr-opencode-model-id>`, for example `llm-opencode~opencode-openai/gpt-5.5`. The `~` separator is an intentional public contract — these labels are persisted on GitHub issues and resolved later for execution routing.
235
+
236
+ **JSON file format** for `--file`:
237
+
238
+ ```json
239
+ {
240
+ "alias": "opencode",
241
+ "type": "opencode",
242
+ "models": ["opencode-minimax-m3-free"],
243
+ "defaultModel": "opencode-minimax-m3-free",
244
+ "dockerImage": "propr/agent-opencode:latest",
245
+ "configPath": "/home/your-user/.config/opencode",
246
+ "enabled": true,
247
+ "envVars": {
248
+ "XDG_DATA_HOME": "/home/node/.config/opencode/xdg-data"
249
+ }
250
+ }
251
+ ```
252
+
253
+ ---
254
+
255
+ ### To-Dos
256
+
257
+ Manage repository-level to-dos for tracking work items.
258
+
259
+ ```bash
260
+ # List and filter
261
+ propr todo list # List open todos
262
+ propr todo list -a # All todos (open + completed)
263
+ propr todo list -d # Completed todos only
264
+ propr todo list -p owner/repo # Specify project
265
+
266
+ # CRUD
267
+ propr todo get <todo-id> # View todo details
268
+ propr todo add "Fix login page" # Create a todo
269
+ propr todo add "Task" -c <category-id> # Create in a category
270
+ propr todo complete <todo-id> # Mark as completed
271
+ propr todo complete <todo-id> --undo # Reopen
272
+ propr todo delete <todo-id> # Delete (with confirmation)
273
+
274
+ # Reorder and move
275
+ propr todo move <todo-id> 1 # Move to top of category
276
+ propr todo move <todo-id> 3 # Move to position 3
277
+ propr todo move <todo-id> 1 -c <cat-id> # Move to different category
278
+ propr todo move <todo-id> 1 -c none # Move to uncategorized
279
+ ```
280
+
281
+ #### Categories
282
+
283
+ ```bash
284
+ propr todo category list # List categories
285
+ propr todo category add "Bug fixes" # Create a category
286
+ propr todo category rename <id> "New name" # Rename a category
287
+ propr todo category delete <id> # Delete (todos go uncategorized)
288
+ propr todo category move <id> 1 # Move to position
289
+ ```
290
+
291
+ ---
292
+
293
+ ### Settings
294
+
295
+ ```bash
296
+ propr setting get # View all settings
297
+ propr setting get -k worker_concurrency # View specific setting
298
+ propr setting update worker_concurrency 4 # Update a setting
299
+ propr setting update github_user_whitelist "a,b,c" # Update whitelist
300
+ ```
301
+
302
+ **Available settings:** `worker_concurrency`, `github_user_whitelist`, `analysis_model_fast`, `planner_context_model`, `planner_generation_model`, `auto_followup_score_threshold`
303
+
304
+ ---
305
+
306
+ ### Logs
307
+
308
+ ```bash
309
+ propr log list # List recent LLM logs
310
+ propr log list -m model-name # Filter by model
311
+ propr log list --failed # Failed executions only
312
+ propr log list --agent my-claude # Filter by agent
313
+ propr log list --draft <draft-id> # Filter by plan
314
+ propr log list --page 2 -l 100 # Pagination
315
+ ```
316
+
317
+ ---
318
+
319
+ ### System
320
+
321
+ ```bash
322
+ propr status # System health check
323
+ propr status --json # JSON output
324
+ propr queue # Queue statistics
325
+ propr queue --json # JSON output
326
+ ```
327
+
328
+ ---
329
+
330
+ ## JSON Output
331
+
332
+ Most commands support `--json` (`-j`) for programmatic use:
333
+
334
+ ```bash
335
+ propr plan list --json
336
+ propr task list -j
337
+ propr repo list --json | jq '.repos_to_monitor[].name'
338
+ ```
339
+
340
+ ---
341
+
342
+ ## Programmatic Usage
343
+
344
+ The CLI package also exports modules for programmatic use:
345
+
346
+ ```typescript
347
+ import {
348
+ createConfigManager,
349
+ createApiClient,
350
+ resolveProject,
351
+ } from '@propr/cli';
352
+
353
+ const config = await createConfigManager();
354
+ const client = await createApiClient();
355
+ const response = await client.get('/api/status');
356
+ ```
357
+
358
+ ---
359
+
360
+ ## Examples
361
+
362
+ ### Complete Workflow
363
+
364
+ ```bash
365
+ # Setup
366
+ propr remote https://api.propr.example.com
367
+ propr login
368
+ propr use myorg/myrepo
369
+
370
+ # Add and index a repository
371
+ propr repo add myorg/myrepo -b main
372
+ propr repo index myorg/myrepo
373
+
374
+ # Create an implementation plan and wait for generation
375
+ propr plan create "Add user authentication with JWT tokens" --wait
376
+
377
+ # Finalize plan to create GitHub issues
378
+ propr plan finalize <draft-id>
379
+
380
+ # View plan issues
381
+ propr plan issues <draft-id>
382
+
383
+ # Implement the first issue from the plan
384
+ propr issue implement <draft-id>/1 --wait --auto-merge
385
+
386
+ # Monitor tasks
387
+ propr task list -s processing
388
+ propr task get <task-id>
389
+ ```
390
+
391
+ ### Managing To-Dos
392
+
393
+ ```bash
394
+ # Create categories and todos
395
+ propr todo category add "Sprint 1"
396
+ propr todo add "Implement auth" -c <category-id>
397
+ propr todo add "Write tests" -c <category-id>
398
+
399
+ # Prioritize by reordering
400
+ propr todo move <todo-id> 1 # Move to top priority
401
+
402
+ # Track progress
403
+ propr todo complete <todo-id>
404
+ propr todo list -d # View completed items
405
+ ```
406
+
407
+ ### Monitoring and Debugging
408
+
409
+ ```bash
410
+ propr status # System health
411
+ propr queue # Queue statistics
412
+ propr log list --failed # Failed LLM executions
413
+ propr log list -l 100 --success # Successful executions
414
+ propr task get <task-id> # Detailed task info
415
+ ```
416
+
417
+ ### Managing Multiple Projects
418
+
419
+ ```bash
420
+ # Switch default project
421
+ propr use org1/repo1
422
+ propr plan list
423
+
424
+ propr use org2/repo2
425
+ propr plan list
426
+
427
+ # Or use -p flag for one-off commands
428
+ propr plan list -p org3/repo3
429
+ propr todo list -p org3/repo3
430
+ ```
431
+
432
+ ---
433
+
434
+ ## E2E Testing
435
+
436
+ End-to-end tests run against a live ProPR instance and exercise the full workflow: system health, repo management, todo CRUD, plan lifecycle (create → generate → finalize), and multi-model implementation across all agents (Claude, Antigravity, Codex, OpenCode).
437
+
438
+ ### Prerequisites
439
+
440
+ - A running ProPR backend (e.g., `https://api.gitfix.dev`)
441
+ - GitHub authentication (via `gh auth login` or a token)
442
+ - A dedicated test repo on GitHub (e.g., `integry/propr-e2e-test`) — the tests will auto-add and index it if needed
443
+
444
+ ### Environment Variables
445
+
446
+ | Variable | Required | Default | Purpose |
447
+ |---|---|---|---|
448
+ | `PROPR_E2E_API_URL` | Yes | — | Backend URL |
449
+ | `PROPR_E2E_TOKEN` | No | `gh auth token` | GitHub token (falls back to `gh` CLI) |
450
+ | `PROPR_E2E_REPO` | Yes | — | Test repo (e.g., `integry/propr-e2e-test`) |
451
+ | `PROPR_E2E_SKIP_SLOW` | No | — | Set to `1` to skip plan/implementation tests |
452
+ | `PROPR_E2E_NO_CLEANUP` | No | — | Set to `1` to keep all created resources |
453
+
454
+ ### Running
455
+
456
+ ```bash
457
+ # Fast tests only (~20s) — system health, repos, settings, logs, tasks, agents, todo CRUD
458
+ PROPR_E2E_REPO=owner/repo PROPR_E2E_API_URL=https://api.example.com \
459
+ PROPR_E2E_SKIP_SLOW=1 npm run test:e2e
460
+
461
+ # Full suite (~20-30min) — includes plan generation, all-models implementation, report
462
+ PROPR_E2E_REPO=owner/repo PROPR_E2E_API_URL=https://api.example.com \
463
+ npm run test:e2e
464
+
465
+ # Keep everything for manual inspection
466
+ PROPR_E2E_REPO=owner/repo PROPR_E2E_API_URL=https://api.example.com \
467
+ PROPR_E2E_NO_CLEANUP=1 npm run test:e2e
468
+ ```
469
+
470
+ ### Test Groups
471
+
472
+ | # | Group | Speed | What it tests |
473
+ |---|-------|-------|---------------|
474
+ | 1 | System health | Fast | API status, queue stats |
475
+ | 2 | Repositories | Fast | List repos, auto-add test repo, ensure indexed |
476
+ | 3 | Settings | Fast | Setting types and values |
477
+ | 4 | Logs | Fast | LLM log listing, filtering, pagination |
478
+ | 5 | Tasks | Fast | Task listing and repo filtering |
479
+ | 6 | Agents | Fast | Agent listing, stores available models |
480
+ | 7 | Todo CRUD | Fast | Full lifecycle: create → list → get → update → reorder → delete |
481
+ | 8 | Plan — greenfield | Slow | Create plan → generate → finalize → verify issues |
482
+ | 9 | Plan — brownfield | Slow | Same flow with a different prompt type |
483
+ | 10 | All-models | Slow | Creates multiple plans, tests multi-model parallel (all models on one issue) + single-model (each model on a separate issue) for every agent/model pair |
484
+ | 11 | Report | Slow | Writes markdown report, validates log fields |
485
+
486
+ ### Report
487
+
488
+ After each full run, a markdown report is written to:
489
+
490
+ - **`test/reports/e2e-{timestamp}.md`** — timestamped report
491
+ - **`test/reports/latest.md`** — symlink to most recent
492
+
493
+ The report includes:
494
+
495
+ - **Plans** — ID, name, status, prompt, issues with their agent/model/task assignments
496
+ - **Multi-model parallel results** — all models implementing the same issue simultaneously, with state, duration, tokens, PR number, history entries, and log counts
497
+ - **Single-model results** — grouped by agent (Claude, Antigravity, Codex, OpenCode), showing each model's performance on its own issue
498
+ - **Totals** — models tested, tasks created, completion rate, token usage
499
+
500
+ ### File Structure
501
+
502
+ ```
503
+ test/
504
+ e2e.test.ts # Main test file (groups 1-11)
505
+ e2e/
506
+ helpers.ts # Shared types, client setup, polling utilities
507
+ report.ts # Markdown report generator
508
+ reports/ # Generated reports (gitignored)
509
+ latest.md
510
+ e2e-2026-03-18T18-55-26.md
511
+ ```
512
+
513
+ ---
514
+
515
+ ## Troubleshooting
516
+
517
+ ### Authentication Errors
518
+
519
+ ```bash
520
+ propr logout
521
+ propr login # Interactive login via gh CLI
522
+ ```
523
+
524
+ Make sure your GitHub token has the required scopes: `repo` and `read:org`.
525
+
526
+ ### Connection Errors
527
+
528
+ ```bash
529
+ propr remote https://correct-api-url.example.com
530
+ propr status
531
+ ```
532
+
533
+ ### Task Failures
534
+
535
+ ```bash
536
+ propr task get <task-id>
537
+ propr log list --draft <draft-id> --failed
538
+ ```
539
+
540
+ ---
541
+
542
+ ## Getting Help
543
+
544
+ ```bash
545
+ propr --help # General help
546
+ propr <command> --help # Command group help
547
+ propr plan --help # Plan commands
548
+ propr todo category --help # Category commands
549
+ ```
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Agent Tank API
3
+ *
4
+ * Agent Tank tracks LLM subscription usage. It is an external service (not a
5
+ * stack container) — toggling it is a backend setting, so these helpers go
6
+ * through the running ProPR API (`/api/config/agent-tank`).
7
+ */
8
+ import { createApiClient } from "./index.js";
9
+ const DEFAULT_AGENT_TANK_URL = "http://127.0.0.1:3456";
10
+ /** Fetch the current Agent Tank settings. */
11
+ export async function getAgentTank(client) {
12
+ const apiClient = client ?? (await createApiClient());
13
+ const response = await apiClient.get("/api/config/agent-tank");
14
+ return response.data;
15
+ }
16
+ /** Enable or disable Agent Tank usage tracking, optionally setting the URL. */
17
+ export async function setAgentTank(enabled, url, client) {
18
+ const apiClient = client ?? (await createApiClient());
19
+ // Preserve the existing URL when the caller doesn't pass one.
20
+ let resolvedUrl = url;
21
+ if (!resolvedUrl) {
22
+ const current = await getAgentTank(apiClient);
23
+ resolvedUrl = current.url || DEFAULT_AGENT_TANK_URL;
24
+ }
25
+ await apiClient.post("/api/config/agent-tank", { body: { enabled, url: resolvedUrl } });
26
+ return { enabled, url: resolvedUrl };
27
+ }