zudo-text

検索したい単語を入力

いつでも検索バーを開ける

Backend API

Overview

zudotext uses Tauri v2 for native OS integration, with no Node.js main process. The cloud workspace is accessed through TypeScript bridge domains. Rust commands cover native concerns such as windows, device-local configuration, file pickers, and the deliberately local External File Editor surface.

The backend exposes functionality to the frontend through two mechanisms:

  • Commands — synchronous or async request/response calls (like RPC)

  • Events — backend-to-frontend push notifications (like pub/sub)

How the Frontend Calls the Backend

Commands via invoke()

The frontend calls Rust functions using Tauri's invoke(). The @takazudo/backend-bridge package abstracts this so that production code uses real Tauri calls while tests and Storybook use an in-memory mock adapter.

import { invoke } from '@tauri-apps/api/core';

// Read an explicitly local file (External File Editor)
const content = await invoke<string>('files_read_text', {
  path: '/Users/example/notes/local.md',
});

Events via listen()

The backend pushes real-time notifications to the frontend using Tauri's event system. The frontend subscribes with listen().

import { listen } from '@tauri-apps/api/event';

// Listen for a file opened in External File Editor changing on disk
const unlisten = await listen<{ path: string }>('files:externalChange', (event) => {
  console.log('File changed:', event.payload.path);
});

Command Naming Convention

All Tauri commands use snake_case naming, grouped by domain:

PrefixDomainExample commands
files_ / local_dir_Explicitly local file surfacesfiles_read_text, files_write_text, files_delete_file, local_dir_list_files
assets_ / download_sink_Native asset import/export helpersassets_download_file, assets_download_many, download_sink_open
settings_App settingssettings_get, settings_save
app_binding_Per-app cloud workspace bindingapp_binding_read, app_binding_persist, app_binding_clear
device_Device identitydevice_get_name, device_set_name, device_clear_name
generator_Child-app generationgenerator_scaffold, generator_assemble_child, generator_open_app, generator_find_leaf_for_workspace
file_search_Spotlight file searchfile_search_start, file_search_cancel, file_search_is_supported
skills_Inline-AI skill filesskills_list_dir, skills_watch_dir, skills_unwatch_dir
fonts_System fontsfonts_list
frame_Window/popout framesframe_pop_out, frame_dock, frame_popout_emit_event
set_window_Window propertiesset_window_opacity, set_window_title
print_Printingprint_webview
reveal_File managerreveal_directory
get_Local environment gettersget_home_dir, get_user_skills_dir
app_mode_App mode (ROOT/LEAF)app_mode_get
fs_Filesystem helpersfs_mkdir

Application State

All commands share a central AppState managed by Tauri's dependency injection:

pub struct AppState {
    pub file_searches: Mutex<HashMap<String, MdfindChild>>,
    pub watchers: Mutex<WatcherState>,
    pub app_config_dir: PathBuf,
    pub settings_cache: Mutex<Option<serde_json::Value>>,
    pub settings_mtime: Mutex<u64>,
    pub event_tx: broadcast::Sender<SseEvent>,
}
  • app_config_dir — immutable path to the app's config directory (e.g. ~/.config/zudotext/<appname>/); not wrapped in a Mutex because it never changes after initialization

  • file_searches — active mdfind subprocess handles keyed by search ID (Spotlight integration)

  • watchers — file watcher instances and content/mtime tracking for self-write detection

  • settings_cache / settings_mtime — cached settings with mtime-based invalidation

  • event_tx — broadcast channel for SSE events (REST adapter)

Native state is synchronized with narrow mutexes; commands avoid holding unrelated locks across I/O.

Page Index

PageDomains covered
MessagesCompatibility message domain; cloud-backed in production, local only in the development REST fallback
PinsCompatibility pin domain over workspace documents
InboxCompatibility Note Tray and active-selection domains
AssetsWorkspace Assets API plus native import/export helpers
Settings and Workspace Bindingsettings_*, app_binding_*, fonts_list, misc getters
WatchersDevelopment REST fallback, user-skills, and External File Editor watchers
Helper ModulesInternal Rust helpers (not Tauri commands)
Sync and AuthCloud sync bridge (bridge.sync, bridge.auth)
Sync Server APISync Worker REST routes and PAT server routes
Generatorgenerator_* — LEAF-app assembly pipeline
Device Identitydevice_* — per-machine device name
File Search and Similarityfile_search_* (Spotlight) plus bridge.similarDocs — the TypeScript BM25 index over the workspace model (no Tauri commands)
Frame Pop-Outframe_pop_out, frame_dock, frame_popout_emit_event, bridge.framePopout restore protocol
Publish and API Tokensbridge.publish (publish Worker), bridge.apiTokens (PAT management)
Automation APIPAT-authenticated, key-session-gated workspace automation routes

Internal / Unlisted Commands

The following Tauri commands are registered in generate_handler! but are not documented on dedicated pages. They are internal utilities, UI conveniences, or native OS dialogs without a significant contract to specify:

CommandDescription
app_mode_getReturns "root" or "leaf" — consumed internally at startup; documented in architecture docs
files_read_textLow-level read of a LOCAL file by absolute path (External File Editor); workspace content goes through bridge.workspaceFiles
files_write_textLow-level write to a LOCAL file by absolute path; workspace content goes through bridge.workspaceFiles
files_delete_fileDelete a file within allowed roots (validate_path_in_roots guard); see Helper Modules
fs_mkdirCreate a directory within allowed roots; see Helper Modules
get_user_skills_dirReturn the user-scoped skills config directory path
skills_list_dirList .md files in the skills directory; used by the inline-command skill loader
set_window_titleSet the native window title string
set_window_opacitySet window opacity (0.0–1.0); documented as a UI convenience on the Settings and Workspace Binding page
print_webviewTrigger the system print dialog for the WebView; documented on the Settings and Workspace Binding page
open_directoryOpen a directory via the native OS file picker dialog
dialog_create_directoryPrompt the user to create a new directory via a native dialog

Event Summary

EventPayloadSource
messages:changed{ filename: string }Development REST fallback watcher
notes:changed{ dir: string }Development REST fallback watcher
draft:externalChange{ draftNumber: number }Development REST fallback watcher
files:externalChange{ path: string }External File Editor watcher
skills:changed{ events: Array<{ path: string, kind: string }> }Skills directory watcher
generator:assemble-progressAssembleProgressGenerator pipeline step
frame:popout-closed{ frameId: string, windowLabel: string }Pop-out window destroy handler
file-search:{id}:hit{ path: string, kind: string }Spotlight search hit
file-search:{id}:complete(none)Spotlight search completed
file-search:{id}:error{ message: string }Spotlight search failed

Security

  • Path traversal prevention — local file operations use purpose-specific containment and canonicalization guards such as validate_path_in_roots; workspace paths are validated by the cloud workspace layer

  • Input validation — settings must be JSON objects, inbox active draft numbers must be 1–99

  • Filename sanitization — asset filenames are stripped of path components to prevent traversal