Documentation
Comprehensive guides for the Weaver toolchain, from low-level protocol specifications to high-level integration patterns.
Design Documents
Weaver Design Document
Architecture, Semantic Fusion Engine, Double-Lock harness, client-daemon model, and composable UNIX primitives.
ADR-001: Plugin Capability Model
Capability-first model for act operations, including extricate-symbol and provider resolution.
Sempai Query Language Design
Semgrep-compatible query engine backed by Tree-sitter for semantics-aware code pattern matching.
Jacquard: Card-First Symbol Graph
Structured symbol cards, bounded graph slices, and time-travel diffs over recent commits.
User's Guide
CLI commands, domain operations, configuration, daemon lifecycle, and plugin system.
Roadmap
Phased delivery plan from foundation through plugin ecosystem to long-term intelligence features.
Configuration
Configuration is layered with ortho-config. Each successive layer overrides earlier sources, so a CLI flag always wins.
This docs hub is the maintained source of truth for configuration defaults, global flags, daemon lifecycle, and the JSONL envelope. Other pages link back here rather than carrying parallel copies of the same contract.
| Priority | Source | Notes |
|---|---|---|
| 4 | CLI flags | Always honoured. See table below. |
| 3 | Environment variables | WEAVER_* convention. Override files, yield to flags. |
| 2 | Configuration files | TOML. Discovered via --config-path or XDG search. |
| 1 | Built-in defaults | Unix socket, info filter, json format, no overrides. |
# Top-level keys (no [section] headers) # Daemon transport (Unix socket or TCP) daemon_socket = { transport = "tcp", host = "127.0.0.1", port = 9779 } # Logging log_filter = "info" log_format = "compact" # Example override: default is "json" # Capability overrides (repeatable) [[capability_overrides]] language = "python" capability = "observe.call-hierarchy" directive = "force"
File Discovery
When --config-path is not supplied, the loader searches the standard XDG locations for weaver.toml or .weaver.toml. Discovery honours XDG_CONFIG_HOME (typically ~/.config/weaver/) and falls back to the project root. If no files exist, the built-in defaults apply.
Fail-Fast Validation
ortho-config v0.6.0 treats invalid configuration files as fatal. Both the CLI and daemon abort with a LoadConfiguration error that lists every offending path. No silent fallback — fix or remove the reported files.
failed to load configuration: multiple configuration errors: 1: Configuration file error in '/etc/weaver/weaver.toml': expected `}` 2: Configuration file error in '/home/alex/.weaver.toml': invalid type: string "yes", expected a boolean
Environment Variables
| Variable | Equivalent Flag | Description |
|---|---|---|
| WEAVER_CONFIG_PATH | --config-path | Explicit configuration file path. |
| WEAVER_DAEMON_SOCKET | --daemon-socket | Daemon transport endpoint (unix:// or tcp://). |
| WEAVER_LOG_FILTER | --log-filter | Tracing filter directive (default: info). |
| WEAVER_LOG_FORMAT | --log-format | Log output format: json or compact. |
| WEAVER_FOREGROUND | env only | Keep weaverd attached to the terminal instead of daemonising. Set to 1 for debugging and CI. |
| WEAVERD_BIN | env only | Override the daemon binary path used by weaver daemon start and automatic daemon startup. |
| WEAVER_ROPE_PLUGIN_PATH | env only | Override the executable path for the built-in Rope refactoring provider. |
| WEAVER_RUST_ANALYZER_PLUGIN_PATH | env only | Override the executable path for the built-in rust-analyzer integration used for Rust semantic operations. |
Capability Overrides
Override directives let operators mask unreliable capabilities or force a feature on when a language server under-reports support. Each directive uses the syntax language:capability=directive.
| Directive | Effect |
|---|---|
| allow | Permits the capability if the server advertises it (the default). |
| deny | Blocks the capability even if the server advertises it. |
| force | Enables the capability regardless of server advertisement. |
Identifiers are case-insensitive and whitespace-trimmed. Duplicates are resolved by keeping the last directive for each language/capability pair. In TOML, use the [[capability_overrides]] array; from the CLI, repeat --capability-overrides:
$ weaver observe get-definition \ --capability-overrides "python:observe.call-hierarchy=force" \ --capability-overrides "rust:observe.call-hierarchy=deny" \ --uri file:///src/main.rs --position 10:5
CLI Flags
| Flag | Description |
|---|---|
| --config-path <PATH> | Read an explicit configuration file instead of using XDG discovery. |
| --daemon-socket <ENDPOINT> | Override the daemon transport. Accepts unix:// or tcp:// URIs. |
| --log-filter <FILTER> | Tracing filter directive (default: info). |
| --log-format <FORMAT> | Log output format: json or compact. |
| --capability-overrides <DIRECTIVE> | Append a language:capability=directive override. Repeatable. |
JSONL Protocol
Communication between the CLI and daemon uses a kind-based JSONL envelope. Each line is a JSON object with kind set to stream or exit.
Treat this section as canonical. Command, install, and safety pages now summarize the protocol and link back here when they need operator detail.
| Field | Type | Description |
|---|---|---|
| kind | enum | Discriminator: "stream" for data messages or "exit" for termination. |
| stream | enum | Target host stream: "stdout" or "stderr". Present when kind is "stream". |
| data | string | Payload (plain text or JSON). Present when kind is "stream". |
| status | number | Numeric exit code. Present when kind is "exit". |
{"kind":"stream","stream":"stdout","data":"[{\"uri\":\"file:///src/main.rs\",\"line\":42,\"column\":17}]\n"}
{"kind":"exit","status":0}
This wrapper is daemon transport, not CLI display. The CLI parses each line, strips the envelope, and then either forwards data verbatim in JSON mode or renders recognised payloads for humans.
Daemon Lifecycle
Start
weaver daemon start verifies the configured socket is free, spawns weaverd (overridable via WEAVERD_BIN), and waits for the health snapshot to report ready. The daemon daemonises itself, creates runtime artefacts, and binds the socket.
Auto-start: domain commands start the daemon automatically if it is not running (30 s timeout).
Serve
The daemon accepts concurrent client connections and runs a JSONL request dispatch loop, routing observe, act, and verify commands to the appropriate domain handlers. Language servers are initialised lazily on first use.
Stop
weaver daemon stop reads the PID file, sends SIGTERM, and waits for the runtime artefacts and socket to disappear. Running language servers receive shutdown + exit. If the socket is reachable but the PID file is missing, the command surfaces an error rather than blindly killing a process.
Runtime Artefacts
The daemon creates three files in the runtime directory (typically $XDG_RUNTIME_DIR/weaver/). PID and health files are written atomically.
| File | Purpose | Lifecycle |
|---|---|---|
| weaverd.lock | Prevents duplicate daemon instances. | Created on start, removed on shutdown. Stale locks from unclean exits are cleaned up automatically. |
| weaverd.pid | Records the daemon process ID. | Written atomically after daemonisation; read by daemon stop and daemon status. |
| weaverd.health | JSON health snapshot for readiness polling. | Updated through state transitions; removed on shutdown. |
Health Snapshot
The health file is a single-line JSON document that operators and automation can poll without speaking the daemon protocol. Status transitions: starting → ready → stopping.
{"status":"ready","pid":12345,"timestamp":1713356400}
Signal Handling
| Signal | Behaviour |
|---|---|
| SIGTERM / SIGINT | Graceful shutdown within a 10-second budget. Language servers receive shutdown + exit. Runtime artefacts and socket are cleaned up. |
| SIGQUIT | Graceful shutdown (same sequence as SIGTERM). |
| SIGHUP | Graceful shutdown (same sequence as SIGTERM). |
Operational Details
Foreground Mode
Set WEAVER_FOREGROUND=1 to keep the daemon attached to the terminal. Useful for interactive debugging and CI jobs. Lock, PID, and health semantics are preserved.
Auto-Start
Domain commands (observe, act, verify) spawn the daemon automatically if it is not running. The CLI prints Waiting for daemon start… to stderr and waits up to 30 seconds. Configuration flags passed to the command are forwarded to the daemon. Errors unrelated to the daemon being offline (e.g. permission denied) bypass auto-start and are reported immediately.
WEAVERD_BIN
Override the daemon binary path via the WEAVERD_BIN environment variable. Primarily useful for development and CI where the daemon is not on $PATH.
Duplicate-Start Handling
If the socket is already bound by a running daemon, daemon start fails fast with an "already running" error reporting the existing PID. If the original launch is still initialising, the second invocation reports "launch already in progress" instead of removing the lock. Stale artefacts from unclean exits are cleaned up automatically.
Plugin System
The weaver-plugins crate delegates specialist tasks to external tools running in sandboxed processes. Plugins fall into two categories:
| Category | Role | Output |
|---|---|---|
| Sensor | Provides data to the intelligence engine (e.g. jedi for Python static analysis). |
Structured JSON. |
| Actuator | Performs actions on the codebase (e.g. rope for Python refactoring). |
Unified diffs, validated by the Double-Lock. |
Plugin Manifest
Each plugin is described by a TOML manifest:
| Field | Description |
|---|---|
| name | Unique plugin identifier (e.g. rope). |
| version | Plugin version string. |
| kind | sensor or actuator. |
| languages | Supported languages (case-insensitive). |
| executable | Absolute path to the plugin binary. |
| timeout_secs | Maximum execution time in seconds (default: 30). |
| capabilities | Capability IDs declared by actuator plugins. Sensors must not declare capabilities. |
name = "rope" version = "1.0.0" kind = "actuator" languages = ["python"] executable = "/usr/bin/weaver-plugin-rope" capabilities = ["rename-symbol"]
IPC Protocol
Plugins are short-lived, one-shot processes communicating via JSONL over standard I/O:
- The broker writes one JSONL request to the plugin's stdin and closes stdin.
- The plugin writes one JSONL response to stdout and exits.
- Plugin stderr is captured for diagnostic logging (not part of the protocol).
File content is passed in-band as part of the request body, so sandboxed plugins do not need filesystem access.
Default Plugins
| Plugin | Kind | Language | Timeout | Path Override |
|---|---|---|---|---|
| rope | actuator | Python | 30s | WEAVER_ROPE_PLUGIN_PATH |
Capability IDs
The daemon routes operations to plugins based on the requested capability and target language. Stable capability identifiers:
| Capability ID | Description | Status |
|---|---|---|
| rename-symbol | Rename a symbol across a codebase. | shipped |
| extricate-symbol | Move a symbol to a different module or file. | Planned |
| extract-method | Extract a code region into a new function or method. | Planned |
| replace-body | Replace the body of a function or method. | Planned |
| extract-predicate | Extract a conditional expression into a predicate. | Planned |
Refusal Reason Codes
When a plugin cannot perform an operation, it returns a failure response with diagnostics. Each diagnostic may include a reason_code for programmatic matching:
| Reason Code | Meaning |
|---|---|
| symbol_not_found | The target symbol could not be located. |
| macro_generated | The symbol is generated by a macro. |
| ambiguous_references | Multiple candidate symbols match the position. |
| unsupported_language | The plugin does not support the target language. |
| incomplete_payload | Required fields are missing from the request. |
| name_conflict | The new name conflicts with an existing symbol. |
| operation_not_supported | The plugin does not support the requested operation. |
Language Servers
The daemon spawns language server processes for each language, communicating via JSON-RPC 2.0 over stdio. Servers are initialised lazily on first use and shut down gracefully (5 s timeout) when the daemon stops.
| Language | Binary | Invocation |
|---|---|---|
| Rust | rust-analyzer | rust-analyzer |
| Python | pyrefly | pyrefly lsp |
| TypeScript | tsgo | tsgo --lsp |
Tree-sitter Parsing
Weaver uses Tree-sitter to generate Concrete Syntax Trees (CST) for supported languages. This allows for error-tolerant parsing even when code is in a broken state during editing.
Supported Languages
Sempai Patterns
The Sempai engine extends Semgrep syntax for structural search. Patterns are defined in YAML and can include metavariables for extraction.
pattern:
- pattern-inside: |
fn $FUNC($ARGS) { ... }
- pattern: |
unsafe { ... }
- message: "Unsafe block in $FUNC"
Need deeper integration?
Check out the plugin development guide for extending Weaver.