agentsmesh 0.19.1 → 0.21.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 +87 -0
- package/README.md +31 -1
- package/dist/canonical.js +66 -13
- package/dist/canonical.js.map +1 -1
- package/dist/cli.js +165 -160
- package/dist/engine.js +66 -13
- package/dist/engine.js.map +1 -1
- package/dist/index.js +66 -13
- package/dist/index.js.map +1 -1
- package/dist/targets.js +7 -2
- package/dist/targets.js.map +1 -1
- package/package.json +2 -2
- package/schemas/installs.json +7 -0
package/dist/engine.js
CHANGED
|
@@ -768,6 +768,33 @@ async function readDirRecursive(dir, visited, branchSegments) {
|
|
|
768
768
|
);
|
|
769
769
|
}
|
|
770
770
|
}
|
|
771
|
+
async function readDirRecursiveNoSymlinks(dir, branchSegments) {
|
|
772
|
+
const currentBranchSegments = branchSegments ?? [basename(dir)];
|
|
773
|
+
try {
|
|
774
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
775
|
+
const files = [];
|
|
776
|
+
for (const ent of entries) {
|
|
777
|
+
if (ent.isSymbolicLink()) continue;
|
|
778
|
+
const full = join(dir, ent.name);
|
|
779
|
+
if (ent.isDirectory()) {
|
|
780
|
+
const nextSegments = [...currentBranchSegments, ent.name];
|
|
781
|
+
if (shouldSkipRecursiveBranch(nextSegments)) continue;
|
|
782
|
+
files.push(...await readDirRecursiveNoSymlinks(full, nextSegments));
|
|
783
|
+
} else if (ent.isFile()) {
|
|
784
|
+
files.push(full);
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
return files;
|
|
788
|
+
} catch (err) {
|
|
789
|
+
const e = err;
|
|
790
|
+
if (e.code === "ENOENT" || e.code === "ENOTDIR" || e.code === "EACCES") return [];
|
|
791
|
+
throw new FileSystemError(
|
|
792
|
+
dir,
|
|
793
|
+
`Failed to read directory ${dir}: ${e.message}. Check permissions.`,
|
|
794
|
+
{ cause: err, errnoCode: e.code }
|
|
795
|
+
);
|
|
796
|
+
}
|
|
797
|
+
}
|
|
771
798
|
var MAX_RECURSIVE_DEPTH, MAX_SEGMENT_REPETITIONS;
|
|
772
799
|
var init_fs_traverse = __esm({
|
|
773
800
|
"src/utils/filesystem/fs-traverse.ts"() {
|
|
@@ -1022,7 +1049,7 @@ ${legacy}`, "");
|
|
|
1022
1049
|
}
|
|
1023
1050
|
return result.trim();
|
|
1024
1051
|
}
|
|
1025
|
-
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, 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_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, 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;
|
|
1026
1053
|
var init_root_instruction_paragraph = __esm({
|
|
1027
1054
|
"src/targets/projection/root-instruction-paragraph.ts"() {
|
|
1028
1055
|
init_managed_blocks();
|
|
@@ -1033,7 +1060,8 @@ var init_root_instruction_paragraph = __esm({
|
|
|
1033
1060
|
ROOT_INSTRUCTION_BODY_V5 = "Use Claude-style Markdown in `.agentsmesh`: `agents/*.md`, `commands/*.md`, and `skills/*/SKILL.md`; keep rules in `rules/*.md`, hooks in `hooks.yaml`, MCP in `mcp.json`, permissions in `permissions.yaml`, and ignore patterns in `ignore`, then run `agentsmesh generate`.";
|
|
1034
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`.";
|
|
1035
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`.";
|
|
1036
|
-
|
|
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.";
|
|
1037
1065
|
LEGACY_AGENTSMESH_ROOT_INSTRUCTION_PARAGRAPH = ROOT_INSTRUCTION_BODY_V1;
|
|
1038
1066
|
LEGACY_AGENTSMESH_ROOT_INSTRUCTION_SECTION = `## Project-Specific Rules
|
|
1039
1067
|
|
|
@@ -1059,12 +1087,16 @@ ${ROOT_INSTRUCTION_BODY_V6}`;
|
|
|
1059
1087
|
AGENTSMESH_CONTRACT_WITH_V7_BODY = `## AgentsMesh Generation Contract
|
|
1060
1088
|
|
|
1061
1089
|
${ROOT_INSTRUCTION_BODY_V7}`;
|
|
1090
|
+
AGENTSMESH_CONTRACT_WITH_V8_BODY = `## AgentsMesh Generation Contract
|
|
1091
|
+
|
|
1092
|
+
${ROOT_INSTRUCTION_BODY_V8}`;
|
|
1062
1093
|
AGENTSMESH_ROOT_INSTRUCTION_PARAGRAPH = `${ROOT_CONTRACT_START}
|
|
1063
1094
|
## AgentsMesh Generation Contract
|
|
1064
1095
|
|
|
1065
1096
|
${ROOT_INSTRUCTION_BODY}
|
|
1066
1097
|
${ROOT_CONTRACT_END}`;
|
|
1067
1098
|
LEGACY_FORMS = [
|
|
1099
|
+
AGENTSMESH_CONTRACT_WITH_V8_BODY,
|
|
1068
1100
|
AGENTSMESH_CONTRACT_WITH_V7_BODY,
|
|
1069
1101
|
AGENTSMESH_CONTRACT_WITH_V6_BODY,
|
|
1070
1102
|
AGENTSMESH_CONTRACT_WITH_V5_BODY,
|
|
@@ -20142,6 +20174,19 @@ init_fs();
|
|
|
20142
20174
|
|
|
20143
20175
|
// src/config/remote/git-remote.ts
|
|
20144
20176
|
init_fs();
|
|
20177
|
+
|
|
20178
|
+
// src/utils/output/redact-url-secrets.ts
|
|
20179
|
+
var URL_WITH_CREDENTIALS = /([a-zA-Z][a-zA-Z0-9+.-]*:\/\/)([^/@\s"'<>]+)@([^\s"'<>]+)/g;
|
|
20180
|
+
function redactUrlSecrets(message) {
|
|
20181
|
+
return message.replace(
|
|
20182
|
+
URL_WITH_CREDENTIALS,
|
|
20183
|
+
(_full, scheme, _userinfo, rest) => {
|
|
20184
|
+
return `${scheme}***@${rest}`;
|
|
20185
|
+
}
|
|
20186
|
+
);
|
|
20187
|
+
}
|
|
20188
|
+
|
|
20189
|
+
// src/config/remote/git-remote.ts
|
|
20145
20190
|
var execFileAsync = promisify(execFile);
|
|
20146
20191
|
var REPO_DIRNAME = "repo";
|
|
20147
20192
|
function ensureNotFlag(value, kind) {
|
|
@@ -20175,12 +20220,13 @@ async function fetchGitRemoteExtend(parsed, extendName, options, cacheDir, build
|
|
|
20175
20220
|
await rm(stagedRoot, { recursive: true, force: true });
|
|
20176
20221
|
const allowFallback = options.allowOfflineFallback !== false;
|
|
20177
20222
|
if (allowFallback && await hasCachedRepo(cacheRepoDir)) {
|
|
20223
|
+
const rawMsg = err instanceof Error ? err.message : String(err);
|
|
20178
20224
|
console.warn(
|
|
20179
|
-
`[agentsmesh] Remote fetch failed for ${extendName}; using cached version. Error: ${
|
|
20225
|
+
`[agentsmesh] Remote fetch failed for ${extendName}; using cached version. Error: ${redactUrlSecrets(rawMsg)}`
|
|
20180
20226
|
);
|
|
20181
20227
|
return readCachedRepo(cacheRepoDir);
|
|
20182
20228
|
}
|
|
20183
|
-
throw err;
|
|
20229
|
+
throw err instanceof Error ? Object.assign(new Error(redactUrlSecrets(err.message)), { cause: err.cause }) : err;
|
|
20184
20230
|
}
|
|
20185
20231
|
}
|
|
20186
20232
|
async function readCachedRepo(repoDir) {
|
|
@@ -20341,13 +20387,14 @@ async function fetchGithubRemoteExtend(parsed, extendName, options, cacheDir, bu
|
|
|
20341
20387
|
if (allowFallback && await exists(extractDir)) {
|
|
20342
20388
|
const topDir2 = await findExtractTopDir(extractDir);
|
|
20343
20389
|
if (topDir2) {
|
|
20390
|
+
const rawMsg = err instanceof Error ? err.message : String(err);
|
|
20344
20391
|
console.warn(
|
|
20345
|
-
`[agentsmesh] Network failed for ${extendName}; using cached version. Error: ${
|
|
20392
|
+
`[agentsmesh] Network failed for ${extendName}; using cached version. Error: ${redactUrlSecrets(rawMsg)}`
|
|
20346
20393
|
);
|
|
20347
20394
|
return { resolvedPath: join(extractDir, topDir2), version: tag };
|
|
20348
20395
|
}
|
|
20349
20396
|
}
|
|
20350
|
-
throw err;
|
|
20397
|
+
throw err instanceof Error ? Object.assign(new Error(redactUrlSecrets(err.message)), { cause: err.cause }) : err;
|
|
20351
20398
|
}
|
|
20352
20399
|
await rm(extractDir, { recursive: true, force: true });
|
|
20353
20400
|
await mkdir(extractDir, { recursive: true });
|
|
@@ -20358,12 +20405,14 @@ async function fetchGithubRemoteExtend(parsed, extendName, options, cacheDir, bu
|
|
|
20358
20405
|
file: tarPath,
|
|
20359
20406
|
cwd: extractDir,
|
|
20360
20407
|
strict: true,
|
|
20408
|
+
// Allowlist entry types instead of denylist: only `File` and `Directory`
|
|
20409
|
+
// can be extracted. Hardlinks (`Link`), symlinks (`SymbolicLink`), FIFOs,
|
|
20410
|
+
// character/block devices, and any future/exotic tar entry type are
|
|
20411
|
+
// rejected. A denylist would silently let an unknown variant through.
|
|
20361
20412
|
filter: (entryPath, entry) => {
|
|
20362
20413
|
if (isZipSlipPath(entryPath)) return false;
|
|
20363
|
-
|
|
20364
|
-
|
|
20365
|
-
}
|
|
20366
|
-
return true;
|
|
20414
|
+
const type = entry && "type" in entry ? entry.type : void 0;
|
|
20415
|
+
return type === "File" || type === "Directory";
|
|
20367
20416
|
}
|
|
20368
20417
|
});
|
|
20369
20418
|
} finally {
|
|
@@ -20461,8 +20510,11 @@ function parseGitSource(source) {
|
|
|
20461
20510
|
return null;
|
|
20462
20511
|
}
|
|
20463
20512
|
const allowInsecure = process.env.AGENTSMESH_ALLOW_INSECURE_GIT === "1" || process.env.AGENTSMESH_ALLOW_INSECURE_GIT === "true";
|
|
20464
|
-
const
|
|
20465
|
-
|
|
20513
|
+
const allowLocalGit = process.env.AGENTSMESH_ALLOW_LOCAL_GIT === "1" || process.env.AGENTSMESH_ALLOW_LOCAL_GIT === "true";
|
|
20514
|
+
const allowed = ["https:", "ssh:"];
|
|
20515
|
+
if (allowInsecure) allowed.push("http:");
|
|
20516
|
+
if (allowLocalGit) allowed.push("file:");
|
|
20517
|
+
if (!allowed.includes(parsedUrl.protocol)) {
|
|
20466
20518
|
return null;
|
|
20467
20519
|
}
|
|
20468
20520
|
return { url, ref };
|
|
@@ -20921,6 +20973,7 @@ async function parseAgents(agentsDir, opts = {}) {
|
|
|
20921
20973
|
|
|
20922
20974
|
// src/canonical/features/skills.ts
|
|
20923
20975
|
init_fs();
|
|
20976
|
+
init_fs_traverse();
|
|
20924
20977
|
init_markdown();
|
|
20925
20978
|
init_boilerplate_filter();
|
|
20926
20979
|
async function readContent(path) {
|
|
@@ -20939,7 +20992,7 @@ function sanitizeSkillName(raw) {
|
|
|
20939
20992
|
return raw.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
20940
20993
|
}
|
|
20941
20994
|
async function listSupportingFiles(skillDir) {
|
|
20942
|
-
const files = await
|
|
20995
|
+
const files = await readDirRecursiveNoSymlinks(skillDir);
|
|
20943
20996
|
const result = [];
|
|
20944
20997
|
for (const absPath of files) {
|
|
20945
20998
|
const raw = absPath.slice(skillDir.length + 1);
|