Minidex should be organized around runtime boundaries first, then product features, then plugin contracts. The long-term goal is to make the app extensible by end users without making plugins depend on internal implementation files.
minidex/
electrobun.config.ts
package.json
tsconfig.json
src/
main/ # Electrobun/Bun process
index.ts
app/
createApp.ts
menu.ts
windows.ts
resolveDefaultCwd.ts
codex/
CodexAppServerClient.ts
codexEvents.ts
codexTypes.ts
rpc/
mainRpc.ts
rpcHandlers.ts
plugins/
host/
PluginHost.ts
PluginRuntime.ts
PluginRegistry.ts
permissions/
pluginPermissions.ts
loader/
loadPluginManifest.ts
resolvePluginEntrypoint.ts
contributions/
registerPluginCommands.ts
registerPluginViews.ts
renderer/
mainview/
index.html
index.tsx
index.css
app.tsx
app/
query-client.ts
rpc-client.ts
bootstrap-snapshot.ts
features/
workspace/
threads/
account/
transcript/
composer/
approvals/
components/
styles/
shared/
codex/
protocol.ts
snapshot.ts
events.ts
rpc/
MinidexRPCSchema.ts
plugin-api/ # Public, versioned plugin SDK
index.ts
manifest.ts
capabilities.ts
permissions.ts
commands.ts
views.ts
storage.ts
events.ts
plugins/
builtin/ # First-party plugins shipped with Minidex
tests/
main/
renderer/
shared/
plugins/
docs/
architecture.md
project-structure.md
plugin-system.md
plugin-manifest.md
plugin-api.md
examples/
plugins/
hello-world/
command-plugin/src/main/ owns desktop process concerns: windows, menus, Codex app-server process management, local plugin loading, permissions, filesystem access, and RPC handlers.
src/renderer/ owns UI code. Keep renderer state, React components, styles, and view-specific hooks here. Renderer code should call main-process capabilities through typed RPC instead of importing main-process implementation.
src/shared/ owns types and pure utilities that can safely run in both runtimes. It should not import from src/main/ or src/renderer/.
There are two separate plugin areas:
src/main/plugins/ is Minidex's plugin host implementation. It can know about internal app services, lifecycle, validation, loading, sandboxing, contribution registration, and permission enforcement.
src/shared/plugin-api/ is the public contract that plugins are allowed to import. Treat it as a versioned SDK. It should be small, explicit, and stable.
src/plugins/builtin/ is for first-party bundled plugins. End-user installed plugins should eventually live outside the repo in the user's application data directory.
Renderer features should be grouped by product workflow rather than by technical type. For example, thread list components, mutations, and helpers should live together under features/threads/.
Shared visual primitives can live in renderer/mainview/components/. Avoid moving feature-specific components into shared components unless they are genuinely reused.
The current repo is small, so migrate gradually:
- Rename
src/bun/tosrc/main/. - Rename
src/mainview/tosrc/renderer/mainview/. - Move
src/shared/codexProtocol.tstosrc/shared/codex/protocol.ts. - Split the large renderer entrypoint into
App.tsx, feature folders, app setup, and stores. - Add
src/shared/plugin-api/before implementing plugin loading. - Add
src/main/plugins/only when the host runtime is actually being built.
A future plugin should declare what it contributes and what it needs:
{
"id": "example.hello-world",
"name": "Hello World",
"version": "0.1.0",
"minidexApi": "^1.0.0",
"entry": "main.js",
"permissions": ["workspace:read"],
"contributes": {
"commands": [
{
"id": "hello.sayHello",
"title": "Say Hello"
}
],
"panels": [
{
"id": "hello.panel",
"title": "Hello"
}
]
}
}Plugins should communicate with Minidex through declared capabilities and typed RPC. They should not import app internals, React components, stores, or main-process services directly.