Documentation
Comprehensive guides for the Weaver toolchain, from low-level protocol specifications to high-level integration patterns.
Design Documents
The vision and the systems it demands: what Weaver is, how Sempai and Jacquard work, and where the roadmap goes next.
Weaver Design Document
Architecture, Semantic Fusion Engine, Double-Lock harness, client-daemon model, and composable UNIX primitives.
Sempai Query Language Design
Operators, tokens, and evaluation semantics for the Semgrep-compatible engine. Its command-surface sections are superseded by RFC 0003.
Jacquard: Card-First Symbol Graph
Structured symbol cards, bounded graph slices, and time-travel diffs over recent commits.
User's Guide
The 0.1.0 command-surface target and the current prototype reference, split honestly. Plus configuration, daemon lifecycle, and plugins.
Roadmap
Phased delivery plan from foundation through plugin ecosystem to long-term intelligence features.
Architecture Decisions
The RFCs and Architecture Decision Records (ADRs) that reset the public surface for 0.1.0, plus the gap analysis that keeps the target honest. The RFC and ADR entries are Status: Proposed.
ADR-007: Agent-Native Command Surface
The 0.1.0 reset: noun-verb grammar, dual renderers, universal --json, and the capability model that hides providers.
RFC 0002: Multi-Workspace Daemon
One per-user daemon, workspace-scoped state, language servers keyed by execution identity, and workspace-local concurrency. With ADRs 008–010.
RFC 0003: Query to Selector
The Sempai pipeline: query input, versioned selector streams, and the typed handoff into safe actuation. With ADRs 011–012.
ADR-001: Plugin Capability Model
Capability-first model for change operations, including extricate-symbol and provider resolution.
UI Gap Analysis
Principle-by-principle audit of the current surface against the target: errors that teach, bounded output, non-interactive defaults.
Configuration
In the planned 0.1.0 target, configuration is layered with ortho-config: built-in defaults < config files < profile < environment < flags. 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 |
|---|---|---|
| 5 | CLI flags | Always honoured. See table below. |
| 4 | Environment variables | WEAVER_* convention. Override profiles and files; yield to flags. |
| 3 | Profile | A saved profile selected with --profile overrides configuration files and is overridden by environment variables and CLI flags. |
| 2 | Configuration files | TOML. Discovered via --config-path or XDG search. |
| 1 | Built-in defaults | Unix socket on Unix; loopback TCP on non-Unix prototype builds; info filter, json format, no overrides. |
The 0.1.0 target remains one local, per-user daemon with no remotely reachable endpoint. Unix targets default to a Unix domain socket. The current prototype retains tcp://127.0.0.1:9779 for non-Unix compatibility; TCP must stay on an IPv4 or IPv6 loopback address and is not a remote-service transport.
# Top-level keys (no [section] headers) # Prototype TCP compatibility (loopback-only; not remote) 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 = "definition.get" 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 | Local daemon endpoint. unix:// is the Unix default; prototype tcp:// compatibility must use loopback. |
| 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 definitions get \ --capability-overrides "python:definition.get=force" \ --capability-overrides "rust:definition.get=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. |
| --profile <NAME> | Planned for 0.1.0. Select a saved profile; it overrides configuration files and is overridden by environment variables and CLI flags. |
| --daemon-socket <ENDPOINT> | Override the local daemon endpoint. unix:// is the Unix default; prototype tcp:// compatibility must use loopback. |
| --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 local endpoint 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 Unix socket or loopback-only prototype TCP endpoint.
Auto-start: routed commands start the daemon automatically if it is not running (30 s timeout).
Serve
The daemon accepts concurrent same-host client connections and runs a JSONL request dispatch loop, routing read, query, and change commands to the appropriate capability 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
Routed commands 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.