Skip to content

Add MoMo Collab (momo-collab) MiniApp - #31

Merged
amszuidas merged 1 commit into
mainfrom
feat/add-momo-collab
Oct 19, 2026
Merged

amszuidas merged 1 commit into
mainfrom
feat/add-momo-collab

Conversation

@amszuidas

@amszuidas amszuidas commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

What

Adds MoMo Collab (plugins/amszuidas/momo-collab/, plugin ID momo-collab, version 0.2.0) and a row in both root README tables.

MoMo is a project steward. You drop a thought, screenshot, or link on it and it files a record under the right idea. Once an idea's goal, deliverable, and done criteria are clear, MoMo writes a task. After you agree, it runs the task in its own Agent session with a full handoff, checks the outputs against each done criterion in a separate session, and hands the result to you for review. A board shows To do / In progress / In review / Done.

preview

Declared capabilities

  • agentAccess: ["session.run"], agentConcurrency: 8, surface.window: requires MiniMax Code 3.1.2 or later. The README states this under ## Tested environment.
  • Managed MCP endpoint momo at /mcp/momo. Its tools read and change ideas, records, and tasks only; they do not touch files.
  • Skill momo-collab: lets an ordinary conversation hand its conclusions to MoMo.

Safety notes for review

  • Approvals: every permission.requested is shown in the page, and allowOnce is sent only after the user clicks it.
  • Retries: a failed task run is retried at most once, in the same session. AGENT_OUTCOME_UNKNOWN is never retried.
  • Network: the Node service makes no outbound requests and the page loads no remote resources.
  • Processes: none spawned.
  • Writes outside context.dataDir: one folder, <dataDir>/agents/mavis/miniapps/momo-collab/, holding uploads/ and outputs/<taskId>/. It is located by going four levels up from context.dataDir. This relies on the current, unspecified Host layout and is documented in ## Data & access; if that folder does not exist, the plugin falls back to context.dataDir. It is used because the primary agent can read it without an approval prompt, so task sessions can read attached screenshots.
  • Output preview and project folders: output preview is limited to paths a task session reported, at most 5 MiB. It refuses anything inside the MiniMax Code data directory except that outputs folder, and project folders may not point there either.

Testing

  • npm run check: plugins/amszuidas/momo-collab: OK, repository: OK, 69/69 tests pass.
  • Installed and used in MiniMax Code 3.1.3 (internal preview build) on macOS 26.6. Main flows were tested manually: capture, ideas, task start, live progress, approvals, review.
  • End-to-end smoke against the real Node entry and MCP endpoint with a mock Agent: create → defer → start → host stop → continue in the same session → approval → submit → per-criterion verification → review → done, plus a project-less task writing to the outputs folder and project-folder validation.
  • Page checked in headless Chromium at 1180 px and 420 px, with no horizontal overflow and no console errors.

Not verified

  • Windows.
  • MiniMax Code 3.1.2 exactly (tested on 3.1.3 preview only).

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

MoMo is a project steward: it files stray thoughts, screenshots, and links
as records under ideas, writes a task once an idea's goal, deliverable, and
done criteria are clear, runs the task in its own Agent session with a full
handoff, checks the outputs against each done criterion in a separate
session, and hands the result to the user for review. A board shows every
task as To do, In progress, In review, or Done.

The package declares agentAccess (session.run), agentConcurrency 8,
surface.window, a managed MCP endpoint (momo), and a Skill that lets an
ordinary conversation hand its conclusions to MoMo. Approvals are only
sent after the user clicks them. The README documents the files it writes,
including the Agent-readable uploads/outputs folder it locates from
context.dataDir, which relies on the current Host data layout.
@amszuidas
amszuidas merged commit 5a74943 into main Oct 19, 2026
1 check passed

@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 contribution — post-merge review found a few security issues that should be fixed in a follow-up PR:

  1. Arbitrary local file read. submit_task_result accepts any absolute path in outputs[].file; GET /api/tasks/:id/outputs/:n then serves it (up to 5 MiB) and checkOutputs inlines text files into the verifier prompt. With a stubbed host I could read /etc/passwd and a file in a simulated home directory. Please restrict outputs to the task's project folder / outputs folder (after realpath), and update the README line saying the MCP tools "cannot read or write files".
  2. Symlink bypass of isProtected. The check is a string prefix test and the outputs folder is exempt, so a symlink in outputs/ pointing at a file in the MiniMax Code data directory is served (reproduced with a fake credentials.json). Resolve with fs.realpath before checking.
  3. Dispatch consent is self-asserted by the model. start_task only checks user_agreed: true; the page auto-creates and claims the session on dispatch.request, so any session (including a running task session or a prompt-injected one) can start a task with no user click. Per docs/security.md, please make the actual dispatch require a user action in the page (e.g. MCP start_task only surfaces a confirm button).
  4. approve_task / revise_task over MCP let the Agent mark a task done or re-run it without the user. Please gate these on a user action or remove them from MCP.

Minor: uploads/outputs are written under <mcodeRoot>/agents/mavis/miniapps/... (outside context.dataDir), but the README describes it as <dataDir>/agents/...; please correct the path. task_report.workspace should be validated like project_dir.

Approvals handling (only user-clicked allowOnce, verifier auto-denies), escaping, upload validation, and no network/child processes all look good.

/** @param {any} task @param {string} file */
resolveOutput(task, file) {
if (typeof file !== 'string' || !file) return undefined;
if (isAbsolute(file)) return resolve(file);

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.

Absolute paths from submit_task_result are accepted verbatim, so any file the user can read can be previewed via /api/tasks/:id/outputs/:n and inlined into the verifier prompt. Please constrain to the task folder after realpath.

* own agent-readable outputs folder.
* @param {string} file
*/
isProtected(file) {

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.

String-prefix check without realpath; a symlink inside the exempt outputs folder reaches the MiniMax Code data directory.

const updated = store.task(task.id);
return { task_id: updated.id, title: updated.title, project_dir: updated.projectDir };
}
case 'start_task': {

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.

user_agreed is asserted by the model; combined with the page's auto-claim this starts a task session with no user interaction.

await engine.receipt(str(args.reply_to) || undefined, { kind: 'task_card', taskId: task.id });
return { task_id: task.id, mode: result.mode, project_dir: task.projectDir, note: '进度会实时显示在任务卡上,不必在回复里复述' };
}
case 'approve_task': {

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.

approve_task has no confirmation; the Agent can mark tasks done on the user's behalf.

- **Processes.** None spawned by the plugin.
- **Network.** The Node service makes no outbound requests, and the page loads no remote resources.
- **Browser storage.** `sessionStorage` keeps a random page ID so a reloaded page keeps receiving its own dispatch requests.
- **MCP.** `servers.mcp.json` declares the `momo` MCP server, served by this Mini App at `/mcp/momo`. Its tools read and change ideas, records, and tasks; they cannot read or write files.

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.

Not accurate: via submit_task_result the tools cause files to be read and served.

- **Files written by the plugin:**
- `context.dataDir/state.json`: ideas, records, tasks, and chat, written atomically through a temporary file and rename.
- `context.dataDir/telemetry.jsonl`: local usage events for the trial metrics page. Nothing is uploaded.
- An Agent-readable folder next to the Host's per-agent data: `<dataDir>/agents/mavis/miniapps/momo-collab/`. Its `uploads/` subfolder holds images you attach. Its `outputs/<taskId>/` subfolder holds outputs of tasks that have no project folder. The plugin locates it from `context.dataDir` by going up four levels. This relies on the current, unspecified layout of the Host data directory; when that folder does not exist, the plugin uses `context.dataDir` instead. It is used because the primary agent can read it without an approval prompt, so a task can read your screenshots.

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.

The folder is four levels above dataDir (<mcodeRoot>/agents/...), not <dataDir>/agents/....

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