Skip to content

Latest commit

 

History

History
362 lines (282 loc) · 23.1 KB

File metadata and controls

362 lines (282 loc) · 23.1 KB

Troubleshooting

The executable does not start

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))) -Beta

A 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 installer finished but threadnote is not found

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" $PATH

The 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.

Start and stop do not launch a service

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.

Cursor does not load the Threadnote instructions

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.

Collect production logs for support

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.

Home or migration problems

The owned home defaults to ~/.threadnote. Check for an accidental override:

echo "$THREADNOTE_HOME"
threadnote doctor
threadnote migrate

migrate 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.

Forget cannot remove a resource subtree

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.

Seed is slow or skips files

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.

Semantic recall is unavailable

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 verify

The 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.

Threadnote shows several processes or uses more memory than expected

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.

An index rebuild was interrupted

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 --all

graph 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 rebuild

Code graph indexing or a language pack fails

The 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 --full

threadnote 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.

MCP does not appear in the agent

threadnote mcp-install codex --apply
threadnote doctor

Then 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.

Recall quality changed

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-contract

Inspect global and per-category deltas. Safety metrics and failure counts cannot regress.