ast-mcp-server 0.7.2 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +43 -1
- package/README.md +36 -14
- package/SECURITY.md +8 -8
- package/dist/cli.js +18 -14
- package/dist/services/agent-setup.js +248 -27
- package/dist/services/agent-targets.js +209 -63
- package/dist/services/checkbox-state.js +31 -0
- package/dist/services/managed-file.js +709 -0
- package/dist/services/managed-guidance.js +229 -0
- package/dist/services/opencode-config.js +135 -0
- package/dist/services/raw-tty.js +75 -0
- package/dist/services/setup-wizard.js +45 -93
- package/dist/services/skill-installer.js +145 -84
- package/docs/support.md +13 -13
- package/package.json +6 -3
- package/skills/structural-code-editing/SKILL.md +9 -3
- package/skills/structural-code-editing/guidance.md +3 -0
- package/skills/structural-code-editing/releases.json +50 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,13 +4,55 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
-
## [
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.8.1] — release candidate (unreleased, 2026-08-14)
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Public-registry verification now prepares the pinned GNU coreutils 9.7 `mv` primitive before running the managed-setup consumer smoke, and workflow policy rejects removal or reordering of that prerequisite.
|
|
14
|
+
|
|
15
|
+
### Release status
|
|
16
|
+
|
|
17
|
+
- This version is bound to exact-SHA CI and the repository's staged `next` publication, public-registry verification, `latest` promotion, annotated-tag, and hosted-release sequence. npm registry and GitHub readbacks remain authoritative for those external transitions.
|
|
18
|
+
|
|
19
|
+
## [0.8.0] — published to `next`, verification failed, not promoted (2026-08-14)
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- OpenCode effective-config discovery and verification now run against disposable routed copies because the client normalizes both configured files even for diagnostic commands; the real planned destination remains snapshot-protected.
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- Added managed `structural-code-editing` activation guidance for the verified Claude, OpenCode, Codex, and Gemini global instruction surfaces; Hermes and Copilot remain explicitly skill-only.
|
|
28
|
+
- Added an exact SHA-256 release manifest for safe upgrades from registry-proven skill bytes and packaged the canonical marker-free guidance payload.
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
|
|
32
|
+
- Setup now preflights MCP, skill, and guidance across every selected client before mutation, preserves user-owned instruction bytes, applies snapshot-checked descriptor-bound file writes, and reports schema v2 with logical outcomes plus completed, possibly committed, rolled-back, rollback-failed, pending, and successful physical asset states.
|
|
33
|
+
- `install-skill` uses the same official-byte manifest but remains skill-only; explicit force never bypasses guidance ownership, route, or race checks.
|
|
34
|
+
- Managed file writes hold staged and preimage inodes through publication, use no-clobber descriptor links for creation and atomic exchange with exact-pair rollback for replacement, reject same-inode content or mode races before cleanup, then reauthenticate unchanged/completed postimages before later asset or MCP writes.
|
|
35
|
+
|
|
36
|
+
### Release status
|
|
37
|
+
|
|
38
|
+
- npm published these immutable bytes under `next` with provenance and the expected Git commit. Public-consumer verification stopped during managed setup because the verification workflow had not prepared its required GNU coreutils 9.7 `mv`; the package was never promoted to `latest`, tagged, or released on GitHub. Version `0.8.1` is the patch candidate intended to supersede it after verified publication.
|
|
39
|
+
|
|
40
|
+
## [0.7.2] — published to `latest`, registry verified (2026-08-13)
|
|
8
41
|
|
|
9
42
|
### Fixed
|
|
10
43
|
|
|
11
44
|
- Promotion preflight now validates raw npm registry metadata exactly once, compares live integrity with the verified artifact before and after mutation, and classifies the normalized readback without reinterpreting its field schema.
|
|
12
45
|
- Added a composed regression covering eligible, already-promoted, and integrity-drift promotion readbacks.
|
|
13
46
|
|
|
47
|
+
### Added
|
|
48
|
+
|
|
49
|
+
- Expanded convergent setup to Claude Code, Hermes, OpenCode, Codex CLI, Gemini CLI, and GitHub Copilot CLI with fail-closed versioned contracts.
|
|
50
|
+
- Added native checkbox selection, shared `.agents/skills` planning, routed JSONC-safe OpenCode configuration, bounded correlated diagnostics, and fixture admission gates.
|
|
51
|
+
|
|
52
|
+
### Release status
|
|
53
|
+
|
|
54
|
+
- npm promoted the immutable `0.7.2` bytes to `latest`. Later `next` assignments do not alter those bytes, and the `0.8.x` sections above describe distinct package versions that cannot be attributed to `0.7.2`.
|
|
55
|
+
|
|
14
56
|
## [0.7.1] — published to `next`, verified, not promoted (2026-08-12)
|
|
15
57
|
|
|
16
58
|
### Fixed
|
package/README.md
CHANGED
|
@@ -82,7 +82,7 @@ The included batch benchmark records a 50% reduction in model round-trips and a
|
|
|
82
82
|
|
|
83
83
|
## Supported environment and trust boundary
|
|
84
84
|
|
|
85
|
-
The
|
|
85
|
+
The package engine floor remains Node.js `>=22.5.0`. The v0.8.1 release matrix covers Linux x64 under exact Node.js 22.5.0 and the current Node.js 24 line, including managed setup-file publication. That mutation additionally requires GNU coreutils 9.7 `mv` supporting `--update=none-fail`, `--exchange`, `--no-copy`, and `--no-target-directory`, GNU coreutils `ln -L -T`, procfs descriptor paths at `/proc/self/fd`, and `O_DIRECTORY`/`O_NOFOLLOW`. Other Linux architectures or systems without those filesystem primitives, macOS, and Windows remain unverified until equivalent exact-tree gates pass.
|
|
86
86
|
|
|
87
87
|
This is a local stdio server. It runs with the invoking user's filesystem permissions, and clients may request any `project_root` that user can access. It does not provide HTTP authentication, sandboxing, tenant isolation, or a remote-service security boundary. Remote, untrusted, and multi-tenant operation is unsupported.
|
|
88
88
|
|
|
@@ -134,24 +134,44 @@ From a source checkout, use the Yarn script; it builds first and then opens the
|
|
|
134
134
|
yarn setup
|
|
135
135
|
```
|
|
136
136
|
|
|
137
|
-
The wizard
|
|
137
|
+
The wizard supports exactly six CLI clients in this order: Claude Code, Hermes, OpenCode, Codex CLI, Gemini CLI, and GitHub Copilot CLI. Cursor, Windsurf, Cline, and other editor-integrated clients are intentionally excluded. Compatible detected clients start checked; unavailable or incompatible clients are disabled with a reason. Use Up/Down to move, Space to toggle, Enter to submit, or Escape/Ctrl-C to cancel.
|
|
138
138
|
|
|
139
|
-
1. preflights
|
|
140
|
-
2. installs the bundled `structural-code-editing` skill;
|
|
141
|
-
3.
|
|
142
|
-
4.
|
|
139
|
+
1. preflights every selected client's existing `ast` MCP registration, skill destination, and effective managed-guidance destination;
|
|
140
|
+
2. installs or safely upgrades the bundled `structural-code-editing` skill;
|
|
141
|
+
3. adds one marker-owned activation block to each verified global instruction surface while preserving all user-owned bytes;
|
|
142
|
+
4. registers this package's MCP server through the agent's official CLI;
|
|
143
|
+
5. reconnects and verifies the expected tools.
|
|
143
144
|
|
|
144
|
-
Existing matching registrations
|
|
145
|
+
Existing matching registrations, skill files, and managed blocks are unchanged. Conflicting MCP registrations or malformed/unknown managed guidance fail before any write; resolve them explicitly instead of letting a setup script guess. Skill upgrades are automatic only when the installed bytes match an exact SHA-256 admitted from a published npm tarball. Unknown or customized skill bytes fail closed unless `--force-skill` is explicit. That flag applies only to the skill and cannot override guidance conflicts, unsafe routes, or filesystem races.
|
|
146
|
+
|
|
147
|
+
Guidance uses each client's verified global instruction contract rather than one universal filename:
|
|
148
|
+
|
|
149
|
+
| Client | Managed guidance destination |
|
|
150
|
+
| -------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
151
|
+
| Claude | `$CLAUDE_CONFIG_DIR/CLAUDE.md`, or `~/.claude/CLAUDE.md` |
|
|
152
|
+
| OpenCode | Effective native `AGENTS.md`; an existing Claude fallback may be shared or preserved when OpenCode has no native file |
|
|
153
|
+
| Codex | Non-empty `$CODEX_HOME/AGENTS.override.md`, otherwise `$CODEX_HOME/AGENTS.md`; `CODEX_HOME` defaults to `~/.codex` |
|
|
154
|
+
| Gemini | The one supported safe `context.fileName` from `~/.gemini/settings.json`, otherwise `~/.gemini/GEMINI.md` |
|
|
155
|
+
| Hermes | `skill_only`; setup does not modify `SOUL.md` or invent a global instruction destination |
|
|
156
|
+
| Copilot | `skill_only`; setup does not invent a personal global instruction destination |
|
|
157
|
+
|
|
158
|
+
The managed range is delimited by `ast-tool:structural-code-editing guidance v1` begin/end markers. Setup updates only that range, preserves the file's UTF-8 BOM, newline style, mode, and all content outside the range, and rejects duplicate, partial, reordered, unknown, symlinked, or non-regular destinations. Writes pin the parent chain, preimage, held temporary inode, and destination. New files use descriptor-bound no-clobber publication; replacements use an atomic same-directory exchange, validate both exchanged identities plus the pinned preimage bytes and mode, and roll the exact pair back when an in-call substitution or same-inode edit is detected. Every completed postimage is reauthenticated before later asset or MCP mutation. Cross-client setup is convergent rather than globally transactional.
|
|
159
|
+
|
|
160
|
+
Successful setup output uses schema `version: 2`. Each agent reports `mcp`, `skill`, and `guidance`; physical writes include an `asset` of `skill`, `guidance`, or `mcp_config`. A complete replay returns every applicable item as `unchanged`/`skill_only` and an empty `physical_writes` array. A failed managed publication separates `completed_writes`, `possibly_committed`, `rolled_back`, `rollback_failed`, and `pending`; an uncertain commit or failed rollback is never reported as untouched and requires inspection plus a fresh replan.
|
|
145
161
|
|
|
146
162
|
For automation, make the target set and confirmation explicit:
|
|
147
163
|
|
|
148
164
|
```bash
|
|
149
165
|
ast-tool setup --agents all --yes
|
|
150
|
-
ast-tool setup --agents claude --yes
|
|
166
|
+
ast-tool setup --agents claude,codex --yes
|
|
151
167
|
```
|
|
152
168
|
|
|
153
169
|
From a source checkout, replace `ast-tool` with `yarn setup` in those commands.
|
|
154
170
|
|
|
171
|
+
`--agents all` is resolved only after detection and means every detected compatible client. If any detected client has unknown or incompatible output, setup fails before writes. Explicit IDs are strict and reject unavailable clients. Non-interactive setup requires both `--agents` and `--yes`.
|
|
172
|
+
|
|
173
|
+
OpenCode 1.18.18 or newer is required. Because `opencode mcp add` ignores custom config routing, setup updates only `mcp.ast` in `OPENCODE_CONFIG`, then `OPENCODE_CONFIG_DIR/opencode.json`, then `~/.config/opencode/opencode.json`. JSONC comments, unrelated keys, and file mode are preserved. OpenCode's nominally diagnostic config command normalizes both routed config files, so setup runs discovery and verification against disposable copies while retaining the selected config bytes and fails closed if the planned real destination changes. Gemini setup may require trusting the current folder before registration. Diagnostics use a correlation ID and omit command arguments, environment, credentials, and raw provider output; setup failures may include a bounded destination path so the operator can inspect an uncertain or pending write.
|
|
174
|
+
|
|
155
175
|
## Install the agent skill
|
|
156
176
|
|
|
157
177
|
The package bundles a `structural-code-editing` skill that teaches an agent when to use the AST tools, how to minimize context, and how to review mutations safely. Install it for both Claude Code and Hermes with one command:
|
|
@@ -169,10 +189,11 @@ ast-tool install-skill hermes
|
|
|
169
189
|
|
|
170
190
|
The default is user scope. It writes to Claude Code's personal skill directory and to the active `HERMES_HOME`:
|
|
171
191
|
|
|
172
|
-
| Target
|
|
173
|
-
|
|
|
174
|
-
| Claude Code
|
|
175
|
-
| Hermes
|
|
192
|
+
| Target | Destination |
|
|
193
|
+
| -------------------------------- | ---------------------------------------------------------------------------------------------------------- |
|
|
194
|
+
| Claude Code | `$CLAUDE_CONFIG_DIR/skills/structural-code-editing/SKILL.md`, or `~/.claude/skills/...` by default |
|
|
195
|
+
| Hermes | `$HERMES_HOME/skills/software-development/structural-code-editing/SKILL.md`, or `~/.hermes/...` by default |
|
|
196
|
+
| OpenCode, Codex, Gemini, Copilot | `~/.agents/skills/structural-code-editing/SKILL.md` (one physical write, four logical outcomes) |
|
|
176
197
|
|
|
177
198
|
To commit the skill into one project for Claude Code, use project scope:
|
|
178
199
|
|
|
@@ -182,7 +203,7 @@ ast-tool install-skill claude --scope project --project-root /absolute/project
|
|
|
182
203
|
|
|
183
204
|
This writes `.claude/skills/structural-code-editing/SKILL.md` below that project. Project scope is intentionally rejected for Hermes because Hermes skills belong to a profile, not a source repository.
|
|
184
205
|
|
|
185
|
-
Installation is idempotent. Existing
|
|
206
|
+
Installation is idempotent. Existing current bytes are left untouched; exact predecessor bytes admitted by the bundled npm-provenance manifest are upgraded safely. Unknown or customized bytes fail closed unless `--force` is explicit. `install-skill` never writes global guidance or configures MCP. From an unlinked source checkout, replace `ast-tool` with `yarn node /absolute/path/to/ast-mcp-server/dist/cli.js`.
|
|
186
207
|
|
|
187
208
|
Claude Code detects changes in an existing skill directory live; restart it if the top-level skills directory did not exist when the session started. In Hermes, run `/reload-skills` or start a new session, then verify with `hermes skills list`.
|
|
188
209
|
|
|
@@ -421,11 +442,12 @@ yarn build
|
|
|
421
442
|
yarn test:mcp
|
|
422
443
|
yarn test:cli
|
|
423
444
|
yarn test:package
|
|
445
|
+
yarn test:installed-agents
|
|
424
446
|
yarn npm audit --all --recursive
|
|
425
447
|
yarn pack --dry-run
|
|
426
448
|
```
|
|
427
449
|
|
|
428
|
-
`test:mcp` exercises the built stdio server. `test:cli` runs a read pipeline and a prepare/apply/replay workflow across separate Node processes.
|
|
450
|
+
`test:mcp` exercises the built stdio server. `test:cli` runs a read pipeline and a prepare/apply/replay workflow across separate Node processes. `test:installed-agents` is a host-dependent manual gate: it builds first, detects locally installed supported clients, uses only disposable homes/config roots, verifies deterministic effective discovery without model calls, reports unavailable clients, and removes the disposable state. It is not a portable CI requirement because CI does not install every external client.
|
|
429
451
|
|
|
430
452
|
## Benchmarks
|
|
431
453
|
|
package/SECURITY.md
CHANGED
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
## Supported versions
|
|
4
4
|
|
|
5
|
-
Security fixes are provided for the
|
|
5
|
+
Security fixes are provided for the exact version currently identified by the npm registry's `latest` dist-tag and for the current `main` development line. The support window is registry-authoritative:
|
|
6
6
|
|
|
7
|
-
|
|
|
8
|
-
|
|
|
9
|
-
| `main` /
|
|
10
|
-
|
|
|
11
|
-
|
|
|
12
|
-
|
|
|
7
|
+
| Release state | Supported |
|
|
8
|
+
| ------------------------------------------- | --------- |
|
|
9
|
+
| `main` / `Unreleased` | Yes |
|
|
10
|
+
| Exact npm version currently tagged `latest` | Yes |
|
|
11
|
+
| Earlier npm versions | No |
|
|
12
|
+
| Unpublished release candidates | No |
|
|
13
13
|
|
|
14
|
-
This project supports trusted single-user local stdio use
|
|
14
|
+
This project supports trusted single-user local stdio use; the supported operating-system and architecture boundary remains Linux x64 only. The package engine floor is Node.js `>=22.5.0`, and the v0.8.1 release matrix covers Linux x64 under exact Node.js 22.5.0 and the current Node.js 24 line, including managed setup-file publication. That mutation requires GNU coreutils 9.7 `mv --update=none-fail --exchange --no-copy --no-target-directory`, GNU coreutils `ln -L -T`, and procfs descriptor-relative paths at `/proc/self/fd` with `O_DIRECTORY`/`O_NOFOLLOW`. Other Linux architectures and systems without those primitives are unverified, as are macOS and Windows. Remote, untrusted, and multi-tenant use is outside the supported security boundary.
|
|
15
15
|
|
|
16
16
|
## Reporting a vulnerability
|
|
17
17
|
|
package/dist/cli.js
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { readFile } from "node:fs/promises";
|
|
3
3
|
import process from "node:process";
|
|
4
|
-
import { createInterface } from "node:readline/promises";
|
|
5
4
|
import { ZodError } from "zod";
|
|
6
5
|
import { BatchExecutionError, parseBatchDocument, runBatchDocument } from "./batch/runner.js";
|
|
7
6
|
import { MAX_BATCH_INPUT_BYTES, isPrepareBatchTool } from "./batch/schema.js";
|
|
8
7
|
import { CliOutputError, serializeCliSuccess } from "./cli-output.js";
|
|
9
8
|
import { applyPersistedOperation, persistOperationPlan } from "./services/operation-plan-file.js";
|
|
10
9
|
import { AgentSetupError, detectInstalledAgents, resolveServerEntryPath, runAgentSetup, } from "./services/agent-setup.js";
|
|
11
|
-
import { installBundledSkill,
|
|
12
|
-
import { parseAgentsArgument, promptForAgentSelection, } from "./services/setup-wizard.js";
|
|
10
|
+
import { installBundledSkill, resolveBundledSkillAssets, } from "./services/skill-installer.js";
|
|
11
|
+
import { parseAgentsArgument, promptForAgentSelection, resolveAgentSelection, } from "./services/setup-wizard.js";
|
|
13
12
|
class CliError extends Error {
|
|
14
13
|
code;
|
|
15
14
|
exitCode;
|
|
@@ -241,30 +240,33 @@ export async function runCli(args) {
|
|
|
241
240
|
const options = parseSetupArgs(commandArgs);
|
|
242
241
|
try {
|
|
243
242
|
const detections = await detectInstalledAgents();
|
|
244
|
-
let agents
|
|
245
|
-
if (agents === undefined) {
|
|
243
|
+
let agents;
|
|
244
|
+
if (options.agents === undefined) {
|
|
246
245
|
if (process.stdin.isTTY !== true || process.stderr.isTTY !== true) {
|
|
247
246
|
throw new CliError("Interactive setup requires a TTY. Use --agents claude,hermes --yes for automation.", "USAGE", 2, command);
|
|
248
247
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
prompt.close();
|
|
255
|
-
}
|
|
248
|
+
agents = await promptForAgentSelection(detections, {
|
|
249
|
+
input: process.stdin,
|
|
250
|
+
output: process.stderr,
|
|
251
|
+
signals: process,
|
|
252
|
+
});
|
|
256
253
|
if (agents.length === 0) {
|
|
257
254
|
return { status: "cancelled", command: "setup", agents: [] };
|
|
258
255
|
}
|
|
259
256
|
}
|
|
257
|
+
else
|
|
258
|
+
agents = resolveAgentSelection(options.agents, detections);
|
|
260
259
|
const executablePath = process.argv[1];
|
|
261
260
|
if (!executablePath) {
|
|
262
261
|
throw new Error("Cannot resolve the ast-tool executable path.");
|
|
263
262
|
}
|
|
263
|
+
const assets = await resolveBundledSkillAssets(executablePath);
|
|
264
264
|
return await runAgentSetup({
|
|
265
265
|
agents,
|
|
266
266
|
detections,
|
|
267
|
-
sourceSkillPath:
|
|
267
|
+
sourceSkillPath: assets.skillPath,
|
|
268
|
+
sourceGuidancePath: assets.guidancePath,
|
|
269
|
+
releaseManifestPath: assets.releasesPath,
|
|
268
270
|
serverEntryPath: await resolveServerEntryPath(executablePath),
|
|
269
271
|
forceSkill: options.forceSkill,
|
|
270
272
|
});
|
|
@@ -286,9 +288,11 @@ export async function runCli(args) {
|
|
|
286
288
|
if (!executablePath) {
|
|
287
289
|
throw new Error("Cannot resolve the ast-tool executable path.");
|
|
288
290
|
}
|
|
291
|
+
const assets = await resolveBundledSkillAssets(executablePath);
|
|
289
292
|
return await installBundledSkill({
|
|
290
293
|
...options,
|
|
291
|
-
sourceSkillPath:
|
|
294
|
+
sourceSkillPath: assets.skillPath,
|
|
295
|
+
releaseManifestPath: assets.releasesPath,
|
|
292
296
|
});
|
|
293
297
|
}
|
|
294
298
|
catch (error) {
|