# LatticeSearch CLI (`lattice`)

`lattice` is a thin command-line client for the running LatticeSearch engine. Every verb is a
single HTTP call to the local engine (default `http://127.0.0.1:8765`), so answers come back from
the warm in-memory index in milliseconds — no disk walk, no model cold-start.

## Launcher

There is no installed `lattice` shim yet; invoke the script with the engine's Python:

```
"C:\sd\kohya_ss\venv\Scripts\python.exe" C:\sd\latticesearch\lattice.py <verb> [args]
```

For brevity the rest of this doc writes that as `lattice <verb>`. Define a shell function/alias if
you use it often, e.g. in PowerShell:

```powershell
function lattice { & "C:\sd\kohya_ss\venv\Scripts\python.exe" "C:\sd\latticesearch\lattice.py" @args }
```

### Environment & auth

| Variable | Default | Purpose |
|---|---|---|
| `LATTICE_URL` | `http://127.0.0.1:8765` | Which engine to talk to. |

The auth token is read automatically from `ls_token.txt` beside `lattice.py` and sent as the
`X-LS-Token` header — mutating verbs (write/edit/mv/cp/rm/star/open/remember/…) need it; the file
is written by the engine on first start, so no manual setup is required on the same machine.

### Global flags

| Flag | Effect |
|---|---|
| `--json` | Emit raw JSON instead of the formatted view. **Goes before the verb**: `lattice --json search "…"`. |

Exit code is `0` on success; `health` exits `2` if the engine is unreachable.

---

## EYES — find things without walking the disk

The read side of the lattice: semantic + name search, "where does this file live", the assistant,
semantic-narrowed grep, and instant filesystem answers straight from the index.

### `search` — semantic + name search across the whole machine

```
lattice search <query> [--cat all|images|video|audio|docs|code|other] [--sort rel] [--limit 15]
```

Fuses three tiers in parallel: ranked filename/path matches, CLIP image-meaning matches, and e5
document-meaning snippets.

```
$ lattice search "a red apple fruit"
# 6 files (48ms), 24 images, 8 docs
  exact   apple.py                                  C:\sd\tools\apple.py
  img 0.31  HITL_Apple.png                          C:\sd\datasets\HITL_Apple.png
  doc 0.86  fire_safety.txt: procedures for checking smoke alarms and evac
```

### `find` — where does this image/video live (and what's similar)

```
lattice find <image_or_video_path>
```

Encodes the file with CLIP and looks for the exact copy (cosine > 0.999), the folders it most
lives in, and — for video — the best-matching moment.

```
$ lattice find C:\Users\Shadow\Desktop\photo.png
# Found the exact file (43ms)
  EXACT  C:\sd\datasets\HITL_Apple.png
  lives  0.88 12x  C:\sd\datasets\fruit
```

### `ask` — the Lattice assistant (natural-language question over your files)

```
lattice ask <question>
```

A deliberate, higher-quality path: fused retrieval **plus** the cross-encoder reranker (which never
fires on plain `search`, to keep it instant). Returns a written answer and the files it used.

```
$ lattice ask "which document explains the evacuation plan"
The means-of-escape guidance is in the EMBER fire-safety course...
  [doc] means-of-escape.html  C:\sd\ember\content\means-of-escape.html
```

### `grep` — the grep amplifier (meaning-narrow, then exact-match)

```
lattice grep <pattern> [--about <meaning>] [--cat all] [--files 40] [--limit 30]
```

Turns "grep the whole disk" (slow/impossible) into "grep the ~N files that *mean* X": the lattice
picks candidate files by meaning (`--about`, falling back to the pattern), then runs ripgrep (or a
Python fallback) **only** inside them.

```
$ lattice grep "deploy" --about "how to deploy the ember course"
# narrowed to 8 files by meaning, grepped in 313ms, 11 matches
  C:\sd\ember\DEPLOY.md:12:hPanel upload_file then 1-click rollback
```

### `fs` — instant filesystem answers from the index (no walk)

```
lattice fs du|largest|find|tree <dir> [pattern] [--limit 30] [--depth 2]
```

The lattice already holds `(path, size, mtime)` in RAM, so `du`/`find`/`tree`/`largest` become
lookups — **~1000× faster than a live directory walk**, with bounded output.

| op | Answers | Extra args |
|---|---|---|
| `du` | total bytes + file count of a folder tree | — |
| `largest` | the N largest files under a folder | `--limit` |
| `find` | files whose name contains `pattern` under a folder | `pattern`, `--limit` |
| `tree` | folder tree with per-folder file counts | `--depth` |

```
$ lattice fs du C:\sd\ember
41.2 GB  (44,230,113,001 bytes)  18,442 files   [3ms from index]

$ lattice fs largest C:\sd --limit 3
    1.2 GB  C:\sd\models\clip\open_clip_pytorch_model.bin
    1.1 GB  C:\sd\models\reranker\model.safetensors
    590 MB  C:\sd\models\clap\pytorch_model.bin
```

### `glob` — wildcard matching from the index (instant)

```
lattice glob <dir> <pattern> [--limit 100]
```

`* ? ` wildcard file matching under a folder, answered from the index (no shell glob, no walk).

```
$ lattice glob C:\sd\ember "*.mjs"
37 hits [4ms from index]
  C:\sd\ember\routes\messages.mjs
  ...
```

### `ls` — browse a folder from the index

```
lattice ls [<dir>]
```

Lists sub-folders and files of a directory (empty = drive roots), served from the pre-built
dir-index with zero disk I/O.

```
$ lattice ls C:\sd\ember
  [dir]  content
  [dir]  routes
  code    server.mjs
  docs    README.md
```

### `photos` — the media timeline

```
lattice photos [--filter all|photos|videos|starred] [--group years|months|days]
```

```
$ lattice photos --filter photos --group months
# 49777 media files (1280ms)
  2026-07: 812 items
  2026-06: 1,140 items
```

---

## HANDS — instant, safe, index-synced file I/O

The write side. Everything written is **instantly searchable**; deletes are **recoverable**;
same-volume moves are **O(1)**. These are 13–20× faster than spawning a shell for the same action,
and they keep the index in sync so the next search sees the change.

### `read` — whole file, or only the chunks about a topic

```
lattice read <path> [--about <topic>]
```

Without `--about`, prints the file. With `--about`, returns only the chunks that mean the topic —
the biggest single token saving for agents on large files.

```
$ lattice read C:\sd\ember\server.mjs --about "how photos are served"
[chunks about 'how photos are served' — 22ms]
---
app.get('/photos', ...) { ... }
```

### `write` — atomic write, instantly searchable

```
lattice write <path> <content>       # content of "-" reads stdin
```

```
$ echo "release notes v34" | lattice write C:\sd\notes\v34.txt -
written 18 bytes — instantly searchable
```

### `edit` — verified exact-string edit

```
lattice edit <path> <old> <new> [--expect 1]
```

Refuses ambiguous or missing anchors (no blind-edit failures), writes atomically, re-indexes. Set
`--expect` to the number of occurrences you intend to replace.

```
$ lattice edit C:\sd\config.ini "port=8000" "port=8765"
edited: 1 replacement(s) in 4.1ms
```

### `mv` — O(1) same-volume move (any size)

```
lattice mv <src> <dst>
```

Same-volume moves are an instant rename regardless of file size; cross-volume falls back to a
verified copy + delete.

```
$ lattice mv C:\sd\a\big.mp4 C:\sd\b\big.mp4
moved via rename in 0.3ms -> C:\sd\b\big.mp4
```

### `cp` — parallel verified copy

```
lattice cp <src> <dst>
```

```
$ lattice cp C:\sd\a C:\sd\a_backup
copied 214 files in 380ms -> C:\sd\a_backup
```

### `rm` — SAFE delete (recoverable)

```
lattice rm <path>
```

Not a hard delete: the bytes are archived to the recovery store (restorable ~90 days) **and** sent
to the Recycle Bin. Recover with `lattice recover` / `lattice restore`.

```
$ lattice rm C:\sd\tmp\old.log
deleted safely (recoverable)
```

---

## MEMORY — persistent, meaning-searchable notes

A private semantic memory store that survives sessions (and, for agents, compaction).

### `remember` — store a fact/note

```
lattice remember <text> [--session <name>] [--tags <csv>]   # text of "-" reads stdin
```

```
$ lattice remember "the render server uses port 4700" --session ember
remembered (1 chunk(s), id a3f1)
```

### `recall` — recall by meaning

```
lattice recall <query> [--session <name>] [--limit 6]
```

```
$ lattice recall "which port did the render server use"
  0.912 [ember] the render server uses port 4700
```

---

## CLIPBOARD — searchable clipboard history

```
lattice clip [list|search|on|off] [query]
```

| Form | Effect |
|---|---|
| `lattice clip` / `lattice clip list` | Show whether capture is on + the recent captured items. |
| `lattice clip search <query>` | Semantic search over captured clips. |
| `lattice clip on` / `lattice clip off` | Enable / disable clipboard capture. |

Credential-looking text (passwords, tokens, API keys, PEM blocks, long base64) is filtered out and
**never stored** — see [PRIVACY.md](PRIVACY.md).

```
$ lattice clip search "runpod api"
  0.874 export RUNPOD_ENDPOINT=https://...
```

---

## CODE — find symbols by name or meaning

```
lattice sym <query> [--limit 10]
```

Resolves "where is the retry logic" to `file:line` over the code-symbol index.

```
$ lattice sym "the retry logic"
  fuzzy   func   _post_with_retry  C:\sd\latticesearch\transfer.py:88
```

(If empty: build the symbol index with `python codesym.py build --roots <dirs>`.)

---

## UTIL — recovery, opening, status, virtual drive, shell

### `recover` — search deleted files

```
lattice recover <query>
```

```
$ lattice recover "the doc I deleted about smoke alarms"
  0.85  fire_safety.txt  (deleted 2026-07-10, RECOVERABLE)  C:\sd\...\fire_safety.txt
```

### `restore` — restore a deleted file

```
lattice restore <path>
```

Restores byte-identical to `~\LatticeSearch Recovered`.

```
$ lattice restore C:\sd\docs\fire_safety.txt
restored -> C:\Users\Shadow\LatticeSearch Recovered\fire_safety.txt
```

### `star` — star / unstar a file

```
lattice star <path> [--off]
```

### `open` — open in the default app

```
lattice open <path>
```

### `health` — engine status

```
lattice health
```

```
$ lattice health
engine OK — 1,659,874 files, 16,059 images, 9,420 doc chunks
```

### `drive` — the always-indexed virtual drive

```
lattice drive mount|unmount [--letter L]
```

Mounts `~\LatticeDrive` as a drive letter via `subst` and registers it as a live-watched root:
anything dropped there is instantly name-indexed and embedded when idle. (Restart the engine once
after the first mount so the watcher picks up the new root.)

```
$ lattice drive mount --letter L
LATTICE DRIVE mounted: L:  ->  C:\Users\Shadow\LatticeDrive
```

### `sh` — the lattice shell (many ops, one process)

```
lattice sh                       # interactive REPL
lattice sh "cmd; cmd; ..."       # batch, semicolon-separated
```

Kills the per-command process-spawn tax: many index ops run in **one** Python process, measured
**~22.6× faster** than the equivalent chain of separate shell/CLI invocations. Sub-commands:
`search  du  largest  find  glob  tree  read  write  mv  cp  rm  suggest`.

```
$ lattice sh "du C:\sd\ember; largest C:\sd\ember 3; find C:\sd\ember server"
41.2 GB  18,442 files  [3ms]
    1.2 GB  C:\sd\ember\...
3 hits [2ms]
   C:\sd\ember\server.mjs
```

---

## Speed at a glance

| Verb group | Win vs the naive alternative |
|---|---|
| `fs` / `glob` / `ls` | **~1000×** vs a live directory walk (answered from the RAM index) |
| `read` / `write` / `edit` / `mv` / `cp` / `rm` | **13–20×** vs spawning a shell for the same action |
| `sh` (chained ops) | **~22.6×** vs the same ops as separate process invocations |
| `search` / `find` / `ask` vs grep+ls chains | **44× fewer tokens, 12× faster** per task (agent benchmark) |

See [MCP.md](MCP.md) for the same capabilities as MCP tools for AI agents, and
[PRIVACY.md](PRIVACY.md) for the local-only security model.
