Skip to content

Sync the package checks and docs with the MiniMax Code 3.1.5 Mini App contract - #81

Merged
MyPrototypeWhat merged 3 commits into
mainfrom
feat/sync-contract-3.1.5
Oct 26, 2026
Merged

MyPrototypeWhat merged 3 commits into
mainfrom
feat/sync-contract-3.1.5

Conversation

@MyPrototypeWhat

@MyPrototypeWhat MyPrototypeWhat commented Oct 26, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Syncs the package checks and contributor docs with the MiniMax Code 3.1.5 Mini App contract. The contract is identical in 3.1.5, 3.1.6, and the current Host main. Since both versions are released, this can merge once reviewed.

npm run check

New manifest fields, validated with the Host's rules:

Field Accepted Minimum client
engines { "mcode": ">=MAJOR.MINOR.PATCH" } 3.1.5, or the bound when higher
toolAccess ["call"] 3.1.5
deviceAccess ["microphone"] (camera / notifications are not released yet) 3.1.5

Fix: agentAccess "session.read" moves from 3.1.4 to 3.1.5. #59 recorded 3.1.4 from a preview build, but the released 3.1.4 still rejects "session.read".

New ACCESS_UNDECLARED check. It scans .js / .mjs / .cjs / .html / .htm files in the page and Node payload for calls whose grant the manifest does not declare. The level depends on whether the call can work on any client that installs the package:

Call Needs Level
context.agent / page agent run, answer, reply, cancel, open, models, agents, create "session.run" error
agent.sessions(), observe({ all: true }), page session() without an id "session.read" error
agent.session(id) / observe({ sessionId }) on the Mini App's own sessions either agentAccess value error
context.tool.* / page tool.request() toolAccess error
speech.transcribe() deviceAccess microphone error
getUserMedia() deviceAccess microphone error if the package already needs ≥3.1.5, otherwise warning

Agent findings are reported once per file, naming every missing value. The first five rows never work without their grant, on any client. getUserMedia worked before 3.1.5 and is denied from 3.1.5, so it only becomes an error once nothing older can install the package.

Supporting changes: the payload walk moved from rules/node.mjs to fs.mjs, and version comparison moved to version.mjs. CI is unchanged.

Docs and example

  • docs/package-contract.md: new fields, per-item permission switches, the version table, and the declared-access check.
  • docs/agent.md: session.read (sessions / session / observe), whenBusy, the 12-turns-per-minute limit, switch-off errors.
  • docs/tool.md (new): context.tool list / call / request, the permission prompt, error table.
  • docs/client.md: capabilities.has, browser permissions from 3.1.5, speech.transcribe, tool.request.
  • docs/runtime.md, docs/security.md, AGENTS.md, CONTRIBUTING*.md, root READMEs: updated to match.
  • docs/snippets/audio-capture.ts: the Host's 16 kHz capture helper. It is not in the example, because the example doesn't record.
  • hello-miniapp: type snapshots synced to 3.1.6. Only their doc references were edited, to point at this repository's docs.

Effect on existing plugins

Still 0 errors repository-wide. New warnings, all expected:

  • webguhui/minimax-video, ACCESS_UNDECLARED: the editor records audio with getUserMedia + MediaRecorder but declares no deviceAccess, so recording fails on 3.1.5+ today. Fixing it means declaring deviceAccess: ["microphone"], which makes the package need 3.1.5. Its README should also mention microphone use. Best done with the author.
  • cristinamadureira353-svg/ai-office, ACCESS_UNDECLARED: this is a false positive. The hit is Godot's built-in audio-input glue in game.js. The unpacked game data (32 MB) has no microphone or recording classes, so the game doesn't record. It should not declare the microphone.
  • hanzijie/cq-viewer, README_MIN_VERSION_MISSING: it declares "session.read", and its README names 3.1.4-preview.4773. The README should name a release it was tested on at ≥3.1.5.

Verification

  • npm run check: 87 tests pass (69 → 87), all 23 plugins and the example validate with 0 errors.
  • New tests were written first and watched fail. The session.read 3.1.5 test was confirmed to fail against the old contract.mjs.
  • Parity with the Host: 48 inputs for engines / toolAccess / deviceAccess / agentAccess, compared against the Host main source: 0 mismatches. engines uses the Host's parseMcodeEngineRequirement; deviceAccess / agentAccess use its exported predicates. The toolAccess rule is not exported, so it was compared against a copy of the Host's one-line check.
  • CLI on a throwaway package, in three stages:
    1. Undeclared calls: 2 errors plus the getUserMedia warning.
    2. All grants declared plus engines >=3.1.6: only the README warning, asking for 3.1.6.
    3. README names 3.1.6: clean.
  • tsc --strict passes for audio-capture.ts and both type snapshots. tsc --checkJs passes for the example entry.

Review follow-up (ea6a501)

A two-axis review (repository standards, and the spec checked against the Host source) found:

  • Fixed bug: any agentAccess value counted as enough. A package declaring only "session.read" could call context.agent.run() without a report, although that call always fails. Agent calls are now checked per value, with one diagnostic per file.
  • Docs completed:
    • the microphone is granted only to audio-only requests from the main frame;
    • an engines bound also withholds mcpEndpoints, and publishing fails with MINIAPP_HOST_TOO_OLD;
    • every declared permission can be switched off;
    • page error codes are now documented;
    • .htm is listed among the scanned file types.
  • Refactor: the default miniapp result is built in one place.
  • Left as is (judgement calls):
    • the access shape mixes a list with flags;
    • an invalid agentAccess list also triggers ACCESS_UNDECLARED, because the Host grants nothing in that case.

Not verified

  • Nothing was installed or run in a real MiniMax Code 3.1.5 / 3.1.6 client.
  • ACCESS_UNDECLARED matches source text. It misses calls made through renamed variables, and can flag dormant code, as with ai-office.

dazhi added 3 commits October 26, 2026 18:04
…alls the manifest does not grant

The checker mirrors the 3.1.5 package reader (unchanged in 3.1.6):

- miniapp.json accepts engines ({ "mcode": ">=MAJOR.MINOR.PATCH" }), toolAccess (only "call"),
  and deviceAccess (only "microphone").
- The minimum-version table registers toolAccess, deviceAccess, and engines at 3.1.5, and moves
  agentAccess "session.read" from 3.1.4 to 3.1.5: only 3.1.4 preview builds accepted it, the
  released 3.1.4 rejects it. An engines bound above that raises the version the README must name.

ACCESS_UNDECLARED reports calls in the page or Node payload that need a grant the manifest does not
make. The level follows the oldest client that installs the package:

- context.agent / page agent calls without agentAccess; sessions(), observe({ all: true }), and the
  page's session() without "session.read"; context.tool / tool.request without toolAccess; and
  speech.transcribe without the microphone never work, so they are errors.
- getUserMedia without the microphone worked before 3.1.5 and is denied from 3.1.5, so it is an
  error only when the package already needs 3.1.5 or later, and a warning otherwise.

The payload walk moves from rules/node.mjs to fs.mjs so both rules share it; version comparison
moves to version.mjs.

Assisted-by: Claude Opus 5.5 (OpenCode)
- package-contract.md: engines, toolAccess, deviceAccess, the "session.read" minimum (3.1.5),
  per-item permission switches, the minimum-version table, and how npm run check compares declared
  access with the code.
- agent.md: session.run and session.read, whenBusy follow-ups, the per-minute turn limit, reading
  and observing the user's sessions, and the errors when the user switches access off.
- tool.md (new): context.tool list/call/request, the permission prompt, and the error table.
- client.md: capabilities.has, browser permissions on 3.1.5, speech.transcribe, tool.request.
- runtime.md: context.tool and context.capabilities.
- security.md: reading conversations, calling tools, and recording the microphone.
- docs/snippets/audio-capture.ts: the Host's 16 kHz PCM capture helper.
- AGENTS.md, CONTRIBUTING, root READMEs: the new docs, declared access, and the 3.1.5 minimum.
- hello-miniapp: miniapp-api.ts and client-api.ts synced to the 3.1.6 Host snapshots; only their
  doc references are pointed at this repository.

Assisted-by: Claude Opus 5.5 (OpenCode)
…s missing agentAccess once

Review follow-up:

- ACCESS_UNDECLARED treated any agentAccess value as enough, so a package declaring only
  "session.read" could call context.agent.run() unreported although every such call fails. Agent
  calls are now checked per value: run/answer/reply/cancel/open/models/agents/create need
  "session.run", sessions()/observe({ all: true })/the page's session() need "session.read", and
  reading or observing the Mini App's own sessions needs either. A file gets one diagnostic naming
  every missing value instead of one per rule.
- The default miniapp result is built in one place (emptyMiniApp).
- Docs: the scan covers .htm; the microphone is granted only to audio-only main-frame requests;
  an engines bound also withholds mcpEndpoints and fails workspace publishing with
  MINIAPP_HOST_TOO_OLD; every declared permission can be switched off; page code is not_permitted.

Assisted-by: Claude Opus 5.5 (OpenCode)
@MyPrototypeWhat
MyPrototypeWhat merged commit f18b3f7 into main Oct 26, 2026
1 check passed
MyPrototypeWhat added a commit that referenced this pull request Oct 26, 2026
…tract docs (#85)

AGENTS.md described only adding or updating a package, and the update path was one sentence.
Two branches agents already take were missing:

- Updating a package: keep the plugin ID, raise version, and call out a newly declared field
  that raises the minimum client version, since it drops older clients.
- Changing the checks or the docs: minimum versions come from the first released client, not a
  preview build (#59 recorded 3.1.4 from a preview; the released 3.1.4 rejects the field, fixed
  in #81); contract, rule, test, and docs change together; the checker stays dependency-free; a
  new error must keep existing packages at zero errors because CI validates all of them; and
  contract changes go in their own PR.

Assisted-by: Claude Opus 5.5 (OpenCode)

Co-authored-by: dazhi <dazhi@minimaxi.com>
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.

1 participant