rosterpicker
v0.1.0
Published
Report-backed OpenCode worker crew recommender
Downloads
151
Maintainers
Readme
Model Roster
Report-backed worker crew recommender for OpenCode.
Playbook first. Live catalog second.
rosterpicker is an npm library + CLI for assembling model crews.
Instead of picking a single “best model,” it fills specialized seats based on the task, the playbook, and which models are actually available.
The Crew
| Tier | Seat | Job | |:---:|---|---| | T1 | Orchestrator | Plans and coordinates | | T2 | Workers | Implement the work | | T3 | Librarian / Reviewer | Search, verify, and review | | T0 | Specialist | Stays on-call for specialized work |
How Selection Works
┌─────────────────┐
│ Task │
└────────┬────────┘
▼
┌─────────────────┐
│ playbook.json │
│ routing + prefs │
└────────┬────────┘
▼
┌─────────────────┐
│ Live Catalog │
│ Zen + Go │
└────────┬────────┘
▼
┌─────────────────┐
│ Crew │
│ T1 · T2 · T3 · T0│
└─────────────────┘Routing comes from playbook.json, which contains the field guide and pricing reports.
Availability comes from the live OpenCode model catalogs:
https://opencode.ai/zen/v1/modelshttps://opencode.ai/zen/go/v1/models
If HTTP catalog discovery fails, rosterpicker falls back to:
opencode modelsInstall
npm
npm install rosterpickerGlobal CLI
npm install -g rosterpickerThen:
roster crew "kotlin compose"From This Repository
npm install
npm test
npm run build
node dist/cli.js crew "kotlin compose"CLI
# Overview, commands, options, and examples
roster --help
roster crew --help
# Build a crew
roster crew "kotlin compose"Infer the stack from the current directory:
roster here
roster crew --here
roster here "debug crash"
roster here --path ../other-app --freeMore examples:
# Native crash investigation
roster crew "jni ndk tombstone"
# Free-model constraint
roster crew "logcat triage" --free
# Machine-readable output
roster crew "release review" --jsonExample Output
┌─ WORKER CREW · android-compose · [PAID] ──────────────┐
│ task kotlin compose │
│ workload Kotlin / Jetpack Compose feature work │
│ domain android │
│ evidence field_guide │
└───────────────────────────────────────────────────────┘
T1 · ORCHESTRATOR opencode-go/glm-5.2 ✓ validated
Plan the work, route tools, coordinate sub-agents...
fallback opencode-go/qwen3.8-max, opencode-go/qwen3.7-maxColors are enabled on interactive terminals and auto-disabled when output is piped
(respects NO_COLOR / FORCE_COLOR). --json always emits plain JSON.
Global flags
| Flag | Description |
|---|---|
| -V, --version | Print the CLI version |
| --json | Machine-readable JSON output |
| --refresh | Bypass the 1-hour catalog cache |
| -h, --help | Show help (add --help to any command) |
roster catalog --free lists only free models.
Exit codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Usage error, unreadable directory, or catalog fetch failure |
| 2 | No live worker could be seated |
Catalog & Playbook
# Refresh the live model catalog
roster catalog --refresh
# List only free models
roster catalog --free
# Inspect the routing playbook
roster playbookAlias:
roster recommendis equivalent toroster crew.
Library API
import { fetchCatalog, scanDirectory, suggestCrew, suggestCrewFromDirectory } from "rosterpicker";
const catalog = await fetchCatalog();
const crew = suggestCrew({
task: "kotlin compose",
catalog,
});
for (const seat of crew.crew) {
console.log(seat.role, seat.spec);
}
const scan = scanDirectory({ root: process.cwd(), hint: "debug crash" });
const fromHere = suggestCrewFromDirectory({ catalog, root: process.cwd() });
console.log(scan.task, fromHere.crew.workload_id);Force a Catalog Refresh
const catalog = await fetchCatalog({ refresh: true });By default, catalog data uses a 1-hour disk cache at $LOCALAPPDATA/rosterpicker (Windows) or $XDG_CACHE_HOME/rosterpicker / ~/.cache/rosterpicker (macOS/Linux).
Reliability
| Feature | Behavior |
|---|---|
| Playbook validation | Validated with Zod on load |
| HTTP timeout | Catalog requests time out after 15 seconds |
| Parallel discovery | Zen + Go catalogs are fetched concurrently |
| Model normalization | IDs are normalized, so glm-5.2 matches glm-5.2 |
| Seat fallback | Missing preferred seats fall through to the next live playbook spec |
| Production filtering | --production requires selection_eligible models |
| HTTP fallback | Falls back to opencode models when HTTP discovery fails |
Selection Philosophy
playbook preference
│
▼
is the model live?
│ │
yes no
│ │
▼ ▼
seat it try next
│
▼
live fallbackThe playbook decides what should be preferred.
The live catalog decides what can actually be seated.
That keeps recommendations report-backed without assuming every preferred model is currently available.
