agentsmesh 0.21.0 → 0.22.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 +57 -0
- package/README.md +13 -1
- package/dist/canonical.js +22 -2
- package/dist/canonical.js.map +1 -1
- package/dist/cli.js +204 -162
- package/dist/engine.js +122 -4
- package/dist/engine.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +592 -221
- package/dist/index.js.map +1 -1
- package/dist/lessons.d.ts +155 -0
- package/dist/lessons.js +305 -0
- package/dist/lessons.js.map +1 -0
- package/dist/targets.js +22 -2
- package/dist/targets.js.map +1 -1
- package/package.json +11 -2
package/dist/engine.js
CHANGED
|
@@ -2,7 +2,7 @@ import { z } from 'zod';
|
|
|
2
2
|
import { stringify, parse } from 'yaml';
|
|
3
3
|
import { basename, join, dirname, relative, win32, posix, sep, resolve, extname } from 'path';
|
|
4
4
|
import { readFile, rm, mkdir, readdir, stat, lstat, unlink, writeFile, rename, chmod, access, realpath, mkdtemp, cp } from 'fs/promises';
|
|
5
|
-
import {
|
|
5
|
+
import { existsSync, readFileSync, constants, realpathSync, statSync } from 'fs';
|
|
6
6
|
import { parse as parse$1 } from 'smol-toml';
|
|
7
7
|
import { Buffer } from 'buffer';
|
|
8
8
|
import { homedir, tmpdir } from 'os';
|
|
@@ -1049,7 +1049,7 @@ ${legacy}`, "");
|
|
|
1049
1049
|
}
|
|
1050
1050
|
return result.trim();
|
|
1051
1051
|
}
|
|
1052
|
-
var ROOT_INSTRUCTION_BODY_V1, ROOT_INSTRUCTION_BODY_V2, ROOT_INSTRUCTION_BODY_V3, ROOT_INSTRUCTION_BODY_V4, ROOT_INSTRUCTION_BODY_V5, ROOT_INSTRUCTION_BODY_V6, ROOT_INSTRUCTION_BODY_V7, ROOT_INSTRUCTION_BODY_V8, ROOT_INSTRUCTION_BODY, LEGACY_AGENTSMESH_ROOT_INSTRUCTION_PARAGRAPH, LEGACY_AGENTSMESH_ROOT_INSTRUCTION_SECTION, AGENTSMESH_CONTRACT_WITH_V1_BODY, AGENTSMESH_CONTRACT_WITH_V2_BODY, AGENTSMESH_CONTRACT_WITH_V3_BODY, AGENTSMESH_CONTRACT_WITH_V4_BODY, AGENTSMESH_CONTRACT_WITH_V5_BODY, AGENTSMESH_CONTRACT_WITH_V6_BODY, AGENTSMESH_CONTRACT_WITH_V7_BODY, AGENTSMESH_CONTRACT_WITH_V8_BODY, AGENTSMESH_ROOT_INSTRUCTION_PARAGRAPH, LEGACY_FORMS;
|
|
1052
|
+
var ROOT_INSTRUCTION_BODY_V1, ROOT_INSTRUCTION_BODY_V2, ROOT_INSTRUCTION_BODY_V3, ROOT_INSTRUCTION_BODY_V4, ROOT_INSTRUCTION_BODY_V5, ROOT_INSTRUCTION_BODY_V6, ROOT_INSTRUCTION_BODY_V7, ROOT_INSTRUCTION_BODY_V8, ROOT_INSTRUCTION_BODY_V9, ROOT_INSTRUCTION_BODY_V10, ROOT_INSTRUCTION_BODY, LEGACY_AGENTSMESH_ROOT_INSTRUCTION_PARAGRAPH, LEGACY_AGENTSMESH_ROOT_INSTRUCTION_SECTION, AGENTSMESH_CONTRACT_WITH_V1_BODY, AGENTSMESH_CONTRACT_WITH_V2_BODY, AGENTSMESH_CONTRACT_WITH_V3_BODY, AGENTSMESH_CONTRACT_WITH_V4_BODY, AGENTSMESH_CONTRACT_WITH_V5_BODY, AGENTSMESH_CONTRACT_WITH_V6_BODY, AGENTSMESH_CONTRACT_WITH_V7_BODY, AGENTSMESH_CONTRACT_WITH_V8_BODY, AGENTSMESH_CONTRACT_WITH_V9_BODY, AGENTSMESH_CONTRACT_WITH_V10_BODY, AGENTSMESH_ROOT_INSTRUCTION_PARAGRAPH, LEGACY_FORMS;
|
|
1053
1053
|
var init_root_instruction_paragraph = __esm({
|
|
1054
1054
|
"src/targets/projection/root-instruction-paragraph.ts"() {
|
|
1055
1055
|
init_managed_blocks();
|
|
@@ -1061,7 +1061,9 @@ var init_root_instruction_paragraph = __esm({
|
|
|
1061
1061
|
ROOT_INSTRUCTION_BODY_V6 = "Create canonical files in `.agentsmesh`: `rules/_root.md` and `rules/*.md` are Markdown rules; `commands/*.md`, `agents/*.md`, and `skills/*/SKILL.md` plus supporting files use Claude-style frontmatter Markdown; `mcp.json` is MCP JSON; `hooks.yaml` and `permissions.yaml` are YAML; `ignore` is gitignore-style text. Then run `agentsmesh generate`.";
|
|
1062
1062
|
ROOT_INSTRUCTION_BODY_V7 = "`.agentsmesh` is the only folder you edit or add these files in: `rules/_root.md` and `rules/*.md` are Markdown rules; `commands/*.md`, `agents/*.md`, and `skills/*/SKILL.md` plus supporting files use Claude-style frontmatter Markdown; `mcp.json` is MCP JSON; `hooks.yaml` and `permissions.yaml` are YAML; `ignore` is gitignore-style text. Do not edit generated tool files; run `agentsmesh generate`.";
|
|
1063
1063
|
ROOT_INSTRUCTION_BODY_V8 = "`agentsmesh.yaml` selects targets/features (`agentsmesh.local.yaml` overrides locally), and `.agentsmesh` is the only place to add or edit canonical items: `rules/_root.md`, `rules/*.md`, `commands/*.md`, `agents/*.md`, `skills/*/SKILL.md` plus supporting files, `mcp.json`, `hooks.yaml`, `permissions.yaml`, and `ignore`; if missing run `agentsmesh init`, use `agentsmesh import --from <tool>` for native configs, `agentsmesh install <source>` or `install --sync` for reusable packs, then run `agentsmesh generate`. Use `diff`, `lint`, `check`, `watch`, `matrix`, and `merge` as needed; never edit generated tool files.";
|
|
1064
|
-
|
|
1064
|
+
ROOT_INSTRUCTION_BODY_V9 = "`agentsmesh.yaml` selects targets/features (`agentsmesh.local.yaml` overrides locally), and `.agentsmesh` is the only place to add or edit canonical items: `rules/_root.md`, `rules/*.md`, `commands/*.md`, `agents/*.md`, `skills/*/SKILL.md` plus supporting files, `mcp.json`, `hooks.yaml`, `permissions.yaml`, and `ignore`; if missing run `agentsmesh init`, use `agentsmesh import --from <tool>` for native configs, `agentsmesh install <source>` or `install --sync` for reusable packs, then run `agentsmesh generate`. Use `diff`, `lint`, `check`, `watch`, `matrix`, `merge`, and `refresh` as needed; never edit generated tool files.";
|
|
1065
|
+
ROOT_INSTRUCTION_BODY_V10 = "**MUST follow when changing any rule, agent, command, skill, hook, MCP server, permission, or ignore pattern.** `agentsmesh.yaml` selects targets/features (`agentsmesh.local.yaml` overrides locally), and `.agentsmesh` is the only place to add or edit canonical items: `rules/_root.md`, `rules/*.md`, `commands/*.md`, `agents/*.md`, `skills/*/SKILL.md` plus supporting files, `mcp.json`, `hooks.yaml`, `permissions.yaml`, and `ignore`; if missing run `agentsmesh init`, use `agentsmesh import --from <tool>` for native configs, `agentsmesh install <source>` or `install --sync` for reusable packs, then run `agentsmesh generate`. Use `diff`, `lint`, `check`, `watch`, `matrix`, `merge`, and `refresh` as needed; never edit generated tool files.";
|
|
1066
|
+
ROOT_INSTRUCTION_BODY = "**NEVER edit generated files** (`.claude/`, `.cursor/`, `AGENTS.md`, `.github/copilot-instructions.md`, and similar target outputs) \u2014 `agentsmesh generate` overwrites them. **All changes MUST go through `.agentsmesh` first**: edit `rules/_root.md`, `rules/*.md`, `commands/*.md`, `agents/*.md`, `skills/*/SKILL.md` plus supporting files, `mcp.json`, `hooks.yaml`, `permissions.yaml`, and `ignore`; `agentsmesh.yaml` selects targets/features (`agentsmesh.local.yaml` overrides locally); if missing run `agentsmesh init`, use `agentsmesh import --from <tool>` for native configs, `agentsmesh install <source>` or `install --sync` for reusable packs, then run `agentsmesh generate`. Use `diff`, `lint`, `check`, `watch`, `matrix`, `merge`, and `refresh` as needed.";
|
|
1065
1067
|
LEGACY_AGENTSMESH_ROOT_INSTRUCTION_PARAGRAPH = ROOT_INSTRUCTION_BODY_V1;
|
|
1066
1068
|
LEGACY_AGENTSMESH_ROOT_INSTRUCTION_SECTION = `## Project-Specific Rules
|
|
1067
1069
|
|
|
@@ -1090,12 +1092,20 @@ ${ROOT_INSTRUCTION_BODY_V7}`;
|
|
|
1090
1092
|
AGENTSMESH_CONTRACT_WITH_V8_BODY = `## AgentsMesh Generation Contract
|
|
1091
1093
|
|
|
1092
1094
|
${ROOT_INSTRUCTION_BODY_V8}`;
|
|
1095
|
+
AGENTSMESH_CONTRACT_WITH_V9_BODY = `## AgentsMesh Generation Contract
|
|
1096
|
+
|
|
1097
|
+
${ROOT_INSTRUCTION_BODY_V9}`;
|
|
1098
|
+
AGENTSMESH_CONTRACT_WITH_V10_BODY = `## AgentsMesh Generation Contract
|
|
1099
|
+
|
|
1100
|
+
${ROOT_INSTRUCTION_BODY_V10}`;
|
|
1093
1101
|
AGENTSMESH_ROOT_INSTRUCTION_PARAGRAPH = `${ROOT_CONTRACT_START}
|
|
1094
1102
|
## AgentsMesh Generation Contract
|
|
1095
1103
|
|
|
1096
1104
|
${ROOT_INSTRUCTION_BODY}
|
|
1097
1105
|
${ROOT_CONTRACT_END}`;
|
|
1098
1106
|
LEGACY_FORMS = [
|
|
1107
|
+
AGENTSMESH_CONTRACT_WITH_V10_BODY,
|
|
1108
|
+
AGENTSMESH_CONTRACT_WITH_V9_BODY,
|
|
1099
1109
|
AGENTSMESH_CONTRACT_WITH_V8_BODY,
|
|
1100
1110
|
AGENTSMESH_CONTRACT_WITH_V7_BODY,
|
|
1101
1111
|
AGENTSMESH_CONTRACT_WITH_V6_BODY,
|
|
@@ -15900,9 +15910,18 @@ function generateIgnore12(canonical) {
|
|
|
15900
15910
|
if (!canonical.ignore || canonical.ignore.length === 0) return [];
|
|
15901
15911
|
return [{ path: QWEN_IGNORE, content: canonical.ignore.join("\n") }];
|
|
15902
15912
|
}
|
|
15913
|
+
function renderQwenGlobalInstructions(canonical) {
|
|
15914
|
+
const root = canonical.rules.find((rule) => rule.root);
|
|
15915
|
+
const nonRootRules = canonical.rules.filter((rule) => {
|
|
15916
|
+
if (rule.root) return false;
|
|
15917
|
+
return rule.targets.length === 0 || rule.targets.includes(QWEN_CODE_TARGET);
|
|
15918
|
+
});
|
|
15919
|
+
return appendEmbeddedRulesBlock(root?.body.trim() ?? "", nonRootRules);
|
|
15920
|
+
}
|
|
15903
15921
|
var init_generator26 = __esm({
|
|
15904
15922
|
"src/targets/qwen-code/generator.ts"() {
|
|
15905
15923
|
init_markdown();
|
|
15924
|
+
init_managed_blocks();
|
|
15906
15925
|
init_constants21();
|
|
15907
15926
|
}
|
|
15908
15927
|
});
|
|
@@ -15985,6 +16004,7 @@ var init_qwen_code2 = __esm({
|
|
|
15985
16004
|
};
|
|
15986
16005
|
globalLayout22 = {
|
|
15987
16006
|
rootInstructionPath: QWEN_GLOBAL_ROOT,
|
|
16007
|
+
renderPrimaryRootInstruction: renderQwenGlobalInstructions,
|
|
15988
16008
|
skillDir: QWEN_GLOBAL_SKILLS_DIR,
|
|
15989
16009
|
managedOutputs: {
|
|
15990
16010
|
dirs: [QWEN_GLOBAL_COMMANDS_DIR, QWEN_GLOBAL_AGENTS_DIR, QWEN_GLOBAL_SKILLS_DIR],
|
|
@@ -22565,6 +22585,104 @@ function lintRuleScopeInversion(input) {
|
|
|
22565
22585
|
}
|
|
22566
22586
|
return out2;
|
|
22567
22587
|
}
|
|
22588
|
+
var TriggersSchema = z.object({
|
|
22589
|
+
file_globs: z.array(z.string()),
|
|
22590
|
+
command_patterns: z.array(z.string()),
|
|
22591
|
+
keywords: z.array(z.string())
|
|
22592
|
+
}).refine((t) => t.file_globs.length + t.command_patterns.length + t.keywords.length > 0, {
|
|
22593
|
+
message: "cluster must declare at least one trigger of any type"
|
|
22594
|
+
});
|
|
22595
|
+
var ClusterSchema = z.object({
|
|
22596
|
+
topic: z.string().regex(/^[a-z0-9-]+$/, "topic must be kebab-case"),
|
|
22597
|
+
/**
|
|
22598
|
+
* Project-relative path (forward slashes) to the cluster's markdown body.
|
|
22599
|
+
* Conventionally `.agentsmesh/lessons/topics/<topic>.md`, but any project
|
|
22600
|
+
* path is accepted — universal across every agent target.
|
|
22601
|
+
*/
|
|
22602
|
+
file: z.string().regex(/\.md$/, "file must be a .md path"),
|
|
22603
|
+
summary: z.string().min(1),
|
|
22604
|
+
triggers: TriggersSchema
|
|
22605
|
+
});
|
|
22606
|
+
var LessonsIndexSchema = z.object({
|
|
22607
|
+
version: z.literal(1),
|
|
22608
|
+
/**
|
|
22609
|
+
* Zero clusters is valid — supports `agentsmesh init --lessons` scaffolding a
|
|
22610
|
+
* fresh project. Topics accumulate via `distill:apply` as failures are
|
|
22611
|
+
* captured.
|
|
22612
|
+
*/
|
|
22613
|
+
clusters: z.array(ClusterSchema)
|
|
22614
|
+
});
|
|
22615
|
+
var BASE_REL = ".agentsmesh/lessons";
|
|
22616
|
+
function lessonsPaths(projectRoot) {
|
|
22617
|
+
const base = join(projectRoot, BASE_REL);
|
|
22618
|
+
return {
|
|
22619
|
+
base,
|
|
22620
|
+
journal: join(base, "journal.md"),
|
|
22621
|
+
index: join(base, "index.yaml"),
|
|
22622
|
+
ledger: join(base, "distill-ledger.yaml"),
|
|
22623
|
+
proposal: join(base, "distill-proposal.md"),
|
|
22624
|
+
topicsDir: join(base, "topics")
|
|
22625
|
+
};
|
|
22626
|
+
}
|
|
22627
|
+
|
|
22628
|
+
// src/core/lint/shared/lessons.ts
|
|
22629
|
+
var LESSONS_TARGET = "lessons";
|
|
22630
|
+
var INDEX_REL = ".agentsmesh/lessons/index.yaml";
|
|
22631
|
+
var ROOT_RULE_REL = ".agentsmesh/rules/_root.md";
|
|
22632
|
+
var LESSONS_HEADING = /^## Lessons \(/m;
|
|
22633
|
+
var RULES_HEADING = /^## Rules\b/m;
|
|
22634
|
+
function lintLessonsSubsystem(projectRoot, scope) {
|
|
22635
|
+
if (scope === "global") return [];
|
|
22636
|
+
const paths = lessonsPaths(projectRoot);
|
|
22637
|
+
if (!existsSync(paths.index)) return [];
|
|
22638
|
+
const out2 = [];
|
|
22639
|
+
const parsed = LessonsIndexSchema.safeParse(parse(readFileSync(paths.index, "utf8")));
|
|
22640
|
+
if (!parsed.success) {
|
|
22641
|
+
return [diag("error", INDEX_REL, `index.yaml is invalid: ${parsed.error.issues[0].message}`)];
|
|
22642
|
+
}
|
|
22643
|
+
for (const cluster of parsed.data.clusters) {
|
|
22644
|
+
const topicAbs = join(projectRoot, cluster.file);
|
|
22645
|
+
if (!existsSync(topicAbs)) {
|
|
22646
|
+
out2.push(
|
|
22647
|
+
diag("error", cluster.file, `topic file for cluster "${cluster.topic}" does not exist.`)
|
|
22648
|
+
);
|
|
22649
|
+
continue;
|
|
22650
|
+
}
|
|
22651
|
+
if (!RULES_HEADING.test(readFileSync(topicAbs, "utf8"))) {
|
|
22652
|
+
out2.push(
|
|
22653
|
+
diag("warning", cluster.file, `topic "${cluster.topic}" is missing a "## Rules" section.`)
|
|
22654
|
+
);
|
|
22655
|
+
}
|
|
22656
|
+
for (const pattern of cluster.triggers.command_patterns) {
|
|
22657
|
+
try {
|
|
22658
|
+
new RegExp(pattern);
|
|
22659
|
+
} catch {
|
|
22660
|
+
out2.push(
|
|
22661
|
+
diag(
|
|
22662
|
+
"warning",
|
|
22663
|
+
INDEX_REL,
|
|
22664
|
+
`cluster "${cluster.topic}" command_patterns entry is not a valid regex: ${pattern}`
|
|
22665
|
+
)
|
|
22666
|
+
);
|
|
22667
|
+
}
|
|
22668
|
+
}
|
|
22669
|
+
}
|
|
22670
|
+
const rootRuleAbs = join(projectRoot, ROOT_RULE_REL);
|
|
22671
|
+
const rootRuleBody = existsSync(rootRuleAbs) ? readFileSync(rootRuleAbs, "utf8") : "";
|
|
22672
|
+
if (!LESSONS_HEADING.test(rootRuleBody)) {
|
|
22673
|
+
out2.push(
|
|
22674
|
+
diag(
|
|
22675
|
+
"warning",
|
|
22676
|
+
ROOT_RULE_REL,
|
|
22677
|
+
'lessons procedural rule ("## Lessons (...)") is missing from _root.md \u2014 recall/capture enforcement will not fire.'
|
|
22678
|
+
)
|
|
22679
|
+
);
|
|
22680
|
+
}
|
|
22681
|
+
return out2;
|
|
22682
|
+
}
|
|
22683
|
+
function diag(level, file, message) {
|
|
22684
|
+
return { level, file, target: LESSONS_TARGET, message };
|
|
22685
|
+
}
|
|
22568
22686
|
|
|
22569
22687
|
// src/core/lint/linter.ts
|
|
22570
22688
|
var EXCLUDE_DIRS = ["node_modules", ".git", "dist", "coverage", ".agentsmesh"];
|
|
@@ -22585,7 +22703,7 @@ async function runLint(config, canonical, projectRoot, targetFilter, options = {
|
|
|
22585
22703
|
const hasMcp = config.features.includes("mcp");
|
|
22586
22704
|
const hasPermissions = config.features.includes("permissions");
|
|
22587
22705
|
const hasHooks = config.features.includes("hooks");
|
|
22588
|
-
const diagnostics = [];
|
|
22706
|
+
const diagnostics = [...lintLessonsSubsystem(projectRoot, scope)];
|
|
22589
22707
|
const projectFiles = scope === "global" ? [] : await getProjectFiles(projectRoot);
|
|
22590
22708
|
for (const target31 of targets) {
|
|
22591
22709
|
const fullDesc = getDescriptor(target31);
|