Skip to main content

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

  1. Log in to the Pawtograder web app.
  2. Navigate to User Menu → API Tokens.
  3. Create a new token with type “CLI” or “MCP + CLI”.
  4. Copy the token. It starts with mcp_.

Logging in

npm run cli -- login
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

npm run cli -- whoami

Logging out

npm run cli -- logout

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:
OptionDescription
--source-classSource class (ID, slug, or name)
--target-classTarget class (ID, slug, or name)
--assignmentSingle assignment to copy (ID or slug)
--scheduleCSV file with assignment slugs/titles and date overrides
--allCopy all assignments from the source class
--workdirLocal directory for git clones (required unless --skip-repos)
--dry-runPreview changes without making them
--skip-reposSkip git repository operations
--skip-rubricsSkip rubric copying
--skip-surveysSkip copying surveys linked to assignments
--concurrencyParallel clone/fetch operations (1-8, default 4)
--delay-msDelay between clone batches in milliseconds
--debugEnable server-side timing logs

Schedule file format

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

Import or sync comments

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:
  1. Fetches the canonical .github/workflows/grade.yml from the handout repository.
  2. Clones all student repositories locally via SSH.
  3. Updates the workflow file in each repository.
  4. 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:
  1. Verifies the source assignment due date has passed.
  2. Clones source and target repositories for each student or group.
  3. Copies files using rsync (excluding .git).
  4. 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

VariableDescription
PAWTOGRADER_HTTP_TIMEOUT_MSHTTP request timeout in milliseconds. Set to 600000 (10 minutes) for large operations.
DEBUGSet 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

  1. Use dry-run first. Preview changes with --dry-run before executing.
  2. Export backups. Export rubrics before importing new versions.
  3. Batch size. For artifact imports, reduce --batch-size if requests time out.
  4. Dedicated workdir. Use a dedicated directory for --workdir to avoid conflicts.
  5. Concurrency. Start with the default and adjust based on network performance.

Troubleshooting

Authentication errors

If you see “Not logged in” or “Authentication failed”:
  1. Run npm run cli -- login to re-authenticate.
  2. Verify your token is valid in the web UI (User Menu → API Tokens).
  3. 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):
  1. Set a longer timeout: PAWTOGRADER_HTTP_TIMEOUT_MS=600000 npm run cli -- ...
  2. Use smaller batch sizes (for example, --batch-size 1 for artifact imports).
  3. 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:
  1. Verify SSH keys are configured: ssh -T git@github.com
  2. Check that you’re a member of the course’s GitHub organization.
  3. Retry with lower --concurrency (try 2 or 1).
  4. 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:
  1. Check your network connection.
  2. Verify GitHub is accessible.
  3. 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