v0.9.0 — Local voice input + plugin extraction sweep
Highlights
Three things shape this release:
🎤 Local voice input (push-to-talk via on-device whisper.cpp)
Toggle the mic icon in chat input, hold to talk, release to send. Audio streams to a sidecar whisper.cpp process bundled with the launcher, so transcription stays on-device (no cloud STT). macOS is the first-class target. Sticky session mic, auto-resume each turn, pause-based segmentation. Extracted as the shared @mulmoclaude/whisper package so MulmoTerminal can reuse the same core. (#1773 + #1775)
⚡ Collection runtime power
- Custom views can open records in the host modal (#1748) — a custom view button can navigate the host into the same record-detail modal the table/calendar uses.
- Custom views can start a draft chat (#1752 + #1755) — a button dispatches
startChatwith a templated body referencing the record, and the host opens a draft chat in a chosen role. Combine with the open-item flow to chat about this specific record. - Live view updates via pubsub (#1740) — built-in
table/calendarand custom views subscribe to a per-collection pubsub channel; record changes from any tab / session / agent tick instantly into the open view. - Field-driven spawn interval (#1738) — collection schema
spawn.everycan read its interval from a record field, so weekly / biweekly / monthly branches off a record's own dropdown without splitting schemas. manageCollectionschema management (#1734) — MCP tool gainsschemaDocs/getSchema/putSchemaso Claude edits collection schemas through a validated surface.- Collection instant-present (#1785) — collection canvas pops the moment a slash-command chat references it.
📦 Plugin extraction sweep — everything moves to standalone npm packages
Six surfaces' server core + Vue View / Preview + 8-locale i18n move into standalone @mulmoclaude/* packages consumable by MulmoTerminal end-to-end with zero MulmoClaude code reuse:
@mulmoclaude/form-plugin—presentForm(#1713)@mulmoclaude/markdown-plugin@0.1.0 → 0.1.4—presentDocument, sharedrenderMarp+ image-fill render core, Marp directive image generation (#1715 / #1717 / #1719)@mulmoclaude/x-plugin+@mulmoclaude/chart-plugin— X tools +presentChart(#1721)@mulmoclaude/html-plugin@0.1.0 → 0.2.2—presentHtmlserver core + Vue View + path-traversal hardening (#1731 / #1732)@mulmoclaude/collection-plugin@0.3.0 → 0.5.2— full Vue UI + i18n + router-less host + record-id dots viasafeRecordId(#1723 / #1725 / #1729 / #1730)@mulmoclaude/whisper@0.1.x— whisper.cpp sidecar core (NEW, #1775)@mulmoclaude/workspace-setup@0.1.8— bundles the newmc-zennpreset skill
A separate packages/services/* tree (#1733) carves out headless-backend services (collection-watchers, scheduler, journal, notifier, plugin-host, skill-bridge, whisper, workspace-setup) so they version + publish independently of the launcher.
🤝 Pre-allowlist 16 additional claude.ai connectors (#1711)
Gmail / Drive / Calendar / Slack / GitHub / Linear / Notion / Asana / Atlassian and 7 others are pre-allowlisted, removing first-use approval friction.
📝 New mc-zenn preset skill
Share your work as a Zenn article (Japanese dev-blog platform). Discover via the skills launcher.
🔧 mulmocast@2.6.22 diagnostic-error sweep picks up
TTS Gemini stops masking ffmpeg SIGABRT behind "TTS Gemini Error". Whisper CLI / Replicate (image / lipsync / movie) / OpenAI image / ElevenLabs all interpolate the underlying provider message into catch-all throws. Same pattern across 7 agents.
Fixed
- MCP
handlePermissionrace could lose the first turn of a fresh session (#1712 / #1698) —handlePermissionis now served immediately so session start can't race MCP load. - Windows
claude.exespawn (#1769 / #1757) — typedClaudeCliNotFoundError, Windows shell for spawn probes, version-agnostic pnpm global probing. - MCP broker path in Docker (#1771 / #1770) — broker resolves relative to
config.ts+ Docker bind mount path. - Attachment companion-file traversal (#1756 / #1760 / #1762 / #1765) — path validator factory +
..strictness restoration + consolidatedhasTraversalSegment(). - Vite pinned to exactly 8.0.13 (#1750) — newer vite 8.x breaks the e2e suite with a dual-runtime
vue-i18n/runtime-domcrash. - Marp image-fill regression (#1719) — Marp directive slides without a pre-supplied image now emit a title-prompt image generation request instead of staying blank.
fix-vite-workspace-path(#1570) — dev token plugin honoursMULMOCLAUDE_WORKSPACE_PATHinstead of assuming$HOME/mulmoclaude.
Infrastructure
- Cache Playwright browsers in the e2e job (#1728) + cache puppeteer browsers in test jobs (#1749) — drops per-job 60-90s Chrome download to a sub-second cache hit. De-flakes against the puppeteer CDN's occasional ZIP corruption.
- e2e dev-server pre-warming in Playwright
globalSetupso the firstpage.gotodoesn't pay the on-demand compile penalty. - CI bump guard (#1737 + #1788) — blocks PRs that change a shared package's
src/but forget to bumpversion; #1788 exempts non-shippingpackage.jsondiffs.
Refactor
- frontend
toError()helper (#1766) —unknown → Errornarrowing. errorMessage()codemod sweep (#1767) — replaces inlinederr instanceof Error ? err.message : String(err)across 12 sites.
Full Changelog
See docs/CHANGELOG.md for the complete list (~50 entries across Added / Changed / Fixed / Infrastructure / Refactor / Docs).
📦 npm: mulmoclaude@0.9.0
🤖 Generated with Claude Code