Sign In

@ataraxy-labs/weave

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ataraxy-labs/weave - npm Package Compare versions

Comparing version
0.3.6
to
0.5.0
+39
bin/weave-driver.js
#!/usr/bin/env node
import { spawn } from 'node:child_process';
import { existsSync } from 'node:fs';
import { getInstalledBinaryPath } from '../scripts/package-meta.mjs';
const binaryPath = getInstalledBinaryPath('weave-driver');
if (!existsSync(binaryPath)) {
console.error(
'weave-driver is not installed yet. Reinstall @ataraxy-labs/weave to download the binary.',
);
process.exit(1);
}
const child = spawn(binaryPath, process.argv.slice(2), {
stdio: 'inherit',
});
child.on('error', (error) => {
console.error(`Failed to launch weave-driver: ${error.message}`);
process.exit(1);
});
child.on('exit', (code, signal) => {
if (signal) {
process.kill(process.pid, signal);
return;
}
process.exit(code ?? 1);
});
for (const signal of ['SIGINT', 'SIGTERM', 'SIGHUP']) {
process.on(signal, () => {
if (!child.killed) {
child.kill(signal);
}
});
}
#!/usr/bin/env node
import { spawn } from 'node:child_process';
import { existsSync } from 'node:fs';
import { getInstalledBinaryPath } from '../scripts/package-meta.mjs';
const binaryPath = getInstalledBinaryPath('weave-mcp');
if (!existsSync(binaryPath)) {
console.error(
'weave-mcp is not installed yet. Reinstall @ataraxy-labs/weave to download the binary.',
);
process.exit(1);
}
const child = spawn(binaryPath, process.argv.slice(2), {
stdio: 'inherit',
});
child.on('error', (error) => {
console.error(`Failed to launch weave-mcp: ${error.message}`);
process.exit(1);
});
child.on('exit', (code, signal) => {
if (signal) {
process.kill(process.pid, signal);
return;
}
process.exit(code ?? 1);
});
for (const signal of ['SIGINT', 'SIGTERM', 'SIGHUP']) {
process.on(signal, () => {
if (!child.killed) {
child.kill(signal);
}
});
}
#!/usr/bin/env node
import { spawn } from 'node:child_process';
import { existsSync } from 'node:fs';
import { getInstalledBinaryPath } from '../scripts/package-meta.mjs';
const binaryPath = getInstalledBinaryPath('weave');
if (!existsSync(binaryPath)) {
console.error(
'weave is not installed yet. Reinstall @ataraxy-labs/weave to download the binary.',
);
process.exit(1);
}
const child = spawn(binaryPath, process.argv.slice(2), {
stdio: 'inherit',
});
child.on('error', (error) => {
console.error(`Failed to launch weave: ${error.message}`);
process.exit(1);
});
child.on('exit', (code, signal) => {
if (signal) {
process.kill(process.pid, signal);
return;
}
process.exit(code ?? 1);
});
for (const signal of ['SIGINT', 'SIGTERM', 'SIGHUP']) {
process.on(signal, () => {
if (!child.killed) {
child.kill(signal);
}
});
}
# Changelog
This file starts at 0.4.0. For earlier releases see the
[GitHub releases page](https://github.com/Ataraxy-Labs/weave/releases).
Versions are shared across every crate in the workspace and the npm package,
so `weave-core`, `weave-crdt`, `weave-driver`, `weave-cli`, `weave-mcp`,
`weave-github` and `@ataraxy-labs/weave` all move together.
## 0.5.0
### New — one line per merge
Set `WEAVE_EVENT=1` and the merge driver writes one JSON line per merge to
stderr, behind a `weave-event: ` prefix:
```text
weave-event: {"schema":"weave-event","schema_version":"1.0.0","file":"src/app.py",
"outcome":"clean","exit_code":0,"confidence":"very_high","conflicts":0,"findings":0,
"entities":{...},"bytes_out":481,"ms_merge":4.43,"ms_total":5.72,...}
```
It answers the question a rebase raises — which files conflicted, on what, and
how long each took — in one pass over the lines instead of four stderr channels
joined by hand. A line is written for every outcome, including the ones that
produce nothing, because a channel that only records successes cannot explain a
bad run. Off by default, and everything on the line was already computed:
turning it on costs one line and no extra work. Fields are documented in
`crates/weave-mcp/schema/weave-event.schema.json`.
### Breaking — library API
Nothing here affects the CLI, the merge driver or the MCP server. These change
Rust code that depends on `weave-core` or `weave-cli` directly.
**A merge is handed what it may touch, instead of reaching for it.**
`weave_core::host::Host` is new: a duplicate-name threshold and an optional
line-level merge, built at a program's entry point and passed down. Two things
inside the merge were not functions of their inputs — `WEAVE_MAX_DUPLICATES`
was read in the middle of the decision that used it, and the line-level route
spawned `git merge-file` with three temporary files. Both are worth having;
neither could be declined.
`entity_merge_fmt` and `entity_merge_with_registry` take a `&Host`, as does
`explain::explain`. `entity_merge` keeps its signature and runs against
`Host::default()`, which grants nothing — so the four-argument call is now a
function of its three inputs. Callers wanting the previous behavior pass:
```rust
let host = weave_core::host::Host {
line_merge: Some(weave_core::host::git_line_merge),
..Default::default()
};
```
`WEAVE_MAX_DUPLICATES` still works: `weave-driver` reads it and puts it on the
host. It is documented in `weave-driver --help` for the first time.
**`weave_core::git` returns a typed error.** All six functions returned
`Box<dyn std::error::Error>` built from `format!`, so "git is not installed",
"this is not a repository", "these two refs share no history" and "git
declined" were one type. They are now `GitError::{NotRunnable, NotARepository,
NoMergeBase, Refused}`, each carrying its operands. Code using `?` into
`Box<dyn Error>` still compiles.
**`weave_core::stats` takes the path it reads and writes.** `load()` and
`save()` derived `~/.weave/stats.json` from the environment themselves.
`load(&Path)` and `save(&Path) -> bool` take it; `stats::default_path(home)`
offers the conventional location to a caller that wants it. `save` reports
whether the write landed instead of swallowing it.
**`weave_cli::patch` types its two boundaries.** `PatchOp::op` is now the `Op`
enum — the schema's own alphabet — rather than a `String` that let an
unrecognised verb decode and be silently ignored. `patch::apply` returns
`PatchError` instead of a sentence with two hashes in it, and
`patch::parse_ops_doc` is the only route from bytes to an `OpsDoc`, refusing
unknown fields and unknown majors by name.
### Stricter — documents that did not match their own schemas
Both published schemas declare `additionalProperties: false`; no decoder
enforced it. Now they do. An ops document with a misspelled field, or an MCP
tool call with a misspelled argument, is refused instead of silently accepted
with the field discarded. A `weave_check` call with nothing but unrecognised
keys used to answer confidently about revisions the caller never named.
### Fixed
- The MCP server answers `invalid_params` for a caller's own mistake — an
unknown entity name, an unreadable path, no repository — instead of
`internal_error` for everything, which told an agent "stop asking" when the
right answer was "ask differently".
- The GitHub webhook decodes the event payload into a type. A missing field
and a hostile one used to produce the same empty string, and the request
returned 200 having read nothing.
## 0.4.0
### Breaking — library API
If you use weave as a CLI, a git merge driver, or through the MCP server,
nothing here affects you. These changes affect Rust code that depends on the
`weave-core` or `weave-crdt` crates directly.
The two library crates published a much larger surface than they supported.
Most of it was reachable by accident rather than on purpose, and some of it
had two spellings for the same function. This release cuts the surface down to
what is actually meant to be called, which breaks code that reached past it.
**`weave-crdt`: the module paths are gone.**
Every module (`content`, `error`, `merge`, `ops`, `state`, `sync`) is now
private to the crate. The `pub use` list in `lib.rs` is the entire public
surface. Previously each item had two paths — `weave_crdt::update_entity_content`
and `weave_crdt::content::update_entity_content` reached the same function —
and the two were free to drift apart without any caller noticing.
Migration: drop the module segment. `weave_crdt::sync::reconstruct_file_from_crdt`
becomes `weave_crdt::reconstruct_file_from_crdt`. Everything that was reachable
through a module path and is still supported is re-exported from the crate
root under the same name.
**`weave-crdt::record_modification` is removed.** It was a strictly weaker
duplicate of `update_entity_content`: same vector-clock increment, same three
summary writes, but it never wrote the `writes` register entry, so it could
leave `content_hash` naming a write no replica could join. Use
`update_entity_content`, which takes the content alongside the hash.
**`weave-crdt::MergeState` is no longer exported.** It was part of no supported
flow. `CrdtMergeResult` and `VersionVector` are unchanged.
**`weave-core::reconstruct` is removed.** The v1 reconstruct path it belonged
to no longer exists; the v2 pipeline does this work internally.
**`ResolutionStrategy::Fallback` is removed.** The variant was unconstructible —
`resolve` never emitted it, and a line-level fallback returns an empty audit
trail instead. If you matched on it exhaustively, that arm was dead. What is
true and now stated on `Op.fallback`: a fallback merge produces no ops at all,
so the read document is silent rather than flagged.
### Added — library API
- `weave-crdt`: `anchor_of`, `ordered_entity_ids` and `Anchor`, so a caller can
read an entity's layout coordinate rather than infer it from the order.
- `weave-crdt`: `join`, `apply_op`, `value_of`, `EntityOp`, `EntityValue` and
`Write` — the join door, replacing ad-hoc detection.
- `weave-core`: the `binding`, `diagnose`, `explain`, `frame` and `v2` modules
are public.
### Added — languages
`weave setup` now writes `merge=weave` lines for 17 more extensions:
.kt .tf .hcl .ml .mli .zig .elm .clj .edn .d
.lua .fish .nix .sql .tex .pl .csv
That is 38 languages and formats in total. The engine could already parse
these; `setup` simply had never claimed them, so git was handling them
line-by-line.
Each one earns its place by passing a five-scenario merge sweep
(`crates/weave-core/tests/language_coverage.rs`): two sides adding different
definitions merges clean, two sides rewriting the same definition conflicts,
a side that stood still is the identity, the same edit made twice lands once,
and nothing is dropped in any of them.
`.vue`, `.svelte`, `.erb` and `.hs` are **not** claimed, and the README no
longer says they are. weave can parse all four, but their entity model treats
a whole `<script>` block, template, or type signature as one unit, so two
people adding two different definitions conflict where they should merge, and
the conflict marker can land in the middle of a definition. Those files keep
getting git's line-level merge, which is the better answer until the parser
gains a real per-definition model for them.
### Fixed
- **npm package was unusable.** `package.json` declared `weave`,
`weave-driver` and `weave-mcp` binaries, but `bin/` had been deleted from the
tree, so every install produced commands pointing at files that were not
there. All three wrappers are restored and the packed tarball is verified to
contain them.
- `package.json` had been sitting at 0.3.4 while the crates were at 0.3.6.
### Changed
- Two merges that used to conflict now compose. When both sides edit inside one
method body, weave resolves at the statement and expression level instead of
handing back the whole method as a conflict — so one side adding a cache
lookup while the other renames a call in the same return statement produces
the composed result rather than a box. No edit is dropped either way; this
turns some conflicts into clean merges, never the reverse.
- The in-tree test suite is 401 tests, up from 268. Three test files that had
stopped shipping are back, and the language sweep is new.
- Documentation comments across the crates were reworded into plain
engineering terms. The rules they describe are enforced by tests, and the
comments now say that rather than borrowing a mathematical register for it.
No behaviour changed.
+2
-1
{
"name": "@ataraxy-labs/weave",
"version": "0.3.6",
"version": "0.5.0",
"description": "npm wrapper for the weave CLI, driver, and MCP server. Downloads matching release binaries and exposes weave, weave-driver, and weave-mcp commands.",

@@ -31,2 +31,3 @@ "license": "MIT OR Apache-2.0",

"README.md",
"CHANGELOG.md",
"LICENSE-APACHE",

@@ -33,0 +34,0 @@ "LICENSE-MIT"

+109
-14

@@ -16,2 +16,3 @@ > **Part of the [Ataraxy Labs](https://ataraxy-labs.com) stack** — agent-native infrastructure for software development. See also: [sem](https://ataraxy-labs.com/sem) (semantic version control) · [inspect](https://github.com/Ataraxy-Labs/inspect) (semantic code review) · [opensessions](https://github.com/Ataraxy-Labs/opensessions) (tmux sidebar for coding agents).

<a href="#install">Install</a> ·
<a href="#quickstart">Quickstart</a> ·
<a href="#how-weave-fixes-this">How It Works</a> ·

@@ -26,6 +27,5 @@ <a href="#mcp-server">MCP Server</a> ·

<img src="https://img.shields.io/badge/rust-stable-orange" alt="Rust">
<img src="https://img.shields.io/badge/tests-124_passing-brightgreen" alt="Tests">
<img src="https://img.shields.io/badge/version-0.3.0-blue" alt="Version">
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-yellow" alt="License"></a>
<img src="https://img.shields.io/badge/languages-28-blue" alt="Languages">
<img src="https://img.shields.io/badge/tests-401_passing-brightgreen" alt="Tests">
<a href="LICENSE-MIT"><img src="https://img.shields.io/badge/license-MIT_OR_Apache--2.0-yellow" alt="License"></a>
<img src="https://img.shields.io/badge/languages-38-blue" alt="Languages">
</p>

@@ -37,2 +37,14 @@

## Quickstart
```bash
weave setup # this repo now merges through weave; git merge/rebase/cherry-pick unchanged
git merge <branch> # real conflicts land as markers with a `refused_by:` line stating why
weave explain <file> # per-hunk detail for one conflicted file, read off the actual git stages
# ...edit to resolve...
weave check # verify the working tree against the three merge stages; exits 1 on findings
```
See [Setup](#setup) for `--global`/`--local` variants and [MCP Server](#mcp-server) for agent-framework integration.
## The Problem

@@ -116,8 +128,21 @@

## Testing
weave's correctness is checked two ways. The open test suite in this
repository covers the documented merge properties and runs in CI. In
addition, every release is gated by a private conformance suite — currently
2,800+ enumerated merge-rule cells and five corpora of real-world merges —
maintained separately, following the held-out-benchmark practice used by
conformance and evaluation suites elsewhere (SQLite/TH3, Khronos CTS, LLM
eval sets). PRs receive a pass/fail status from this suite automatically.
## Conflict Markers
When a real conflict occurs, weave gives you context that Git doesn't:
When a real conflict occurs, weave gives you context that Git doesn't: which
entity, what type, and — on the line inside the box — which internal guard
declined to auto-merge and exactly which lines both sides disagree about.
```
<<<<<<< ours — function `process` (both modified)
<<<<<<< ours — function `process` (T, confidence: high)
// refused_by: statement_fold · collision: ` return data.upper()` +1 more
export function process(data: any) {

@@ -130,11 +155,33 @@ return JSON.stringify(data);

}
>>>>>>> theirs — function `process` (both modified)
>>>>>>> theirs — function `process` (T, confidence: high)
```
You immediately know: what entity conflicted, what type it is, and why it conflicted.
Run `weave explain <file>` for more detail on every conflicted entity in the
file, and `weave check` after editing to verify your resolution against the
three merge stages — see [Quickstart](#quickstart).
## Supported Languages
TypeScript, TSX, JavaScript, Python, Go, Rust, Java, C, C++, Ruby, C#, PHP, Swift, Kotlin, Elixir, Bash, HCL/Terraform, Fortran, Dart, Perl, OCaml, Scala, Zig, Vue, Svelte, XML, ERB, JSON, YAML, TOML, CSV, Markdown. Falls back to standard line-level merge for unsupported file types.
TypeScript, TSX, JavaScript, Python, Go, Rust, Java, C, C++, Ruby, C#, PHP, Swift, Kotlin, Scala, Dart, Elixir, Bash, Fish, Fortran, Perl, OCaml, Zig, Elm, Clojure, EDN, D, Lua, Nix, SQL, HCL/Terraform, LaTeX, XML, JSON, YAML, TOML, CSV, Markdown. Falls back to standard line-level merge for everything else.
`weave setup` writes a `merge=weave` line for exactly this list and nothing
else. Each language on it passes a five-scenario merge sweep — two sides adding
different definitions merges clean, two sides rewriting the same definition
conflicts, and nothing is dropped — in `crates/weave-core/tests/language_coverage.rs`.
Vue, Svelte, ERB and Haskell are parsed but deliberately **not** claimed. Their
entity model treats a whole `<script>` block, template, or type signature as a
single unit, so two people adding two different definitions conflict where they
should merge cleanly, and the conflict marker can land mid-definition. Those
files get Git's line-level merge instead, which is the better answer until the
parser gains a real per-definition model for them.
That is what the merge engine can parse. `weave setup` writes `.gitattributes`
rules for a narrower set, so Kotlin, HCL/Terraform, Vue, Svelte, ERB, CSV, Perl,
OCaml and Zig files still take git's line merge until you add the rule yourself:
```bash
echo '*.kt merge=weave' >> .gitattributes # same shape for any extension above
```
## Install

@@ -146,3 +193,5 @@

Or build from source (requires Rust):
Or build from source (requires Rust). Two binaries, both required: `weave`
(the CLI you run — `setup`/`explain`/`check`/...) and `weave-driver` (the one
git itself invokes on every merge; `weave setup` fails without it on `PATH`):

@@ -152,6 +201,9 @@ ```bash

cd weave
cargo install --path crates/weave-cli
cargo install --path crates/weave-driver
cargo install --path crates/weave-cli # the `weave` binary
cargo install --path crates/weave-driver # the `weave-driver` binary git calls
```
Upgrading an existing source install? `cargo install` refuses to overwrite a
binary it didn't put there itself — add `--force` to either command above.
## Setup

@@ -179,2 +231,20 @@

### Global (every repo)
To make weave the default merge driver for **all** your repos at once (no per-repo setup, like [mergiraf](https://mergiraf.org/usage.html#registration-as-a-git-merge-driver)):
```bash
weave setup --global
```
This writes the driver to your `~/.gitconfig` and the supported file-type rules to git's global attributes file (`~/.config/git/attributes`, or your `core.attributesfile` if set). No git repo required. Make sure `weave-driver` is on your `PATH` (it ships next to the `weave` binary).
The equivalent manual config, if you prefer:
```bash
git config --global merge.weave.name "Entity-level semantic merge"
git config --global merge.weave.driver "weave-driver %O %A %B %L %P"
# then add `*.ts merge=weave` (etc.) to ~/.config/git/attributes
```
## Jujutsu (jj)

@@ -204,3 +274,3 @@

```bash
weave-cli preview feature-branch
weave preview feature-branch
```

@@ -217,2 +287,25 @@

After a real conflict, `weave explain <file>` and `weave check` are the
next two commands — see [Quickstart](#quickstart).
## MCP Server
For agent frameworks that speak [MCP](https://modelcontextprotocol.io):
```bash
# Claude Code
claude mcp add --scope user weave -- weave-mcp
# Any MCP client, via stdio (~/.config/claude/claude_desktop_config.json etc.)
{ "mcpServers": { "weave": { "command": "weave-mcp" } } }
```
The server discovers the repo from the first tool call's file path, the
`WEAVE_REPO` env var, or its working directory. It exposes `weave_check` and
`weave_findings` as the read contract for acting on a merge, entity
inspection tools (`weave_extract_entities`, `weave_diff`,
`weave_get_dependencies`/`_dependents`), and a claim/release layer for
coordinating multiple agents in one repo. Each tool's own description states
when to call it and what an empty result means.
## Architecture

@@ -223,3 +316,5 @@

weave-driver # Git merge driver binary (called by git via %O %A %B %L %P)
weave-cli # CLI: `weave setup` and `weave preview`
weave-cli # CLI: `weave setup`, `weave explain`, `weave check`, `weave preview`, ...
weave-crdt # Automerge-backed multi-agent coordination state
weave-mcp # MCP server exposing weave to agent frameworks
```

@@ -226,0 +321,0 @@