Pawtograder CLI (Beta)
The Pawtograder CLI provides command-line tools for instructors and site administrators to manage courses, copy assignments between semesters, import rubrics and submission data, and perform bulk repository operations.
The CLI is in beta. Commands and options may change in future releases.
Installation
The CLI ships inside the platform repository and runs via npm scripts. Run it from the repository root:
npm run cli -- <command> [options]
For repository commands, use the shortcut:
npm run cli:repos -- <subcommand> [options]
Prerequisites
- Node.js 18 or later
- SSH access to GitHub (for repository operations)
- A Pawtograder API token with CLI access
Authentication
Before using the CLI, authenticate with an API token.
Creating an API token
- Log in to the Pawtograder web app.
- Navigate to User Menu → API Tokens.
- Create a new token with type “CLI” or “MCP + CLI”.
- Copy the token. It starts with
mcp_.
Logging in
You’ll be prompted to enter your API token. The token is stored securely in ~/.pawtograder/credentials.json.
You can also provide the token directly:
npm run cli -- login --token mcp_your_token_here
For custom deployments, specify the API URL:
npm run cli -- login --url https://your-instance.com/functions/v1/cli
Checking authentication
Logging out
Commands
Classes
List all classes you have access to:
npm run cli -- classes list
Show details for a specific class:
npm run cli -- classes show <class-id-or-slug>
The identifier can be a class ID, slug, or name.
Assignments
List assignments for a class:
npm run cli -- assignments list --class <class-id-or-slug>
Show assignment details:
npm run cli -- assignments show <assignment-id-or-slug> --class <class-id-or-slug>
Copy assignments
Copy assignments between classes. Supports single-assignment copy, full-course copy, and schedule-driven copy:
# Copy a single assignment
npm run cli -- assignments copy \
--source-class cs3500-fall-2025 \
--target-class cs3500-spring-2026 \
--assignment hw1 \
--workdir /tmp/pawtograder-repos
# Copy all assignments
npm run cli -- assignments copy \
--source-class cs3500-fall-2025 \
--target-class cs3500-spring-2026 \
--all \
--workdir /tmp/pawtograder-repos
# Copy with a schedule CSV (custom due dates)
npm run cli -- assignments copy \
--source-class cs3500-fall-2025 \
--target-class cs3500-spring-2026 \
--schedule schedule.csv \
--workdir /tmp/pawtograder-repos
The copy command handles:
- Assignment record creation
- Rubrics (deep copy)
- Autograder configuration
- Self-review settings
- Handout and solution repository content (via local SSH git)
--workdir is required for repository content copying. The CLI uses local SSH git operations to avoid Supabase timeout limits.
Options:
| Option | Description |
|---|
--source-class | Source class (ID, slug, or name) |
--target-class | Target class (ID, slug, or name) |
--assignment | Single assignment to copy (ID or slug) |
--schedule | CSV file with assignment slugs/titles and date overrides |
--all | Copy all assignments from the source class |
--workdir | Local directory for git clones (required unless --skip-repos) |
--dry-run | Preview changes without making them |
--skip-repos | Skip git repository operations |
--skip-rubrics | Skip rubric copying |
--skip-surveys | Skip copying surveys linked to assignments |
--concurrency | Parallel clone/fetch operations (1-8, default 4) |
--delay-ms | Delay between clone batches in milliseconds |
--debug | Enable server-side timing logs |
Create a CSV with assignment slugs and new due dates:
slug,due_date
hw-01,2026-09-15T23:59:00
hw-02,2026-09-22T23:59:00
project-01,2026-10-01T23:59:00
Delete an assignment
npm run cli -- assignments delete <assignment-id-or-slug> --class <class-id-or-slug>
Add --force to skip the confirmation prompt.
Rubrics
Import and export rubrics in YAML format.
List rubrics for an assignment:
npm run cli -- rubrics list \
--assignment <assignment-id-or-slug> \
--class <class-id-or-slug>
Export a rubric to YAML:
npm run cli -- rubrics export \
--assignment hw1 \
--class cs3500-spring-2026 \
--type grading \
--output hw1-rubric.yml
Import a rubric from YAML:
npm run cli -- rubrics import \
--assignment hw1 \
--class cs3500-spring-2026 \
--file hw1-rubric.yml \
--type grading
Use --dry-run to preview the import without making changes.
Surveys
Copy surveys between classes:
# Copy a single survey
npm run cli -- surveys copy \
--source-class cs3500-fall-2025 \
--target-class cs3500-spring-2026 \
--survey "Midterm Feedback"
# Copy all surveys
npm run cli -- surveys copy \
--source-class cs3500-fall-2025 \
--target-class cs3500-spring-2026 \
--all
# Link copied survey to a target assignment
npm run cli -- surveys copy \
--source-class cs3500-fall-2025 \
--target-class cs3500-spring-2026 \
--survey "HW1 Reflection" \
--target-assignment hw1
List surveys for a class:
npm run cli -- surveys list --class cs3500-fall-2025
Flashcards
List flashcard decks:
npm run cli -- flashcards list --class <class-id-or-slug>
Copy flashcard decks between classes:
npm run cli -- flashcards copy \
--source-class cs3500-fall-2025 \
--target-class cs3500-spring-2026 \
--all
Submissions
List submissions for an assignment:
npm run cli -- submissions list \
--class cs3500-fall-2025 \
--assignment hw1
Batch import submission comments from autograder results:
# Add-only import
npm run cli -- submissions comments import \
--class cs3500-spring-2026 \
--assignment hw1 \
--file batch-results.json \
--author-profile-id <uuid>
# Sync (insert new + soft-delete missing)
npm run cli -- submissions comments sync \
--class cs3500-spring-2026 \
--assignment hw1 \
--file batch-results.json \
--rubric-part-id <id>
Use --rubric-part-id instead of --author-profile-id to attribute comments to review assignment assignees.
Import artifacts
Upload submission artifact blobs from a manifest:
npm run cli -- submissions artifacts import \
--class cs3500-spring-2026 \
--assignment hw1 \
--file manifest.json \
--batch-size 5
Options:
--overwrite – Replace existing artifacts with the same name
--dry-run – Preview counts only
--batch-size <n> – Artifacts per API request (default 5)
The manifest is a JSON file with this structure:
{
"artifacts": [
{
"submission_id": 123,
"name": "coverage-report",
"data": {
"format": "html",
"display": "Coverage Report"
},
"content_base64": "PGh0bWw+Li4uPC9odG1sPg=="
}
]
}
You can use content_file instead of content_base64 to reference an external file:
{
"submission_id": 123,
"name": "coverage-report",
"data": { "format": "html", "display": "Coverage Report" },
"content_file": "./reports/coverage-123.html"
}
Help requests
List office hours help requests:
npm run cli -- help-requests list --class cs3500-fall-2025
Discussions
List discussion board threads:
npm run cli -- discussions list --class cs3500-fall-2025
Reviews
List peer and grading review assignments:
npm run cli -- reviews list \
--class cs3500-fall-2025 \
--assignment hw1
Repository operations
Repository commands use local SSH git operations for reliability and performance.
Repository commands require SSH access to GitHub. Ensure your SSH keys are configured and you have access to the course organization.
List repositories
npm run cli:repos -- list --class <class-id-or-slug> --assignment <assignment-id-or-slug>
Sync grade workflow
Synchronize .github/workflows/grade.yml from the handout repository to all student repositories:
npm run cli:repos -- sync-grade-workflow \
--class cs3500-spring-2026 \
--assignment hw1 \
--workdir /tmp/pawtograder-repos \
--concurrency 2
This command:
- Fetches the canonical
.github/workflows/grade.yml from the handout repository.
- Clones all student repositories locally via SSH.
- Updates the workflow file in each repository.
- Commits and pushes changes.
Options:
--dry-run – Preview which repos would be updated
--concurrency <n> – Parallel git operations (1-8, default 2)
--delay-ms <n> – Delay between clone batches
Cross-assignment copy
Copy files from source assignment repositories to target assignment repositories after the source due date. This is useful for sequential assignments where students build on previous work:
npm run cli:repos -- copy-after-source-due \
--class cs3500-spring-2026 \
--source-assignment hw1 \
--target-assignment hw2 \
--workdir /tmp/pawtograder-repos \
--concurrency 2
The CLI:
- Verifies the source assignment due date has passed.
- Clones source and target repositories for each student or group.
- Copies files using rsync (excluding
.git).
- Commits and pushes to target repositories.
Options:
--dry-run – Preview with rsync -n only
--mirror-delete – Pass rsync --delete (still excludes .git)
--concurrency <n> – Parallel operations (1-8, default 2)
--delay-ms <n> – Delay between batches
Common options
Most commands support these options:
--dry-run – Preview changes without making them
--help – Show command-specific help
--class or -c – Specify a class by ID, slug, or name
--assignment or -a – Specify an assignment by ID or slug
Environment variables
| Variable | Description |
|---|
PAWTOGRADER_HTTP_TIMEOUT_MS | HTTP request timeout in milliseconds. Set to 600000 (10 minutes) for large operations. |
DEBUG | Set to 1 to enable verbose HTTP logging. |
export PAWTOGRADER_HTTP_TIMEOUT_MS=600000
export DEBUG=1
npm run cli -- <command>
API token scopes
CLI tokens require specific scopes:
cli:read – Read-only operations (list, show, export)
cli:write – Write operations (copy, import, delete)
Create tokens with appropriate scopes in the web UI under User Menu → API Tokens.
Common workflows
Semester rollover
Copy an entire course to a new semester:
# 1. Copy all assignments with new dates
npm run cli -- assignments copy \
--source-class cs3500-fall-2025 \
--target-class cs3500-spring-2026 \
--schedule spring-2026-schedule.csv \
--workdir ./repos
# 2. Copy surveys
npm run cli -- surveys copy \
--source-class cs3500-fall-2025 \
--target-class cs3500-spring-2026 \
--all
# 3. Copy flashcards
npm run cli -- flashcards copy \
--source-class cs3500-fall-2025 \
--target-class cs3500-spring-2026 \
--all
Bulk rubric updates
# 1. Export the current rubric
npm run cli -- rubrics export \
--assignment hw1 \
--class cs3500-spring-2026 \
--output hw1-rubric.yml
# 2. Edit hw1-rubric.yml locally
# 3. Preview changes
npm run cli -- rubrics import \
--assignment hw1 \
--class cs3500-spring-2026 \
--file hw1-rubric.yml \
--dry-run
# 4. Apply changes
npm run cli -- rubrics import \
--assignment hw1 \
--class cs3500-spring-2026 \
--file hw1-rubric.yml
Repository maintenance
# Update grade workflows across all student repos
npm run cli:repos -- sync-grade-workflow \
--class cs3500-spring-2026 \
--assignment hw1 \
--workdir ./repos \
--dry-run
# Copy starter code from hw1 to hw2 after hw1 due date
npm run cli:repos -- copy-after-source-due \
--class cs3500-spring-2026 \
--source-assignment hw1 \
--target-assignment hw2 \
--workdir ./repos \
--dry-run
Best practices
- Use dry-run first. Preview changes with
--dry-run before executing.
- Export backups. Export rubrics before importing new versions.
- Batch size. For artifact imports, reduce
--batch-size if requests time out.
- Dedicated workdir. Use a dedicated directory for
--workdir to avoid conflicts.
- Concurrency. Start with the default and adjust based on network performance.
Troubleshooting
Authentication errors
If you see “Not logged in” or “Authentication failed”:
- Run
npm run cli -- login to re-authenticate.
- Verify your token is valid in the web UI (User Menu → API Tokens).
- Ensure your token has the correct scopes (
cli:read or cli:write).
Common HTTP errors:
- 401 Unauthorized – Token expired or revoked. Log in again.
- 403 Forbidden – Token lacks required scopes.
- 504 Gateway Timeout – Operation took too long. Increase the timeout or use smaller batches.
Command not found
Run the CLI from the platform repository root and make sure dependencies are installed with npm install.
Timeout errors
For large operations (copying many assignments, importing large artifacts):
- Set a longer timeout:
PAWTOGRADER_HTTP_TIMEOUT_MS=600000 npm run cli -- ...
- Use smaller batch sizes (for example,
--batch-size 1 for artifact imports).
- Use
--dry-run first to validate before running the full operation.
For assignment copy operations, the CLI validates and fixes existing assignments on retry, so you can safely re-run failed commands.
Repository clone failures
If SSH git operations fail:
- Verify SSH keys are configured:
ssh -T git@github.com
- Check that you’re a member of the course’s GitHub organization.
- Retry with lower
--concurrency (try 2 or 1).
- Use
--delay-ms 1000 to add delays between batches.
Connection reset errors
The CLI automatically retries git operations that fail due to connection resets. If failures persist:
- Check your network connection.
- Verify GitHub is accessible.
- Reduce
--concurrency to avoid rate limits.
Getting help
For detailed help on any command:
npm run cli -- <command> --help
For example:
npm run cli -- assignments --help
npm run cli -- assignments copy --help