Bundled Modules

Shipped modules, install flow, and bundled module lifecycle.

Bundled modules are prepackaged modules stored in the repository under bundled-modules/*. They are visible in Module Store as source bundled. Normal bundled modules can be installed or uninstalled by admins; fixed bundled modules declare "fixed": true and are always installed, not installable, and not removable. A few modules are additionally gated in code: agent-orchestrator and terminal are visible only with Developer mode enabled (terminal also refuses to run without it), and video-studio is admin-only (src/lib/module-store/developer-mode-modules.ts).

What ships bundled right now

  • agent-orchestrator (Agent Orchestrator, hidden unless Developer mode is enabled)
  • agents (Spezial-Agenten, lightweight overview of specialized agents with running sessions and admin setup)
  • athlete-brand-matching (Athlete-Brand Matching, isolated pilot workflow for athlete profiles, brand database, matching, import review, and outreach drafts)
  • book-appointment (Termine, appointment types with optional public prices, weekly bookable windows, internal bookings, public iframe appointment requests, pending-request confirmation emails, and public-safe appointment tools)
  • call-agent (Call & Fax Agent)
  • canvas (Canvas)
  • cases (Cases, matter and case management for law firms with clients, assigned lawyers, parties, key dates, communication logs, documents, tasks, and timeline context)
  • excel-canvas (Excel Editor)
  • file-explorer (File Explorer)
  • news (News, tile view for internal and external news with RSS import and API inbox)
  • notizen (Notizen)
  • social-media (Social Media, cross-platform post drafts with AI, media, scheduling, and direct publishing to LinkedIn, X, Mastodon, Bluesky, and YouTube; replaces the legacy linkedin module)
  • tax-manager (Finanzen, generates UStVA overviews for manual ELSTER transfer and EÜR drafts for tax-adviser review)
  • terminal (Terminal, developer-mode admin Bash terminal in the Clapilot web container)
  • video-studio (Video Studio, admin-only gallery for agent-rendered Clapilot demo videos)
  • website-canvas (Website Canvas)
  • wiki (Wiki, fixed agent-first Markdown knowledge base)
  • word-canvas (Word Editor)

accounting (Buchhaltung, Mandanten bookkeeping with period reporting and tax overview) also appears in the module list, but it is not a bundled-modules/ package — it renders natively in React from src/components/modules/accounting-module.tsx.

Manifest location per module:

  • bundled-modules/<slug>/module.json

Every bundled manifest declares store categories (multiple per module) so the module appears in the matching App Store-style sections on /modules. See Modules for the allowed category keys, the renderer/workers manifest fields, and the optional icon.png store icon convention.

Install state and defaults

Instance-wide bundled-module state is stored in module_installs, with the default policy in app_settings.module_install_policy:

  • New instances use minimal: notizen, excel-canvas, word-canvas, and agents start installed. These support Notes, document editing, and the Spezial-Agenten redirect.
  • Instances that already had users when migration 214_module_installs.sql was applied use legacy_all, preserving the former opt-out behavior and the existing .clapilot-bundled-modules.json disabled list.
  • Per-module rows in module_installs override either policy.
  • Fixed modules such as wiki are always installed regardless of policy or overrides.

Workspace and managed modules remain installed because their presence is already explicit. Uninstalled bundled modules remain visible in Module Store but are excluded from the effective module inventory. As a result, they have no sidebar or module-owned settings entry, /modules/<slug> renders not found, and module asset/API/storage endpoints return 404 with {"error":"module_not_installed"}. Agent-tool removal is delivered separately in the companion native-runtime change.

Install and uninstall flow

Fixed bundled modules skip this lifecycle: they remain installed from the bundled source and install-bundled / deactivate-bundled reject them.

  1. Admin installs bundled module via POST /api/module-store/install-bundled.
  2. Module migrations run once from bundled-modules/<slug>/migrations/*.sql if enabled.
  3. module_installs is upserted to installed = true and the legacy disabled state is cleared.
  4. Module becomes available in the effective module list directly from the bundled source; no workspace copy is created.

Uninstalling through POST /api/module-store/deactivate-bundled writes installed = false, keeps the legacy disabled file consistent, and removes an older workspace clone only when it carries .clapilot-bundled-install.json.

Implementation: src/app/api/module-store/install-bundled/route.ts.

Bundled module migrations

Bundled migrations are executed from migrations/*.sql when installing, unless disabled:

  • MODULE_BUNDLED_MIGRATIONS_ENABLED=false -> skip migrations
  • migration state table: module_schema_migrations

Source precedence

Module source layers are workspace, managed, and bundled. When one slug exists in several layers, resolution picks (see Modules for details):

  1. a fixed bundled module, always
  2. otherwise the higher manifest version
  3. at equal versions the bundled copy, then the newer manifest mtime, then source priority workspace > managed > bundled

The legacy state file remains synchronized for compatibility and is consulted only by the legacy_all fallback when no DB override exists:

  • /app/workspace/.clapilot-bundled-modules.json

Discovery and precedence logic:

  • src/lib/module-store/local-modules.ts

Build pipeline for bundled modules

During app build, bundled TypeScript sources are transpiled:

  • script: scripts/compile-bundled-modules.mjs
  • backend source: bundled-modules/<slug>/api/handler.ts
  • backend output: bundled-modules/<slug>/api/handler.mjs
  • optional frontend source: bundled-modules/<slug>/ui/**/*.ts
  • optional frontend output: bundled-modules/<slug>/ui/**/*.js

If ui/index.ts exists, the build script wires index.html automatically via:

  • <!-- CLAPILOT_UI_ENTRY --> marker replacement, or
  • rewriting src="./ui/index.ts" to src="./ui/index.js"

Detailed module docs