Complete reference for all tsm CLI subcommands.
These commands run directly (not routed through the daemon).
Initialize the workspace: schema, scaffold files, WordNet import, user synonym sync. All steps are idempotent and re-runnable.
tsm init
Performs the following per-workspace setup steps. Every file write uses
OpenOptions::create_new, so existing user-customized files are never
overwritten:
$TSM_DB_PATH
(default: $TSM_INDEX_ROOT/.tsm/tsm.db)..tsmignore (project root) — .gitignore-style ignore patternstsm.toml (project root) — fully commented configuration template.tsm/user_dict.simpledic — empty (lindera user dictionary).tsm/custom_terms.toml — header comment with format example.tsm/synonyms.csv — header comment for user synonym pairs.tsm/wnjpn.db if present.
If missing, logs a warning and continues — run tsm setup to
download the file, then re-run tsm init to import..tsm/synonyms.csv (diff-based,
safe to re-run).Flags: none
Example:
export TSM_INDEX_ROOT=~/my-notes
tsm setup # one-time: fetch ruri model + WordNet DB
tsm init # per-workspace: schema, scaffold, synonym import
Start the tsmd daemon (embedder + file watcher).
tsm start [--no-watcher]
Spawns tsmd as a detached background process. Waits up to 30 seconds for the
daemon socket to become ready. If the daemon is already running, exits immediately.
Stale sockets are removed automatically.
Flags:
| Flag | Description |
|---|---|
--no-watcher |
Skip starting the file watcher child process |
Examples:
# Start daemon with file watcher (default)
tsm start
# Start daemon without file watcher (manual indexing only)
tsm start --no-watcher
Stop the tsmd daemon.
tsm stop
Sends a shutdown request to the running daemon. If the daemon socket exists but is unreachable, removes the stale socket and logs a warning.
Flags: none
Example:
tsm stop
Stop and start the daemon.
tsm restart
Equivalent to running tsm stop followed by tsm start.
Flags: none
Example:
tsm restart
Download external resources (embedding model + WordNet DB). System-wide; no workspace DB writes. Run once per machine; re-run only when the upstream resources change.
tsm setup
Pure resource-fetch layer:
cl-nagoya/ruri-v3-30m model files (config.json,
tokenizer.json, model.safetensors) from HuggingFace Hub
and copies them to .tsm/models/ruri-v3-30m/.wnjpn.db.gz) from GitHub and
decompresses it to .tsm/wnjpn.db.Importing WordNet synonyms into the workspace DB is tsm init’s job.
After running tsm setup for the first time, run tsm init (or re-run
it) so the freshly downloaded WordNet DB gets imported.
Flags: none
Example:
tsm setup
tsm init # imports WordNet synonyms into the workspace DB
Reload tsm.toml configuration without restarting the daemon.
tsm reload
Daemon-routed command — auto-starts tsmd if not running. Applies config
changes that do not require a full restart. Warnings about non-reloadable
settings are printed to stderr.
Flags: none
Example:
# Edit tsm.toml, then apply without downtime
tsm reload
These commands are daemon-routed: tsm forwards them to tsmd via a UNIX socket,
auto-starting the daemon if it is not running.
Search indexed documents.
tsm search -q <query> [options]
Performs hybrid search (FTS5 + vector) fused via Reciprocal Rank Fusion (RRF). Temporal expressions embedded in the query are automatically extracted and applied as date filters (see Temporal Query Syntax).
Flags:
| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--query |
-q |
string | (required) | Search query |
--top-k |
-k |
integer | 5 |
Maximum number of results |
--format |
-f |
text|json |
text |
Output format |
--include-content |
integer | Include full file content for top N results (JSON only) | ||
--after |
date | Return only documents after this date | ||
--before |
date | Return only documents before this date | ||
--recent |
duration | Return documents from the last N days/weeks/months | ||
--year |
integer | Return documents from a specific year | ||
--path |
string | Filter by path prefix (relative, repeatable — OR logic) | ||
--fallback |
error|fts-only |
error |
Behavior when embedder is unavailable |
Date format for --after / --before: YYYY-MM-DD, YYYY-MM, or YYYY.
Duration format for --recent: Nd (days), Nw (weeks), Nm (months).
Example: 30d, 2w, 3m.
--path flag: Accepts a relative path prefix. Multiple --path flags are
combined with OR logic (any match). Must be a relative path, not absolute.
--fallback flag: When error (default), search fails if the embedder is
not running. When fts-only, falls back to full-text search only.
Examples:
# Basic search
tsm search -q "Rust async runtime"
# Return top 10 results in JSON
tsm search -q "memory management" -k 10 -f json
# Filter by date range
tsm search -q "release notes" --after 2025-01-01 --before 2026-01-01
# Documents from the last 30 days
tsm search -q "meeting notes" --recent 30d
# Documents from 2025
tsm search -q "architecture decisions" --year 2025
# Filter to a specific subdirectory
tsm search -q "config" --path daily/
# Multiple path prefixes (OR)
tsm search -q "API design" --path projects/ --path research/
# Include full content for top 3 results
tsm search -q "deployment" -f json --include-content 3
# FTS-only mode (no embedder required)
tsm search -q "lindera tokenizer" --fallback fts-only
Index documents from the configured content directories.
tsm index [--files-from-stdin]
Without --files-from-stdin, scans directories configured in tsm.toml
(content_dirs). If content_dirs is not configured, auto-discovers
non-hidden subdirectories under TSM_INDEX_ROOT.
With --files-from-stdin, reads file paths (one per line) from stdin.
Each path is resolved relative to TSM_INDEX_ROOT.
Index updates are incremental: only changed chunks are re-indexed.
Flags:
| Flag | Description |
|---|---|
--files-from-stdin |
Read file paths from stdin instead of scanning directories |
Examples:
# Index all documents
tsm index
# Index only changed files (from git diff)
git diff --name-only HEAD | tsm index --files-from-stdin
# Index a specific directory
find ~/my-notes/daily -name "*.md" | tsm index --files-from-stdin
Ingest a Claude Code session JSONL file as searchable knowledge.
tsm ingest-session <session_file>
Parses Claude session transcripts (JSONL format) and indexes Q&A pairs as chunks. Skips unchanged files based on content hash.
Arguments:
| Argument | Description |
|---|---|
<session_file> |
Path to the .jsonl session file |
Example:
tsm ingest-session ~/.claude/projects/my-project/session-abc123.jsonl
Fill missing vector embeddings for indexed chunks.
tsm vector-fill [--batch-size N]
Processes chunks that have been indexed via FTS5 but do not yet have vector
embeddings. Requires the embedder (tsmd --embedder) to be running.
If the daemon is running, delegates to it.
Flags:
| Flag | Type | Default | Description |
|---|---|---|---|
--batch-size |
integer | 64 |
Number of chunks to embed per batch |
Example:
# Fill missing vectors with default batch size
tsm vector-fill
# Use a larger batch for faster processing
tsm vector-fill --batch-size 128
These commands are daemon-routed — auto-starts tsmd if not running.
Show current system status.
tsm status
Displays a summary of daemon, embedder, watcher, backfill, and data statistics.
Flags: none
Example output:
=== The Space Memory Status ===
Daemon: running (PID 12345)
Embedder: running (since 10m ago, PID 12346)
Watcher: running (since 10m ago)
Documents: 1234
Chunks: 5678
Vectors: 5678
Example:
tsm status
Run health checks and report system issues.
tsm doctor [-f json]
Checks database integrity, embedder availability, vector coverage, and dictionary state. Outputs a formatted report with pass/warn/fail indicators.
Flags:
| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--format |
-f |
text|json |
text |
Output format |
Example text output:
╭─ Knowledge Search Doctor ──────────────────────────╮
│ │
│ Database │
│ ✔ DB: /home/user/.tsm/tsm.db (12.3 MB) │
│ ✔ Documents: 1234 │
│ ✔ Chunks: 5678 │
│ │
│ Embedder │
│ ✔ Running (idle timeout: 600s) │
│ ✔ Vectors: 5678 (matches all chunks) │
│ │
│ All good. │
│ │
╰─────────────────────────────────────────────────────╯
Example JSON output fields:
{
"sections": [
{
"name": "Database",
"items": [
{ "status": "ok", "message": "DB: /home/user/.tsm/tsm.db (12.3 MB)" },
{ "status": "ok", "message": "Documents: 1234" },
{ "status": "ok", "message": "Chunks: 5678" }
]
},
{
"name": "Embedder",
"items": [
{ "status": "ok", "message": "Running (idle timeout: 600s)" },
{ "status": "ok", "message": "Vectors: 5678 (matches all chunks)" }
]
}
],
"issue_count": 0
}
Examples:
tsm doctor
tsm doctor -f json
Re-index in background while the daemon is running (non-destructive).
tsm reindex <kind>
Sends a reindex request to the running daemon. The daemon processes the reindex in batches, yielding to search requests between batches.
Arguments:
| Argument | Description |
|---|---|
all |
Re-tokenize FTS and re-compute vectors |
fts |
Re-tokenize FTS only (after dictionary changes) |
vectors |
Re-compute vectors only (after model changes) |
Requires: Running daemon (tsm start).
Examples:
# Re-index FTS after adding words to user dictionary
tsm reindex fts
# Re-index everything
tsm reindex all
# Check progress
tsm doctor
Rebuild the database from scratch (destructive).
tsm rebuild [--apply]
Without --apply: dry run showing database size, chunk count, and vector count.
With --apply: backs up the database, deletes it, re-initializes, and runs a
full index.
Flags:
| Flag | Description |
|---|---|
--apply |
Actually perform the rebuild (without: dry run) |
Requires: Daemon must not be running (tsm stop first) when using --apply.
Examples:
# Dry run — see what would be rebuilt
tsm rebuild
# Rebuild
tsm stop && tsm rebuild --apply
Import Japanese WordNet synonyms into the database.
tsm import-wordnet <wnjpn.db>
Imports synonym pairs from a Japanese WordNet SQLite database (wnjpn.db)
into the local synonyms table. Used for query expansion during search.
tsm setup downloads and imports WordNet automatically. This command is
for manual import from a custom path.
Arguments:
| Argument | Description |
|---|---|
<wnjpn.db> |
Path to the Japanese WordNet SQLite database |
Example:
tsm import-wordnet ~/downloads/wnjpn.db
Show or apply user dictionary candidates.
tsm dict update [--threshold N] [--apply]
Without --apply: dry run — shows candidate words that appear frequently
enough to be added to the user dictionary.
With --apply: writes the dictionary file and triggers FTS re-index. If the
daemon is running, the FTS re-index is sent via IPC (no need to stop). If the
daemon is stopped, FTS is rebuilt directly. No git operations are performed —
if you want the dictionary under version control, commit the file yourself.
Flags:
| Flag | Type | Default | Description |
|---|---|---|---|
--threshold |
integer | 5 |
Minimum frequency for a word to be a candidate |
--apply |
Write CSV and trigger FTS re-index |
Examples:
# Show candidates with default threshold
tsm dict update
# Show candidates with higher threshold
tsm dict update --threshold 10
# Apply changes (works with or without daemon)
tsm dict update --apply
Manage the dictionary reject list.
tsm dict reject [--apply] [--all]
The reject list (reject_words.txt) prevents specific words from being added
to the user dictionary.
Without flags: shows words currently in reject_words.txt that are pending
sync.
--apply: syncs reject_words.txt to the database.
--all: shows all rejected words stored in the database.
--apply and --all are mutually exclusive.
Flags:
| Flag | Description |
|---|---|
--apply |
Sync reject_words.txt to the database |
--all |
Show all rejected words in the database |
Examples:
# Sync reject list to DB
tsm dict reject --apply
# Show all rejected words
tsm dict reject --all
Sync user-defined synonym pairs from a CSV file to the database.
tsm dict synonym sync
Reads .tsm/synonyms.csv and syncs its contents to the synonyms table.
The CSV file is the source of truth:
source = 'user' (score 0.7, no decay)tsm setup runs this automatically when the file exists.
CSV format:
# Comments start with #
猟銃,散弾銃
猟銃,鉄砲
LoRa,LPWAN
Two columns, no header. Lines starting with # are ignored.
Example:
# Create synonyms file
echo "猟銃,散弾銃" > .tsm/synonyms.csv
# Sync to database
tsm dict synonym sync
Temporal expressions embedded in search queries are automatically extracted and converted to date filters. The matched expression is removed from the query before search.
CLI flags (--after, --before, --recent, --year) take precedence over
query-embedded expressions.
| Expression | Meaning |
|---|---|
先月 |
Last calendar month |
今月 |
Current month (no upper bound) |
去年 / 昨年 |
Last year |
一昨年 / おととし |
Two years ago |
今年 |
This year (no upper bound) |
最近 / 少し前 |
Last N days (configured via RECENT_DAYS, default 30) |
先週 |
Last 7 days |
半年前 |
Last 180 days |
年末 |
November–December of current (or previous) year |
年始 / 年初 |
January–February of current (or previous) year |
| Pattern | Meaning |
|---|---|
N年前 |
N years ago (1 year = 365 days) |
N週間前 / N週前 |
N weeks ago |
N日前 |
N days ago |
Nヶ月前 / Nか月前 |
N months ago (1 month = 30 days) |
| Pattern | Meaning |
|---|---|
N月の / N月に |
Month N of the current year; if N is in the future, uses the previous year |
| Flag | Format | Examples |
|---|---|---|
--recent |
Nd, Nw, Nm |
30d, 2w, 3m |
--after |
YYYY, YYYY-MM, YYYY-MM-DD |
2025, 2025-06, 2025-06-15 |
--before |
YYYY, YYYY-MM, YYYY-MM-DD |
2026, 2026-01, 2026-01-01 |
--year |
YYYY |
2025 |
# Query-embedded temporal expression
tsm search -q "先月のミーティングメモ"
tsm search -q "去年のアーキテクチャ決定"
tsm search -q "3ヶ月前のリリースノート"
tsm search -q "6月のスプリント振り返り"
# CLI flag overrides query expression
tsm search -q "最近のバグ報告" --recent 7d
# Explicit date range
tsm search -q "release notes" --after 2025-01-01 --before 2026-01-01
Default output for tsm search. One result per block:
1. [markdown] projects/api-design.md — ## Authentication (score: 0.8421)
Token-based authentication using JWT. Refresh tokens are stored in...
status: active
related:
- [wiki_link] projects/security.md (strength: 0.85)
2. [session] sessions/2025-06-10.jsonl — Q: How to handle auth? (score: 0.7103)
A: Use short-lived JWT access tokens with refresh token rotation...
Fields:
| Field | Description |
|---|---|
| Result number | Sequential index starting at 1 |
[source_type] |
markdown for .md files, session for JSONL sessions |
| File path | Relative path from TSM_INDEX_ROOT |
| Section path | Heading path or Q&A label |
| Score | RRF-fused relevance score |
| Snippet | Relevant excerpt |
| Status | Frontmatter status field (if present) |
| Related docs | Inferred document links with link type and strength |
Output for tsm search -f json. Returns a JSON array:
[
{
"source_file": "projects/api-design.md",
"source_type": "markdown",
"section_path": "## Authentication",
"snippet": "Token-based authentication using JWT...",
"score": 0.8421,
"status": "active",
"related_docs": [
{
"file_path": "projects/security.md",
"link_type": "wiki_link",
"strength": 0.85
}
],
"content": "Full file content here..."
}
]
The content field is only present when --include-content N is used and
the result is within the top N.