Threadnote releases are standalone executables with an embedded Bun runtime; users do not need Bun, Node, npm, or
Python installed. Verify the immutable release and archive checksum, then run threadnote doctor --dry-run. On macOS,
codesign --verify --strict --verbose=2 "$(command -v threadnote)" checks the Developer ID signature. On Windows,
Get-AuthenticodeSignature (Get-Command threadnote).Source should report Valid.
If an older npm-based Threadnote command shadows the standalone launcher, compare every result from
command -v -a threadnote on POSIX or Get-Command threadnote -All in PowerShell. The standalone installer removes
verified npm-distributed Threadnote installations automatically, including early Node-based 4.0 betas. If it warns
that a package manager could not remove one, run the exact printed uninstall command and rerun the installer. Threadnote
does not remove unverified third-party files. Threadnote 3 cannot install v4 through threadnote update; a fresh
standalone install is the supported upgrade path.
The bootstrap defaults to stable-only selection. Pass the beta flag to select the newest immutable release across both stable and prerelease builds; this can install stable when it is newer than every prerelease:
curl -fsSL https://raw.githubusercontent.com/Kashkovsky/threadnote/main/scripts/install.sh | sh -s -- --beta& ([scriptblock]::Create((irm https://raw.githubusercontent.com/Kashkovsky/threadnote/main/scripts/install.ps1))) -BetaA prerelease installation follows this inclusive beta channel for ordinary updates. After it graduates to stable,
unflagged updates infer stable-only selection again; use threadnote update --beta to explicitly re-enter preview
selection.
The PowerShell installer path is available for testing but no official Windows 4 asset is published until Authenticode signing is re-enabled.
The POSIX launcher lives in ~/.local/bin. When that directory is absent from PATH, the standalone installer adds an
idempotent entry to the detected zsh, bash, fish, or POSIX shell profile. A child installer cannot modify the shell that
launched it, so either open a new terminal or apply the command printed by the installer:
export PATH="$HOME/.local/bin:$PATH"For fish, use:
set -gx PATH "$HOME/.local/bin" $PATHThe absolute command printed at the end of installation also works immediately, for example
"$HOME/.local/bin/threadnote" doctor --dry-run. A custom THREADNOTE_BIN_DIR is never added to a profile
automatically; add that directory to PATH yourself or use its absolute launcher path.
Threadnote 4 owns no daemon. threadnote start verifies the on-demand runtime and threadnote stop is a compatibility
no-op. Use threadnote doctor for storage, index, and model diagnostics.
Do not put a rule under ~/.cursor/rules; Cursor documents .cursor/rules/*.mdc as project scope. Install Threadnote
from Cursor's public Marketplace, or ask a Teams or Enterprise administrator to allow it or add it to a team
marketplace. Configure the MCP server separately with threadnote mcp-install cursor --apply, then reload Cursor.
Run threadnote doctor afterward. When Cursor is installed, doctor verifies the global MCP entry and the plugin's
manifest, version, .mdc anatomy, and complete always-applied instruction block. When Cursor is not installed, the
Cursor plugin check is omitted. Threadnote lifecycle commands never install or repair the plugin.
If doctor reports ~/.cursor/plugins/local/threadnote, fully quit Cursor and move only that unsupported local copy aside
before installing through the Marketplace. Threadnote does not remove it automatically. If model access is affected on
a managed device, preserve needed settings and coordinate with the Cursor administrator or Cursor support before
clearing broader application state.
Run threadnote logs to list the available files. Threadnote writes JSON Lines operational diagnostics under
~/.threadnote/logs/threadnote.log, rotates at 1 MiB, and retains five rotated files (threadnote.log.1 through
threadnote.log.5). Appends and rotation are serialized both within one process and across concurrent agent
processes.
The log schema is intentionally narrower than console output: it includes the Threadnote and embedded Bun versions,
operating system and architecture, CLI command or MCP tool name, duration, outcome, and typed failure name. It never
records command arguments, environment values, memory content, recall queries or results, MCP request/response
payloads, or exception messages. Help, dry-run, implicit preview, and report-issue commands do not write logs.
Logging starts only after Threadnote owns a valid home, never creates a home before migration, and is best-effort so a
logging failure cannot fail the command.
Review the files before attaching them to a support report. The active file is newest; numbered files are progressively older.
For failures that are difficult to reproduce, optional anonymous telemetry can correlate allowlisted command and MCP
tool outcomes during one agent session. It is off by default. Run threadnote telemetry enable to preview the data and
destination, then rerun with --apply only if you consent. Use threadnote telemetry status to inspect the effective
state and threadnote telemetry disable --apply to revoke it. Telemetry never replaces the local logs or an explicit
support report; see Optional anonymous telemetry.
Create a Threadnote GitHub issue through an exact public preview:
threadnote report-issue \
--title "Short failure summary" \
--body "What happened, what was expected, and how to reproduce it"Preview does not require GitHub CLI. For submission, install it from cli.github.com (or use
brew install gh on macOS / winget install --id GitHub.cli on Windows), authenticate with gh auth login, and rerun
with --apply --approval sha256:... using the approval digest printed by the preview. Threadnote refuses submission if
the title, body, diagnostics, or selected log excerpt changed after review. Add --include-logs only when you want the
newest valid production-log entries embedded in the issue. Threadnote re-parses those JSONL entries through a strict
field allowlist, omits older entries beyond the issue-body budget, and never posts raw command output. The request body
is passed to gh api through an owner-only temporary file rather than process arguments.
The owned home defaults to ~/.threadnote. Check for an accidental override:
echo "$THREADNOTE_HOME"
threadnote doctor
threadnote migratemigrate is a dry run unless --apply is present. It never deletes the legacy source. An interrupted copy can be
resumed; a promoted target has a checksummed receipt. If the target is unrelated or free space is insufficient,
migration stops before promotion.
The standalone installer removes verified obsolete runtimes, not legacy data. It may uninstall the old global
Threadnote package, the Threadnote-owned OpenViking uv/pipx/user-pip tool, and the macOS
io.threadnote.openviking LaunchAgent. It never deletes ~/.openviking; run threadnote migrate --apply to import
that source into the native Threadnote 4 home.
threadnote forget --dry-run <uri> inspects the same exact target as apply. A directory preview says it will remove a
resource subtree; apply then removes that directory and its descendants recursively while preserving siblings.
Anchored resources and broad namespace or collection roots are refused, so use the unanchored URI of the narrowest
directory you intend to remove.
A genuine mutation-lock failure identifies the local owner PID when available. Wait for that operation, inspect
threadnote processes, and run threadnote doctor --dry-run if the owner is stale or unknown. Filesystem removal
errors are reported as removal errors rather than being mislabeled as lock failures.
Threadnote applies .threadnoteignore while walking the filesystem, before entering ignored directories. The default
rules exclude dependency and build caches such as node_modules/ and .nx/. Broad patterns also skip every directory
whose name starts with ., while an explicitly named manifest pattern such as .github/** or .claude/** still
includes that directory.
Each project is limited to 20,000 candidates, 250,000 visited non-ignored entries, and 4 MiB per file. Narrow the
project's seed patterns or extend .threadnoteignore if a limit is reported. A failed project no longer prevents later
projects from being processed, but the command returns a failure after writing the completed project state.
The final summary reports safety skips and project failures. Local POSIX home paths are redacted from every seeded text
file. Windows paths such as C:/Users/..., Git-Bash paths such as /c/Users/..., and WSL paths such as
/mnt/c/Users/... are retained because they describe portable path conventions rather than a macOS home.
The core BGE embedding model and vector index are installed automatically by threadnote install. Repair their
derived state without selecting a model manually:
threadnote repair
threadnote models list
threadnote models runtime
threadnote models verify bge-small-en-v1.5-q8
threadnote index status
threadnote index verifyThe initial model download requires HTTPS access to the manifest’s pinned repository revision and resumes after an
interruption. Repeat installs preserve a verified existing model. A checksum mismatch deletes the invalid partial file
and never activates it. Lexical recall remains available if native inference is temporarily unavailable, while
threadnote doctor reports the missing core capability as a failure.
The runtime requests prebuilt node-llama-cpp binaries only. If models runtime reports that no compatible prebuilt
binary exists, install the Threadnote archive matching your operating system and architecture; Threadnote will not
silently compile one.
Install and repair also retire the old 3.x Python local-AI daemon after migration. Threadnote signals a process only after its legacy receipt, loopback health response, PID, launch ID, model ID, and token-derived proof all agree. Unverified or unresponsive PIDs are left untouched with a warning.
Each active stdio client owns one MCP process, and semantic work lazily starts one crash-isolated local-model worker
below that parent. Run threadnote processes to see a bounded privacy-safe inventory with role, parent PID, age,
current operation, and RSS. The output excludes command lines, working directories, repository names, prompts, and
model input.
The Processes tab in threadnote manage presents the same bounded registered-runtime inventory and refreshes while
workers start and stop. Its stop icon requires confirmation and is bound to the exact private registration and operating
system start identity shown in that row; it refuses stale, replaced, legacy, or unverifiable processes. The Manager
process hosting the page is intentionally protected. Isolated automatic-compaction and deep-diagnostics workers appear
there only while their operation is alive, so seeing only Manager after compaction completes is expected.
ROLE is how the process was started and never changes: ordinary roles include mcp, cli, and manager; dedicated
workers include graph-parser-worker, graph-compaction-worker, graph-diagnostics-worker, and
local-model-worker. While a process builds or waits for a code graph, the role it is temporarily acting as is
appended, as in cli (graph-builder) for a dedicated threadnote graph index run or mcp (graph-waiter) for an MCP
server queued behind another build. A process is therefore identifiable by its own identity and by the graph work it
currently owns.
An unused model worker unloads after five minutes by default. Set
THREADNOTE_LOCAL_MODEL_WORKER_IDLE_TIMEOUT_MS=<milliseconds> before starting the client to use a different idle
window; 0 disables idle eviction. Closing the stdio client closes both its MCP server and worker.
Code graph vector builds can use up to eight embedding contexts on CPU and divide the detected math-core thread budget
between them. The native runtime caps the pool on smaller CPUs; a model with GPU layers, or unknown offload state,
stays on one context. Ordinary recall and semantic-query embeddings remain serial by default. Set
THREADNOTE_EMBEDDING_CONTEXTS=1, 2, 4, or 8 to override every embedding session in that process; prefix only
the threadnote graph index command to limit the override to a graph build. 1 is the low-memory rollback.
Re-run threadnote repair or threadnote index rebuild. The lexical and vector SQLite databases are disposable and
rebuilt from canonical Markdown after corruption. Vector values are content-addressed, so a retry reuses every valid
value already written. A changed active mapping is committed in one SQLite transaction only after every required
vector is present; an interrupted embedding run leaves the previous mapping available.
threadnote repair --deep runs a full SQLite integrity check over each derived native code graph. Large monorepo
graphs can take time to scan, and a pause at one database means SQLite is still reading that database's pages. Use the
home-wide graph commands when the issue is isolated to native code graphs:
threadnote graph diagnostics --analyze --json
threadnote graph repair --all --dry-run
threadnote graph repair --allgraph diagnostics does not depend on the current directory. Its default health pass is quick; add --deep only when
you need full SQLite integrity and foreign-key checks. graph repair --all immediately applies pending persistent
schema migrations instead of waiting for a later graph query, while also keeping its default pass quick. Add --deep
to discard an unreadable or corrupt derived graph database after the full check; its source repository and Threadnote
memories are untouched, and the next graph query rebuilds the disposable graph.
threadnote index verify
threadnote index rebuildThe native graph supports compiler-backed TypeScript/JavaScript and structural Java, Kotlin, Swift, Bash, C, C++, C#, Dart, Elixir, Go, HCL/Terraform, Julia, Lua, Objective-C, PHP, PowerShell, Python, Ruby, Rust, Scala, Solidity, Svelte, SystemVerilog/Verilog, Vue, Zig, Apex, Fortran, and Razor without invoking repository build tools. The standalone archive bundles checksum-verified grammar WASM for the AST-backed structural packs. Apex, Fortran, and Razor are bounded deterministic text-structural packs and do not claim AST coverage. Threadnote also has deterministic extractors for common schema/configuration formats and local document corpora. Check the disposable graph and rebuild it with:
threadnote graph status
threadnote graph inventory
threadnote doctor --dry-run
threadnote graph index --fullthreadnote graph inventory is a non-mutating, aggregate-only admission preview. It reports exact file and byte totals
for eligible and skipped inputs, grouped by language, file role, language-pack classifier, and decision reason. The
breakdown makes SVG, heavy/generated JSON, Git ignore, and .threadnoteignore decisions visible while separately
showing admitted TypeScript, package manifests, Nx configuration, and TypeScript configuration. Add --json for the
versioned path-free payload. Ordinary source blobs are not hydrated; Threadnote reads only the small resolution
manifests needed to apply the same declared-source-root rules as indexing.
Interactive indexing shows each Git read batch, then each extraction file and language with parse timing, followed by
the persistence batches. Long pauses can therefore be attributed to input, parsing, or SQLite publication instead of
appearing as an undifferentiated spinner. Generated roots such as node_modules, dist, build, out, hidden caches, and
bazel-* are pruned before reads. SVG and snapshot/golden/fixture or generated JSON/JSONC are excluded before blob
reads and hashing. Generic JSON/JSONC at or above 256 KiB is also excluded, while recognized package, Nx, TypeScript,
schema, and configuration inputs remain eligible below their separate 1 MiB safety cap.
A large cold MCP inspection can return state: "indexing" with measured phase progress, an optional phase-scoped
estimate, and adaptive retry timing. Continue useful targeted text or path investigation while it builds, then retry
the same inspect_code_graph call before making relationship-aware graph claims. There is no repository-size admission
limit and no daemon to start. Nested Maven, Gradle, SwiftPM, and Xcode scopes are detected statically. Dynamic build
logic and ambiguous dependencies remain syntactic rather than being guessed. Bazel workspaces, packages, targets,
loads, and labels are also detected statically from WORKSPACE*, MODULE.bazel, BUILD*, .bzl, .axl, and
.bazelrc (including Aspect CLI sources under .aspect/); Threadnote never invokes Bazel or evaluates Starlark
macros.
Use threadnote graph query --package <exact-package> --query <terms> when a monorepo question is explicitly
package-local. Its bounded examined/matched counts make a zero-result useful as an absence hint, but never as proof of
repository-wide absence. For a named seed-manifest workset, threadnote graph query --workset <name> --query <terms>
uses Workset Search 2.0 to route normal task text, not a public DSL, across the complete published generation with no
eight-repository admission cap. It globally ranks catalog candidates, then opens only the strongest repositories in
bounded adaptive batches. The public logical evidence sequence defaults to 40 cards and has a separate 512-card
internal safety maximum. That search breadth is independent from the compact response projection, which defaults to
1,250 estimated tokens and accepts at most 1,500. Every returned card identifies its repository and exact snapshot;
unavailable members remain explicit, and queries never cold-index repositories as a fan-out side effect.
Android res XML and Apple plist, storyboard, XIB, and asset-catalog metadata contribute explicit searchable resource
wiring. Binary images remain metadata-only: no query result may be used to infer pixel bounds, visual appearance, OCR,
or other image semantics Threadnote did not extract.
Manager keeps ready graph views readable while another process owns the graph writer. A lease-deferred notice means
snapshot retention was postponed by that active build, not that the database or ready snapshot is unhealthy; retry
after the build completes. A graph detail request that cannot safely retain its snapshot returns HTTP 409 with
retryAfterMilliseconds, and Manager exposes a bounded request failure with a Try again action instead of waiting
indefinitely. A lease-failed notice indicates a non-contention storage problem; run threadnote doctor --dry-run
before retrying.
Likewise, threadnote graph diagnostics reports an actively owned checkout as Health: deferred: inspection was
skipped for that pass, rather than finding the database unhealthy. Its ready-snapshot and indexed-view counts continue
to describe the inventoried graph state, so 0 ready is not inferred merely because health inspection was deferred.
For whole-repository topology, call MCP analyze_code_graph or run threadnote graph analyze --view full. Analysis
has no repository-size admission cap. The MCP surface independently caps topology retention at 100,000 symbols,
500,000 distinct relationships, and 1,000,000 relationship visits; larger snapshots still return aggregate statistics,
with topology explicitly marked partial or unavailable. CLI and Manager analysis keep their complete snapshot-derived
budgets. MCP structured content and rendered text each have an independent deterministic 24 KiB UTF-8 envelope with
output coverage and omission metadata. Reaching any analysis or response budget does not imply that the stored
snapshot was truncated. Manager shows statistics, community drill-down, structural groups, confidence, hubs, and
cross-community signals only after Analyze is selected.
Document extraction is deliberately local and deterministic. PDFs, OpenXML/OpenDocument files, EPUB, text documents, notebooks, and text-based diagram formats contribute extractable text and links. A scanned PDF, image, audio file, or video is indexed as an asset with deterministic metadata only: Threadnote does not perform OCR, image understanding, transcription, or video analysis. An extraction diagnostic for one such asset does not mean the rest of the graph failed. Any corpus artifact over 64 MiB is intentionally kept as metadata only instead of being rejected or semantically decompressed. OpenXML, OpenDocument, and EPUB expand only selected text entries, bounded to 16 MiB per entry and 64 MiB cumulatively; crossing a budget falls back to asset metadata. These are per-artifact extraction safety budgets, not repository or graph-size limits.
For a portable artifact, threadnote graph export --format json|graphml|html|svg --output <new-file> never overwrites
an existing file. JSON, GraphML, and HTML default to the complete snapshot. SVG defaults to 300 nodes and 1,000 edges;
pass --node-limit all --edge-limit all only when an intentionally large SVG is acceptable. Export limits affect the
artifact, not graph admission or snapshot coverage. threadnote graph report --output <new-file.md> produces a
deterministic architecture report and likewise refuses to overwrite.
If doctor reports a missing or mismatched grammar asset, reinstall or update the standalone archive for the current platform. Threadnote never downloads parser grammars at runtime. Repair may discard and rebuild graph SQLite files, but it does not modify the repository or canonical memories.
A Manager card labeled Unassociated graph storage has neither a verified local repository folder nor a ready
queryable snapshot. If the repository still exists, run threadnote graph index --cwd <path> from that folder and
refresh Manager. If the database is obsolete, preview and purge it instead; graph databases are derived data and
purging does not remove repository files or canonical memories.
threadnote mcp-install codex --apply
threadnote doctorThen start a fresh agent session. Replace codex with the relevant client. Threadnote supports local stdio MCP only;
there is no HTTP endpoint, bearer token, host, or port to configure.
Run the frozen release gate before changing ranking weights, chunking, model manifests, or fixture judgments:
bun run eval:recall:v2 -- \
--baseline test/evaluation/baselines/threadnote-3.0.3/recall-v2-lexical.json \
--fail-on-regression --fail-on-contractInspect global and per-category deltas. Safety metrics and failure counts cannot regress.