Skip to content

About

Build and try out an edrys-Lite lab on your own computer before you share it with your students

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

59 Commits

Folders and files

Repository files navigation

edrys-dev

Build and try out an edrys-Lite lab on your own computer before you share it with your students.

You write your lab in a file (lab.yml), edrys-dev opens it as a class in your browser, and every time you save the file the class updates in all open tabs. No account and no deploy needed while you work.

Quick start

You need Node.js 20 or newer.

  1. Make a folder for your lab and create a file lab.yml in it:

    name: My first lab
    meta:
      description: Trying out edrys-dev.
    modules:
      - url: https://edrys-labs.github.io/module-markdown-it/index.html
        config:
          content: |
            # Welcome
    
            Edit lab.yml, save it, and watch this text change.
        width: full
        height: tall
  2. Start edrys-dev in that folder:

    npx @edryslabs/edrys-dev lab.yml --open

    Your browser opens the class. In the terminal you see two addresses:

    edrys-dev: /home/you/my-lab/lab.yml
      http://localhost:3210/?dev
    class open, share link:
      http://localhost:3210/?/classroom/…
    students join at:
      https://edrys-labs.github.io/?/classroom/…
    
  3. Change something in lab.yml and save. The class updates on its own.

If you use edrys-dev often, install it once with npm install -g @edryslabs/edrys-dev and then start it with just edrys-dev lab.yml --open.

Stop it with Ctrl+C.

Working on a lab

  • The /?dev tab is yours. It is the teacher's view of the class. Keep it open: it is the tab that picks up your changes to lab.yml.

  • Try the lab as a student or station. Open the share link in a different browser or a private window. In the same browser you would be the teacher again.

  • Let students in from their own computers. Give them the link after students join at:. It opens the same class on https://edrys-labs.github.io, so students need nothing but a browser, while your /?dev tab stays on your computer and keeps following lab.yml. Keep that tab open while students join: they get the class from the browsers that have it open. With an agent or the tutor, the agent chat in your /?dev tab shows this link at the top, with a Copy button. The class's Settings (Members, Communication) give the same link, and below it the address of your tab, which works only on your computer. Three things to know:

    • Both sides must connect the same way. Without --local they do. With --local the class runs through edrys-dev on your computer, which other computers cannot reach, so edrys-dev prints no link for students.
    • If you picked a WebSocket server in the class's Settings, the link carries it (#comm=…); don't cut that part off.
    • Modules from http://localhost:… (see below) do not load on the students' computers. edrys-dev warns you about them.

    --student-url points the link to another edrys-Lite site, e.g. your own copy; it has to use the same connection settings as the edrys-Lite inside edrys-dev.

  • The file wins. Anything you change in the class's Settings dialog is replaced the next time you save lab.yml. Make your changes in the file.

  • Restarting is safe. The same lab.yml reopens the same class, so share links you opened before keep working.

  • Mistakes are reported. If the class cannot take your lab (for example a YAML typo), the terminal prints lab error: …. Fix the file and save again.

  • Offline? Start with --local. The class then connects through edrys-dev itself instead of the internet.

Which modules exist and how to configure them is described in the edrys-Lite documentation and the edrys skills.

When the lab is done

Publish lab.yml the way you normally would, for example in a GitHub repository with a deploy link to https://edrys-labs.github.io. Nothing from edrys-dev ends up in the file.

Writing your own modules

If you are also writing a module, put it into a modules/ folder next to the lab, one subfolder per module:

my-lab/
├── lab.yml
└── modules/
    └── my-module/
        └── index.html

edrys-dev serves this folder on the next port (3211 by default). Use that address in lab.yml:

modules:
  - url: http://localhost:3211/my-module/index.html

When you save a file in modules/my-module/, only that module reloads in the class. Errors from your module's page are collected so an AI agent can see them (see below).

These addresses only work on your computer. Publish the module (for example on GitHub Pages) and put its real address into lab.yml before you share the lab.

With an AI agent

edrys-dev can work together with an AI coding agent such as Claude Code or GitHub Copilot. The agent edits lab.yml for you, sees whether the class accepts it, and can look into the class: rooms, users, modules and their messages.

Setup

The quick way, for a new lab:

npx @edryslabs/edrys-dev init my-lab

This makes the folder my-lab with a starter lab.yml, the agent configuration for Claude Code (.mcp.json) and VS Code Copilot (.vscode/mcp.json), instructions for the agent (AGENTS.md, CLAUDE.md), Claude Code settings that let the agent use edrys-dev and edit lab.yml and modules/ without asking each time (.claude/settings.json), and a .gitignore. In a folder that already has some of these files, it keeps them. If the edrys skills (step 2 below) are not installed yet, it offers to install them for you; if they are, it updates them when a newer version is out. Then open the folder in your agent and write "start".

To give your students a tutor as well:

npx @edryslabs/edrys-dev init my-lab --tutor

The agent then starts edrys-dev with the tutor. The tutor needs Claude Code on your computer, also if you work with Copilot. Add --tutor-agent codex to have Codex answer instead of Claude Code. In a folder that already has its agent configuration, add "--tutor" to the args in .mcp.json (and .vscode/mcp.json) yourself, then restart the agent.

By hand:

  1. Create a file .mcp.json in your lab folder:

    {
      "mcpServers": {
        "edrys": { "command": "npx", "args": ["-y", "@edryslabs/edrys-dev", "--mcp", "lab.yml"] }
      }
    }

    If you installed edrys-dev globally, "command": "edrys-dev", "args": ["--mcp", "lab.yml"] starts faster.

  2. Install the edrys skills, so the agent knows how labs and modules are written:

    npx skills add edrys-labs/skills
  3. Start your agent in the lab folder. The agent starts edrys-dev itself; don't start it by hand as well. If the folder has no lab.yml yet, edrys-dev creates a starter lab there. Ask the agent for the class address if your browser doesn't open it.

Talking to the agent from the class

The class tab has an agent chat button (sparkles icon) in its top bar, next to the class chat button. It opens the chat on the right side of the class, like the class chat; drag its left edge to make it wider or narrower. On a phone it fills the screen. What you write there goes straight to the agent. Only you see this chat; it is not the class chat. The agent can answer with text and also with buttons or checkboxes for you to pick from.

When the class cannot take your lab file, for example after a typing mistake, a red note in the chat says so in plain words, with edrys-Lite's message under "Details". It goes away once the file loads again.

Under your message you see "Waiting for the agent…" until the agent picks it up, then "Thinking…". If nothing happens for 30 seconds, the agent may not be listening. Your message is kept and answered once it is.

Some agents don't notice new messages on their own while they are idle. In that case start the chat prompt of the edrys server once (in VS Code Copilot: type /edrys.chat, or /mcp.edrys.chat in older versions), and the agent keeps waiting for your messages.

Chats are saved in .edrys-dev/chats/ next to the lab, so a restarted agent can pick up where you left off. The menu at the top of the chat starts a new chat or reopens an old one. Add .edrys-dev/ to your .gitignore.

For safety, the chat only accepts messages from the class page on your own computer. Other websites or people on your network cannot write to your agent, as long as you keep --host at its default.

What the agent can do

Tool
get_state the lab file, class address, share links (also the one for students), rooms, users and modules
goto move your class tab to a room, or open a student or station tab
chat, read_chat write to you in the agent chat, read your messages
read_messages messages between modules, and errors from your own modules
read_module_state what the modules share in a room
read_student_chats what students asked the tutor and what it answered (with --tutor)
run_in_module run JavaScript inside one of your own modules, only when you ask for it
wait_for_event wait for the next thing that happens in the class

A tutor for your students

Start edrys-dev with --tutor, and your students get a tutor button (robot icon) in the class's top bar. What they ask there is answered by an AI on your computer: Claude Code must be installed and signed in (claude in a terminal). With --tutor-agent codex, Codex answers instead (codex login first). Students need nothing but the class link.

  • It knows the lab. The tutor reads lab.yml with every question, so it always knows the version the class shows. It gives hints and explanations instead of whole solutions.

  • Notes only for the tutor. Put a file tutor.md next to lab.yml, for example "Task 2 is about Ohm's law, don't give the number". Students don't receive this file. A student who tries hard may still get the tutor to repeat it, so keep secrets out of it.

  • It sees the student's room. With each question it gets what the modules of the student's room share, such as the code in an editor, read through your /?dev tab. It cannot change it or run it. It does not see terminal output or the screen, so it asks the student to paste those.

  • It cannot do anything but answer. It runs as a separate claude without tools, MCP servers or your settings. A student cannot reach your files, your shell or the agent that edits your lab. Codex has no switch for "no tools", so edrys-dev turns off each of its tools and your config, runs it read-only, and drops any answer for which it still used a tool. This was checked with Codex 0.165. If a newer version no longer knows one of these settings, the tutor gives no answers, and the terminal says why.

  • Your /?dev tab passes the messages on. Keep it open. The button shows only while it is, and only on an edrys-Lite new enough to have it, on your computer and on the students' site alike.

  • You watch and switch it in the agent chat. The agent chat button (sparkles icon) in the top bar of your /?dev tab has a Students view: every question and answer as it happens, and a switch that turns the tutor off and on without restarting. While it is off, students don't see their button.

  • Each student has their own conversation, which continues with the next question. Chats are saved in .edrys-dev/tutor/, and the agent keeps its own copy of each conversation (Claude Code and Codex in their usual session folders). Your agent can read them with read_student_chats and tell you where students get stuck.

  • Limits. At most two answers are written at once; a question that finds no free turn within 30 seconds gets "the tutor is busy". Each student can have one open question and up to 20 questions an hour, of up to 2000 characters each. The whole class gets up to 200 questions an hour, not counting those turned away as busy (--tutor-per-hour changes it), so a student cannot get past the limits with new names and use up your account. When the class reaches it, the terminal and the Students view say so.

  • Cost. Each question uses the account claude or codex is signed in to. Answering students with a personal plan (Claude Pro/Max, ChatGPT) may break its terms, which don't let you make your account available to others. For a class, use an API key: start edrys-dev with it, and only the tutor uses it, not your own agent.

    ANTHROPIC_API_KEY=sk-ant-... npx edrys-dev lab.yml --tutor
    CODEX_API_KEY=sk-...         npx edrys-dev lab.yml --tutor --tutor-agent codex

    The terminal says what pays when edrys-dev starts, e.g. tutor: on (claude, answers paid with API key from ANTHROPIC_API_KEY). With a key, claude runs in its minimal mode (--bare), which takes only the key and never your login. Codex reads CODEX_API_KEY, not OPENAI_API_KEY. --tutor-model picks a cheaper model, e.g. --tutor-model haiku.

  • Privacy. Students are told that an AI on your computer answers and that you can read the chat. Questions and answers are encrypted between the student's browser and your tab, on every connection. Other members of the class can't read them, and neither can a WebSocket server that relays the class.

Options

edrys-dev [lab.yml] [options]
Option Default
[lab.yml], -i, --input <file> ./lab.yml the lab file, YAML or JSON
-o, --open off open the class in the browser
-p, --port <port> 3210 if it is taken, the next free port is used
--local off connect the class through edrys-dev instead of the internet; works offline
-m, --modules <dir> ./modules, if it exists folder with your own modules
--student-url <url> https://edrys-labs.github.io/ the edrys-Lite site in the link for students
--tutor off a tutor chat for students, answered by an AI agent on your computer
--tutor-agent <claude|codex> claude the agent that answers: Claude Code or Codex
--tutor-model <model> the agent's default the model the tutor uses
--tutor-per-hour <n> 200 questions the tutor answers per hour for the whole class
--host <host> 127.0.0.1 0.0.0.0 lets others on your network open the class (and, with --mcp, write to your agent)
--mcp off for AI agents; set it in .mcp.json, see above
-h, --help show help

Troubleshooting

  • no lab file at …: edrys-dev looks for lab.yml in the current folder. Start it in your lab folder or give the path: edrys-dev path/to/lab.yml.
  • The share link opens me as the teacher. Open it in another browser or a private window.
  • My changes in Settings are gone. They are replaced by lab.yml on every save. Put them into the file.
  • The class doesn't connect / no internet. Try --local.
  • Students see an empty class. Keep your /?dev tab open while they join. Check that they got the whole link, including any #comm=… at the end, and that you didn't start with --local. A site set with --student-url must use the same connection settings as edrys-dev's edrys-Lite.
  • A different port than 3210. Another program uses it; edrys-dev took the next free one. The terminal shows the address.
  • The agent doesn't answer in the chat. Check that your agent is running in the lab folder with .mcp.json, and if it does not wake up on its own, start the chat prompt (see above).

Development

To work on edrys-dev itself:

npm install
npm run build    # tsc → dist/
npm test         # builds, then runs test/*.test.js

How the parts talk to each other:

flowchart LR
  lab[lab.yml] -- watch --> srv
  mods[modules/] -- watch --> msrv["module server :3211<br/>(module pages + error script)"]
  subgraph srv ["edrys-dev :3210"]
    direction TB
    static["edrys-Lite dist + reload.js"]
    api["/edrys-dev/lab · events · reload · bridge · module-error<br/>chat · tutor · link"]
  end
  srv -- "reload-lab, reload-module, tutor answers (SSE events)" --> tab["class tab /?dev"]
  tab -- "GET lab, republish signed, tutor answers" --> room((class))
  tab -- "state, messages, replies, tutor questions (POST bridge)" --> srv
  msrv -- module frames --> tab
  msrv -. "errors (POST module-error)" .-> srv
  srv -- "reload (SSE)" --> peers
  room -- "default transport, or --local on :3210" --> peers[student / station tabs]
  peers -- "tutor questions" --> room
  room -- "tutor questions" --> tab
  agent[AI agent] <-- "MCP over stdio (--mcp)" --> srv
  srv <-- "question in, answer out (--tutor)" --> tutor["tutor: claude or codex<br/>without tools"]
Loading
  • index.ts reads the options and starts the server, and with --mcp the MCP server (mcp.ts).
  • server.ts serves edrys-Lite, watches the lab (watch.ts) and talks to the class tab: events go out over SSE, the tab's reports come back over POST /edrys-dev/bridge.
  • In the class tab, edrys-Lite's own DevBridge (src/ts/DevBridge.ts in edrys-Lite, active with ?dev) loads and republishes the lab and reports the class. GET /edrys-dev/lab also tells it which views of the agent chat there are (chat: {agent, students}); edrys-Lite then shows its AgentChat.vue drawer, which talks to chat.ts (Agent view, /edrys-dev/chat) and tutor.ts (Students view, /edrys-dev/tutor) on the server, and to /edrys-dev/link/events for the students' link.
  • edrys-dev adds views/reload.js to the page: student and station tabs load again when a local module changed.
  • tutor.ts answers students with --tutor: the class tab passes their questions on over the bridge, tutor.ts runs claude or codex without tools for each one, and the answer goes back to the tab as an event, which sends it to the student through the class.
  • modules.ts serves local modules on the next port and adds the error reporter to their pages.
  • sync.ts is the Yjs sync for --local, on edrys-dev's own port.

edrys-Lite comes from npm as @edryslabs/edrys-lite, pinned to one version: its dist/ is what edrys-dev serves. To try changes to edrys-Lite, build it (npm run build there) and link the checkout with npm install ../edrys-Lite; pin the published version again afterwards. The same goes for @edryslabs/websocket-server, an optional dependency that only --local uses.

Releases are published by .github/workflows/publish.yml: npm version <version> and git push --follow-tags on main. The workflow checks that the tag matches package.json, runs the tests, publishes to npm (a pre-release version like 0.5.0-dev.0 under the next tag, any other under latest) and creates the GitHub release.

Issues and pull requests: https://github.com/edrys-labs/edrys-devserver

License

MIT. The MCP server and the agent chat follow LiaScript DevServer (MIT).

About

Build and try out an edrys-Lite lab on your own computer before you share it with your students

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages