CS50xUrmia Assistant
CS50xUrmia is an independent, beginner-friendly VS Code extension for the CS50x learning workflow. It turns assignment selection, safe workspace setup, official check50 and submit50 use, and optional bring-your-own-key AI help into a focused interface for VS Code, GitHub Codespaces, and compatible browser-hosted VS Code deployments.
It is not an official Harvard or CS50 product. It contains no solutions, answer keys, shared AI credentials, credential collection, telemetry, or custom submission backend.
Built by Behrad Ghasemi.
Purpose
The extension gives a student one simple workflow:
- Open CS50xUrmia from the Activity Bar.
- Select a week and assignment.
- Create a protected workspace from an empty file or the official CS50 starter ZIP.
- Write code.
- Run official
check50 where the host supports it.
- Ask an educational AI assistant using explicitly selected context.
- Start official, interactive
submit50.
Features
- Activity Bar dashboard with week, assignment, workspace, check, submit, AI, settings, and about sections.
- Validated, versioned CS50x 2026 assignment manifest with official-spec requirement summaries, concepts, planning prompts, remote HTTPS updates, and optional SHA-256 pinning.
- A per-assignment Pseudocode Planner for inputs, outputs, algorithm steps, edge cases, and manual tests. Plans are student-authored and never inserted into source files.
- Cross-platform filesystem operations through
vscode.workspace.fs; no hard-coded operating-system paths.
- Official starter ZIP downloads only from
https://cdn.cs50.net, with path traversal, file count, per-file, compressed-size, and extracted-size limits.
- Preflight conflict handling: Keep Existing, Replace, or Cancel. Cancel writes no starter files; replacement is always explicit.
- Automatic assignment detection from workspace paths, with manual selection always available.
- Official
check50 integration. The remote Node host captures and parses output; a web host uses Terminal Shell Integration when available, then falls back honestly to a visible terminal.
- Official
submit50 integration in a visible interactive terminal, preserving CS50 authentication, file review, and confirmation.
- CS50 tool detection plus an explicit Install CS50 Tools workflow. It runs the fixed official-package command in a visible terminal only after confirmation; it never silently changes the system.
- Modular OpenAI, Anthropic, Google Gemini, and OpenAI-compatible AI providers.
- API keys stored in VS Code
SecretStorage, never in source code, .env, workspace files, or settings.json.
- Explicit AI context controls for selected code, current file, diagnostics, check50 output, and assignment metadata. The entire project is never uploaded automatically.
- Teaching-focused system prompt that gives explanations and incremental hints instead of complete graded solutions by default.
- Editor context actions for explaining code, finding a bug, giving a hint, and improving readability.
- Readability suggestions use an explicit Preview/Apply/Cancel flow and verify the source selection has not changed before applying.
- Strict webview Content Security Policy and allowlisted, schema-validated messages.
- No telemetry and no CS50xUrmia backend.
- Localization-ready command strings (
package.nls.json) and centralized extension strings (src/localization/en.ts).
Prerequisites
- Node.js 20 or later for development (Node.js 22 LTS recommended).
- npm 10 or later.
- VS Code 1.93 or later.
- A trusted workspace to create files or run CS50 tools.
- For CS50 integration: Python 3, pip, and Git. The official tools are normally preinstalled in the CS50 Codespace at
cs50.dev; the extension can offer a confirmed terminal installation elsewhere.
- On Windows, the official CS50 documentation requires WSL. Open the project in a VS Code WSL window before installing or running the tools.
- For AI: the student's own provider API key. No shared key is included.
Setup
git clone https://github.com/justbehrad/cs50xurmia.git
cd cs50xurmia
npm install
npm run compile
Repository links in the extension metadata point to justbehrad/cs50xurmia. If the project is hosted under a different repository name, update homepage, repository, and bugs in package.json before publishing.
Environment variables
The extension itself requires no environment variables and never reads .env.
.env.example contains only an optional maintainer-side VSCE_PAT placeholder for Marketplace publishing. Never commit the populated file.
Running locally
- Open the project in VS Code.
- Run
npm install and npm run compile.
- Open Run and Debug.
- Choose Run Extension (Node/Remote) to test the remote/desktop entry or Run Extension (Web Worker) to exercise the browser entry.
- In the Extension Development Host, open a disposable folder, trust it, and select the CS50xUrmia Activity Bar icon.
For a browser-hosted development instance, install the official @vscode/test-web runner and point it at the project:
npx @vscode/test-web --extensionDevelopmentPath=.
Network behavior in that pure browser host is subject to browser CORS rules.
Development commands
npm install
npm run compile
npm run watch
npm test
npm run lint
npm run package
npm run check performs linting, strict type-checking, tests, and both production bundles.
Architecture
The published package is hybrid. The same browser-safe application code is bundled behind two small entry points:
dist/web/extension.js: VS Code web extension host; no Node APIs.
dist/node/extension.js: remote/desktop workspace extension host; adds a no-shell check50 process runner.
In a browser-connected GitHub Codespace, extensionKind: ["workspace", "ui"] lets VS Code prefer the remote workspace host. In a pure vscode.dev-style environment, the browser entry runs instead.
flowchart TD
UI["Dashboard and editor commands"] --> Core["Validated shared services"]
Core --> FS["VS Code workspace.fs"]
Core --> Host{"Extension host"}
Host -->|"Codespace remote host"| Process["check50 process / submit50 terminal"]
Host -->|"Browser web host"| Terminal["Shell Integration or visible terminal"]
Core --> AI["Student-selected AI provider"]
Important modules:
src/core: manifest, path, archive, overwrite, check output, and command policies.
src/services: assignment selection, workspace, tool setup, check, submit, pseudocode, AI, context, and proposals.
src/platform: remote Node and web-host command runners plus VS Code filesystem adapter.
src/providers: provider adapters with bounded HTTP responses and redacted errors.
src/security: SecretStorage wrapper, URL/model validation, and redaction.
src/webviews: CSP-protected dashboard, pseudocode planner, AI, and settings UI.
manifests/cs50x-2026.json: metadata, concise non-solution guidance, and official starter locations.
No backend is required or included.
Configuration
Open CS50xUrmia: Open Settings or VS Code Settings and search for CS50xUrmia.
| Setting |
Default |
Purpose |
cs50xurmia.course.version |
2026 |
Active course manifest year. |
cs50xurmia.course.manifestUrl |
empty |
Optional independent HTTPS manifest update. |
cs50xurmia.course.manifestSha256 |
empty |
Optional required lowercase SHA-256 digest for that remote manifest. |
cs50xurmia.workspace.pathPattern |
cs50x/{version}/week{week} |
Workspace-relative assignment parent. Absolute paths and .. are rejected. |
cs50xurmia.workspace.autoOpen |
true |
Opens the assignment main file after creation. |
cs50xurmia.workspace.autoDetect |
true |
Detects an assignment directory in the active path. |
cs50xurmia.ai.provider |
openai |
openai, anthropic, gemini, or openai-compatible. |
cs50xurmia.ai.model |
gpt-5 |
Provider model identifier. |
cs50xurmia.ai.baseUrl |
OpenAI API |
Used for OpenAI-compatible/custom providers. Official providers use their official endpoints. |
cs50xurmia.ai.temperature |
0.2 |
Provider-supported response variability. |
cs50xurmia.ai.timeoutSeconds |
45 |
Request timeout, limited to 5–120 seconds. |
Updating assignment data independently
- Copy the schema used by
manifests/cs50x-2026.json.
- Use only current official CS50 assignment pages and
cdn.cs50.net starter ZIPs. Every assignment needs a concise guide with overview, requirements, concepts, and pseudocodePrompts; do not include solutions.
- Host the JSON over HTTPS.
- Set
cs50xurmia.course.manifestUrl.
- Prefer calculating
sha256sum manifest.json and setting the result as cs50xurmia.course.manifestSha256.
Remote manifests are capped at 1 MB and fully validated before use. Invalid updates fall back to the last validated or bundled copy. A new manifest year needs no code change; select its year and URL in settings. A bundled offline copy for that year requires an extension release.
Workspace generation
Empty-file assignments create only the files the official specification tells the student to create. Archive assignments download the official ZIP and extract it under the configured workspace-relative directory.
Existing files are checked before any starter content is written. Keep Existing is the first and recommended action. Replace requires a modal confirmation for each conflict. Cancel writes no starter files.
Complexity for f starter files and b extracted bytes is O(f + b) time and O(b) peak memory because ZIP extraction is browser-compatible and bounded. Manifest validation is O(w + a + f) for weeks, assignments, and listed starter paths. Check output parsing is O(c) for c output characters.
CS50, check50, and submit50 integration
CS50xUrmia never reimplements grading or submission.
- In a remote Node extension host,
check50 is invoked as an argument array with shell: false; output is bounded, captured, parsed into passed/failed rows, and also shown raw.
- In a web extension host, Terminal Shell Integration is used when the host exposes it. If unavailable, a visible terminal is opened and the extension clearly says output cannot be captured.
submit50 is always started visibly and interactively. The extension never claims submission succeeded; only official submit50 can do so.
- Tool slugs come from a validated manifest, never directly from webview input.
- If a tool is unavailable, the extension offers Open Terminal, Copy Command, or official documentation instead of showing fabricated results.
- The extension does not inspect GitHub or CS50 credentials. CS50's normal authorization at
submit.cs50.io remains authoritative.
On first use in a trusted remote/desktop workspace, the extension checks both executables and offers setup once if either is missing. It never starts installation without a second modal confirmation. You can also use CS50xUrmia: Verify CS50 Tools and CS50xUrmia: Install CS50 Tools at any time. After confirmation, the extension opens a visible terminal and runs this fixed command:
python3 -m pip install --user check50 submit50
This installs the official Python packages documented by CS50; it does not download an installer script, use sudo, or accept a command from a webview. The user can inspect all output. The extension cannot itself install Python, pip, Git, or WSL. If the command is rejected by a managed Python installation, follow the linked official pip/pipx instructions instead.
In cs50.dev, CS50 says both tools should work after the student has signed into and authorized submit.cs50.io. The extension opens that official page but never reads the resulting credentials.
See TECHNICAL-LIMITATIONS.md for the documented host capability matrix.
AI configuration and use
- Run CS50xUrmia: Configure AI.
- Choose a provider, model, and—only for an OpenAI-compatible provider—an HTTPS base URL.
- Save the non-secret settings.
- Select Configure API Key. VS Code opens a masked native input and stores the value in
SecretStorage; the key never enters the webview.
- Select Test Connection.
- Open the AI Assistant, choose context toggles, enter a question, and select Send.
Provider calls go directly from the active extension host to the selected provider. Known providers use official API endpoints. Custom URLs must use HTTPS (HTTP is accepted only for loopback development), cannot contain URL credentials, and receive only the chosen context plus the teaching prompt. Browser-hosted calls can fail when a provider does not allow the VS Code web origin via CORS; use the remote Codespaces host or a provider that officially supports browser origins.
Privacy
- No telemetry, analytics, tracking identifier, or backend is included.
- GitHub passwords, personal access tokens, OAuth tokens, cookies, and CS50 credentials are never requested, read, or stored.
- AI API keys are scoped to the extension's VS Code
SecretStorage and are not written to workspace files or settings.
- Code is sent only after an explicit AI request and only according to the visible context toggles.
- The entire project is never uploaded automatically.
- Starter and manifest fetches use
credentials: "omit".
Read PRIVACY.md and SECURITY.md for precise data flows and controls.
Security
The extension uses strict CSP webviews, escaped dynamic content, validated message unions, allowlisted CS50 tools, argument-array process execution, safe relative paths, official starter host restrictions, bounded downloads/extraction, response limits, request timeouts, redacted provider errors, SecretStorage, workspace trust checks, and no hidden telemetry.
Do not weaken the HTTPS/host/path checks when adding assignments. Never put solutions or secrets in a manifest. Report vulnerabilities using SECURITY.md.
Testing
npm test
npm run lint
npm run typecheck
npm run compile
The unit suite covers manifest parsing/selection/rejection, workspace directories/files/conflicts/cancellation, ZIP traversal, check parsing, all provider selections, credential handling, invalid keys, network failures, malformed responses, SecretStorage, webview CSP/credit, dashboard messages, assignment selection, AI messages, and settings messages.
Manual release checks should also be performed in both hosts:
- Run the browser bundle and confirm dashboard, settings, offline empty-file creation, and terminal fallback.
- Run inside a disposable GitHub Codespace with official CS50 tools installed.
- Create an empty starter and an archive starter; verify conflict choices.
- Run a real practice
check50 slug and compare parsed and raw output.
- Start
submit50 only against a disposable/test assignment and cancel at its official confirmation prompt.
- Test each AI provider with a personal low-privilege development key, then remove it.
No test in this repository performs a real submission.
Building and packaging
npm install
npm run compile
npm install -g @vscode/vsce
vsce package
Or use the pinned local toolchain:
npm run package
The result is cs50xurmia-0.2.0.vsix. Inspect it before distribution:
vsce ls
unzip -l cs50xurmia-0.2.0.vsix
Installing a .vsix
Desktop or a compatible remote VS Code host:
- Open Extensions.
- Select the
… menu.
- Choose Install from VSIX….
- Select
cs50xurmia-0.2.0.vsix.
- Reload when prompted.
CLI alternative:
code --install-extension cs50xurmia-0.2.0.vsix
In a browser Codespace, upload the VSIX into the Codespace and use Extensions: Install from VSIX… if the deployment exposes that command. Some managed deployments disable third-party or VSIX installation; that is an administrator policy, not something the extension can or should bypass.
Marketplace publishing
Publishing is intentionally not automated.
- Create a Visual Studio Marketplace publisher whose identifier is
behrad-ghasemi, or change publisher in package.json to the publisher you own.
- Verify the repository, homepage, support URL, license, privacy text, icon, README, and assignment manifest.
- Create the publisher-scoped Azure DevOps personal access token required by
vsce; keep it outside the repository.
- Authenticate and publish:
npm install -g @vscode/vsce
vsce login behrad-ghasemi
vsce package
vsce publish
- Install the Marketplace build in a fresh Codespace and a pure web host, then repeat the manual release checks.
Never publish under a name or description that claims official CS50, Harvard, GitHub, Microsoft, or VS Code ownership.
Known limitations
- A pure web extension cannot spawn
check50 or submit50. Terminal Shell Integration may capture check50; otherwise the official command runs visibly with uncaptured output.
- Tool verification and automatic process execution are available in the remote/desktop Node host. A pure web host reports tool state as unknown and can only use a terminal exposed by that deployment.
- The installer can install only the Python packages. It cannot install Python, pip, Git, WSL, or overcome managed-device policy. Windows users must use WSL per CS50's documentation.
submit50 remains interactive and its result is not parsed, by design.
- Browser
fetch is subject to provider CORS policy. Some AI APIs work only from the remote Node host.
- There is no supported API for safely reading CS50/GitHub authorization state. The extension reports tool errors and links to official setup guidance instead.
- Marketplace and VSIX availability in
cs50.dev depends on that managed deployment's current extension policy. No official CS50 document guarantees third-party installation.
- Check output parsing recognizes stable smile/frown/check/cross lines and always retains raw output. A future
check50 format can appear raw until the parser is updated.
- The bundled assignment manifest is a verified point-in-time 2026 copy. CS50 can change assignments; verify and update the external manifest against official pages.
- ZIP extraction uses bounded in-memory data for web compatibility; oversized starter archives are rejected safely.
Troubleshooting
“Open a folder or workspace”
Open a writable folder in VS Code. In Codespaces, open the repository or course workspace rather than an empty browser window.
Workspace is not trusted
Review the folder first, then use VS Code's Workspace: Manage Workspace Trust. File generation and CS50 tool execution are disabled while untrusted.
check50 is unavailable
Run CS50xUrmia: Verify CS50 Tools. If the remote/desktop host reports a missing tool, choose Install CS50 Tools, inspect the visible python3 -m pip command, and wait for it to finish. Then verify again. A plain vscode.dev tab with no terminal cannot install or spawn the CLI; Windows requires a WSL window.
If pip reports success but verification still says missing, open a new terminal or reload the VS Code window so its PATH includes the Python user-scripts directory. Otherwise follow CS50's linked pip/pipx instructions for that operating system.
Check ran but no structured results appeared
Open CS50xUrmia: check50 in the Output panel or the visible terminal. The raw official result is authoritative.
AI says the key is invalid
Open CS50xUrmia Settings, remove and re-enter the key using the masked native prompt, confirm the provider/model, and select Test Connection. The key is never shown back to you.
AI reports a network or CORS error
Confirm the endpoint and network. In a pure browser host, use a provider that supports the web origin or install the extension in the Codespace remote host. Do not use an untrusted proxy.
Remote manifest is rejected
Validate its schema, paths, year, official URLs, size, and optional SHA-256. The extension will retain a last-known-good or bundled manifest rather than accepting unsafe data.
Contribution guide
Read CONTRIBUTING.md. Every change must preserve browser compilation, strict TypeScript, no solutions, no credentials, no hidden telemetry, official CS50 mechanisms, and non-overwrite behavior.
Glossary
- CS50x: Harvard's open-access introduction to computer science.
- Codespace: A GitHub-hosted development environment that can run a remote VS Code extension host.
- Web extension host: VS Code's browser sandbox for extensions; it has no Node.js process or filesystem APIs.
- Remote extension host: The Node.js extension process running inside a remote workspace such as a Codespace.
- check50: CS50's official correctness-checking command-line tool.
- submit50: CS50's official interactive submission command-line tool.
- SecretStorage: VS Code's extension-scoped API for storing secret values outside normal settings and workspace files.
- CSP: Content Security Policy, which restricts what a webview can load or execute.
- CORS: Browser rules controlling whether a web origin may call a remote HTTP API.
- VSIX: The installable archive format for a VS Code extension.
License
MIT. See LICENSE.