the-space-memory

Command Reference

Complete reference for all tsm CLI subcommands.

Table of Contents


Lifecycle Commands

These commands run directly (not routed through the daemon).

tsm init

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:

  1. Creates the SQLite database at $TSM_DB_PATH (default: $TSM_INDEX_ROOT/.tsm/tsm.db).
  2. Writes default scaffold files when missing:
    • .tsmignore (project root) — .gitignore-style ignore patterns
    • tsm.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
  3. Imports Japanese WordNet synonyms from .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.
  4. Syncs user-defined synonyms from .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

tsm start

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

tsm stop

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

tsm restart

Stop and start the daemon.

tsm restart

Equivalent to running tsm stop followed by tsm start.

Flags: none

Example:

tsm restart

tsm setup

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:

  1. Downloads 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/.
  2. Downloads Japanese WordNet (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

tsm reload

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

Search and Index

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

tsm index

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

tsm ingest-session

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

tsm vector-fill

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

Diagnostics

These commands are daemon-routed — auto-starts tsmd if not running.

tsm status

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

tsm doctor

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

Maintenance

tsm reindex

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

tsm rebuild

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

tsm import-wordnet

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

Dictionary Management

tsm dict update

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

tsm dict reject

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

tsm dict synonym sync

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:

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 Query Syntax

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.

Single-Token Keywords

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

Relative N + Unit Patterns

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)

Specific Month Pattern

Pattern Meaning
N月の / N月に Month N of the current year; if N is in the future, uses the previous year

CLI Flag Formats

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

Examples

# 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

Output Formats

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.