Page Clone logo

Page Clone

OrganizationPopular
THU-MAIC
page-clone

Building one page that looks like a page the course already has — copy the model page with `duplicate_scene`, then rewrite the copy's words with one `patch_stage` op per content slot. Use when a new page has to inherit an existing page's design, whether the model page came from an imported deck or the course wrote it earlier. Not for revising a page that is already the page you want (that is `pro-editing`), and not for the course-level work of cataloguing layouts and assigning one per outline entry (that is `style-clone`).

Overview

PublisherTHU-MAIC
RepositoryOpenMAIC
Skill namepage-clone
Stars
37.6K
Forks
5.9K
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by THU-MAIC on GitHub. Read the source before you install it.

Installation

Install the Page Clone AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/THU-MAIC/OpenMAIC.git /tmp/OpenMAIC
mkdir -p .claude/skills
cp -r /tmp/OpenMAIC/skills/agent-runtime/page-clone .claude/skills/page-clone
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Page Clone in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Page Clone on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Page Clone is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Cloning one page's design

The design already exists on another page. Your job is to put new content into that design without redrawing it: copy the page, then swap what it says.

Copy-then-edit is the only clone path in this runtime. generate_scene always re-rolls a page from its outline entry — the model invents a fresh element tree every time — so calling it on a copied page destroys exactly the design you came for. Nothing here validates the shape of your result either: the design is preserved because you copied it, and the judgement about which elements are content and which are the skeleton is yours.

The sequence

  1. duplicate_scene({ templateSceneId, targetOrder, title }) — an exact copy of the model page at the position you want (templateOrder works too, but an id is safer). The copy carries the full content, no narration actions, and a new outline entry. Pass a title that names the NEW page; the entry inherits the model page's brief, and a copy still called 「第 3 章回顾」 misleads both the learner and the narration step.
  2. Read the copy with read_stage, path:/scenes/<order|id>, detail:"source" — this is your address space and your fidelity source. It returns the whole page's persisted JSON, including raw content HTML, inline spans, fonts, colours, fills, shadows, geometry and z-order, and it is the root your patch paths are written against: a field you read at /content/canvas/elements/2/content is written back through that same path. Copy unchanged markup and style fields from this result; do not reconstruct them from stripped text.
  3. Decide, element by element, what each one is. Content slots are the ones whose words belong to the old subject. Skeleton is everything else — rules, bands, page numbers, logos, decorative shapes, background art — and it stays untouched even when it holds text.
  4. Call patch_stage once per content slot, with op:"set" on the exact path that holds that slot's words — /content/canvas/elements/3/content for a paragraph, /content/canvas/elements/5/data/0/0/text for a table cell. One leaf per call: everything you do not name keeps the value you copied. slide-dsl is the manual for which field holds the words in each element type. Do not patch geometry or style paths while cloning — they ARE the design you copied.
  5. Read the copy with read_stage detail:"text" after the edits. It returns every text-bearing element as { path, id, type, text } plus a page-wide combinedText, so you read the whole page's words in one call and get the pointer to fix with them. Search it for source-topic residue; the read reports, and you decide what is stale, then set, remove, or delete_element it.
  6. generate_actions on the copy to give it narration (audio is on by default). A duplicated page arrives silent.

Work one page at a time and re-read before you edit. Every patch_stage result already carries the page's fresh inventory, so a run of edits on the same page needs one read_stage call at the start, not one per call.

Where a change goes

For a cloned slide, patch_stage uses set, remove, str_replace, add_element, and delete_element; for cloning the usual choice is set on the smallest content leaf. The only question is which path carries the change.

NeedCallWhat really happens
New words in a text blockset /content/canvas/elements/N/contentStores your HTML byte for byte — nothing filters it; preserve the source element's <span> marks and inline styles while changing the words
New words in a shape's labelset /content/canvas/elements/N/text/contentOnly the label's HTML moves; font, colour, vertical alignment, line height, shape fill and path all stay
One table cellset /content/canvas/elements/N/data/0/0/textOne cell's plain text; every other cell, id, colspan, rowspan and per-cell style is untouched
One line of codeset /content/canvas/elements/N/lines/1/contentOne line's text, with every line id kept — language, filename, font size and box survive
A formulaset /content/canvas/elements/N/latexReplaces the source and re-renders the cached KaTeX html the renderer actually paints
A chart label or numberset /content/canvas/elements/N/data/labels/2One entry; keep labels, legends and series dimensionally consistent
A different imageset /content/canvas/elements/N/srcPoints the element at another source. It never creates a picture — get a real src from generate_image first, and keep the original rather than invent a URL
Nudge a boxset /content/canvas/elements/N/left (or top / width / height)One number at a time. On a cloned page this is a repair, not a step
Drop an optional fieldremove /content/canvas/elements/N/fillDeletes that key. remove on a path that is not there fails, and so does removing a required field
One content slot too manydelete_element (elementId)Removes the element and any animation bound to it
A genuinely new elementadd_element (complete element JSON, no id)Validates every field and rich-text value, assigns the id, inserts at afterId or index
Restack overlapping elementsset /content/canvas/elementsThe only change with no leaf — write the array whole, reordered, with the same ids and types
Rename the pageedit_deck retitleTitle only, in both the deck and the outline entry

Three properties make this safe to lean on, and all three are worth knowing before you do: only the path you name changes, identity is not patchable (the id set and each id's type must come back identical, which is why adding or removing an element has its own op), and a rejected patch changes nothing — a bad path, an unknown field, unsafe HTML or an invalid result fails loud with the page as it was. Nothing normalises your colours or fonts toward a house style either, which is the property that makes a copied design survive editing at all.

The content rule is simple: source HTML in, source HTML out. Change the text inside the returned paragraphs and spans; do not flatten the block to plain text or synthesize fresh styling. For lists, keep one <p> per item with the marker in the text (slide-craft explains why <ul> does not render its markers here).

When a cloned page needs one more slot, the cheapest honest source is an element already on it: read its JSON and add_element a copy with the words and box you want. add_element is full fidelity, so its caller supplies every geometry and style field — which is why an existing element is a better starting point than a blank one, and why this is the last resort rather than a step.

When the new content does not fit the layout

This is the normal case, not an error: a layout with three bullet slots and content with seven points is a mismatch you resolve, and no tool will resolve it for you. In order of preference:

  1. Cut the content to the layout's capacity. A borrowed layout is a statement about how much can be said on one page. Tightening the expression preserves the design; growing the page destroys it.
  2. Split across two clones. Duplicate the model page again and carry the remainder onto the second copy. Two pages in the deck's own form beat one overstuffed page.
  3. Pick a roomier model page. If the course has a layout built for more content, clone that one and abandon this copy (edit_deck delete).
  4. Grow the layout, only as a last resortadd_element a copy of the closest content element, with its box set into the rhythm of the ones around it (match their left edge and spacing exactly, taken from the source boxes) and the new words already in it. You are now drawing, and it shows if you are careless.

Fewer content slots than the layout has is the easier direction: fill what you can meaningfully fill and delete_element the rest. Never leave a template's words standing on the page. A slot you neither replaced nor deleted is a bug — the old subject leaking into the new one — and a detail:"text" read with read_stage detail:"text" is the sweep that catches it before shipping.

Overflow discipline

Text sized for the model page's words is not sized for yours. Aim for the same order of magnitude as the text you replaced — that length was chosen for that box, and it is the only sizing information you have. When your replacement runs much longer, shorten the wording rather than resizing the box.

Verify with render_scene_preview when it is registered, and spend the calls where they buy something: the first page you clone from a given model page, and any later clone whose text is visibly longer than what it replaced. Skip it otherwise; previews cost calls. If a page overflows, load pro-editing and converge inside its budget of two preview rounds — shorten text first, and set a box only when the text is already tight. If two rounds have not converged, move the content to a roomier layout or name the page to the user. Do not ship a page with text running off it.

Finish the page

generate_actions on the copy, with a styleDirective when the surrounding pages have a register worth matching. Narration is written from the page's persisted content plus its outline entry, and that entry's brief came from the model page — so the content you just wrote has to be unambiguous on its own, and the title has to be the new page's title. Then read the result back with read_stage detail:"source" and check both halves of the result: every speech action carries an audioId, and every speech line is about this page's subject rather than the model page's — a narrated wrap-up or a topic name inherited from the brief is residue exactly as template words on the slide are. Repair it with patch_stage on that action's /actions/N/text pointer, then generate_tts the page so the audio matches the words.

Where this sits

  • style-clone governs the course-level job: reading an imported deck as a library of layouts, classifying them, and assigning one to each outline entry. It calls into this skill for the per-page mechanics.
  • slide-dsl is the field manual for the JSON you are patching — the ten element types, which field holds the words in each, what values are legal, and what the renderer really does with the HTML you write. Load it when you are about to patch a field you have not patched before, or when a patch comes back rejected.
  • pro-editing governs editing a page that is already the page you want. Load it when a clone comes out wrong, and follow its preview budget.
  • slide-craft is the design law the replacement content has to satisfy — the height table, the type scale, contrast pairs, how rich text really renders. Load it when a slot needs more than a like-for-like sentence swap.
  • stage-design still governs the build of the stage as a whole.

Hard rules

  • Copy, then edit. Never generate_scene on a copied page. It re-rolls the element tree from the outline entry and the borrowed design is gone.
  • Content changes; design does not. No geometry path, no style path, no new element and no restacking while cloning, unless the layout genuinely has to grow and you have read the neighbouring boxes first.
  • Every element ends up replaced, deliberately kept, or deleted. No template words survive by accident.
  • Always run the text sweep. read_stage detail:"text" returns every element's words plus one combinedText; read all of it, and fix what it turns up at the path it hands you. The read reports — it never decides or edits.
  • Facts do not travel with the layout. Text carried over from the model page is a claim in its new context; if it belongs to the old subject, it goes.
  • One page at a time. duplicate_scene, then that page's edits, then its actions — then the next page. Each write persists as it lands.

Frequently asked questions

What does the Page Clone AI skill do?

Building one page that looks like a page the course already has — copy the model page with `duplicate_scene`, then rewrite the copy's words with one `patch_stage` op per content slot. Use when a new page has to inherit an existing page's design, whether the model page came from an imported deck or the course wrote it earlier. Not for revising a page that is already the page you want (that is `pro-editing`), and not for the course-level work of cataloguing layouts and assigning one per outline entry (that is `style-clone`).

Why use Page Clone on TypingMind?

Because you install it once and use it with any model. Page Clone is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Page Clone in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/THU-MAIC/OpenMAIC/tree/main/skills/agent-runtime/page-clone. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Page Clone?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Page Clone?

As many as you like. As long as a model supports skills, you can use Page Clone with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Page Clone AI skill free?

Yes. It is published on GitHub by THU-MAIC under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇