@yearofthedan/weaver
v0.1.1
Published
Headless CLI refactoring engine for AI agents
Maintainers
Readme
weaver
A refactoring bridge between AI coding agents and the compiler APIs that understand your codebase.
Experimental. This project is in active development. The goal is deterministic, token-reducing refactoring for AI agents through compiler-driven semantics, drawing inspiration from IDE integration patterns. Core operations are stable and tested, but some features remain incomplete or will evolve as we explore better approaches.
AI agents can read and write files, but cross-file refactoring is expensive. Renaming a shared symbol or moving a file means loading every affected file into context, manually patching import paths, and hoping nothing is missed. weaver removes that burden — the agent issues an intent, weaver handles the cascade, and the agent gets back a semantic summary without ever seeing the raw diffs.
Why weaver? — speed, determinism, and context efficiency; how it fits into the AI coding ecosystem.
How it works
weaver has a daemon and two transports:
Daemon — a long-lived process that loads the project graph into memory and watches the filesystem for changes. It stays alive between agent sessions so the engine is always warm. Start it once; it handles the rest.
MCP server (weaver serve) — a thin process started by the agent host for each session. It connects to the running daemon, receives tool calls from the agent over stdio, and returns semantic summaries. If no daemon is running, it spawns one automatically.
CLI subcommands (weaver rename '...') — for agents that can shell out but don't have MCP configured. Each subcommand connects to the running daemon (auto-spawning if needed) and prints the JSON response to stdout. Same operations, same daemon, no MCP setup.
The underlying language intelligence comes from ts-morph (pure TypeScript projects) and Volar (projects containing Vue files), covering both .ts and .vue files in a unified project graph.
The agent calls tools or CLI commands. weaver applies changes. The context window stays clean.
flowchart TD
A["Agent host\n(Claude Code / Roo / Cursor)"]
B["weaver serve\n(MCP server, stdio)"]
C["weaver daemon\n(project graph + watcher)"]
D[ts-morph]
E[Volar]
F["Project files\n(.ts · .tsx · .vue)"]
A -- "MCP tool call" --> B
B -- "Unix socket" --> C
C --> D & E
D & E --> FInstallation
pnpm add -D @yearofthedan/weaver@alpha
# or
npm install -D @yearofthedan/weaver@alphaOr install from GitHub for unreleased builds:
pnpm add -D github:yearofthedan/weaverCLI Commands
weaver daemon
Start the daemon for a workspace. Loads the project graph, starts the filesystem watcher, and listens for connections from serve instances.
weaver daemon --workspace /path/to/projectOutput (stderr):
{ "status": "ready", "workspace": "/absolute/path/to/project" }The daemon runs until terminated with SIGTERM or SIGINT. It does not exit when agent sessions end.
weaver serve
Start the MCP server for an agent session. Connects to the running daemon (spawning it if needed) and accepts tool calls over stdio.
weaver serve --workspace /path/to/projectOutput (stderr):
{ "status": "ready", "workspace": "/absolute/path/to/project" }Terminates cleanly on SIGTERM. The daemon continues running after the session ends.
weaver stop
Stop a running daemon for a workspace.
weaver stop --workspace /path/to/projectOutput (stdout):
{ "ok": true, "stopped": true }CLI operations
All operations are available as CLI subcommands. Each accepts a JSON argument and prints the daemon's response to stdout:
weaver rename '{"file": "src/a.ts", "line": 5, "col": 3, "newName": "bar"}'
weaver move-file '{"oldPath": "src/old.ts", "newPath": "src/new.ts"}'
weaver find-references '{"file": "src/a.ts", "line": 10, "col": 5}'Path params can be relative (resolved against --workspace or cwd):
weaver rename --workspace /path/to/project '{"file": "src/a.ts", "line": 5, "col": 3, "newName": "bar"}'The daemon auto-spawns if not already running. Exit code is 0 for success/warn, 1 for errors. Pipe JSON via stdin for longer inputs.
MCP tools
All refactoring operations are also exposed as MCP tools via weaver serve. The agent host calls them; weaver handles the cascade.
| Tool | TS | Vue | Read-only | Notes |
|---|---|---|---|---|
| rename | ✓ | ✓ | no | Renames a symbol at a given position; updates every reference project-wide |
| moveFile | ✓ | ✓ | no | Moves a file; rewrites all import paths that reference it |
| moveDirectory | ✓ | ✓ | no | Moves an entire directory; rewrites all imports across the project |
| moveSymbol | ✓ | ✓* | no | Moves a named export to another file; updates all importers |
| deleteFile | ✓ | ✓† | no | Deletes a file; removes every import and re-export of it across the workspace |
| extractFunction | ✓ | — | no | Extracts a selected block of statements into a new named function at module scope |
| findReferences | ✓ | ✓ | yes | Returns every reference to the symbol at a given position |
| getDefinition | ✓ | ✓ | yes | Returns definition location(s) for the symbol at a given position |
| getTypeErrors | ✓ | — | yes | Returns type errors for a single file or whole project (capped at 100) |
| searchText | n/a | n/a | yes | Regex search across workspace files with optional glob/context controls |
| replaceText | n/a | n/a | no | Regex replace-all (pattern mode) or exact-position edits (surgical mode) |
All tools take absolute paths. Write operations return filesModified and filesSkipped (files outside the workspace boundary that were not touched). Type errors in modified files are checked automatically and returned in the response (typeErrors, typeErrorCount); pass checkTypeErrors: false to suppress.
* moveSymbol supports moving exports from .ts/.tsx sources inside Vue workspaces and updates .vue importers in a post-step. Moving symbols from a .vue source file is still pending.
† deleteFile removes imports and re-exports from .ts/.tsx/.js/.jsx files (via ts-morph) and Vue SFC <script> blocks (via regex scan).
Response format
Every response contains a status field: "success", "warn", or "error".
{
"status": "success",
"filesModified": ["src/utils/math.ts", "src/index.ts"]
}"warn" means the operation completed but left type errors — check typeErrors in the response:
{
"status": "warn",
"filesModified": ["src/utils/math.ts"],
"typeErrorCount": 2,
"typeErrors": [...]
}On failure:
{
"status": "error",
"error": "SYMBOL_NOT_FOUND",
"message": "Could not find symbol at line 5, column 10"
}Error codes
VALIDATION_ERROR— invalid command argumentsFILE_NOT_FOUND— source file does not existSYMBOL_NOT_FOUND— symbol not found at specified positionRENAME_NOT_ALLOWED— symbol cannot be renamed (e.g. built-in types)NOT_SUPPORTED— requested operation shape is not supportedWORKSPACE_VIOLATION— path is outside the workspace boundarySENSITIVE_FILE— operation attempted on a blocked sensitive fileTEXT_MISMATCH— surgical replace precondition failed (oldTextmismatch)PARSE_ERROR— malformed request payload or invalid regexREDOS— unsafe regex rejectedNOT_A_DIRECTORY— path exists but is not a directoryDESTINATION_EXISTS— destination directory already exists and is non-emptyMOVE_INTO_SELF— destination is inside the source directoryINTERNAL_ERROR— unexpected server-side failureDAEMON_STARTING— daemon is still initialising; retry the tool call
When NOT to use this
weaver is a specialised tool. Use the right tool for the job:
| Alternative | Use instead when… | weaver wins when… |
|---|---|---|
| Base agent tools (grep, read/write) | The change is in one file, or the agent's context window can hold everything comfortably | The change fans out across many files; missing one import breaks the build |
| Claude's built-in typescript-lsp plugin | You only need diagnostics and navigation (jump to definition, find references) | You need to apply structural changes (rename, move, extract) — the two complement each other, not compete |
| IntelliJ MCP | You're already running IntelliJ and want the full IDE refactoring suite | You're in a devcontainer, CI, or remote environment where a GUI IDE isn't available |
See docs/why.md for a broader look at where weaver fits in the AI coding ecosystem.
Agent integration
weaver serve is a stdio MCP server. Configure your agent host to launch it for the workspace you want to refactor.
Installing the MCP server
Add a .mcp.json according to your project root. The location depends upon your agent framework (eg. Claude Code, Cursor, Roo Code). Using npx is the easiest option — it avoids path resolution issues that can occur when the MCP host spawns the process from a different working directory:
{
"mcpServers": {
"weaver": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@yearofthedan/weaver", "serve", "--workspace", "."]
}
}
}Alternatively, if weaver is installed as a dependency, you can use the weaver bin directly (requires node_modules/.bin to be on the host's PATH when it spawns the process):
{
"mcpServers": {
"weaver": {
"type": "stdio",
"command": "weaver",
"args": ["serve", "--workspace", "."]
}
}
}Guiding the agent (skill files)
Tool descriptions tell agents what each operation does, but not when to reach for them. weaver ships three skill files that provide trigger-matched workflow guidance — each covers a specific category of operations.
| Skill | Covers | Path in package |
|---|---|---|
| search-and-replace | search-text, replace-text | .claude/skills/search-and-replace |
| move-and-rename | rename, move-file, move-directory, move-symbol, delete-file, extract-function | .claude/skills/move-and-rename |
| code-inspection | find-references, get-definition, get-type-errors | .claude/skills/code-inspection |
Reference the appropriate skills from your agent configuration, or write your own tailored to your use case. The correct location for skill files depends on your agent framework.
## Refactoring
Load the weaver skills for compiler-aware refactoring guidance:
see `node_modules/@yearofthedan/weaver/.claude/skills/search-and-replace`
see `node_modules/@yearofthedan/weaver/.claude/skills/move-and-rename`
see `node_modules/@yearofthedan/weaver/.claude/skills/code-inspection`Notes
- The daemon auto-spawns on first tool call if not already running. For faster first-call response, start it manually:
weaver daemon --workspace /path/to/project. - One
serveinstance per agent session; one daemon per workspace. The daemon keeps running between sessions.
Security
To report a vulnerability, see SECURITY.md.
Contributing
See CONTRIBUTING.md for setup, build, test, and project structure.
