/stage-dsl
The map for reading and editing an OpenMAIC stage document with read_stage, patch_stage, and grep_stage. Load it before patching a structure you have not patched before, when patch_stage rejects an operation, or whenever the path from a stage, outline, scene, content object, or
Claude Code
$ npx -y skills add thu-maic/openmaic --skill stage-dsl --agent claude-code
Codex
$ npx skills add thu-maic/openmaic --skill stage-dsl -a codex -y
Cursor
$ npx skills add thu-maic/openmaic --skill stage-dsl -a cursor -y
Gemini CLI
$ npx skills add thu-maic/openmaic --skill stage-dsl -a gemini-cli -y
GitHub Copilot
$ npx skills add thu-maic/openmaic --skill stage-dsl -a github-copilot -y
OpenCode
$ npx skills add thu-maic/openmaic --skill stage-dsl -a opencode -y
Windsurf
$ npx skills add thu-maic/openmaic --skill stage-dsl -a windsurf -y
SKILL.md
stage-dsl.SKILL.mdname: stage-dsl
title: "课堂文档结构"
description: The map for reading and editing an OpenMAIC stage document with read_stage, patch_stage, and grep_stage. Load it before patching a structure you have not patched before, when patch_stage rejects an operation, or whenever the path from a stage, outline, scene, content object, or action to the field you need is uncertain. It routes to field-level references for quizzes, interactive widgets, actions, and PBL projects; the installed slide-dsl skill remains the complete slide canvas manual.
The stage document map
This is a map, not the field manual.
Use it to decide which subtree owns a value, which path to read, and which reference chapter to load. Then read the exact source before writing.
The document model
The durable structure is:
stage
├── outline
└── scenes[] ordered by scene.order, shown as pages 1..N
├── id stable scene identity
├── order 1-based page position
├── type slide | quiz | interactive | pbl
├── content shape selected by scene.type
│ ├── slide.canvas
│ ├── quiz.questions[]
│ ├── interactive.html / widgetConfig
│ └── pbl.projectV2
└── actions[] ordered playback verbs`stage` is the stage's metadata. `outline` is the generation plan. A persisted page is a scene. Its `type` and `content.type` must agree.
The three generic tools do not replace page-list operations. Insert, delete, reorder, and retitle pages with `edit_deck`.
Tool vocabulary
| Need | Tool | How | | --- | --- | --- | | Read a scene | `read_stage` | `path:/scenes/<order|sceneId>` with the required detail | | Edit scene content or actions | `patch_stage` | `target:/scenes/<order|sceneId>` and scene-root JSON Pointer ops | | Search visible text or source | `grep_stage` | literal search over the whole stage | | List stages in folders | `list_folder_stages` | returns the explicit `stageId` required by every stage tool | | Insert, delete, reorder, or retitle pages | `edit_deck` | page-list operations stay outside the document patcher | | Plan and build a new stage | conversation + `create_stage` + `generate_scene` | settle the page plan in conversation, then call `generate_scene` once per page with an explicit brief | | Set the classroom cast | `set_roster` | write the settled roster before page generation |
Addressing with read_stage
| Path | Resolves to | | --- | --- | | `""` or omitted | the whole stage | | `/outline` | the persisted outline snapshot | | `/scenes/3` | the scene whose `order` is 3 | | `/scenes/scene_abc` | the scene with that stable id | | `/scenes/scene-abc` | the historical hyphenated scene-id form | | `/scenes/3/actions` | only scene 3's action array |
Orders are 1-based. Array indices inside source JSON are 0-based.
`detail:"tree"` is the compact structural inventory. It reports scene id, order, type, title, element/question/project counts, and action counts. It is for finding a target, never for reconstructing a write value.
`detail:"source"` is the exact JSON at the selected path. A scene source is the persisted scene object, so writable pointers begin `/content/...` or `/actions/...`. Inline media bytes larger than 2 KiB are replaced in this read projection by a read-only placeholder. The stored document is unchanged.
`detail:"text"` is the visible-text projection. Use it to find learner-facing copy or prove that old wording no longer remains. It deliberately omits known internal PBL prompts and runtime state.
Source and text responses are character-paged after 12,000 characters. Pass the returned `nextOffset` back as `offset` until it disappears.
Writing with patch_stage
`target` is one scene path: `/scenes/<order|sceneId>`.
Every call carries a human `intent` and one or more `ops`. The ops are atomic: the server applies them to a clone, validates the resulting scene, and writes once. If op 2 fails, op 1 is not persisted.
| Op | Fields | Meaning | | --- | --- | --- | | `set` | `path`, `value` | replace an existing leaf or add an optional object key | | `remove` | `path` | delete an existing object key or splice an array index | | `str_replace` | `path`, `oldText`, `newText`, optional `replaceAll` | replace one exact occurrence of `oldText` inside the string field at `path`; `replaceAll:true` replaces every occurrence | | `add_element` | `element`, optional `afterId` or `index` | add one complete id-less slide element | | `delete_element` | `elementId` | delete one slide element by stable id |
Set/remove/str_replace paths are JSON Pointers rooted at the scene source:
/content/canvas/elements/0/content
/content/questions/1/options/0/label
/content/widgetConfig/description
/content/projectV2/milestones/0/title
/actions/2/text
Escape `/` in an object key as `~1` and `~` as `~0`. Array indices are canonical zero-based integers: `0`, `1`, `2`, never `03`, `-1`, or `+1`.
Every intermediate segment must exist. `set` may create only the final object key. `remove` requires the final key or array slot to exist.
For a change inside a large HTML document or long text field, prefer `str_replace` over rewriting the whole field with `set`: transcribing 27 KB of HTML to change one number is expensive, and any transcription error silently corrupts the page. Read `detail:"source"`, pick a short unique anchor, replace it, then read back and `grep_stage` to verify. `oldText` must appear exactly once in the stored string; on multiple matches extend the anchor or set `replaceAll:true`. Neither `oldText` nor `newText` may contain a read-side media omission placeholder; `newText` may be empty to delete the anchor.
Scene metadata is not writable here. Paths must begin `/content/` or `/actions/`; use `edit_deck` for page metadata and page-list changes.
Finding with grep_stage
`scope:"text"` searches the visible-text projection. `scope:"source"` searches s
Read more
name: stage-dsl title: "课堂文档结构" description: The map for reading and editing an OpenMAIC stage document with read_stage, patch_stage, and grep_stage. Load it before patching a structure you have not patched before, when patch_stage rejects an operation, or whenever the path from a stage, outline, scene, content object, or action to the field you need is uncertain. It routes to field-level references for quizzes, interactive widgets, actions, and PBL projects; the installed slide-dsl skill remains the complete slide canvas manual.
The stage document map
This is a map, not the field manual.
Use it to decide which subtree owns a value, which path to read, and which reference chapter to load. Then read the exact source before writing.
The document model
The durable structure is:
stage
├── outline
└── scenes[] ordered by scene.order, shown as pages 1..N
├── id stable scene identity
├── order 1-based page position
├── type slide | quiz | interactive | pbl
├── content shape selected by scene.type
│ ├── slide.canvas
│ ├── quiz.questions[]
│ ├── interactive.html / widgetConfig
│ └── pbl.projectV2
└── actions[] ordered playback verbs`stage` is the stage's metadata. `outline` is the generation plan. A persisted page is a scene. Its `type` and `content.type` must agree.
The three generic tools do not replace page-list operations. Insert, delete, reorder, and retitle pages with `edit_deck`.
Tool vocabulary
| Need | Tool | How | | --- | --- | --- | | Read a scene | `read_stage` | `path:/scenes/<order|sceneId>` with the required detail | | Edit scene content or actions | `patch_stage` | `target:/scenes/<order|sceneId>` and scene-root JSON Pointer ops | | Search visible text or source | `grep_stage` | literal search over the whole stage | | List stages in folders | `list_folder_stages` | returns the explicit `stageId` required by every stage tool | | Insert, delete, reorder, or retitle pages | `edit_deck` | page-list operations stay outside the document patcher | | Plan and build a new stage | conversation + `create_stage` + `generate_scene` | settle the page plan in conversation, then call `generate_scene` once per page with an explicit brief | | Set the classroom cast | `set_roster` | write the settled roster before page generation |
Addressing with read_stage
| Path | Resolves to | | --- | --- | | `""` or omitted | the whole stage | | `/outline` | the persisted outline snapshot | | `/scenes/3` | the scene whose `order` is 3 | | `/scenes/scene_abc` | the scene with that stable id | | `/scenes/scene-abc` | the historical hyphenated scene-id form | | `/scenes/3/actions` | only scene 3's action array |
Orders are 1-based. Array indices inside source JSON are 0-based.
`detail:"tree"` is the compact structural inventory. It reports scene id, order, type, title, element/question/project counts, and action counts. It is for finding a target, never for reconstructing a write value.
`detail:"source"` is the exact JSON at the selected path. A scene source is the persisted scene object, so writable pointers begin `/content/...` or `/actions/...`. Inline media bytes larger than 2 KiB are replaced in this read projection by a read-only placeholder. The stored document is unchanged.
`detail:"text"` is the visible-text projection. Use it to find learner-facing copy or prove that old wording no longer remains. It deliberately omits known internal PBL prompts and runtime state.
Source and text responses are character-paged after 12,000 characters. Pass the returned `nextOffset` back as `offset` until it disappears.
Writing with patch_stage
`target` is one scene path: `/scenes/<order|sceneId>`.
Every call carries a human `intent` and one or more `ops`. The ops are atomic: the server applies them to a clone, validates the resulting scene, and writes once. If op 2 fails, op 1 is not persisted.
| Op | Fields | Meaning | | --- | --- | --- | | `set` | `path`, `value` | replace an existing leaf or add an optional object key | | `remove` | `path` | delete an existing object key or splice an array index | | `str_replace` | `path`, `oldText`, `newText`, optional `replaceAll` | replace one exact occurrence of `oldText` inside the string field at `path`; `replaceAll:true` replaces every occurrence | | `add_element` | `element`, optional `afterId` or `index` | add one complete id-less slide element | | `delete_element` | `elementId` | delete one slide element by stable id |
Set/remove/str_replace paths are JSON Pointers rooted at the scene source:
/content/canvas/elements/0/content /content/questions/1/options/0/label /content/widgetConfig/description /content/projectV2/milestones/0/title /actions/2/text
Escape `/` in an object key as `~1` and `~` as `~0`. Array indices are canonical zero-based integers: `0`, `1`, `2`, never `03`, `-1`, or `+1`.
Every intermediate segment must exist. `set` may create only the final object key. `remove` requires the final key or array slot to exist.
For a change inside a large HTML document or long text field, prefer `str_replace` over rewriting the whole field with `set`: transcribing 27 KB of HTML to change one number is expensive, and any transcription error silently corrupts the page. Read `detail:"source"`, pick a short unique anchor, replace it, then read back and `grep_stage` to verify. `oldText` must appear exactly once in the stored string; on multiple matches extend the anchor or set `replaceAll:true`. Neither `oldText` nor `newText` may contain a read-side media omission placeholder; `newText` may be empty to delete the anchor.
Scene metadata is not writable here. Paths must begin `/content/` or `/actions/`; use `edit_deck` for page metadata and page-list changes.
Finding with grep_stage
`scope:"text"` searches the visible-text projection. `scope:"source"` searches s
Open Multi-Agent Interactive Classroom — Get an immersive, multi-agent learning experience in just one click
Other skills on openmaic.
More skills from other plugins.
blueprint-figure
Draws static SVG figures for lessons, READMEs and manuals in the AI Engineering from Scratch look: paper panel, blueprint accent,…
concept-workflow
End-to-end workflow for creating complete JavaScript concept documentation, orchestrating all skills from research to final review
lesson-quiz
Test a learner on a single Claude Code tutorial lesson (01-10) with 10 questions, scoring answers and flagging weak spots. Use…
harness-creator
Build, audit, and improve harnesses that make AI coding agents reliable: AGENTS.md/CLAUDE.md instruction files, feature/state…
Questions about stage-dsl.
- Which coding agents can use stage-dsl?
- stage-dsl installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

