agentsmesh 0.28.0 → 0.29.0
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 +16 -0
- package/README.md +59 -10
- package/dist/canonical.d.ts +2 -2
- package/dist/canonical.js +63 -4
- package/dist/canonical.js.map +1 -1
- package/dist/cli.js +180 -180
- package/dist/engine.d.ts +2 -2
- package/dist/engine.js +75 -5
- package/dist/engine.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +77 -7
- package/dist/index.js.map +1 -1
- package/dist/{schema-CzaoYJlG.d.ts → schema-CH_JJep8.d.ts} +5 -0
- package/dist/{target-descriptor-ItDY3NR0.d.ts → target-descriptor-CaLUz7SR.d.ts} +1 -1
- package/dist/targets.d.ts +3 -3
- package/package.json +1 -1
- package/schemas/agentsmesh.json +11 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.29.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 663f0e6: Strip elevated artifacts from remote `extends` sources by default
|
|
8
|
+
|
|
9
|
+
`hooks`, `permissions`, and `mcp` contributed by a **remote** `extends` source (`github:`, `gitlab:`, `git+…`, including `git+file://`) are now stripped during config load unless the entry opts in with `accept: [hooks, permissions, mcp]`. This closes a gap where a remote `extends` could inject shell-executing config (settings hooks, MCP launch specs) without the per-artifact consent that `agentsmesh install` already requires. Local `extends` remain trusted as-is, and a warning reports anything that was stripped.
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 11f90bc: Harden plugin source containment against intermediate-symlink escapes
|
|
14
|
+
|
|
15
|
+
The plugin loader now canonicalizes an unresolvable source path against its nearest existing ancestor instead of falling back to the raw path. This closes a gap where a local plugin `source` routed through a symlinked directory that resolves outside the project root could slip past the trust-boundary check when its entry file did not exist yet. Legitimate in-project plugins are unaffected.
|
|
16
|
+
|
|
17
|
+
- c647c9b: Docs: the README now leads with lessons (the shared agent memory), adds a head-to-head comparison with Ruler and rulesync, embeds demo GIFs, leads the quickstart with the import-first path for existing repos, and documents the new `extends` `accept:` consent. Documentation-only — no behavior change.
|
|
18
|
+
|
|
3
19
|
## 0.28.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-
# AgentsMesh
|
|
3
|
+
# AgentsMesh
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
### One source for every AI coding tool — with a shared agent memory that learns from your repo.
|
|
6
|
+
|
|
7
|
+
<img src="https://raw.githubusercontent.com/sampleXbro/agentsmesh/master/assets/agentsmesh-banner.jpeg" alt="AgentsMesh — One source. Every AI coding tool. Agents that learn." width="100%" />
|
|
6
8
|
|
|
7
9
|
[](https://github.com/sampleXbro/agentsmesh/actions/workflows/ci.yml)
|
|
8
10
|
[](https://www.npmjs.com/package/agentsmesh)
|
|
@@ -23,6 +25,28 @@ Every AI coding assistant has its own config format — `CLAUDE.md`, `AGENTS.md`
|
|
|
23
25
|
> [!NOTE]
|
|
24
26
|
> Full documentation, guides, and the per-tool reference live at **[samplexbro.github.io/agentsmesh](https://samplexbro.github.io/agentsmesh/)**.
|
|
25
27
|
|
|
28
|
+
## How AgentsMesh compares
|
|
29
|
+
|
|
30
|
+
Most config tools stop at copying rule files into each assistant's folder. AgentsMesh is the only one that also gives your agents a **shared memory that learns**, round-trips **losslessly** in both directions, and lets anyone **add a new tool as a plugin** — no release required.
|
|
31
|
+
|
|
32
|
+
| Capability | AgentsMesh | [Ruler](https://github.com/intellectronica/ruler) | [rulesync](https://github.com/dyoshikawa/rulesync) |
|
|
33
|
+
|---|:---:|:---:|:---:|
|
|
34
|
+
| Generate native config for many tools | ✅ | ✅ | ✅ |
|
|
35
|
+
| Import existing tool config back to source | ✅ | — | ✅ |
|
|
36
|
+
| **Lossless round-trip** (re-import restores originals) | ✅ | — | partial |
|
|
37
|
+
| Convert one tool's config directly to another | ✅ | — | ✅ |
|
|
38
|
+
| **Automatic cross-tool link rebasing** | ✅ | — | — |
|
|
39
|
+
| **Lessons — a shared agent memory that learns** | ✅ | — | — |
|
|
40
|
+
| **Plugins — add a target without a release** | ✅ | — | — |
|
|
41
|
+
| Cross-target lint (warn before silent data loss) | ✅ | — | — |
|
|
42
|
+
| CI drift gate + git-merge recovery | ✅ | partial | partial |
|
|
43
|
+
| Self-serve MCP server (agent-operable config) | ✅ | — | — |
|
|
44
|
+
| `--json` everywhere + typed programmatic API | ✅ | — | partial |
|
|
45
|
+
|
|
46
|
+
<sub>Reflects the public projects as of June 2026 — see the [alternatives guide](https://samplexbro.github.io/agentsmesh/reference/alternatives/) for sources and detail. Corrections welcome.</sub>
|
|
47
|
+
|
|
48
|
+
Built to be depended on: **8,000+ tests** run on Linux, macOS, and Windows CI (Node 22 & 24), configs are JSON-Schema-validated, npm releases ship with [provenance](https://docs.npmjs.com/generating-provenance-statements), and standalone binaries are published with SHA-256 checksums.
|
|
49
|
+
|
|
26
50
|
## Install
|
|
27
51
|
|
|
28
52
|
Every install method ships the same CLI (`agentsmesh`, plus the shorter `amsh` alias) and the same TypeScript library.
|
|
@@ -45,11 +69,14 @@ Standalone binaries are also on [GitHub Releases](https://github.com/sampleXbro/
|
|
|
45
69
|
|
|
46
70
|
## 60-second quickstart
|
|
47
71
|
|
|
48
|
-
Works on Linux, macOS, and Windows. After [installing](#install):
|
|
72
|
+
Works on Linux, macOS, and Windows. After [installing](#install), `agentsmesh init` adapts to your repo:
|
|
73
|
+
|
|
74
|
+
- **Already using AI tools?** It detects your existing `.cursor/`, `.claude/`, `.github/copilot-instructions.md`, and more, and offers to import them all into one `.agentsmesh/` source — nothing rewritten by hand. (`agentsmesh init --yes` does it non-interactively.)
|
|
75
|
+
- **Starting fresh?** It scaffolds a minimal `.agentsmesh/` to grow from.
|
|
49
76
|
|
|
50
77
|
```bash
|
|
51
|
-
agentsmesh init #
|
|
52
|
-
agentsmesh generate # write native
|
|
78
|
+
agentsmesh init # detect & import existing configs, or scaffold fresh
|
|
79
|
+
agentsmesh generate # write each tool's native config from the one source
|
|
53
80
|
agentsmesh check # CI-friendly drift gate against .agentsmesh/.lock
|
|
54
81
|
```
|
|
55
82
|
|
|
@@ -99,15 +126,35 @@ AGENTS.md
|
|
|
99
126
|
|
|
100
127
|
Edit canonical sources, run `agentsmesh generate`, and every native file above is (re)written for you — always in sync. Alongside the directory, `agentsmesh.yaml` selects which targets and features are enabled, `agentsmesh.local.yaml` holds per-developer overrides (gitignored), and `.agentsmesh/.lock` records the checksums that `agentsmesh check` enforces.
|
|
101
128
|
|
|
129
|
+
<div align="center">
|
|
130
|
+
<img src="https://raw.githubusercontent.com/sampleXbro/agentsmesh/master/assets/generate-demo.gif" alt="agentsmesh detects existing tool configs, imports them into one source, and generates native config for every tool" width="100%" />
|
|
131
|
+
</div>
|
|
132
|
+
|
|
102
133
|
## Teach your agents: lessons
|
|
103
134
|
|
|
104
|
-
Lessons give your AI agents a **memory of past mistakes** — read *before* they touch anything, written *after* something goes wrong, so the same mistake doesn't happen twice in any tool.
|
|
135
|
+
This is the part no other config-sync tool has. Lessons give your AI agents a **memory of past mistakes** — read *before* they touch anything, written *after* something goes wrong, so the same mistake doesn't happen twice in any tool. It's what turns a static pile of rules into an agent that gets better at *your* codebase over time.
|
|
136
|
+
|
|
137
|
+
<div align="center">
|
|
138
|
+
<img src="https://raw.githubusercontent.com/sampleXbro/agentsmesh/master/assets/lessons-demo.gif" alt="an AI agent captures a lesson after a failure, then recalls it before editing the same file — triggered by file, command, or keyword" width="100%" />
|
|
139
|
+
</div>
|
|
105
140
|
|
|
106
141
|
The memory is one git-tracked file, `.agentsmesh/lessons/lessons.json`, and every agent talks to it through two commands:
|
|
107
142
|
|
|
108
143
|
- **Recall** — before an edit or a state-changing command, the agent runs `agentsmesh lessons query --file <path> --cmd <command>` and follows the rules that match.
|
|
109
144
|
- **Capture** — right after a failure (red test, lint error, review comment, wrong assumption), it saves the rule with `agentsmesh lessons add "<rule>" --topic <id> --trigger-file <glob>`.
|
|
110
145
|
|
|
146
|
+
In practice:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
# An agent breaks the Windows build, finds the cause, and writes the lesson down:
|
|
150
|
+
agentsmesh lessons add "Normalize CLI display paths to forward slashes" \
|
|
151
|
+
--topic windows-paths --trigger-file "src/cli/**/*.ts"
|
|
152
|
+
|
|
153
|
+
# Days later, any agent — in any tool — about to touch that path recalls it first:
|
|
154
|
+
agentsmesh lessons query --file src/cli/output.ts
|
|
155
|
+
# → "Normalize CLI display paths to forward slashes"
|
|
156
|
+
```
|
|
157
|
+
|
|
111
158
|
```bash
|
|
112
159
|
agentsmesh init --lessons && agentsmesh generate # wire the recall/capture loop once
|
|
113
160
|
```
|
|
@@ -125,8 +172,8 @@ Full walkthrough: [Teach your AI agents with lessons](https://samplexbro.github.
|
|
|
125
172
|
- **Migrate between tools** — `convert --from <a> --to <b>` rewrites one tool's config directly into another's native format. [convert →](https://samplexbro.github.io/agentsmesh/cli/convert/)
|
|
126
173
|
- **Global mode** — `~/.agentsmesh/` syncs your personal config to `~/.claude/`, `~/.cursor/`, `~/.codex/`, and more. Every command accepts `--global`. [Global paths →](https://samplexbro.github.io/agentsmesh/reference/supported-tools/#global-mode)
|
|
127
174
|
- **Team-safe and CI-ready** — `check` is a drift gate against `.agentsmesh/.lock`, `diff` previews changes, `merge` rebuilds the lock after a 3-way Git conflict, and `lock_features` + per-feature `strategy` prevent accidental overrides. `lint` adds cross-target warnings (`silent-drop-guard`, `hook-script-references`, `rule-scope-inversion`) for content a tool would silently mishandle. [check →](https://samplexbro.github.io/agentsmesh/cli/check/) · [lint →](https://samplexbro.github.io/agentsmesh/cli/lint/)
|
|
128
|
-
- **Community packs and `extends`** — install shared rules, skills, agents, and commands from any git repo (`install`, `--sync`, `refresh`, remote `extends`); a multi-signal classifier auto-detects Anthropic-style skill packs. Elevated artifacts (hooks, permissions, MCP) from remote sources are stripped unless you opt in with `--accept
|
|
129
|
-
- **Plugins** — ship support for a new tool as a standalone npm package, with full parity to built-in targets (project + global, conversions, lint hooks, hook post-processing). [Build a plugin →](https://samplexbro.github.io/agentsmesh/guides/building-plugins/)
|
|
175
|
+
- **Community packs and `extends`** — install shared rules, skills, agents, and commands from any git repo (`install`, `--sync`, `refresh`, remote `extends`); a multi-signal classifier auto-detects Anthropic-style skill packs. Elevated artifacts (hooks, permissions, MCP) from remote sources are stripped unless you opt in — with `--accept-*` on `install`, or `accept:` on a remote `extends` entry. [Install reference →](https://samplexbro.github.io/agentsmesh/cli/install/)
|
|
176
|
+
- **Plugins — add a tool without waiting for a release** — ship support for a new AI tool as a standalone npm package, with full parity to built-in targets (project + global, conversions, lint hooks, hook post-processing). When a tool ships or changes its format, you don't file an issue and wait on the maintainer — you publish a plugin. [Build a plugin →](https://samplexbro.github.io/agentsmesh/guides/building-plugins/)
|
|
130
177
|
- **Schema-validated configs** — each config ships a JSON Schema, so editors give you autocomplete and validation out of the box. [JSON schemas →](https://samplexbro.github.io/agentsmesh/reference/json-schemas/)
|
|
131
178
|
- **Typed programmatic API** — drive `generate` / `import` / `lint` / `diff` / `check` from scripts or CI via `agentsmesh`, `/engine`, `/canonical`, `/targets`, `/lessons`. [API reference →](https://samplexbro.github.io/agentsmesh/reference/programmatic-api/)
|
|
132
179
|
- **Self-serve MCP server** — `agentsmesh mcp` (seeded by `init`) exposes canonical config as MCP tools so agents can introspect rules, commands, and skills and trigger `generate` in-conversation. [MCP server →](https://samplexbro.github.io/agentsmesh/reference/mcp-server/)
|
|
@@ -135,9 +182,11 @@ Full walkthrough: [Teach your AI agents with lessons](https://samplexbro.github.
|
|
|
135
182
|
> [!TIP]
|
|
136
183
|
> Commit **both** `.agentsmesh/` and the generated tool files, the same way you commit `package-lock.json`: they're deterministic build output that the AI tools read directly, and `agentsmesh check` guards the two from drifting.
|
|
137
184
|
|
|
138
|
-
## Why not just `AGENTS.md`?
|
|
185
|
+
## Why not Ruler, rulesync, or just `AGENTS.md`?
|
|
186
|
+
|
|
187
|
+
**vs. `AGENTS.md`** — [`AGENTS.md`](https://agents.md) is a great shared instruction file, and AgentsMesh emits it natively wherever a tool supports it. But a single markdown file isn't enough on its own: most assistants expose configuration *beyond* it — Cursor's `.cursor/rules/*.mdc` and MCP config, Claude Code's agents/skills/commands/hooks/permissions, Copilot's `.github/instructions/`, Gemini's `.gemini/settings.json`, and so on — and those surfaces don't overlap. AgentsMesh canonicalizes all of them so you never have to pick one tool's surface as the lowest common denominator.
|
|
139
188
|
|
|
140
|
-
[
|
|
189
|
+
**vs. other sync tools** — [Ruler](https://github.com/intellectronica/ruler) and [rulesync](https://github.com/dyoshikawa/rulesync) solve the rules-distribution half well. AgentsMesh goes further on the parts that are hardest to keep in sync: a shared [lessons](#teach-your-agents-lessons) memory your agents learn from, lossless two-way [import](https://samplexbro.github.io/agentsmesh/cli/import/), automatic cross-tool [link rebasing](https://samplexbro.github.io/agentsmesh/reference/generation-pipeline/), [plugins](https://samplexbro.github.io/agentsmesh/guides/building-plugins/) so a new tool ships without a release, and [lint](https://samplexbro.github.io/agentsmesh/cli/lint/) that warns before a tool would silently drop content. See the [full comparison](#how-agentsmesh-compares) and the [alternatives guide](https://samplexbro.github.io/agentsmesh/reference/alternatives/).
|
|
141
190
|
|
|
142
191
|
## Commands
|
|
143
192
|
|
package/dist/canonical.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { b as CanonicalFiles, V as ValidatedConfig } from './schema-
|
|
2
|
-
export { C as CanonicalAgent, a as CanonicalCommand, c as CanonicalRule, d as CanonicalSkill, H as HookEntry, e as Hooks, I as IgnorePatterns, M as McpConfig, f as McpServer, P as Permissions, S as SkillSupportingFile, g as StdioMcpServer, U as UrlMcpServer } from './schema-
|
|
1
|
+
import { b as CanonicalFiles, V as ValidatedConfig } from './schema-CH_JJep8.js';
|
|
2
|
+
export { C as CanonicalAgent, a as CanonicalCommand, c as CanonicalRule, d as CanonicalSkill, H as HookEntry, e as Hooks, I as IgnorePatterns, M as McpConfig, f as McpServer, P as Permissions, S as SkillSupportingFile, g as StdioMcpServer, U as UrlMcpServer } from './schema-CH_JJep8.js';
|
|
3
3
|
import 'zod';
|
|
4
4
|
|
|
5
5
|
interface UnrecognizedFormatsWarningOptions {
|
package/dist/canonical.js
CHANGED
|
@@ -20874,7 +20874,9 @@ async function resolveExtendPaths(config, configDir, options = {}) {
|
|
|
20874
20874
|
as: ext.as,
|
|
20875
20875
|
version: fetched.version,
|
|
20876
20876
|
path: ext.path,
|
|
20877
|
-
pick: ext.pick
|
|
20877
|
+
pick: ext.pick,
|
|
20878
|
+
isRemote: true,
|
|
20879
|
+
accept: ext.accept
|
|
20878
20880
|
});
|
|
20879
20881
|
continue;
|
|
20880
20882
|
}
|
|
@@ -20891,7 +20893,9 @@ async function resolveExtendPaths(config, configDir, options = {}) {
|
|
|
20891
20893
|
target: ext.target,
|
|
20892
20894
|
as: ext.as,
|
|
20893
20895
|
path: ext.path,
|
|
20894
|
-
pick: ext.pick
|
|
20896
|
+
pick: ext.pick,
|
|
20897
|
+
isRemote: false,
|
|
20898
|
+
accept: ext.accept
|
|
20895
20899
|
});
|
|
20896
20900
|
}
|
|
20897
20901
|
return result;
|
|
@@ -22421,6 +22425,47 @@ function applyExtendPick(canonical, features, pick, extendName) {
|
|
|
22421
22425
|
return next;
|
|
22422
22426
|
}
|
|
22423
22427
|
|
|
22428
|
+
// src/install/core/elevated-artifacts.ts
|
|
22429
|
+
function stripUntrustedElevatedArtifacts(canonical, options) {
|
|
22430
|
+
if (options.sourceKind === "local") {
|
|
22431
|
+
return { canonical, stripped: [] };
|
|
22432
|
+
}
|
|
22433
|
+
const stripped = [];
|
|
22434
|
+
let hooks = canonical.hooks;
|
|
22435
|
+
let permissions = canonical.permissions;
|
|
22436
|
+
let mcp = canonical.mcp;
|
|
22437
|
+
if (hooks !== null && !options.acceptHooks) {
|
|
22438
|
+
hooks = null;
|
|
22439
|
+
stripped.push("hooks");
|
|
22440
|
+
}
|
|
22441
|
+
if (permissions !== null && !options.acceptPermissions) {
|
|
22442
|
+
permissions = null;
|
|
22443
|
+
stripped.push("permissions");
|
|
22444
|
+
}
|
|
22445
|
+
if (mcp !== null && !options.acceptMcp) {
|
|
22446
|
+
mcp = null;
|
|
22447
|
+
stripped.push("mcp");
|
|
22448
|
+
}
|
|
22449
|
+
if (stripped.length === 0) {
|
|
22450
|
+
return { canonical, stripped: [] };
|
|
22451
|
+
}
|
|
22452
|
+
return {
|
|
22453
|
+
canonical: { ...canonical, hooks, permissions, mcp },
|
|
22454
|
+
stripped
|
|
22455
|
+
};
|
|
22456
|
+
}
|
|
22457
|
+
|
|
22458
|
+
// src/canonical/extends/extend-elevated.ts
|
|
22459
|
+
function gateExtendElevatedArtifacts(canonical, ext) {
|
|
22460
|
+
const accept = ext.accept ?? [];
|
|
22461
|
+
return stripUntrustedElevatedArtifacts(canonical, {
|
|
22462
|
+
sourceKind: ext.isRemote ? "git" : "local",
|
|
22463
|
+
acceptHooks: accept.includes("hooks"),
|
|
22464
|
+
acceptPermissions: accept.includes("permissions"),
|
|
22465
|
+
acceptMcp: accept.includes("mcp")
|
|
22466
|
+
});
|
|
22467
|
+
}
|
|
22468
|
+
|
|
22424
22469
|
// src/install/pack/pack-reader.ts
|
|
22425
22470
|
init_fs();
|
|
22426
22471
|
|
|
@@ -22454,7 +22499,14 @@ var extendSourceSchema = z.object({
|
|
|
22454
22499
|
features: z.array(featureSchema),
|
|
22455
22500
|
/** Repo-relative POSIX path for discovery (skill packs, nested .agentsmesh). */
|
|
22456
22501
|
path: z.string().optional(),
|
|
22457
|
-
pick: extendPickSchema.optional()
|
|
22502
|
+
pick: extendPickSchema.optional(),
|
|
22503
|
+
/**
|
|
22504
|
+
* Per-entry consent for "elevated" artifacts (`hooks`, `permissions`, `mcp`)
|
|
22505
|
+
* from a remote source. These control local code execution at generate time,
|
|
22506
|
+
* so for non-local extends they are stripped by default and only merged for
|
|
22507
|
+
* the artifacts listed here. Local extends are trusted and ignore this field.
|
|
22508
|
+
*/
|
|
22509
|
+
accept: z.array(z.enum(["hooks", "permissions", "mcp"])).optional()
|
|
22458
22510
|
});
|
|
22459
22511
|
var collaborationSchema = z.object({
|
|
22460
22512
|
strategy: z.enum(["merge", "lock", "last-wins"]).default("merge"),
|
|
@@ -22646,7 +22698,14 @@ async function loadCanonicalWithExtends(config, configDir, options = {}, canonic
|
|
|
22646
22698
|
for (const ext of resolvedExtends) {
|
|
22647
22699
|
const extCanonical = await loadCanonicalForExtend(ext);
|
|
22648
22700
|
const filtered = filterCanonicalByFeatures(extCanonical, ext.features);
|
|
22649
|
-
const
|
|
22701
|
+
const gated = gateExtendElevatedArtifacts(filtered, ext);
|
|
22702
|
+
if (gated.stripped.length > 0) {
|
|
22703
|
+
const list = gated.stripped.join(", ");
|
|
22704
|
+
logger.warn(
|
|
22705
|
+
`[agentsmesh] Extend "${ext.name}": stripped elevated artifacts from a remote source: ${list}. Add \`accept: [${list}]\` to this extends entry in agentsmesh.yaml to keep them.`
|
|
22706
|
+
);
|
|
22707
|
+
}
|
|
22708
|
+
const picked = applyExtendPick(gated.canonical, ext.features, ext.pick, ext.name);
|
|
22650
22709
|
merged = mergeCanonicalFiles(merged, picked);
|
|
22651
22710
|
}
|
|
22652
22711
|
const packsCanonical = await loadPacksCanonical(canonicalDir);
|