Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>prairielearn-navigatorNew to Visual Studio Code? Get it now.
prairielearn-navigator

prairielearn-navigator

sybelblue

|
2 installs
| (0) | Free
provides definitions and inlay hints for prairielearn assessments and questions
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

PrairieLearn Navigator

A prototype VS Code extension that provides definitions and inlay hints for PrairieLearn assessments and questions.

This extension is still experimental and may change or break.

Features

  • Diagnostics for course files: PrairieLearn schema validation for a chosen PrairieLearn version; missing, incomplete, duplicate, and unused questions; question directories PrairieLearn can't load for lack of an info.json; unused tags and assessment sets; and every file a course names that doesn't exist (see the rules).
  • For every one of those file references:
    • jump to the file: go-to-definition and Ctrl/Cmd-click;
    • find its uses: Find All References on a reference or inside the referenced file, a "N uses" CodeLens at the top of referenced files, and PrairieLearn: Find Uses of File in the explorer's context menu (works for images too).
  • When a question directory, or an ancestor containing questions, is moved within questions/ in VS Code, offer to update all affected assessment IDs, alternative IDs, and question templates as part of the same operation.
  • Preview or apply the same semantic QID reference updates from the CLI with prairielearn-navigator rename-qids.
  • Completions, code lenses, and quick fixes that create missing files, ignore one diagnostic occurrence in a file, or open that rule's severity setting.
  • UUID completions in PrairieLearn info files, generated with uuidgen by default, plus quick fixes for a missing or invalid root uuid field.
  • Editor-title buttons for switching between a question's question.html, info.json, and server.py. The current or missing source file remains visible but is disabled.

Settings

Set these in .vscode/settings.json. They take precedence over the course's .pl-navigator.jsonc, which the CLI also reads. User-level settings rank below that file.

Setting
prairielearn-navigator.plVersion latest (default), a date (YYYY-MM-DD), or a commit sha
prairielearn-navigator.schemaCacheDir Schema cache, relative to the workspace folder. Default: the extension's storage
prairielearn-navigator.uuidCommand Shell command for UUID completions. It must print one UUID. Default: uuidgen
prairielearn-navigator.rules Rule id → off / info / warning / error
prairielearn-navigator.diagnostics.<rule-id> Dedicated severity dropdown for every built-in rule: default / off / info / warning / error. A non-default named setting overrides the rules object.
prairielearn-navigator.excludes Glob patterns of files never to check, relative to the workspace folder. Adds to the course file's excludes rather than replacing them.

The older unusedQuestions, unusedTags, unusedAssessmentSets, and missingQuestionInfo setting names remain supported as aliases. The uniform diagnostics.* setting takes precedence when both specify a severity in the same scope.

Every PrairieLearn Navigator diagnostic offers Ignore this violation in this file, which adds a suppression to .pl-navigator.jsonc, and Configure severity for …, which opens that rule's dropdown in VS Code Settings. Suppressions use semantic identifiers when available—question ids, tag names, and assessment-set names—and fall back to exact message/occurrence matching. Unused tags and assessment sets can be removed directly; an unused question can be moved to Trash after confirmation.

Run PrairieLearn: Reload Schemas and Config to retry downloads after going back online.

CLI

The extension's diagnostics are also published as a CLI, @sybelblue/prairielearn-navigator, so a course repo can fail CI on them:

npx -y @sybelblue/prairielearn-navigator check --format github

To update references after explicitly renaming one or more QIDs, preview the changes first and then apply them with --write:

npx -y @sybelblue/prairielearn-navigator rename-qids old new topic/one unit/one
npx -y @sybelblue/prairielearn-navigator rename-qids --write old new topic/one unit/one

This command changes semantic QID references only; it never moves question directories or infers moves made by Git or shell tools.

See packages/cli/README.md for options and a GitHub Actions example.

The npm package also has a typed, headless createQuestionFileResolver API for applications that need normalized question-local, inherited-template, and course-level file usage without invoking the CLI.

Development

Common commands are in the Makefile. Run make help to list them:

make install     # npm ci
make test-all    # lint, CLI tests (Vitest), extension tests (VS Code)
make package     # build a .vsix
make check ARGS="path/to/course"   # run the CLI against a course

To try every feature, run the Run Extension (Demo Course) launch configuration (F5 in the Run and Debug view). It opens demo/course, a small course with deliberate problems, and its TOUR.md. This repo's own .vscode/settings.json excludes demo/ and the broken test fixtures, so they don't fill the Problems panel while you work on the extension itself.

Adding a rule

Other rules live in src/core/rules/registry.ts. Each rule id maps to an ordered list of [plVersionRange, courseRelativeGlob, impl] entries, and for each file the first entry that matches both runs. Version ranges compare dates, e.g. ">=2025-04-17". When PrairieLearn changes, add a newer entry above the old one instead of editing it. Also add a new rule id to schemas/pl-navigator.schema.json; a test checks the two agree.

Every JSON field and element attribute that names a file is one entry in src/core/references/specs.ts. Each entry gets its existence rule, jump-to-file, and uses from that table, so adding a reference is one entry there plus its rule id in the config schema. Tests check every entry has a registered rule, a schema entry, and a fixture.

Releasing

The extension and the npm CLI (@sybelblue/prairielearn-navigator) share one version. To release, put your notes under ## [Unreleased] in CHANGELOG.md, then run:

make publish patch   # or: minor / major

This:

  1. Checks you're on a clean main that matches origin/main, and runs lint and all tests.
  2. Bumps both package.json files, dates the CHANGELOG entry, commits, tags vX.Y.Z, and pushes.
  3. Creates the GitHub release, which runs publish-npm.yml to stage the CLI on npm (with provenance), and waits for that run.
  4. Opens your npmjs.com Staged Packages page so you can review and approve the version with 2FA. The script then waits for quit or check published; the latter verifies the version is public before continuing.
  5. Publishes the extension with vsce publish, only once the npm version is public.

Use make publish patch DRY_RUN=1 to run the checks and print the release steps without changing anything.

If a step after the push fails, the tag and GitHub release already exist but the extension isn't published. Fix the problem (for a failed workflow, rerun it with gh run rerun <id>), then run make publish-vscode from the release commit. It opens the staged npm version for approval if needed, then publishes the extension after you confirm npm has made the version public. If you chose quit at the npm prompt, use this command when you're ready to resume; it reopens the Staged Packages page unless the version is already public.

One-time setup:

  • gh auth login
  • Sign in to npmjs.com with 2FA enabled, needed to approve staged publishes
  • npx vsce login sybelblue, using a Marketplace personal access token
  • On npmjs.com, the package's trusted publisher must be GitHub Actions, SybelBlue/prairielearn-navigator, workflow publish-npm.yml, environment npm, with stage-publish permission.
  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft