Skip to content

Feature: secret variables, separated window - #2516

Open
erow wants to merge 5 commits into
GCWing:mainfrom
API4ward:cursor/secret-variables-7a6f
Open

Feature: secret variables, separated window#2516
erow wants to merge 5 commits into
GCWing:mainfrom
API4ward:cursor/secret-variables-7a6f

Conversation

@erow

@erow erow commented Aug 26, 2026

Copy link
Copy Markdown

Summary

Secrets: 在对话中使用{{Secret}}避免暴露key等关键信息给agents。仅对Tool可见。
View mode: 给mini app 增加多种view模式。

Type and Areas

Type: UI, Feature

Areas: web UI

Motivation / Impact

  • 保护隐私内容。
  • 优化小程序的显示

Verification

独立窗口:
image

写入secret {{c}}

image

Reviewer Notes

Checklist

  • This PR is focused and does not include secrets, temporary prompts, generated scratch files, or unrelated artifacts.
  • Relevant verification is recorded above, or skipped checks are explained.
  • User-facing strings, docs, and locales are updated where applicable.

erow and others added 5 commits August 25, 2026 16:11
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
… spec

Introduce the foundational contract layer for the Mini App system upgrade:
- MiniAppViewMode (background/front/full) with wire (de)serialization and Front default
- MiniAppLifecycleEvent (install/uninstall/start/stop) and MiniAppLifecycleScripts manifest
- view_mode and lifecycle fields on MiniApp/MiniAppMeta (additive, defaulted, upgrade-safe)
- HOOKS_DIR + resolve_contained_relative path-traversal guard in the storage layout
- plan_lifecycle_script pure resolver and miniapp_lifecycle_event_payload
- design specification doc (docs/features/mini-app-system.md)

Contracts stay pure (no IO); services/assembly/desktop/web-ui wiring follows.
Includes unit + contract tests in bitfun-product-domains.

Co-authored-by: erow <erow@users.noreply.github.com>
Add run_lifecycle_script in services-integrations that executes a resolved
lifecycle script (Bun/Node) as a one-shot child process via the shared
non-interactive process facade, capturing stdout/stderr/exit code with a
timeout. LifecycleScriptOutcome::from_output keeps result mapping pure and
unit-tested; a runtime-gated test exercises a real script run.

Path containment and event selection remain pure decisions in
bitfun-product-domains; this module only performs concrete execution.

Co-authored-by: erow <erow@users.noreply.github.com>
* feat(miniapp): dispatch lifecycle events and view-mode/lifecycle updates in manager

- MiniAppManager::run_lifecycle_event resolves the declared script (traversal-
  guarded), detects Bun/Node, and runs it via the services runner, injecting
  app id/dir/event/policy as env; returns a MiniAppLifecycleReport (incl. failures)
- MiniAppManager::set_view_mode and set_lifecycle_scripts persist those app
  properties without recompiling the document
- lifecycle_runner gains env injection for trusted script context
Adds core manager tests (view mode, no-script, real script run, traversal reject).

Co-authored-by: erow <erow@users.noreply.github.com>

* feat(miniapp): desktop commands for view mode, lifecycle, and full window

- miniapp_set_view_mode / miniapp_set_lifecycle_scripts / miniapp_run_lifecycle_event
- open_miniapp_full_window opens an independent OS window hosting the app
  (?bitfunWindow=miniapp&miniAppId=...), mirroring the agent-companion window
- automatic lifecycle dispatch: install on create/import, uninstall on delete
  (before removal), stop on worker stop; each emits a miniapp-lifecycle event
- re-export MiniAppLifecycleReport; register new commands in invoke_handler
- spec: correct execution semantics to best-effort and update status checklist

Desktop crate compiles and the running tauri dev app restarted cleanly.

Co-authored-by: erow <erow@users.noreply.github.com>

* feat(miniapp): web UI view-mode routing, lifecycle triggers, and full window

- MiniAppAPI: setViewMode / setLifecycleScripts / runLifecycleEvent / openFullWindow
  and view_mode / lifecycle types on MiniAppMeta
- gallery open branches on view_mode: full opens an independent OS window,
  front/background open a scene tab; fires the start lifecycle event on open
- main.tsx renders a standalone MiniApp window for ?bitfunWindow=miniapp
  (reusing MiniAppScene) so full mode has real content
Type-check and lint pass.

Co-authored-by: erow <erow@users.noreply.github.com>

* feat(miniapp): add view-mode selector to the gallery detail modal

Users can switch an app between background / tab (front) / window (full) from
the app detail modal; calls miniapp_set_view_mode and refreshes the store.
Adds i18n keys (detail.viewMode.*) for en-US / zh-CN / zh-TW.
type-check, i18n:audit, and lint pass.

Co-authored-by: erow <erow@users.noreply.github.com>

* feat(miniapp): background collapsed-panel dock for background view mode

- MiniAppBackgroundDock: resident, collapsible bottom-right panel hosting
  background view-mode apps (multi-app tabs, per-app close stops worker)
- store: backgroundAppIds + openBackground/closeBackground, pruned in setApps
- gallery: background mode routes to the dock (not a tab); dock mounted in AppLayout
- i18n dock.* keys for en-US/zh-CN/zh-TW
Completes the three view modes end to end. type-check, i18n:audit, theme audit, lint pass.

Co-authored-by: erow <erow@users.noreply.github.com>

* fix(miniapp): dismiss startup overlay in standalone full-window render

The full-mode MiniApp window renders MiniAppScene directly and returns before
the main startup pipeline, so the static startup overlay never hid and covered
the app. Call hideStartupOverlay() explicitly in that branch.

Co-authored-by: erow <erow@users.noreply.github.com>

* fix(miniapp): carry hooks/ directory on import so lifecycle scripts exist

Import previously copied only meta.json + source/, so a declared lifecycle
script under hooks/ was missing after install and the dispatch reported
'script not found'. write_import_bundle now recursively copies the optional
hooks/ directory into the app dir. Extends the import-bundle IO test.

Co-authored-by: erow <erow@users.noreply.github.com>

* docs(miniapp): record verification results and market-hooks follow-up

Co-authored-by: erow <erow@users.noreply.github.com>

* feat(miniapp): add named-scripts contract to extend app capabilities

- MiniAppScriptDef { name, path, description } + scripts field on MiniApp/MiniAppMeta
  (additive, defaulted, content-hashed, upgrade-safe)
- find_script_path + plan_named_script (traversal-guarded) resolver
- MiniAppUpdatePatch.scripts + apply + draft copy; miniapp_script_event_payload
- update all construction sites; contract + unit tests

Co-authored-by: erow <erow@users.noreply.github.com>

* feat(miniapp): run named scripts in manager + carry scripts/ on import

- run_miniapp_script (args-aware) generalizes the script runner; lifecycle
  delegates to it
- MiniAppManager::run_named_script (traversal-guarded, runtime-detected, env
  BITFUN_MINIAPP_SCRIPT) and set_scripts; MiniAppScriptRunReport
- SCRIPTS_DIR constant; import copies both hooks/ and scripts/
- manager test runs a real named script with args

Co-authored-by: erow <erow@users.noreply.github.com>

* feat(miniapp): desktop + web UI for named scripts

- Tauri commands miniapp_set_scripts and miniapp_run_script (emits miniapp-script)
- MiniAppAPI setScripts/runScript + MiniAppScriptDef/ScriptRunResult types + scripts on meta
- gallery detail modal lists declared scripts with a Run button; result via notification
- i18n detail.scripts.* for en-US/zh-CN/zh-TW
type-check, i18n:audit, lint pass.

Co-authored-by: erow <erow@users.noreply.github.com>

* docs(miniapp): document named-scripts capability and market security boundary

Co-authored-by: erow <erow@users.noreply.github.com>

* fix(miniapp): register remote policy and peer-local window command

Declare LocalOnly remote-workspace policies for the new MiniApp view-mode,
lifecycle, named-script, and full-window Tauri commands so the policy
contract test stays green. Keep open_miniapp_full_window on the controller
in Peer Device Mode (window chrome) across desktop, CLI, and web deny lists.

Co-authored-by: erow <erow@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Store user secrets in an AES-GCM vault under the user data directory and
expose a Settings → Secrets tab for write-only CRUD. Chat and model
history keep {{name}} placeholders unchanged; the tool pipeline resolves
them into a local copy used only for tool.call, so agents never see
plaintext values. Unknown placeholders fail closed at execution.

Co-authored-by: erow <erow@users.noreply.github.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.

2 participants