User documentation lives in README.md. The contribution workflow is in CONTRIBUTING.md. For a deep dive into the webview architecture, message contracts, and stores, see extension/docs/DEVELOPER-GUIDE.md.
This guide covers building, running, and shipping the extension. The codebase is a React-based webview UI driving a VS Code extension host, bundled with esbuild and communicating over a typed message contract.
- Node.js v22.x or higher
- npm
- VS Code version 1.93.0 or higher
- (Optional, for packaging)
vsce:npm install -g @vscode/vsce
All npm commands run from the extension/ directory.
# 1. Clone
git clone https://github.com/ls1intum/artemis-extension.git
cd artemis-extension/extension
# 2. Install dependencies
npm install
# 3. Compile (type-check + lint + bundle)
npm run compile
# 4. Watch for changes during development
npm run watchThen press F5 in VS Code to launch the extension (see Running Locally).
artemis-extension/
├── README.md # User documentation (also shipped to the stores)
├── DEVELOPER.md # This file
├── CONTRIBUTING.md # Contribution workflow
├── CHANGELOG.md # Single source of truth for release notes
├── extension/ # VS Code extension package (npm root)
│ ├── src/
│ │ ├── extension.ts # Entry point & activation
│ │ ├── extension/ # Extension host (Node.js)
│ │ │ ├── activation/ # Command registration, wiring
│ │ │ ├── api/ # Artemis REST API client
│ │ │ ├── controller/ # Message handling, state, routing
│ │ │ ├── dataCollection/ # Consent-gated data collection
│ │ │ ├── domain/ # Domain model classes
│ │ │ ├── provider/ # Webview providers, CodeLens
│ │ │ ├── services/ # Business logic (auth, iris, telemetry, ui, websocket, workspace)
│ │ │ ├── telemetry/ # Struggle detection & recording pipeline
│ │ │ ├── theia/ # EduIDE/Theia environment detection (data bridge)
│ │ │ ├── types/ # Domain types & ambient shims
│ │ │ └── utils/ # Shared utilities (incl. serverUrl resolution)
│ │ ├── shared/ # Cross-runtime types & message contracts
│ │ └── webview/ # React UI (components, views, stores, hooks, styles)
│ ├── test/ # unit/ (extension host) + react/ (component) tests
│ ├── scripts/ # Packaging & build helpers
│ └── docs/ # DEVELOPER-GUIDE.md, ADRs, diagrams
└── recording-viewer/ # Standalone session recording viewer (Vite/React)
The codebase spans three runtimes:
extension/(host, Node.js) - services, providers, controllers, the REST client, and the telemetry pipeline.webview/(React) - page-level views and components rendered in VS Code webview panels, with Zustand stores hydrated from extension messages.shared/- types and the typed message contracts used by both sides.
UI styling uses CSS Modules scoped per component, integrated with VS Code themes via native CSS custom properties.
For the detailed walkthrough (adding a view, the message-contract system, store architecture, the build pipeline), read extension/docs/DEVELOPER-GUIDE.md.
Run from extension/:
| Script | Purpose |
|---|---|
npm run compile |
Type-check, lint, and bundle (dev) |
npm run watch |
Watch mode (esbuild + tsc) |
npm run package |
Production bundle (type-check + lint + esbuild --production) |
npm run package:vsix |
Build and package the full marketplace .vsix |
npm run lint |
ESLint over src and test |
npm run check-types |
Type-check without emitting |
npm run test:vscode |
All extension host tests (vscode-test). What CI runs |
npm run test:struggle |
Struggle detection tests only (a subset of the above) |
npm run test:react |
React component tests (vitest) |
npm run test:all |
Extension host + React tests |
- Open the project in VS Code.
- Press
F5(or Run → Start Debugging). - A new Extension Development Host window opens with the extension loaded.
- Click the Artemis icon in the activity bar to test.
- Run Extension (recommended) - starts watch mode and recompiles on change.
- Run Extension (No Watch) - runs without auto-recompilation.
- Run Extension (Recording) - starts the local-recording watch build (session recorder and consent flow present) for recorder/replay development. Not for release builds.
- Extension Tests - compiles tests, then runs the suite.
- Set breakpoints in the gutter next to TypeScript line numbers.
- Inspect via the Debug Console, Variables, and Call Stack panels.
- Check the "Artemis" / "Extension Host" output panels for logs.
- Use Restart (
Ctrl+Shift+F5) to reload the extension with changes.
The release ships two packages from the same source, plus a third local-only variant for recorder development:
- Full build (VS Marketplace) - built by
scripts/package-desktop.jsfrom a staging directory usingscripts/generate-clean-manifest.js. The Desktop VSIX now also excludes the session recorder and the data-collection consent flow while keeping the struggle-detection engine;scripts/verify-clean-bundle.jsfails the build if the recorder reappears in the bundle. - Clean build (Open VSX, bundled into EduIDE) - built by
scripts/package-openvsx.jsfrom a staging directory usingscripts/generate-clean-manifest.js. The clean variant excludes the struggle-detection engine, the recording pipeline, and the data-collection consent flow. In its manifest theartemis.dataCollectionConsentsetting and theartemis.replaySession/artemis.openRecordingsFolder/artemis.showStruggleScorecommands are removed, while theartemis.struggleDetection.*settings are kept but defaulted tofalse;scripts/verify-clean-bundle.js --profile=openvsxfails the build if any excluded code reappears in the bundle. - Local recording build (not shipped) - keeps the session recorder and consent flow for local development, via
npm run package:recor the "Run Extension (Recording)" launch config. It is refused under CI (resolveBuildVariantthrows whenGITHUB_ACTIONS === 'true'orCI === 'true'), so it never reaches a release.
The extension runs both in desktop VS Code and inside EduIDE (browser-based, managed Theia). In a managed environment it reads the connected server and credentials from the EduIDE data bridge (DATA_BRIDGE_ENABLED + the dataBridge.getEnv command) instead of the local config. resolveServerUrl() (src/extension/utils/serverUrl.ts) is the single source of truth for the active server: it returns the data-bridge ARTEMIS_URL in Theia, otherwise the artemis.serverUrl setting. All server-facing links ("Open in Artemis", problem-statement assets) resolve through it, so they point at the connected server rather than the config default.
Releasing is driven by .github/workflows/release-openvsx.yml (manual workflow_dispatch from main or dev):
- Validates the branch, version (must match
extension/package.json), changelog section, and the green CI gate. - Builds both VSIX variants and attaches build provenance.
- Publishes to Open VSX and/or the VS Marketplace, then tags and creates a GitHub release with the changelog notes.
- On a successful Open VSX publish, dispatches EduIDE's
artemis_extension_auto_update.yml, which opens a PR bumping the bundled extension version. Reviewing, merging, building, and deploying in EduIDE stay manual.
-
Bump the
versioninextension/package.jsonand add the matching## [x.y.z]section toCHANGELOG.md; merge todev(ormain). -
For a normal release, sync
devintomainwith a real merge commit, never a squash. A squash carries no parent link, somainnever getsdevas an ancestor and the next sync computes its merge base from the release before it. The 0.4.7 and 0.4.8 syncs were squashed, and by 0.4.9 that produced conflicts in eight files that had nothing to do with the release. If the sync PR conflicts for this reason, the resolution is "main becomes dev": the tree should end up identical todev, withdevrecorded as the second parent.The GitHub UI cannot do this. The repository allows squash merges only (
allow_merge_commitis off), so the merge button on the sync PR would undo the point of the step and the API rejects--mergeoutright. Do it locally and push, which also lets you verify the result before it reachesmain:git fetch origin git checkout -B sync-main origin/main git merge --no-ff origin/dev -m "chore(release): sync dev → main for X.Y.Z (#PR)" # verify before pushing: the tree must equal dev's, and dev must be a parent [ "$(git rev-parse HEAD^{tree})" = "$(git rev-parse origin/dev^{tree})" ] && echo "tree ok" git log -1 --format='%P' # two parents: main, then dev git push origin HEAD:main
The push goes straight at a protected branch and needs admin rights. Open the sync PR anyway (
--base main --head dev): it carries the release notes and CI runs on it, and GitHub closes it as merged once the push lands. Do not delete the branch afterwards, since the head branch isdevitself. -
Wait for CI to finish on the commit you are about to release. The workflow requires a green
CI gatecheck run on that exact SHA and fails immediately if none exists yet, which is easy to trip by dispatching straight after a push. -
Go to Actions → "Release to Open VSX and VS Marketplace" → Run workflow.
-
Pick the branch (
mainfor a normal release,devfor an ad-hoc / hotfix release of pre-merge work), enter the exactversion(must matchpackage.json), and leave both publish toggles on - or tick Dry run to build and validate only. -
Approve the
productionenvironment gate when prompted. -
On success the workflow tags the commit, creates the GitHub release with the changelog notes, and (after the Open VSX publish) dispatches the EduIDE bundled-extension bump PR.
The store listings show the repo-root README.md (user docs) and CHANGELOG.md. At package time both shipped packagers (scripts/package-desktop.js, scripts/package-openvsx.js) copy them from the repo root into their staging directory, so the listing matches the release. A plain non-staged vsce package (e.g. the vscode:prepublish hook used by the local recording build) instead runs scripts/sync-marketplace-docs.js, which generates extension/README.md and extension/CHANGELOG.md. Those extension/ copies are therefore generated and git-ignored - edit only the repo-root copies.
| File | Audience / purpose |
|---|---|
| README.md | Users (also the store listing) |
| DEVELOPER.md | This guide: build, run, release |
| CONTRIBUTING.md | Contribution workflow & conventions |
| extension/docs/DEVELOPER-GUIDE.md | Deep dive: webview architecture, message contracts, stores |
| recording-viewer/README.md | The standalone session recording viewer |
| CHANGELOG.md | Release notes (single source) |
- Artemis Platform: artemisapp.github.io
- Artemis Documentation: docs.artemis.cit.tum.de
- Artemis Repository: github.com/ls1intum/Artemis
- VS Code Extension Guidelines: code.visualstudio.com/api