Skip to content

Add "Run in VS Code": model-check playground specs in a GitHub codespace - #23

Merged
FedericoPonzi merged 4 commits into
tlaplus:mainfrom
formal-systems:demo
Oct 15, 2026
Merged

FedericoPonzi merged 4 commits into
tlaplus:mainfrom
formal-systems:demo

Conversation

@formal-systems

@formal-systems formal-systems commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

What

Adds a Run in VS Code button next to Run TLC in every lesson and spec playground. It opens this repository in a GitHub codespace with the full TLA+ tooling and hands over the current spec and config, including the learner's edits.

  • .devcontainer/: Ubuntu with Java 21 (for TLC), Node 24, the tlaplus.vscode-ide extension, every lesson exported as .tla/.cfg files under lessons/, and a clone of tlaplus/Examples. A welcome page explains the flow.
  • scripts/export-lessons.mjs (npm run export-lessons): writes each lesson's spec and config to lessons/<section>/<lesson>/<Module>.{tla,cfg}, reusing src/lib/parse-lesson.ts.
  • Handoff: the site and the codespace can't talk to each other directly, so the button copies a one-line command, echo <base64url payload> | node scripts/run-in-codespace.mjs. Pasted into the codespace terminal, it writes the files to playground/<dir>/, opens them in the editor and runs TLC. Folder and file names from the payload are restricted to plain names, so a payload can't write outside playground/.
  • The codespace repo and branch can be set with NEXT_PUBLIC_CODESPACES_REPO / NEXT_PUBLIC_CODESPACES_REF, for testing from a fork. The default is tlaplus/tla-by-example.

Large specs

Linux caps a single program argument at 128 KiB, so the payload is piped in by bash's builtin echo instead of being passed as an argument, and the script reads it from stdin as a stream. Spec pages also send only the modules the spec transitively EXTENDS/INSTANCEs. The largest one, SpecifyingSystems, goes from about 235 KB to about 62 KB.

Testing

  • npm test: 54 tests, including new suites for the handoff lib (module naming, sanitising, non-ASCII round-trip, module pruning), the Playground button (copy, open, banner, dismiss) and run-in-codespace.mjs (rejected folder and file names, bad payloads, a 300 KB payload). Run on macOS and in a node:24-bookworm container.
  • tsc --noEmit and npm run build pass.
  • In a Linux container: a 400 KB pasted command writes its files intact, while the old argument form fails with Argument list too long.
  • End to end with the TLA+ extension's tla2tools.jar: a handed-over lesson spec model-checks with "No error has been found".
  • Every spec page's spec/config combination parses with SANY after module pruning. 7 combinations fail with and without pruning alike, because they need TLAPS or the community modules, which the standalone jar lacks.
  • Not covered automatically: the devcontainer itself, which can only be checked by starting a real codespace.

🤖 Generated with Claude Code

formal-systems and others added 3 commits October 13, 2026 19:52
Open the repo in a codespace with the TLA+ VS Code extension, Java for
TLC, every lesson exported as .tla/.cfg files and the tlaplus/Examples
specifications, so learners can graduate from the in-page playground to
the full tooling without installing anything.

- scripts/export-lessons.mjs (npm run export-lessons): write each
  lesson's spec/cfg to lessons/<section>/<lesson>/<Module>.tla|.cfg,
  reusing src/lib/parse-lesson.ts via Node's type stripping (>= 22.18)
- .devcontainer/devcontainer.json: Java 21, Node 24, tlaplus.vscode-ide;
  postCreate runs npm ci, exports the lessons and clones Examples/
- "Open in VS Code" navbar link on lesson and spec pages
- README section and Navbar tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
NEXT_PUBLIC_CODESPACES_REPO (default tlaplus/tla-by-example) and
NEXT_PUBLIC_CODESPACES_REF let a fork or demo branch point the
"Open in VS Code" button at its own devcontainer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replace the navbar's "Open in VS Code" link with a "Run in VS Code"
button next to "Run TLC" (which still runs TLC in the browser). It
copies the current spec, config and extra modules, including the
learner's edits, as a one-line command and opens the codespace. Pasted
into the codespace terminal, scripts/run-in-codespace.mjs writes the
files to playground/<section>/<lesson>/, opens them in the editor and
runs TLC with the extension's tla2tools.jar.

The site and the codespace cannot talk to each other (codespaces.new
links carry no data), so the files travel in the command as base64url
JSON. File names follow the MODULE name, since TLC on disk requires
it; folder and file names are validated before writing.

The codespace now opens .devcontainer/WELCOME.md with these steps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The pasted command passed the spec as a program argument, which Linux caps
at 128 KiB: SpecifyingSystems' command (~235 KB) failed in the codespace
with "Argument list too long". Pipe the payload through the shell's builtin
echo instead, which has no such limit, and read it from stdin as a stream
(fs.readFileSync(0) fails with EAGAIN on large pipes on Linux).

Also send only the extra modules the spec transitively EXTENDS or
INSTANCEs, so the command stays short: the largest spec page goes from
~235 KB to ~62 KB.

Add tests for the Playground button (copy, open, banner, dismiss) and for
run-in-codespace.mjs: rejected folder/file names, bad payloads, and a
300 KB payload.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Ovidiu-Cristian Marcu <ovidiu@formalsystems.lu>
@FedericoPonzi

Copy link
Copy Markdown
Collaborator

I've checked out the branch locally and run it.
Preview:
image
I'm not fully convinced by "Run in Vs Code" as a label, when i click it I would expect my vscode to open up, but instad gets opened in codespaces. I didn't have a codespace setup, so I was a bit confused on how to move forward. After I created it, the vscode loaded with the repo checked out - the file I was looking at it's not opened. Going back to the page now I see:
image
After I pasted this to the terminal of my codespace, it fails with an error but I guess it's caused by missing files added by this PR. One UX change I'd ask is that as a user I click on Open in vscode, the bar is shown with echo command,, then I can click on a new button to open in a new tab. We can also explain that it will open codespaces and have a link to the documentation. For now, I think it's worth merging so that it can be better tested. Thank you!

@FedericoPonzi
FedericoPonzi merged commit ec0cc03 into tlaplus:main Oct 15, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants