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/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 { constants, existsSync, realpathSync, statSync, readFileSync } from 'fs';
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
- ROOT_INSTRUCTION_BODY = "`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.";
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);