Repository navigation
Add OpenFilm MiniApp - #73
MyPrototypeWhat merged 1 commit into
Conversation
41bfbcc to
7527d86
Compare
MyPrototypeWhat
left a comment
There was a problem hiding this comment.
Reviewed at 7527d86.
Thanks for the careful write-up and the acceptance script. The items below are mostly about the trust boundary between this package and code or data that lives outside it.
Must fix
-
Code is loaded and run from a local path outside the package.
plugins/cristinamadureira353-svg/openfilm/miniapp/node/desktop-host.mjs:86-91and:193-199import()modules from<openfilmRepo>/apps/desktop/src.server.mjs:83andserver.mjs:206default that path to~/Developer/openfilm(orOPENFILM_REPO), andminiapp.config.jsonturns desktop mode on by default. Whatever happens to sit in that folder runs inside the MiniApp process. Nothing pins it to a version or checks its integrity, and none of it is reviewed as part of this PR.docs/package-contract.mdasks for third-party runtime code to be vendored inside a payload root. Please vendor the handlers you need, under their license, intominiapp/node/, or make the web mode the default and drop the import from the local clone. -
The page receives the Studio key.
server.mjs:871-876returnskeyfrom/miniapp/studio, andminiapp/client/index.html:84-88puts it into the iframe URL (/open?key=…).docs/security.md("Secrets stay in the Node process. Never place credentials in HTML, Client JavaScript…") does not allow this, and it contradictsREADME.md:66. Please keep the key server-side, for example by serving the web mode through the same proxy, and removekeyfrom the/miniapp/studioresponse. -
The proxies forward everything.
server.mjs:927-930sends every/api/*method and path to Studio with the key attached (:778).server.mjs:921-924forwards every/p/*path.server.mjs:957-972forwards any WebSocket upgrade path and copies all incoming headers.docs/security.mdsays "do not proxy arbitrary URLs". It also says not to forward authentication headers, and:962-966passes every request header through excepthostandorigin. Please limit each proxy to the routes and methods the UI actually uses, and forward only the headers you need, such ascontent-typeandaccept. -
Every desktop IPC handler is reachable with
trusted: () => true.desktop-host.mjs:118,:127and:140mark every caller as trusted.server.mjs:695-735then exposes all registered channels to any page request. That includes starting and steering local agents (miniapp/client/bridge-web.js:140-149) anddesktop:agents:install/connect/own-model(desktop-host.mjs:219-228). Most notably,answerPermission(bridge-web.js:147) lets the page answer the local agent's permission requests directly, anddesktop:agents:automatic(desktop-host.mjs:223) turns on automatic mode.docs/security.mdasks you to treat the page as untrusted input and validate every parameter. Please register an explicit allowlist of channels with validated payloads, and leave out installer and sign-in flows. -
Process launches use paths taken from config.
server.mjs:541-549accepts anydesktopApppath and args from config, and:611runsopen -n <path> --args ….server.mjs:327runsopenfilmBin/openfilmArgsfrom config with the fullprocess.env(:330). The calls use argument arrays, which is good. Even so,POST /miniapp/open-desktop(server.mjs:891) can launch whatever the config names. Please restrictopen-desktopto a fixed list of OpenFilm app bundle locations and drop the free-formdesktopAppandargs. Also pinopenfilmBinto the bundled default and pass a minimal environment. -
Writes can land outside
context.dataDir.server.mjs:56and:177-178fall back to~/.minimax/openfilm-studio, andconfig.studioHomecan point anywhere. State must stay undercontext.dataDir. Please remove the home-directory fallback and thestudioHomeoverride. -
Reads outside the package are undeclared or misstated.
server.mjs:60-63and:401-402read the real~/.openfilm/studio.json(or~/.openfilm-dev).server.mjs:477-479reads.film/idfrom every path listed there.server.mjs:554-558lists<repo>/apps/desktop/.dev/runtime.desktop-host.mjs:236-248reads/api/doctorand an app report and copies them to the clipboard withpbcopy. Please document every one of these, along with theopen,ps,pbcopyandnpxcommands and the npm registry as an outbound host, inREADME.md## Data & access(README.md:55-61), asdocs/security.mdrequires. -
npx -y openfilm@0.2.5is downloaded and run on first start.server.mjs:79-80and:327do this. Runtime code then comes from the registry instead of from the reviewed package. Please disclose it prominently (see item 7). Bundling or vendoring would be preferable.
Optional
forwardToFilmrewrites upstream JavaScript to remove the same-origin guard inbridge.js(server.mjs:835-838). This is fragile across OpenFilm versions and weakens a check upstream relies on. Consider a separate origin or port for the film pages instead.server.mjs:842has a leftover "temporary troubleshooting" comment.desktop-host.mjs:155hard-codes version0.2.5, which can drift fromopenfilmArgs./miniapp/health(server.mjs:895-911) returns the boot log and local paths. Consider trimming it.plugin.jsondescription,exampleQueries,skills/openfilm/SKILL.md, the_说明key inminiapp.config.json:7, and most code comments are in Chinese. An English description and skill text would help English-language agents and reviewers.- The BYOK master key sits next to the ciphertext in the same directory (
desktop-host.mjs:274-280), so the AES-256-GCM layer protects against little beyond casual reads. Please say so inREADME.md:68.unsealKeyalso accepts a plaintextraw:prefix (desktop-host.mjs:291). test/accept-miniapp.mjs:107hard-codes port 52987, and the process-count check callslsof. On a Linux machine withoutlsofthat check fails. Picking a free port and skipping the check whenlsofis missing would make the script portable.NOTICE.md:10states that the author gave permission. Linking the upstream license (and its SPDX id) directly inNOTICE.mdwould make attribution clear, especially once any upstream code is vendored (see Must fix 1).desktop:revealaccepts an arbitrary path (desktop-host.mjs:167). Consider limiting it to project directories.skills/openfilm/SKILL.md:24says the agent can call/miniapp/*through the host's MCP, butminiapp/miniapp.json:19has an emptymcpEndpoints. Please align the two: either declare the endpoints or drop the claim.desktop-host.mjs:198-199loads the upstreamagent-usageandapp-reportmodules. Could you state which paths on disk these read?
Verified
npm run checkon Node 22.23.4: validate reportsplugins/cristinamadureira353-svg/openfilm: OK, and 69/69 repository tests pass.- The root README changes are a single catalog row each in
README.md:60andREADME.zh-CN.md:60. No CI, roottest/, or script changes. - Tests are inside the plugin (
test/accept-miniapp.mjs), outside theminiapp/payload. The payload is about 100 KB with no build output ornode_modules. - The server binds only
context.listenwithnode:http(server.mjs:1014) and logs throughcontext.logger. Nothing under/__mavis/. - Child processes are spawned with argument arrays and no shell (
server.mjs:327,:578,:611;desktop-host.mjs:108,:244). disposecloses SSE streams, local agent sessions, and the Studio it spawned (server.mjs:1030-1069).test/accept-miniapp.mjson Linux (Node 22,SKIP_PROBE=1, no local OpenFilm clone): web mode, the fallback for an unbuilt shell, dual-panel locking, and dispose pass. The desktop-mode checks fail as expected without a clone, and thelsofcheck fails becauselsofis not installed.- The package
LICENSEis MIT. No OpenFilm source is vendored in this PR.
|
Update to the review above: items 1 (loading code from |
7527d86 to
a7e48fe
Compare
|
Thanks again for the thorough review. I have addressed the Must fix items and most of the Optional ones, and re-run the acceptance (all checks pass) plus Must fix
Optional
Re-verified
|
MyPrototypeWhat
left a comment
There was a problem hiding this comment.
Thanks for the quick, thorough turnaround. I re-reviewed a7e48fe, and seven of the eight items are resolved. One disclosure gap remains, so I'm keeping this at request changes. It only needs a README update, no code changes.
Must fix
-
## Data & accessstill leaves out several files the desktop handlers read. The README says agent records are read "under~/.claudeand~/.codex(agent-records.mjs)". The upstream modules this package imports from<openfilmRepo>/apps/desktop/srcread more than that, and the plugin reaches them through allowlisted channels (desktop:agents:mcp,desktop:agents:skills,desktop:skills:*,desktop:chat:*,desktop:local-agents:*). Checked against current openfilm/openfilmmain:agent-skills.mjsownMcpServers:~/.claude.json(a file in the home directory, not inside~/.claude; the code takes only themcpServersentries) and project.mcp.json;~/.codex/config.toml(only[mcp_servers.*]command/url);~/.config/opencode/opencode.json(c),~/.qwen/settings.json,~/.copilot/mcp-config.json.agent-skills.mjsownSkills:~/.claude/skills,~/.codex/skills,~/.agents/skills,~/.copilot/skills, plus the project-level.claude/skills,.agents/skills,.codex/skills,.github/skillsand.opencode/skill(s).agent-records.mjs:~/.claude/projects/**/<session>.jsonl(includingsubagents/),~/.codex/sessions/**and~/.codex/archived_sessions,~/.kimi-code/session_index.jsonland its session folders,~/.copilot/session-state/<id>/events.jsonl.CLAUDE_CONFIG_DIR,CODEX_HOMEandCOPILOT_HOMEare honored.environment.mjsloginShellVariables: runs the user's login shell ($SHELL -l -i -c 'env -0') to collect environment variables, which are then passed to the local agents it starts.
None of these are credentials. Nothing touches
~/.claude/.credentials.json,~/.codex/auth.json, the keychain or MiniMax Code's login data. They still need to be disclosed:- List the files, globs and the login-shell step above in
## Data & access, in bothREADME.mdandREADME.zh-CN.md. - Say that only MCP server names and commands or URLs are read from those config files, and only session transcripts from the record folders.
- Note that the exact set follows the upstream version in
openfilmRepo, since it depends on the user's checkout.
Optional
desktop:revealcompares the raw string withroot + '/'(desktop-host.mjs). A path like<project>/../../somewherepasses the check. It only reveals the path in Finder, so the impact is small. Runningpath.resolve(orrealpath) before the prefix check would make the restriction do what the README says.desktop:skills:revealanddesktop:chat:revealgo to the upstreamrevealwithout the same check.desktop:local-agents:permissionis still allowlisted, so the page can answer a local agent's permission prompts. This is how the desktop UI works and the page is the user's own UI, so I'm not blocking on it. A short note in## Securitywould help users understand it.- The Configuration table still lists
openfilmBin/openfilmArgsanddesktopAppas keys, although none of them can be configured anymore. Removing those rows, or marking them as fixed values, would avoid confusion. ThedesktopCandidates()doc comment inserver.mjsstill says the candidates come fromdesktopAppin the config. DEFAULT_STUDIO_HOME(~/.minimax/openfilm-studio) is still the fallback whencontext.dataDiris missing. The same path is mentioned in themasterKeycomment indesktop-host.mjs. Consider dropping the fallback, or at least updating the comment.- The Dev candidates in
open-desktopdepend onopenfilmRepo/OPENFILM_REPO. That is reasonable, since the user already trusts that checkout for desktop mode. Please mention it in theopen -nbullet of## Data & access.
Verified
npm run checkon Node 22: validate reportsplugins/cristinamadureira353-svg/openfilm: OK, and 69/69 repository tests pass.- Item 1: loading
<openfilmRepo>/apps/desktop/src/*.mjsis disclosed in## Data & access. - Item 2:
/miniapp/studiono longer returnskey. Web mode is served through the same-origin editor proxy, and the key is added only server-side (studioHeaders, WebSocket handshake). - Item 3:
/api/*goes through theSTUDIO_API_ALLOWprefix list (other paths get 403), and onlyaccept,content-typeandrangeare forwarded./p/*is GET/HEAD only. WebSocket upgrades are limited to/api/eventsand/api/projects/<id>/eventsand forward only the handshake headers. No cookies or incoming auth headers are forwarded. - Item 4:
/ipc/<channel>answers 403 for any channel not inIPC_RULES, and each allowed channel has a payload check.desktop:agents:install,connectandautomatic(and the sign-in flow) are not in the allowlist.desktop:revealis limited to project folders (see Optional 1). - Item 5:
desktopApp/desktopAppArgsare gone.open-desktoptakes no input from the request and opens only<openfilmRepo>/apps/desktop/.dev/runtime/*/OpenFilm Dev.app,/Applications/OpenFilm.appor~/Applications/OpenFilm.app, with fixed arguments and aPATH/HOME-only environment. The Studio is started as the pinnednpx -y openfilm@0.2.5 openwithPATH,HOME,LANG,TMPDIRand theOPENFILM_*values set by the plugin, so nothing else fromprocess.envis passed through. Neither the page nor the config can choose the executable or its arguments. All spawns use argument arrays without a shell. - Item 6: writes outside
context.dataDir(thestudioHomeoverride) are disclosed. - Item 8: the first-run download from
registry.npmjs.orgis disclosed. - The plugin name, id and skill do not use "MiniMax". Tests stay in the plugin's
test/folder. The only changes outside the plugin are one catalog row each inREADME.mdandREADME.zh-CN.md. No CI,.github, root script or root test changes. test/accept-miniapp.mjson Linux (Node 22,SKIP_PROBE=1, no OpenFilm clone): the new boundary checks for/miniapp/studiowithoutkeyand for/api/quitand/api/openreturning 403 pass, as do web mode, the unbuilt-shell fallback, the two-panel lock and dispose. The free-port andlsofskip changes work. The desktop-mode checks fail as expected without a clone. These include the IPC 403/400 andrevealassertions, so I verified those parts by reading the code.
Run OpenFilm inside MiniMax Code with the desktop interface: the Studio editor plus the desktop chat column and local agents, by serving the desktop page and bridging window.openfilmNative over HTTP, reusing the desktop app's own Node handlers (chat, local agents, skills, roster). - desktopMode with web-Studio fallback when the OpenFilm clone/shell build is unavailable - project switcher, desktop-app launcher, concurrent-boot lock, dispose that closes agents, SSE streams and only our own Studio - state under context.dataDir; no secrets in pages or logs - README (en/zh-CN), LICENSE, root README rows Validated: npm run check (this package OK, 0 errors 0 warnings); 32-check acceptance covering boot, tree, desktop IPC, roster, SSE, web fallback, missing shell, concurrent boot and dispose.
a7e48fe to
ae12684
Compare
|
The disclosure gap is filled in both
The section also says explicitly what is read from them (only MCP names and Re-ran |
MyPrototypeWhat
left a comment
There was a problem hiding this comment.
Thanks for the update. Approving. I re-reviewed ae12684. Since a7e48fe, only the plugin's README.md and README.zh-CN.md changed, so the code I reviewed last time is unchanged.
Previous must-fix: resolved
## Data & access now covers the MCP config files, skill directories, session records and the login-shell environment capture in both languages, and says what is taken from each. I checked it against the upstream handlers (agent-skills.mjs, agent-records.mjs, environment.mjs) and it matches. The $SHELL wording is right, since the code spawns the user's login shell rather than a fixed /bin/zsh. The credentials statement holds too: none of these handlers read ~/.claude/.credentials.json, ~/.codex/auth.json or the keychain.
The open -n note on openfilmRepo / OPENFILM_REPO and the Security note on desktop:local-agents:permission are in place as well.
Optional
- The upstream handlers read a few more locations than the list names: the opencode and Qwen skill folders (
~/.config/opencode/skill(s),~/.qwen/skills, project.qwen/skills), project-levelopencode.json(c)and.qwen/settings.json, the per-projectmcpServersinside~/.claude.json, Codex plugin skills in its plugin cache, andQWEN_HOME/XDG_CONFIG_HOME. The README already says the set follows the upstream version, so this doesn't block merge. - Still open from the last review:
desktop:revealchecks the raw string before resolving it, anddesktop:skills:reveal/desktop:chat:revealskip that check.DEFAULT_STUDIO_HOMEis still the fallback whencontext.dataDiris missing.- The
desktopCandidates()doc comment inserver.mjsstill refers todesktopAppin the config.
Verified
git diff a7e48fe ae12684touches only the two plugin READMEs (+20/-6). No code, tests, package files,.github/,scripts/or root tests changed.npm run checkat the repo root onae12684: validation passes and 69/69 tests pass.
Add OpenFilm MiniApp
What and why
OpenFilm is an open-source video editor with an agent chat — original repository: https://github.com/openfilm/openfilm. This package puts the OpenFilm desktop interface inside MiniMax Code as a MiniApp: the Studio editor with the desktop chat column and local agents, not only the plain web Studio.
The desktop app is Electron, and a MiniApp can only be a page + a Node process, so the Electron window itself cannot be embedded. What this package does instead is serve the desktop app's own page and replace the Electron native bridge (
window.openfilmNative) with an HTTP one:apps/desktop/shell/bridge.tsnever imports electron — it only consumeswindow.openfilmNative, so the builtshell/distcan be served as-is with a small injected bridge (miniapp/client/bridge-web.js).chat-ipc.mjs,local-agents-ipc.mjs,skills-ipc.mjs,agent-roster.mjs,agents.mjs,agent-usage.mjs,app-report.mjs— none of them imports electron). They are registered against an HTTPipcMainshim, so chat, local agents, skills and Settings → Agents run the desktop app's real code.webContents.send()forwards to it. Studio's/api/*and its WebSocket event stream are proxied same-origin, with the key attached on the server side only.@openfilm/desktopis not published to npm, so desktop mode needs a local clone of openfilm/openfilm and onepnpm --filter @openfilm/desktop build:shell. Without it the panel falls back to the plain web Studio (no chat column). This is documented in the README.Also included: opens the most recent project on launch (project switching then happens inside OpenFilm itself — no extra chrome of our own), an agent-callable endpoint that launches/activates the installed desktop app, a concurrent-boot lock (two panels start one Studio), and a
disposethat closes local agent sessions, ends SSE streams, and quits only the Studio this instance spawned.Security
context.dataDir(openfilm-studio/). The user's own desktop Studio home is never taken over.0600master key in that state directory (the desktop app uses the OS keychain; they are not shared).studio.jsonand.film/idfiles are only read, never written by the panel itself.Testing
Environment: MiniMax Code desktop on macOS (Apple Silicon), Node 22, OpenFilm 0.2.5, an openfilm/openfilm clone with
build:shellrun.npm run check— this package: OK, 0 errors, 0 warnings (other warnings in the output belong to existing packages).hello,local-agents:list,prefs), realchat:loadsessions, agent roster (11 agents), skills/MCP channels, SSE, web fallback, missing-shell error, two instances racing (one spawned, one reused, a single Studio process), anddisposewith an open SSE stream (does not hang; no Studio left behind).desktop:local-agents:probefor Codex starts a real ACP session (@agentclientprotocol/codex-acp1.13.1); Claude Code correctly reportsnot-installed.Not exercised: a full agent turn end to end (it would spend the user's agent quota and modify a real project) — only the ACP probe was run. Windows/Linux are untested (some paths use
open,pbcopy,ps). Native file pickers and screen capture returnnullby design.Notes for the reviewer
miniapp.config.local.jsonis gitignored: machine-specific overrides (repo path, which desktop app to launch, legacy state home) stay out of the package.Update after the maintainer's review
The Must fix items are addressed: no Studio key reaches any page (web mode is proxied same-origin too), API/proxy and WebSocket routes are allowlisted with only the needed headers, IPC channels are an explicit allowlist with payload validation (installer/sign-in/
automaticremoved), process launches are fixed to auto-detected OpenFilm apps withnpx -y openfilm@0.2.5and a minimal environment, and every external read plus thenpxdownload is documented in## Data & access. The two items relaxed by the reviewer (local clone loading, the legacystudioHomeoverride) are documented there as well. Optional items are mostly handled too (English description/SKILL, trimmed health endpoint, derived version, upstream LICENSE link, project-limited reveal, no MCP-endpoint claim, free test ports,lsof-optional checks, BYOK plaintext caveat). Acceptance is now 44 checks, all passing, including the new security assertions.