Skip to content
This repository was archived by the owner on Oct 13, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/pr-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,7 @@ jobs:

BUNDLE_ID="$(/usr/libexec/PlistBuddy -c 'Print :CFBundleIdentifier' "$APP_PATH/Contents/Info.plist")"
VERSION="$(/usr/libexec/PlistBuddy -c 'Print :CFBundleShortVersionString' "$APP_PATH/Contents/Info.plist")"
node scripts/evaosVerifyRendererDependencyPrune.js "$APP_PATH"

{
echo "## Thin app smoke"
Expand All @@ -715,6 +716,7 @@ jobs:
echo "- Version: \`$VERSION\`"
echo "- Bundle ID: \`$BUNDLE_ID\`"
echo "- Package smoke reasons: \`$PACKAGE_SMOKE_REASONS\`"
echo "- Renderer dependency prune: verified \`app.asar\` and \`app.asar.unpacked/node_modules\`"
echo
echo "This PR artifact is intentionally unpacked and may be ad-hoc/non-Developer-ID signed by packaging hooks. It produces no DMG, no release metadata, no notarization/stapling proof, no TCC or permission proof, and no public release proof."
echo
Expand Down
74 changes: 37 additions & 37 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

57 changes: 57 additions & 0 deletions docs/evaos/workbench-renderer-dependency-ledger.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Workbench Renderer Dependency Ledger

This ledger supports #452. Its purpose is to keep renderer-only libraries out of production raw `app.asar/node_modules` while preserving the runtime packages used by the main process, preload scripts, native modules, MCP servers, packaged resources, and updater/release flows.

## Rule

Move a root package from `dependencies` to `devDependencies` only when all of these are true:

- It is imported only by `packages/desktop/src/renderer/**` or renderer-focused tests.
- It is bundled by the renderer Vite build into `out/renderer`.
- It is not imported by `packages/desktop/src/process/**`, `packages/desktop/src/preload/**`, `packages/desktop/src/common/**`, `packages/web-host/**`, `packages/web-cli/**`, or `scripts/**`.
- It is not explicitly included in `packages/desktop/electron-builder.yml` as a raw runtime `node_modules` or `asarUnpack` resource.

## Moved Renderer-Only Packages

| Package | Renderer evidence | Runtime evidence | Notes |
| ------------------------------------------------------------------------------------------ | ------------------------------------------------ | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `@arco-design/web-react` | 204 renderer imports plus DOM tests | no process/preload/common/script imports | UI component library; bundled into renderer. |
| `@icon-park/react` | 122 renderer imports | no process/preload/common/script imports | Icon library; bundled into renderer. |
| `mermaid` | `components/Markdown/MermaidBlock.tsx` | no process/preload/common/script imports | Large diagram renderer; bundled into renderer. |
| `react-syntax-highlighter` | Markdown, diff, and code preview renderers | no process/preload/common/script imports | Code highlighting stays in renderer chunks. |
| `@monaco-editor/react` | HTML preview viewer | no process/preload/common/script imports | Editor surface stays renderer-bundled. |
| `@uiw/react-codemirror`, `@uiw/codemirror-extensions-langs`, `@codemirror/*` | settings editors and preview editors | no process/preload/common/script imports | CodeMirror editor dependencies stay build-time/renderer only. |
| `diff`, `diff2html` | diff viewer and renderer message diff UI | no process/preload/common/script imports | Diff UI stays renderer-bundled. |
| `katex`, `react-markdown`, `rehype-*`, `remark-*`, `streamdown` | Markdown and preview rendering | no process/preload/common/script imports | Markdown/math rendering stays renderer-bundled. |
| `react`, `react-dom`, `react-i18next`, `react-router-dom`, `react-virtuoso`, `swr` | renderer app, router, list, i18n, and data hooks | no process/preload/common/script imports | Runtime UI libraries are bundled into `out/renderer`; the app does not require raw React from `app.asar/node_modules`. |
| `@dnd-kit/*`, `@floating-ui/react`, `classnames`, `dayjs`, `eventemitter3`, `qrcode.react` | renderer UI helpers | no process/preload/common/script imports | Small direct dependencies kept out of production raw shipping when used only by renderer. |

## Kept Or Deferred Packages

These package families stay in `dependencies` for this PR. Some are proven runtime keepers; others are deferred because #452 is intentionally limited to renderer-only direct dependency moves, not broad unused-dependency removal.

- Proven main/process/preload/updater keepers: `electron-log`, `electron-squirrel-startup`, `electron-updater`, `fix-path`, `i18next`, `semver`, `zod`.
- Proven native or explicit package-shape keepers: `better-sqlite3`, `web-tree-sitter`, plus the explicit `electron-builder.yml` `node_modules` and `asarUnpack` allowlist.
- Proven API, bridge, agent, or preload keepers: `@anthropic-ai/sdk`, `@google/genai`, `@modelcontextprotocol/sdk`, `@office-ai/aioncli-core`, `@office-ai/platform`, `@sentry/electron`, `openai`.
- Deferred latent or ambiguous common/runtime packages: `docx`, `html-to-text`, `jsonrepair`, `jsonwebtoken`, `mammoth`, `officeparser`, `pptx2json`, `qrcode-terminal`, `smol-toml`, `strip-json-comments`, `turndown`, `turndown-plugin-gfm`, `xlsx-republish`, `@xmldom/xmldom`.
- Deferred unused-looking server/channel/runtime packages that need a separate removal issue and package proof: `@agentclientprotocol/sdk`, `@aws-sdk/client-bedrock`, `@grammyjs/transformer-throttler`, `@larksuiteoapi/node-sdk`, `@wecom/aibot-node-sdk`, `bcryptjs`, `cookie`, `cookie-parser`, `cors`, `dingtalk-stream`, `express`, `express-rate-limit`, `grammy`, `multer`, `sharp`, `tiny-csrf`, `ws`, `yauzl`.
- Browser/node polyfill packages that need a separate audit before removal: `buffer`, `process`, `stream-browserify`.

## Verification

Local source checks:

```bash
rg -n "from ['\"](@arco-design/web-react|@icon-park/react|mermaid|react-syntax-highlighter|@monaco-editor/react|@uiw/react-codemirror|diff2html|react-markdown|streamdown|swr)" \
packages/desktop/src/common packages/desktop/src/process packages/desktop/src/preload packages/web-host/src packages/web-cli/src scripts
```

Remote package proof is enforced by Thin App Smoke after `electron-builder --dir` produces an unpacked `.app`:

```bash
node scripts/evaosVerifyRendererDependencyPrune.js "out/mac-arm64/AionUi.app"
```
Comment thread
coderabbitai[bot] marked this conversation as resolved.

The verifier inspects both `app.asar` and `app.asar.unpacked/node_modules`. Absence from `app.asar` alone is not enough because native/WASM/runtime packages are intentionally unpacked.

The renderer bundle must still launch and cover Markdown, diff UI, Mermaid diagrams, code highlighting, editor surfaces, settings, and updater UI.
74 changes: 37 additions & 37 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,50 +72,30 @@
"@agentclientprotocol/sdk": "^0.18.2",
"@aionui/web-host": "workspace:*",
"@anthropic-ai/sdk": "^0.71.2",
"@arco-design/web-react": "^2.66.1",
"@aws-sdk/client-bedrock": "^3.987.0",
"@codemirror/commands": "^6.8.1",
"@codemirror/lang-css": "^6.3.1",
"@codemirror/lang-html": "^6.4.11",
"@codemirror/lang-json": "^6.0.2",
"@codemirror/lang-markdown": "^6.5.0",
"@codemirror/view": "^6.38.6",
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
"@dnd-kit/utilities": "^3.2.2",
"@floating-ui/react": "^0.27.16",
"@google/genai": "^1.16.0",
"@grammyjs/transformer-throttler": "^1.2.1",
"@icon-park/react": "^1.4.2",
"@larksuiteoapi/node-sdk": "^1.58.0",
"@modelcontextprotocol/sdk": "^1.20.0",
"@monaco-editor/react": "^4.7.0",
"@office-ai/aioncli-core": "^0.30.6",
"@office-ai/platform": "^0.3.16",
"@sentry/electron": "^7.10.0",
"@types/bcryptjs": "^2.4.6",
"@types/jsonwebtoken": "^9.0.10",
"@uiw/codemirror-extensions-langs": "^4.25.1",
"@uiw/react-codemirror": "^4.25.2",
"@wecom/aibot-node-sdk": "^1.0.6",
"@xmldom/xmldom": "^0.8.11",
"bcryptjs": "^2.4.3",
"better-sqlite3": "^12.4.1",
"buffer": "^6.0.3",
"classnames": "^2.5.1",
"cookie": "^1.0.2",
"cookie-parser": "^1.4.7",
"cors": "^2.8.5",
"croner": "^9.1.0",
"dayjs": "^1.11.18",
"diff": "^8.0.3",
"diff2html": "^3.4.55",
"dingtalk-stream": "^2.1.4",
"docx": "^9.5.1",
"electron-log": "^5.4.3",
"electron-squirrel-startup": "^1.0.1",
"electron-updater": "^6.6.2",
"eventemitter3": "^5.0.1",
"express": "^5.1.0",
"express-rate-limit": "^7.5.1",
"fix-path": "^4.0.0",
Expand All @@ -125,35 +105,18 @@
"i18next": "^23.7.16",
"jsonrepair": "^3.13.0",
"jsonwebtoken": "^9.0.2",
"katex": "^0.16.22",
"mammoth": "^1.11.0",
"mermaid": "^11.13.0",
"multer": "^2.1.1",
"officeparser": "^5.2.2",
"openai": "^5.12.2",
"pptx2json": "^0.0.10",
"process": "^0.11.10",
"qrcode-terminal": "^0.12.0",
"qrcode.react": "^4.2.0",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-i18next": "^14.0.5",
"react-markdown": "^10.1.0",
"react-router-dom": "^7.8.0",
"react-syntax-highlighter": "^16.1.0",
"react-virtuoso": "^4.18.1",
"rehype-katex": "^7.0.1",
"rehype-raw": "^7.0.0",
"remark-breaks": "^4.0.0",
"remark-gfm": "^4.0.1",
"remark-math": "^6.0.0",
"semver": "^7.7.2",
"sharp": "^0.34.3",
"smol-toml": "^1.6.1",
"stream-browserify": "^3.0.0",
"streamdown": "^1.5.1",
"strip-json-comments": "^3.1.1",
"swr": "^2.3.6",
"tiny-csrf": "^1.1.6",
"turndown": "^7.2.2",
"turndown-plugin-gfm": "^1.0.2",
Expand All @@ -164,8 +127,21 @@
"zod": "^3.25.76"
},
"devDependencies": {
"@arco-design/web-react": "^2.66.1",
"@codemirror/commands": "^6.8.1",
"@codemirror/lang-css": "^6.3.1",
"@codemirror/lang-html": "^6.4.11",
"@codemirror/lang-json": "^6.0.2",
"@codemirror/lang-markdown": "^6.5.0",
"@codemirror/view": "^6.38.6",
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
"@dnd-kit/utilities": "^3.2.2",
"@electron/fuses": "^1.8.0",
"@electron/notarize": "^3.1.0",
"@floating-ui/react": "^0.27.16",
"@icon-park/react": "^1.4.2",
"@monaco-editor/react": "^4.7.0",
"@playwright/test": "^1.58.2",
"@sentry/vite-plugin": "^5.1.1",
"@testing-library/jest-dom": "^6.9.1",
Expand All @@ -187,24 +163,48 @@
"@types/turndown": "^5.0.6",
"@types/ws": "^8.18.1",
"@types/yauzl": "^2.10.3",
"@uiw/codemirror-extensions-langs": "^4.25.1",
"@uiw/react-codemirror": "^4.25.2",
"@vitest/coverage-v8": "^4.0.18",
"builder-util": "^26.8.1",
"classnames": "^2.5.1",
"cross-env": "^7.0.3",
"dayjs": "^1.11.18",
"diff": "^8.0.3",
"diff2html": "^3.4.55",
"dotenv": "^17.2.1",
"electron": "^37.10.3",
"electron-builder": "^26.6.0",
"electron-devtools-installer": "^4.0.0",
"electron-vite": "^5.0.0",
"esbuild": "^0.25.11",
"eventemitter3": "^5.0.1",
"husky": "^9.1.7",
"jest": "^30.1.3",
"jest-diff": "^30.0.4",
"jsdom": "^28.1.0",
"katex": "^0.16.22",
"lint-staged": "^16.2.7",
"mermaid": "^11.13.0",
"oxfmt": "^0.41.0",
"oxlint": "^1.56.0",
"patch-package": "^8.0.0",
"playwright": "^1.59.1",
"qrcode.react": "^4.2.0",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-i18next": "^14.0.5",
"react-markdown": "^10.1.0",
"react-router-dom": "^7.8.0",
"react-syntax-highlighter": "^16.1.0",
"react-virtuoso": "^4.18.1",
"rehype-katex": "^7.0.1",
"rehype-raw": "^7.0.0",
"remark-breaks": "^4.0.0",
"remark-gfm": "^4.0.1",
"remark-math": "^6.0.0",
"streamdown": "^1.5.1",
"swr": "^2.3.6",
"ts-morph": "^28.0.0",
"ts-node": "^10.9.2",
"tsx": "^4.19.1",
Expand Down
Loading
Loading