A terminal-first CLI for Monash OnTrack / Doubtfire
ontrack-cli turns common Monash OnTrack workflows into a single command surface:
ontrack <command>The CLI targets the Monash OnTrack API by default:
https://ontrack.infotech.monash.edu/api
It is designed to work out of the box, with no mandatory base URL setup and a command set that is suitable for both interactive terminal use and scriptable automation.
- What it does
- Installation
- Quick start
- Core concepts
- Authentication and session management
- Command reference
- Typical workflows
- Output, highlighting, and JSON
- Environment variables
- Files and directories
- Local development
- Testing and verification
- Project structure
- Troubleshooting
- Current scope
ontrack-cli currently covers the following areas:
- Authentication and session handling
- SSO auto capture
- manual redirect URL login
- direct
auth token + usernamelogin
- Read access for account, unit, project, and task data
projectsunitstasksinboxtask show
- Feedback and live tracking
feedback listfeedback watchwatch
- File operations
pdf taskpdf submissionsubmission uploadsubmission upload-new-files
- Engineering and diagnostics
doctordiscoverdiscover --probe
- Terminal UX
- colored table output by default
--jsonfor automation and scripting- fallback handling when some endpoints are not accessible for the current account
- Node.js
22+ - macOS, Linux, or Windows
- Network access on first guided login (
ontrack login) if Playwright Chromium runtime needs to be installed automatically
Recommended:
npm install -g ontrack-cliAfter installation, the CLI is available as:
ontrackIf you prefer to keep the package local to a workspace:
npm install
npm exec ontrack -- auth-methodnpm install
npm run build
node dist/cli.js auth-methodDevelopment mode:
npm run dev -- auth-methodThis is the shortest stable path from install to useful output.
ontrackThe launcher displays the ALWAYS ONTRACK digital-style menu. Enter a number to run a command path directly.
Launcher actions now include guided task selection:
- actions
7/8/11/12support guided single-task and batch selection - you can choose
single,multiple(comma-separated selectors), orall tasks - task selection is based on
taskcode (for exampleP1,D4) or numeric task id - you can still switch to manual
--project-id+ selector input - upload actions
13/14remain single-task guided by design
ontrack auth-methodRecommended:
ontrack loginExplicit headless mode (same as default behavior):
ontrack login --hide-browserontrack whoamiontrack projects
ontrack units
ontrack tasksontrack task show --project-id 87 --abbr D4Batch examples:
ontrack task show --project-id 87 --abbr P1,D4
ontrack task show --project-id 87 --all-tasksontrack feedback list --project-id 87 --abbr D4
ontrack feedback watch --project-id 87 --abbr D4Batch list example:
ontrack feedback list --project-id 87 --abbr P1,D4ontrack pdf task --project-id 87 --abbr D4
ontrack pdf submission --project-id 87 --abbr D4Batch PDF example:
ontrack pdf task --project-id 87 --all-tasksontrack submission upload --project-id 87 --abbr D4 --file ./report.pdfontrack submission upload-new-files --project-id 87 --abbr D4 --file ./evidence.pdfUnderstanding a few OnTrack terms makes the command surface much easier to use.
A teaching unit, for example FIT1045.
Your project instance inside a unit. Most task-level commands require --project-id.
A concrete task such as P1, D4, or T2.
The task abbreviation. This is usually the most practical selector for day-to-day use:
P1D4T2
In most cases, --abbr is easier to read and remember than a numeric ID.
The CLI supports --task-id, but for normal usage --abbr is usually the better default.
Batch-capable commands (task show, feedback list, pdf task, pdf submission) support:
- repeated selectors:
--abbr P1 --abbr D4 - comma selectors:
--abbr P1,D4 - mixed selectors:
--task-id 501 --abbr D4 - project-wide selection:
--all-tasks
Most read commands support --json. Use it when you want to pipe results into scripts, CI steps, or your own tooling.
This is the default recommended path on all environments:
ontrack loginThis flow:
- prompts for Monash username/password in CLI (password is hidden)
- launches guided SSO automation in hidden-browser (headless) mode by default
- shows structured login progress in terminal panels
- prompts MFA method selection in CLI when multiple methods are available
- highlights Okta Verify number challenge values in terminal output
- captures credentials and signs in through
/api/auth - stores a local session cache
- auto-installs Playwright Chromium runtime when missing (best-effort)
ontrack login now defaults to hidden-browser (headless) mode across local and server environments.
Use ontrack login --show-browser only for debugging.
You can still use ontrack login --sso as an explicit guided alias.
--auto keeps the previous browser-driven capture behavior without guided credential entry.
The current implementation can capture credentials from:
- URL query parameters
/api/authrequest payload/api/authresponse bodylocalStorage- cookies
If you already have the final redirect URL, you can import it directly:
ontrack login --redirect-url "https://ontrack.infotech.monash.edu/sign_in?authToken=...&username=..."The expected redirect format looks like this:
https://ontrack.infotech.monash.edu/sign_in?authToken=...&username=...
Guided SSO automatically falls back to this manual redirect mode when it detects unsupported MFA, captcha, selector mismatch, or timeout. Treat this as a backup path rather than a daily login path.
If you already have a token and username:
ontrack login --auth-token <token> --username <username>After login, the CLI stores a session locally and reuses it for subsequent commands. You do not need to sign in again for each run unless the session expires or you log out.
The API client authenticates with these headers:
Auth-TokenUsername
ontrack logout| Command | Purpose | Typical use |
|---|---|---|
ontrack |
Open the interactive command launcher | Fastest way to run common workflows by number |
ontrack welcome |
Open the interactive command launcher explicitly | Useful for scripts/aliases that pass arguments |
ontrack auth-method |
Show the advertised authentication method | Verify whether the server is using SSO |
ontrack login |
Run guided Monash SSO with Okta Verify push/number (default path) | Primary login command |
ontrack login --sso |
Run guided Monash SSO with Okta Verify push/number | Explicit guided alias |
ontrack login --show-browser |
Force visible browser mode for guided SSO | Debug selector or MFA edge cases |
ontrack login --hide-browser |
Keep explicit headless guided SSO | Optional explicit flag (default behavior) |
ontrack login --auto |
Run browser-only capture mode | Use when you only need passive capture |
ontrack logout |
Clear the local session | Switch accounts, reset state, troubleshoot |
ontrack whoami |
Show the cached account | Confirm who is currently logged in |
ontrack doctor |
Probe key endpoints | Quickly identify session or permission issues |
| Command | Purpose | Notes |
|---|---|---|
ontrack projects |
List accessible projects | One of the main starting points |
ontrack project show --project-id <id> |
Show detailed project information | Useful for unit, grading, and task overview |
ontrack units |
List units | Some accounts fall back to units derived from /projects |
ontrack unit show --unit-id <id> |
Show detailed unit information | Includes task definitions when available |
ontrack tasks |
List tasks | Supports --project-id and --status |
ontrack unit tasks --unit-id <id> |
List tasks for one unit | Unit-scoped view |
ontrack inbox |
Load inbox tasks or fallback task list | Prefers /units/:id/tasks/inbox and falls back when needed |
ontrack task show --project-id <id> --abbr <abbr> |
Show one or many tasks | Supports repeated/comma selectors and --all-tasks |
| Command | Purpose | Notes |
|---|---|---|
ontrack feedback list --project-id <id> --abbr <abbr> |
Fetch comments/events for one or many tasks | Supports repeated/comma selectors and --all-tasks |
ontrack feedback watch --project-id <id> --abbr <abbr> |
Poll task feedback in real time | Default interval is 15s |
ontrack watch |
Monitor task status, due date, and new comment changes | Default interval is 60s |
| Command | Purpose | Notes |
|---|---|---|
ontrack pdf task --project-id <id> --abbr <abbr> |
Download task PDF(s) | Supports repeated/comma selectors and --all-tasks; saves to ./downloads by default |
ontrack pdf submission --project-id <id> --abbr <abbr> |
Download submission PDF(s) | Supports repeated/comma selectors and --all-tasks; saves to ./downloads by default |
ontrack submission upload ... |
Upload a submission | Supports --trigger and --comment |
ontrack submission upload-new-files ... |
Upload extra evidence files | Does not force a default trigger |
| Command | Purpose | Notes |
|---|---|---|
ontrack discover |
Scan frontend bundles for route and API templates | Engineering-focused inspection tool |
ontrack discover --probe |
Probe discovered API templates with the current session | Useful for real-account investigation |
ontrack login
ontrack whoami
ontrack projects
ontrack tasksTo narrow the result set:
ontrack tasks --project-id 87Or scope by unit:
ontrack units
ontrack unit tasks --unit-id 1ontrack task show --project-id 87 --abbr D4
ontrack feedback list --project-id 87 --abbr D4
ontrack pdf task --project-id 87 --abbr D4
ontrack pdf submission --project-id 87 --abbr D4For one task conversation:
ontrack feedback watch --project-id 87 --abbr D4To watch only new messages, with no history replay:
ontrack feedback watch --project-id 87 --abbr D4 --history 0For project-wide or unit-wide status monitoring:
ontrack watch --project-id 87ontrack watch --unit-id 1ontrack pdf task --project-id 87 --abbr D4ontrack pdf submission --project-id 87 --abbr D4Custom output directory:
ontrack pdf submission --project-id 87 --abbr D4 --out-dir ./exportsDefault filename format:
<unitCode>_<abbr>_<type>.pdf
For example:
FIT1045_D4_submission.pdf
Simplest form:
ontrack submission upload --project-id 87 --abbr D4 --file ./report.pdfMultiple files:
ontrack submission upload \
--project-id 87 \
--abbr D4 \
--file ./report.pdf \
--file ./demo.mp4Explicit upload key mapping:
ontrack submission upload \
--project-id 87 \
--abbr D4 \
--file file0=./report.pdf \
--file file1=./demo.mp4Upload and post a comment:
ontrack submission upload \
--project-id 87 \
--abbr D4 \
--file ./report.pdf \
--comment "Updated submission with revised report."Set the trigger explicitly:
ontrack submission upload \
--project-id 87 \
--abbr D4 \
--file ./report.pdf \
--trigger ready_for_feedbacksubmission upload- designed for normal submission flows
- infers
trigger=need_helpwhen the current task status isworking_on_itorneed_help - otherwise leaves trigger handling to server defaults
submission upload-new-files- closer to a "new evidence" flow
- does not apply a default trigger automatically
If the task definition exposes upload requirements, the CLI maps files to the required keys such as file0, file1, and so on.
Rules:
- at least one
--fileis required - if a task requires two files, you must provide two files
- if you mix explicit keys and plain paths, the CLI fills remaining keys in definition order
- if
--task-idand--abbrare both provided, they must resolve to the same task - if
--all-tasksis provided, do not combine it with--task-idor--abbr
The default output mode is a colored terminal table. Important fields are highlighted:
- header: bold cyan
task: boldunit: cyanstatus: color-coded by statusdue: highlighted when a deadline is close or overdue
ontrack login now renders guided SSO status with styled terminal panels and event lines:
- guided SSO start panel
- MFA method selection panel (plus a plain-text fallback list)
- Okta Verify number challenge panel with highlighted numbers
- login success panel with account, role, and suggested next commands
Force color:
FORCE_COLOR=1 ontrack inboxDisable color:
NO_COLOR=1 ontrack inboxUse --json for scripting, automation, or downstream tooling:
ontrack tasks --project-id 87 --jsonwatch and feedback watch do not emit a single final JSON array. They emit multiple JSON documents over time as a stream.
That makes them a better fit for:
jq- custom Node scripts
- log collectors
- stream-oriented automation
| Variable | Purpose | Notes |
|---|---|---|
ONTRACK_BASE_URL |
Override the default API base URL | Defaults to Monash OnTrack API |
ONTRACK_BROWSER_PATH |
Set the browser executable path for SSO automation | Highest priority browser override |
FORCE_COLOR |
Force colored terminal output | Example: FORCE_COLOR=1 |
NO_COLOR |
Disable colored output | Useful for plain logs or CI |
XDG_CONFIG_HOME |
Override the config root on Linux and macOS | Affects session storage |
APPDATA |
Config root on Windows | Affects session storage |
Default session file location:
- macOS / Linux:
~/.config/ontrack-cli/session.json - Windows:
%APPDATA%\ontrack-cli\session.json
The CLI creates the directory automatically and writes the session file with stricter permissions where the platform allows it.
Default PDF download directory:
./downloads
The real smoke test script uses:
./downloads-smoke
Compiled output is written to:
dist/
npm installnpm run buildnpm testnpm run dev -- tasks --project-id 87npm run smoke:real -- --project-id 87 --abbr D4This script verifies:
auth-methodwhoamidoctordiscoverdiscover --probeprojectstaskstask showunitsproject showunit showunit tasksinboxfeedback listpdf taskpdf submissionwatchfeedback watch
It currently avoids upload actions on purpose, to reduce the chance of mutating real account data during a smoke check.
The repository currently includes:
- api.test.ts
- API client auth headers
- error handling
- PDF download
- submission upload
- comment posting
- cli-helpers.test.ts
- task selector parsing
- watch diff logic
- filename rules
- upload argument parsing
- auto-login.test.ts
- SSO credential capture helpers
- discovery.test.ts
- frontend bundle route and API extraction
- utils.test.ts
- base URL and redirect URL utilities
Minimum recommended validation before release:
npm test
npm run buildIf you have a valid real session, add:
npm run smoke:real -- --project-id <id> --abbr <abbr>.
├── always-ontrack-logo.png # README logo
├── package.json # npm metadata and scripts
├── scripts/
│ └── smoke-real.mjs # real-account smoke verification
├── src/
│ ├── cli.ts # command router and top-level handlers
│ └── lib/
│ ├── api.ts # API client, downloads, uploads
│ ├── auto-login.ts # browser-based SSO credential capture
│ ├── discovery.ts # frontend surface discovery and probe
│ ├── session.ts # local session persistence
│ ├── types.ts # shared types
│ └── utils.ts # selectors, formatting, colors, helpers
├── test/ # unit tests
└── tsconfig.json # TypeScript build config
Some accounts do not have direct access to /units. This is an account capability difference, not a CLI crash.
The current implementation tries to derive unit data from /projects when necessary. In practice, these commands are usually more reliable:
ontrack projects
ontrack tasksThis means /units/:id/tasks/inbox is not accessible for the current account, and the CLI has already fallen back to a task list derived from /projects.
Typical reasons:
- the account has limited permissions
- the endpoint is role-restricted
- the inbox API is unavailable for that unit
Set the browser path explicitly:
ONTRACK_BROWSER_PATH="/path/to/browser" ontrack loginOr install bundled Chromium support manually:
npx playwright install chromiumontrack login already attempts this installation automatically on first run when possible.
The cached session has expired. Re-authenticate:
ontrack logout
ontrack loginThe abbreviation is not unique inside that project. Use --task-id instead:
ontrack task show --project-id <id> --task-id <id>Inspect the task in JSON and then upload with explicit keys:
ontrack task show --project-id 87 --abbr D4 --jsonontrack submission upload \
--project-id 87 \
--abbr D4 \
--file file0=./report.pdf \
--file file1=./demo.mp4Force color manually:
FORCE_COLOR=1 ontrack tasks --project-id 87The current version already supports real-account-driven read flows, live feedback tracking, PDF download, and upload operations, but it still keeps write capabilities intentionally narrow.
Supported now:
- login
- units, projects, tasks, and inbox reads
- feedback reads and live conversation watch
- task and submission PDF download
- submission upload
- new evidence or new file upload
- posting a comment after upload
Not expanded yet:
- broader task status mutations
- more complex staff-side write workflows
- interactive task pickers
- persistent long-term watch deduplication across processes
If you plan to extend the project, the main entry point is cli.ts and the protocol layer is api.ts.
