Local-first AI workspace desktop app for Korean knowledge/document operations. Tauri 2 + Rust + React 19 + TypeScript. Current version 0.4.0.
Maru is the author SSOT for a single user's ~/workspace/work/ β it edits
markdown with byte-identical frontmatter, ingests an inbox, runs bundled Claude
Code skills, drives Korean document (HWPX/DOCX/PDF) operations, and visualizes
the vault as a knowledge graph. Releases before v0.3.0 shipped under the name
Anchor; the M0 rename (kr.maru.desktop, ~/.maru/) landed in v0.3.0.
| Phase | State | Outcome |
|---|---|---|
| 0 β Hardening | β shipped | Open existing workspaces safely. Frontmatter byte-identical round-trip. Multi-workspace registry. ko/en parity. |
| 0.5 β UI polish | β shipped | Topbar, sidebar with type filters + recents, command palette (βK), Pretendard Korean typography, light/dark. |
| 1A β Killer feature MVP | β shipped | Doc-selection reliability, frontmatter inline edit (InspectorPane), wikilink autocomplete (Korean IME-aware) + click-to-navigate, typed neighborhood pane, in-memory nav history (β[ / β]). |
| 1B β Rich editor / git | β feature-complete | Git status badge + commit-from-app (file list + per-file diff + syntax color). Rayon-parallel workspace scan + cache-backed warm startup. Multi-tab editor (β1..β8 / βW, dirty stash). BlockNote rich + source + preview 3-way toggle. Browser smoke e2e. Deferred: monorepo extraction. |
| 2 β Inbox + AI | β write loop live | Polling scan + notify watcher + Korean date parser + Claude CLI bridge + classifier + Gmail via gws, plus InboxPane (classify/accept/reject/process, approval gate, Maru labels, a/r/p, bulk actions, mission log tails). |
| 2.5 β Tree + Cursor shell + Terminal | β shipped | Documents/Files Explorer, VS Code-style file tree + copy/move queue, Cursor-style activity rail, split panes (βD), Rust-native alacritty_terminal PTY tabs (Claude/Codex/Shell), layered ~/.maru/settings.json + <workspace>/.maru/workspace-state.json, signed auto-update, native menu bar. |
| 3 β Unified document ops (M1βM7) | β W1βW6 + skills SSOT | Operations Catalog mode (ops_catalog::scan, fs watcher, Hub HTTP read + ETag/offline fallback, drilldown + Reveal), Hub Library client + template-aware new doc, Writing Guideline sidebar. Rust skill_host owns tiers (core/public/private/imported/managed), doctor validation, dirty/reconcile. maru-hub backs shared catalog (REST + Alembic + seeds). |
| 4 β Document Studio + Templates | β W7βW12 | 7-step Studio mode (source β template β guideline β sections β HWP fields β export β package). create_document frontmatter prefill, M4 export pipeline (export/ plan/validate/dispatch, docx/hwpx/pdf + sha256 manifest), HWPX field map (hwpx slots + template_fill), κ°μ‘°μ inline lint (linter/gaejosik). |
| 5 β Evidence Binder | β W13 shipped | Right-pane Evidence Binder tab keyed by doc id, state under <workspace>/.maru/binder/<doc-id>.json, seeds from inbox-processed files + <binary>.evidence.yaml sidecars scoped to the active BU, kordoc_lite format detection + HWPX field previews. W14βW18 (section/KPI/checklist bindings + Deck Studio) planned. |
| D β Concept-map Diagram mode | β shipped (Phase 0β7, hardened) | diagram mode: HWP-style 9-tab ribbon, 13 node kinds, 4-port edges, smart-guide snap, 11 templates, PNG/JPG/SVG/JSON/PDF/Mermaid export + Mermaid import, version history, viewport culling for 1000-node smoothness. Docs at <workspace>/diagrams/<name>.cmd.json (v:7). See docs/diagram.md. |
| 8 β Knowledge graph | β 8a/8b/8c + V4 shipped | graph mode: stable Sigma WebGL + Graphology multi-directed model, Barnes-Hut ForceAtlas2 worker, visibility reducers, 10k+ node target, knowledge/workspace/all-files sources, local depth/direction controls, background insights, reviewed relationship writes, incremental cache/watch refresh. Managed writes remain schema-gated, revision-checked, snapshotted, and atomic. See docs/graph.md. |
| M0 β Anchor β Maru rename | β shipped (v0.3.0) | Full rename across app id, dirs, CLI, tap. One-time on-disk migration (~/.anchor β ~/.maru, com.anchor.app β com.maru.app) with back-compat symlink; .maruignore preferred with .anchorignore fallback read. |
Rule SSOTs live in the work repo at
~/workspace/work/_meta/rules/{frontmatter-schema,document-lifecycle,hub-contract,evidence-policy}.md.
The deeper "what's next + how to continue" reference is ROADMAP.md.
The activity rail exposes eleven top-level modes (Settings opens as a separate window, so it is not an app mode). Diagram and Graph default on; E2E Flow is flag-gated.
| Mode | Label (ko / en) | What it does |
|---|---|---|
pkm |
λ¬Έμ / Docs | Default. Markdown editor + Documents/Files Explorer + right utility rail. |
inbox |
μΈλ°μ€ / Inbox | Configured drop / pending / processed / Files / Gmail sections with classify + a/r/p. |
comms |
λ©μμ§ / Messages | Multichannel comms settings (Telegram auth/mapping, source config, macOS migration). |
meetings |
νμλ‘ / Meetings | Transcript + auto-summary intake and the meeting-notes review workbench. |
tasks |
νμ€ν¬ / Tasks | File-backed tasks with Google Tasks/Calendar links; edit details, month/week/day calendar. |
catalog |
μΉ΄νλ‘κ·Έ / Catalog | M1 Operations Catalog β deadlines, in-flight approvals, unlinked evidence, inbox pending. |
studio |
μ€νλμ€ / Studio | M2 Document Studio 7-step authoring wizard. See docs/studio.md. |
diagram |
λ€μ΄μ΄κ·Έλ¨ / Diagram | Concept-map editor. See docs/diagram.md. |
graph |
κ·Έλν / Graph | Vault knowledge graph. See docs/graph.md. |
sites |
μ¬μ΄νΈ / Sites | Left-rail site switcher with an embedded native browser pane. |
e2e |
E2E νλ‘μ° / E2E Flow | Hidden end-to-end flow console (flag-gated e2eFlowEnabled). |
Maru ships the desktop app and CLI as separate artifacts. On macOS, both are
distributed through the STAIxBWLB/homebrew-cask tap:
brew tap STAIxBWLB/homebrew-cask
# Desktop app only:
brew install --cask maru-workspace
# Standalone CLI only. Installs the executable as `maru`:
brew install maru-cli
maru --versionThe app cask installs Maru.app and does not create a CLI symlink. The CLI
formula installs only the standalone maru executable. The desktop app keeps
using signed Tauri updater metadata from GitHub Releases; Homebrew users can
also upgrade via brew upgrade --cask maru-workspace and brew upgrade maru-cli.
For repo-local management shortcuts:
make cli-install
make cli-smoke
make release-preflight
make homebrew-update RELEASE_TAG=v0.4.0 HOMEBREW_TAP_DIR=../homebrew-caskβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Tauri Webview (src/) β
β React 19 + Radix UI + BlockNote + marked + DOMPurify β
β Sigma WebGL + Graphology Β· CodeMirror Β· alacritty canvas β
β β
β Activity rail (11 modes): β
β Docs / Inbox / Messages / Meetings / Tasks / β
β Catalog / Studio / Diagram / Graph / Sites / E2E β
β Explorer + editor tabs + copy/move queue + terminal panel β
ββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββ
β Tauri IPC
ββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββ
β Rust core (src-tauri/src/) β
β workspace scan β walkdir + .maruignore + cached index β
β frontmatter/ β line-by-line YAML edit (preserves order) β
β document.rs β read/save/create/version + field patch β
β git.rs β status/commit/diff via shell-out β
β vault_list.rs / vault.rs / vault_graph.rs / vault_guard.rs β
β inbox.rs / inbox_watcher.rs / inbox_classifier.rs β
β gmail_gws.rs / outlook_mso.rs / telegram_io.rs / ai_router β
β ops_catalog/ Β· hub_client/ Β· export/ Β· studio/ Β· diagram/ β
β skill_host/ Β· agent_host/ Β· terminal/ Β· linter/ β
β maru_dir.rs β layered settings + .maru rules/templates β
β maru_migration.rs β one-time Anchor β Maru on-disk rename β
ββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β stdio bridge
ββββββββΌβββββββββ ββββββββββββββββββββββ
β MCP server β β User's Claude Code β
β (Node sidecar) β β CLI (~/.maru/skills)β
βββββββββββββββββ ββββββββββββββββββββββ
Module boundary rules:
- Rust core owns workspace FS / cache / git / frontmatter / inbox
scan/watch/classification / Gmail
gws+ Outlook + Telegram bridges / layered Maru settings / Claude inbox subprocess / integrated terminal PTY + screen model / skills registry (skill_host) / agent proposal host (agent_host) / ops catalog / export pipeline / Studio + Diagram + Graph backends. - React handles only BlockNote / command palette / neighborhood / graph layout worker / diagram canvas. No business logic.
- Node sidecar (
sidecars/maru-mcp/) holds the local read-first MCP server. - Deferred (Phase 4 original plan, on hold): a Whisper (Korean large-v3) Python sidecar + MediaPipe voice/gesture editing. Not shipped β Phase 4 was repurposed to Document Studio. Voice/gesture remains a future track.
- Catalog watcher + auto-refresh β notify recursively watches
inbox/items/,tasks/{active,calendar}, every BU's02-admin-approvals/+03-evidence-cert/+.maru/bu-config.yaml; bursts are debounced 500 ms and the React pane re-queries in another 300 ms. - Hub catalog read path β
hub_client::http::fetch_with_cacheGETs/api/v1/{templates,guidelines,glossary,...}with ETag revalidation, falls back to<workspace>/.maru/cache/hub/on any network error. - Drilldown dialog + Reveal β Catalog row β modal showing frontmatter + manifest + README excerpt + sibling paths + "Finderμμ 보기".
- Real-workspace timing β
MARU_CATALOG_BENCH_WORKSPACE=~/workspace/work cargo test --lib -- --ignored catalog_real_workspace_smokeindexed 110 entries across 4 BUs in 986 ms (30Γ under the 30-second budget). - Template-aware new doc β
β β§ N/ palette "Hub ν νλ¦ΏμΌλ‘ μ λ¬Έμ" β BU/category filter β template picker prefills body + title + docType β optional guideline multi-select βmaru:template/maru:business_unit/maru:guidelinesprovenance. - Guideline sidebar β opening a doc created via the template flow surfaces its guideline bodies in the right-pane
BookOpentab.
The above gates run fully offline (cache fallback). To exercise the live Hub read path:
# maru-hub: start FastAPI + sqlite (or run docker compose up -d db for Postgres)
cd dev/maru-hub
uv run python -m scripts.seed_catalog
MARU_HUB_DATABASE_URL=sqlite:///tmp/maru-hub.db uv run uvicorn maru_hub.main:app --port 8017
# maru: flip workspace.config.yaml
# hub.enabled: true
# hub.endpoint: http://127.0.0.1:8017/api/v1
# hub.api_token_ref: ~/workspace/work/.maru/secrets/hub-token (empty file is fine for local)Then in Maru: open Catalog mode β footer "λ§μ§λ§ μ€μΊ" populates; β β§ N β toggle "Hub ν
νλ¦Ώμμ μμ" β templates load from Hub; pick business-plan-default β body prefills with slot hints.
After Phase 6 W21 ships, the same operator procedure will also exercise the POST /api/v1/documents/{id}/finalize round-trip β Maru pushes the approved markdown body + rendered artifacts + linked evidence binaries to Hub, and the document then appears under the Hub Finalized tab inside Catalog mode.
The active plan lives in ROADMAP.md β a 7-module (M1βM7) decomposition with weekly deliverables (W1βW34+) plus the Diagram and Graph side tracks. Phases 0β5, the Diagram mode, and the Phase 8 graph mode (8a/8b/8c) are shipped. See CHANGELOG.md for the release-by-release history.
Each phase is defined in outcomes the user actually exercises. No phase exists just to grow infrastructure. The entry gate for each phase is the verification of the previous one.
Git has run ahead of the linear W-plan: Phase 8 (graph mode) shipped before the remaining Phase 5 evidence work. The nearest pending items:
- W14βW15 Evidence bindings β section/KPI/submission-checklist binding model on the W13 Binder (
evidence_links[].section_bindings,kpi_bindings, checklist bindings), Verify / Mark-as-submitted controls, then Hubevidence_indexsha256 reuse. Entry files:src-tauri/src/evidence_binder.rs,src/components/evidence/*,src/lib/evidenceBinder.ts. - W16βW18 Deck Studio (M6) β a
Decksmode wrapping the gpt-images-deck wizard with the bundled 14-style catalog (skills/docs/slide-decks/). - Phase 6 (W19βW22) Approval + Finalize-to-Hub β submission gates, gate-state polling, and the approval-gated
POST /api/v1/documents/{id}/finalizewrite path (the only Maru client path allowed to carry body/binary payloads). Requires a matchinghub_client/safety.rspre-flight. - Phase 7 (W23βW26) Certification & KPI bundle β Hub-backed certification vault, KPI composer, and PDF bundle assembly.
Maru stays the author SSOT β drafting and editing always happen under
~/workspace/work/. Maru Hub becomes the published SSOT the moment an
approval route closes. Two write paths land on Hub from Maru:
POST /api/v1/documents/sync(planned M7 caller) β drafting metadata only:document_uri,body_sha256,frontmatter, and the evidence link graph. No body, no binary. Used for cross-BU lookups and "μ΄λ―Έ λκΈ°νλ μ΄μ" hints.POST /api/v1/documents/{id}/finalize(Phase 6 W21) β approval-gated canonical push. The instantsubmission_gate.stateflips toapproved, Maru auto-calls finalize with the full markdown body, every rendered artifact in the M4 manifest (docx/hwpx/pdf), and the binary bytes of every evidence file linked viafrontmatter.evidence_links. On201, the local frontmatterstatusflips toarchived-hub:<finalized_id>@v<N>.
Gate submits made while the Hub is disabled or unreachable persist in
<workspace>/.maru/queue/hub/ (one JSON per request) and drain FIFO via
the hub_queue_drain command β exposed in the Catalog footer as a queue
depth badge with a retry action.
pnpm install
# Browser dev (mocked Tauri):
pnpm dev
# Native Tauri dev (cleans stale local app bundles first):
pnpm tauri:dev
# Type check:
pnpm typecheck
# i18n lint (ko/en parity + hardcoded UI string scan; also in make verify):
pnpm lint:i18n
# Production build:
pnpm build
# Full verification (typecheck + vitest + cargo test --lib + build):
make verify
# Signed native release build:
make tauri-build
# Raw pnpm build still requires explicit updater signing env:
export TAURI_SIGNING_PRIVATE_KEY="$(cat ~/.tauri/maru-updater.key)"
export TAURI_SIGNING_PRIVATE_KEY_PASSWORD="$(cat ~/.tauri/maru-updater.key.password)"
pnpm tauri:build
# Prune oversized local Tauri debug artifacts (also runs from tauri:dev/build):
pnpm clean:tauri-debug
# Checks once every 24h and prunes src-tauri/target/debug when artifacts exceed 4GiB.
# Rust unit + integration tests (587 declarations; 2 ignored benchmarks):
cd src-tauri && cargo test
# or: make test-rust (cargo test --lib)
# Frontend unit tests (vitest, 87 test files / 638 tests):
pnpm test
# End-to-end (Playwright, 7 specs):
pnpm test:e2e
# Local Maru MCP sidecar smoke:
MARU_MCP_WORKSPACE="$PWD" node sidecars/maru-mcp/index.mjs
# Skills registry doctor / reconcile:
cargo run --manifest-path src-tauri/Cargo.toml --bin maru-cli -- --version
cargo run --manifest-path src-tauri/Cargo.toml --bin maru-cli -- doctor --json
cargo run --manifest-path src-tauri/Cargo.toml --bin maru-cli -- skills dirty --json
cargo run --manifest-path src-tauri/Cargo.toml --bin maru-cli -- skills reconcile <name-or-id> --accept --dry-run
cargo run --manifest-path src-tauri/Cargo.toml --bin maru-cli -- skills import /path/to/skill --copy
# Bench workspace scan on a real workspace:
cd src-tauri && cargo test --release bench_scan_real_workspace \
-- --ignored --nocapture --test-threads=1
# β MARU_BENCH_WORKSPACE=/some/path overrides the default ~/workspace/workCI runs make verify (typecheck + vitest + cargo test --lib + build) on every
pull request and push to main via .github/workflows/ci.yml; pushes that
touch only skills/** run make skills-verify instead of the full app
toolchain. The heavier release-preflight (adds CLI + e2e + a debug Tauri
build) runs on version tags.
Skills deploy independently of app releases. Merging skills/** changes to
main triggers .github/workflows/release-skills.yml: it verifies and
packages the tree (make skills-verify / make skills-package), signs the
zip and metadata with the Tauri updater key, and uploads immutable assets to
the fixed skills-channel prerelease. The app checks that channel at launch
and applies new bundles automatically when the local skills are clean and
runtime-compatible; maru skills update --check|--apply [--repair-env] and
the Skills UI cover manual flows. The binary embeds only a frozen
src-tauri/skills-bootstrap/ snapshot as the offline first-run fallback, so
editing skills/ requires no Rust rebuild.
Publishing a GitHub Release (a v* tag; the skills channel is excluded)
triggers .github/workflows/release-bundles.yml.
The workflow builds native Tauri bundles on macOS, Ubuntu, and Windows, then
uploads the generated .app / .dmg, .deb / .rpm / .AppImage, .exe,
and .msi assets to that same release. It also uploads signed updater
metadata consumed by the startup auto-updater and native Check for Updates...
menu action. A separate macOS CLI job builds maru-cli, packages it as a
tarball containing an maru executable, and uploads
maru-cli_<version>_darwin_{aarch64,x86_64}.tar.gz plus SHA256 files to the
same release.
macOS bundles must be code signed before publishing. Until Apple Developer ID
secrets are configured, Maru uses explicit ad-hoc bundle signing
(bundle.macOS.signingIdentity = "-") so Apple Silicon downloads are not
shipped as unsigned/broken app bundles. For fully trusted Gatekeeper launches,
configure these GitHub Secrets and publish a new release:
APPLE_CERTIFICATEβ base64 encoded Developer ID Application.p12APPLE_CERTIFICATE_PASSWORDKEYCHAIN_PASSWORDAPPLE_API_ISSUER_IDAPPLE_API_KEY_IDAPPLE_API_KEYβ base64 encoded App Store Connect API.p8
The release workflow imports APPLE_CERTIFICATE only inside the macOS signing
prep step, and it sends Apple notarization env vars only to the Developer ID
build branch. It intentionally does not pass unset Apple secrets into
tauri-apps/tauri-action, because empty environment variables make Tauri try
to import or notarize with blank credentials.
Minimum Apple Developer setup for direct distribution:
-
In Apple Developer
Certificates, Identifiers & Profiles, create only aDeveloper ID Applicationcertificate. Maru does not need an Identifier or Provisioning Profile for the current direct-distribution path because it does not use iCloud, Push Notifications, App Groups, or another advanced entitlement that requires a Developer ID provisioning profile. -
Install the downloaded
.cerinto Keychain Access, then export it with its private key as a password-protected.p12. -
Encode the
.p12and set the release secrets:tmp_cert_b64="$(mktemp)" openssl base64 -A -in DeveloperIDApplication.p12 -out "$tmp_cert_b64" gh secret set APPLE_CERTIFICATE --repo STAIxBWLB/maru --body-file "$tmp_cert_b64" rm "$tmp_cert_b64" gh secret set APPLE_CERTIFICATE_PASSWORD --repo STAIxBWLB/maru gh secret set KEYCHAIN_PASSWORD --repo STAIxBWLB/maru gh secret set APPLE_API_ISSUER_ID --repo STAIxBWLB/maru gh secret set APPLE_API_KEY_ID --repo STAIxBWLB/maru gh secret set APPLE_API_KEY --repo STAIxBWLB/maru
-
Confirm release readiness without printing secret values:
make macos-distribution-check make macos-distribution-local-check
For a local notarization smoke test, keep Apple files under
~/workspace/work/.maru/secrets/apple/:
DeveloperIDApplication.p12AuthKey_<APPLE_API_KEY_ID>.p8certificate-passwordapi-issuer-id- optional
api-key-id(defaults to theAuthKey_<id>.p8filename) - optional
keychain-password(generated locally if missing)
Then run:
make macos-notarize-local TARGET=aarch64-apple-darwinKeep the Tauri updater secrets (TAURI_SIGNING_PRIVATE_KEY,
TAURI_SIGNING_PRIVATE_KEY_PASSWORD) in place; they sign updater metadata and
are separate from Apple Developer ID signing. The workflow fails on partial
Apple signing configuration instead of silently producing an unintended ad-hoc
macOS release.
Release asset versions come from the app metadata in package.json,
src-tauri/tauri.conf.json, and src-tauri/Cargo.toml; keep those in sync
before tagging or publishing a release. After release assets exist, update the
Homebrew tap with:
make homebrew-update-commit RELEASE_TAG=v0.4.0 HOMEBREW_TAP_DIR=../homebrew-cask
make homebrew-audit HOMEBREW_TAP_DIR=../homebrew-cask
make homebrew-fetch HOMEBREW_TAP_DIR=../homebrew-caskAfter downloading the release DMG, verify Gatekeeper-facing state on macOS:
xcrun stapler validate Maru_*.dmg
spctl -a -vv -t open --context context:primary-signature Maru_*.dmg
codesign --verify --deep --strict --verbose=4 /Applications/Maru.app
spctl -a -vv -t exec /Applications/Maru.appAn AI workspace is any folder containing .md (or .markdown, .html, .htm) files.
Private workspace is the required default. Public workspace is optional and means a provider-managed shared root, not internet publishing. V1 capability support is registry-only: Maru stores non-secret provider metadata in workspaces.json, maps a manually entered provider role to coarse capabilities, intersects that with a filesystem writability probe, and gates direct writes in the UI and Rust commands. OAuth, Microsoft Graph, Google Drive, and Nextcloud live API checks are deferred.
Supported public providers are Local, Google Drive, OneDrive, SharePoint, Nextcloud, Obsidian, and Unknown. workspace.config.yaml accepts:
paths:
private: ~/workspace/work
public:
- label: Team Drive
path: ~/gdrive-workspace/work
provider: googleDrive
providerId: shared-drive-id
writePolicy: direct
role: contentManager
- label: Reference Site
path: ~/shared/reference
provider: sharePoint
writePolicy: readOnly
role: Can viewMaru stores user/global preferences at:
~/.maru/
settings.json # UI/theme/layout/window/split/terminal/explorer/file-queue/AI defaults
Maru stores workspace-local state and resources at:
<workspace>/
.maru/
cache/ # disposable workspace index for warm startup
workspace-state.json # collapsed folders, initialization flags, binary patterns, overrides
versions/ # snapshots created via the "Version" button
studio/ # per-document Studio wizard state
binder/ # per-document Evidence Binder state
.maruignore # optional, gitignore-style segment patterns (falls back to legacy .anchorignore)
<workspace>/.maru/settings.json is a legacy migration input only. Maru reads
it when present to build effective settings, but new workspaces do not get that
file.
.maruignore example for the user's ~/workspace/work:
node_modules
.venv
dist
build
target
.next
.turbo
.cache
.maru/cache
- Filesystem is authoritative. The fingerprinted cache (
<workspace>/.maru/cache/workspace-index-v3.json) is disposable. Warm reconciliation reuses unchanged entries and reparses changed files only; React state remains derived. - Frontmatter key order + comments preserved. A single-field patch must never disturb the order or comments of any other key (verified by cargo test).
src-tauri/src/frontmatter/ops.rsis the only allowed write path. - Crash-safe rename.
.maru-rename-txn/staging dir + recovery on the next workspace scan. - Dynamic relationship detection. Any frontmatter field containing
[[wikilink]]is treated as a relationship. No hard-coded field lists. - Symlinks inside the workspace are honored. Deliberate user-created symlinks (e.g.
~/workspace/work/inbox/downloads β ~/gdrive-workspace/...) are considered part of the workspace. Maru uses lexical containment, notcanonicalize(). - Managed vault writes are schema-gated + snapshotted.
write_policy: "managed"writes passvault_guard::validate_managed_writeand take a snapshot before mutation; note deletion stays MCP-only.
Out of scope for v1 by explicit decision:
- Semantic / embedding search (keyword + wikilink + git-grep cover 10k notes).
- Cloud sync, maru account, default telemetry (opt-in only).
- Mobile (Tauri 2 mobile is unstable; Obsidian owns mobile for now).
- Public marketplace server (cloned sources carrying a
maru.source.jsonmanifest are schema-validated on install and rolled back on failure; the manifestsignedflag is a metadata check, not cryptographic signature verification β no server, no moderation policy). - iMessage / Slack ingestion (permission pain > value).
- Multi-user collab, CRDT, realtime (single user, single device, git for history).
- PDF annotation, OCR (file-extracted text is enough).
- Agent-autonomous edits as default behavior. Autonomy is staged behind disposable workspaces, protected writes, approval policy, and audit events.
- iCloud / Dropbox workspace awareness (user's responsibility).
- Unsigned / ad-hoc auto-updater feeds (updates are accepted only through signed GitHub Release artifacts).
No license file is currently published. All rights reserved unless a license is added.