# Proxym Examples — Testing Report

**Date:** 2026-03-25
**Tested on:** Linux, Python 3.13, Node.js v20.19.5

---

## 1. New CLI Commands Tested

### `proxym ticket analyze <id>` / `proxym analyze <id>`

| Test Case | Result | Notes |
|-----------|--------|-------|
| Ticket with successful execution | **PASS** | Shows PASS, job details, files, duration |
| Ticket with failed execution | **PASS** | Shows FAIL, error message, stderr, next steps |
| Ticket with no execution | **PASS** | Shows "not dispatched yet", suggests dispatch command |
| Non-existent ticket | **PASS** | Shows "Ticket not found" |
| `proxym ticket analyze` (subcommand) | **PASS** | Same output as top-level shortcut |
| `proxym analyze` (shortcut) | **PASS** | Same output as subcommand |

### `proxym ticket list --project <name>`

| Test Case | Result | Notes |
|-----------|--------|-------|
| Filter by project name (single) | **PASS** | Returns only project's tickets |
| Filter by project name (duplicates) | **PASS** | Resolves all matching IDs, returns union |
| Filter by project ID | **PASS** | Same behavior |
| No matching project | **PASS** | Returns empty list |

### `proxym ticket export --project <name>`

| Test Case | Result | Notes |
|-----------|--------|-------|
| Export JSON with --project filter | **PASS** | Returns correct count after multi-ID fix |
| Export markdown | **PASS** | Renders ticket table |

### `proxym tools dispatch` (output)

| Test Case | Result | Notes |
|-----------|--------|-------|
| Dispatch shows concise summary | **PASS** | 3-line output instead of 50+ lines raw JSON |

## 2. Examples Tested

### `examples/todo-app-ts/run.sh`

| Mode | Result | Notes |
|------|--------|-------|
| `--dry-run` | **PASS** | Shows plan for all 6 phases without executing |
| `--skip-dispatch --clean` | **PASS** | Creates scaffold, registers, creates 7 tickets, skips AI |
| Build verification | **PASS** | npm install, tsc, build all succeed on scaffold |
| Smoke tests | **EXPECTED FAIL** | Stubs throw "Not implemented" (no AI ran) |

**Reduction:** 1163 → 381 lines. All raw `curl` calls replaced with `proxym` CLI.

### `examples/simple-3-tickets/run.sh`

| Mode | Result | Notes |
|------|--------|-------|
| `--dry-run` | **PASS** | Shows plan for 3 tickets |
| Full run (with dispatch) | **PASS** | Creates 3 tickets, dispatches, analyzes each |
| Dispatch results | **EXPECTED FAIL** | AuthenticationError (no API key in test env) |
| Analyze after failure | **PASS** | Correctly reports FAIL with error details |

### `examples/multi-project/run.sh`

| Mode | Result | Notes |
|------|--------|-------|
| `--dry-run` | **PASS** | Shows plan for 2 projects, 2 sprints, 4 tickets |
| Full run (with dispatch) | **PASS** | All 4 tickets created, dispatched, analyzed |
| Sprint creation | **PASS** | Both sprints show correct ticket counts and tools |
| Project isolation | **PASS** | `ticket list --project calculator` → 2, `--project greeter` → 2 |
| Sprint details | **PASS** | `sprint show` shows goals, tools breakdown, progress |
| Dispatch results | **EXPECTED FAIL** | AuthenticationError (no API key in test env) |
| Project dirs in examples/ | **PASS** | `--project-dir` points to `examples/multi-project/src/*` |

### `examples/cli_shell_scenario.sh`

| Mode | Result | Notes |
|------|--------|-------|
| Full run | **PASS** | All 8 steps execute: status, project add, ticket add ×2, board, queue, jobs |
| Project dir | **PASS** | Uses `examples/todo_list_project/` as project dir |

**BUG-6 FIXED:** Script defaulted to port 5001 (no `--proxy`). Rewritten to use `PROXYM_URL` env var, `ticket add` (was `project task`), and consistent `--proxy` flag.

## 3. Bugs Found and Fixed

### BUG-1: `print_json_if_yaml` not imported in `tickets_ctl.py` (FIXED)

- **Symptom:** `proxym ticket list --project X` crashes with `NameError`
- **Root cause:** Missing import in `src/proxym/cli/_groups/tickets_ctl.py`
- **Fix:** Added `from proxym.cli._client import print_json_if_yaml`

### BUG-2: `ticket list --project` filter ignored by backend (FIXED)

- **Symptom:** `proxym ticket list --project simple-demo` returns ALL tickets
- **Root cause:** `GET /dashboard/tickets` endpoint didn't accept `project_id` query param; `TicketManager.list_tickets()` didn't pass it to `_apply_filters()`
- **Fix:**
  - Added `project_id` param to `_tickets_api.py::list_tickets()`
  - Added `project_id` param to `_manager.py::list_tickets()` and `_apply_filters()`
  - CLI resolves project name → ID before sending (same as `ticket add`)

### BUG-3: Smoke test failures don't affect verification result (FIXED)

- **Symptom:** `run.sh` says "All verifications passed" even when smoke:add fails
- **Root cause:** Smoke test `||` branches used `_warn` without `ok=false`
- **Fix:** Added `ok=false` to all smoke test failure branches

### BUG-4: `tools dispatch` dumps raw JSON (FIXED)

- **Symptom:** Dispatching a ticket prints 50+ lines of raw JSON
- **Root cause:** `tools_ctl.py` used `print_json(r.json())` unconditionally
- **Fix:** Concise 3-line summary (message, job ID, dir). Full JSON still available via `--format yaml`

### BUG-5: `ticket list/export --project` fails with duplicate project names (FIXED)

- **Symptom:** `proxym ticket export --project todo-app-ts` returns empty or all tickets
- **Root cause:** Multiple projects with same name; resolution picked only one ID
- **Fix:**
  - `_apply_filters()` now accepts `str | set[str]` for `project_id`
  - CLI resolves name → ALL matching IDs (comma-separated)
  - Backend `GET /tickets` parses comma-separated `project_id` into a set
  - Export endpoint resolves `project_name` → set of all matching IDs

## 4. Unit Test Results

```
891 passed, 17 skipped, 0 failed (19s)
```

Excluded from run:
- `tests/e2e/` — requires full environment
- `tests/gui/` — requires Playwright
- `test_diagnostics_status` — timeout hitting live server (infra, not code)

## 5. Files Changed

### New files

| File | Description |
|------|-------------|
| `examples/simple-3-tickets/run.sh` | Simple example: 3 tickets with sequential analysis |
| `examples/simple-3-tickets/README.md` | Documentation for the simple example |
| `examples/multi-project/run.sh` | Multi-project: 2 projects × 2 tickets × sprints |
| `examples/multi-project/README.md` | Documentation for the multi-project example |
| `examples/multi-project/src/.gitignore` | Ignores AI-generated .py files |
| `examples/TESTING_REPORT.md` | This report |

### Modified files

| File | Change |
|------|--------|
| `src/proxym/cli/tickets.py` | Added `cmd_ticket_analyze()` |
| `src/proxym/cli/_groups/tickets_ctl.py` | Registered `analyze`, fixed import, multi-ID project resolution |
| `src/proxym/cli/_groups/tools_ctl.py` | Concise dispatch output (was raw JSON) |
| `src/proxym/ctl.py` | Added `proxym analyze` top-level shortcut |
| `src/proxym/dashboard/_tickets_api.py` | `project_id` filter on `GET /tickets` + multi-ID export |
| `src/proxym/dashboard/tickets/_manager.py` | `project_id` filter: `str \| set[str]` support |
| `examples/todo-app-ts/run.sh` | Rewritten: 1163 → 381 lines, uses proxym CLI |
| `examples/todo-app-ts/README.md` | Simplified to match new CLI-based approach |
| `examples/cli_shell_scenario.sh` | Updated with analyze, board, q commands |
| `docs/CLI_USAGE.md` | Added analyze docs, Scenarios F+G, quick reference |

### Deleted files

| File | Reason |
|------|--------|
| `examples/todo-app-ts/prompts.md` | 753KB conversation dump, not useful |

## 6. Summary

- **6 bugs found and fixed** during testing
- **891 unit tests pass**, 0 regressions
- **All 4 examples work** (`simple-3-tickets`, `multi-project`, `todo-app-ts`, `cli_shell_scenario`)
- **New `analyze` command** works for all ticket states (pass/fail/pending/not-found)
- **`--project` filter** works in `ticket list` and `ticket export` (incl. duplicate names)
- **`tools dispatch`** shows concise output instead of raw JSON
- **run.sh reduced 3x** (1163 → 381 lines) by replacing curl with CLI commands
- **multi-project example** validates full cycle: project → sprint → ticket → dispatch → analyze
- **Generated code dirs** inside `examples/*/src/` so examples are self-contained
