agentsmesh 0.33.0 → 0.34.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 +20 -0
- package/README.md +72 -121
- package/dist/canonical.js +491 -274
- package/dist/canonical.js.map +1 -1
- package/dist/cli.js +254 -253
- package/dist/engine.d.ts +1 -1
- package/dist/engine.js +569 -242
- package/dist/engine.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +772 -401
- package/dist/index.js.map +1 -1
- package/dist/{init-rvKjGLTB.d.ts → init-ChDbKSJ0.d.ts} +8 -8
- package/dist/lessons.d.ts +2 -2
- package/dist/lessons.js +1121 -973
- package/dist/lessons.js.map +1 -1
- package/dist/{target-descriptor-DeS4XOtV.d.ts → target-descriptor-DtgeHKPG.d.ts} +7 -0
- package/dist/targets.d.ts +2 -2
- package/dist/targets.js +331 -110
- package/dist/targets.js.map +1 -1
- package/package.json +27 -22
package/dist/canonical.js
CHANGED
|
@@ -24,7 +24,7 @@ var __export = (target34, all) => {
|
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
// src/core/errors.ts
|
|
27
|
-
var AgentsMeshError, ConfigNotFoundError, ConfigValidationError, FileSystemError;
|
|
27
|
+
var AgentsMeshError, ConfigNotFoundError, ConfigValidationError, CanonicalParseError, FileSystemError;
|
|
28
28
|
var init_errors = __esm({
|
|
29
29
|
"src/core/errors.ts"() {
|
|
30
30
|
AgentsMeshError = class extends Error {
|
|
@@ -59,6 +59,21 @@ var init_errors = __esm({
|
|
|
59
59
|
this.issues = issues;
|
|
60
60
|
}
|
|
61
61
|
};
|
|
62
|
+
CanonicalParseError = class extends AgentsMeshError {
|
|
63
|
+
path;
|
|
64
|
+
constructor(path, cause) {
|
|
65
|
+
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
66
|
+
super(
|
|
67
|
+
"AM_CONFIG_INVALID",
|
|
68
|
+
`Invalid canonical file ${path}: ${detail}. Fix the syntax and try again.`,
|
|
69
|
+
{
|
|
70
|
+
cause
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
this.name = "CanonicalParseError";
|
|
74
|
+
this.path = path;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
62
77
|
FileSystemError = class extends AgentsMeshError {
|
|
63
78
|
path;
|
|
64
79
|
errnoCode;
|
|
@@ -332,24 +347,28 @@ var init_fs = __esm({
|
|
|
332
347
|
}
|
|
333
348
|
});
|
|
334
349
|
function parseFrontmatter(content) {
|
|
335
|
-
const
|
|
336
|
-
if (
|
|
337
|
-
|
|
338
|
-
}
|
|
339
|
-
const close = content.indexOf("---", 3);
|
|
340
|
-
if (close === -1) {
|
|
341
|
-
return { frontmatter: {}, body: content.trim() };
|
|
342
|
-
}
|
|
343
|
-
const yamlStr = content.slice(3, close).trim();
|
|
344
|
-
const body = content.slice(close + 3).trim();
|
|
350
|
+
const split = splitFrontmatter(content);
|
|
351
|
+
if (split === null) return { frontmatter: {}, body: content.trim() };
|
|
352
|
+
const yamlStr = split.yaml.trim();
|
|
345
353
|
const frontmatter = yamlStr === "" ? {} : parse(yamlStr) ?? {};
|
|
346
|
-
return { frontmatter, body };
|
|
354
|
+
return { frontmatter, body: split.body };
|
|
355
|
+
}
|
|
356
|
+
function splitFrontmatter(content) {
|
|
357
|
+
const opener = OPENER.exec(content);
|
|
358
|
+
if (opener === null) return null;
|
|
359
|
+
const yamlStart = opener[0].length;
|
|
360
|
+
const closer = CLOSER.exec(content.slice(yamlStart));
|
|
361
|
+
if (closer === null) return null;
|
|
362
|
+
const closeStart = yamlStart + closer.index;
|
|
363
|
+
const closeEnd = closeStart + closer[0].length;
|
|
364
|
+
return {
|
|
365
|
+
yaml: content.slice(yamlStart, closeStart),
|
|
366
|
+
body: content.slice(closeEnd).trim(),
|
|
367
|
+
prefix: content.slice(0, closeEnd)
|
|
368
|
+
};
|
|
347
369
|
}
|
|
348
370
|
function extractBody(content) {
|
|
349
|
-
|
|
350
|
-
const close = content.indexOf("---", 3);
|
|
351
|
-
if (close === -1) return content.trim();
|
|
352
|
-
return content.slice(close + 3).trim();
|
|
371
|
+
return splitFrontmatter(content)?.body ?? content.trim();
|
|
353
372
|
}
|
|
354
373
|
function tryParseFrontmatter(content, filePath2) {
|
|
355
374
|
try {
|
|
@@ -381,8 +400,11 @@ ${yamlStr}
|
|
|
381
400
|
|
|
382
401
|
${body}`;
|
|
383
402
|
}
|
|
403
|
+
var OPENER, CLOSER;
|
|
384
404
|
var init_markdown = __esm({
|
|
385
405
|
"src/utils/text/markdown.ts"() {
|
|
406
|
+
OPENER = /^---[ \t]*\r?\n/;
|
|
407
|
+
CLOSER = /^---[ \t]*\r?$/m;
|
|
386
408
|
}
|
|
387
409
|
});
|
|
388
410
|
|
|
@@ -465,6 +487,21 @@ var init_boilerplate_filter = __esm({
|
|
|
465
487
|
}
|
|
466
488
|
});
|
|
467
489
|
|
|
490
|
+
// src/canonical/features/syntax-error.ts
|
|
491
|
+
function failSyntax(filePath2, cause, onParseError) {
|
|
492
|
+
const error = new CanonicalParseError(filePath2, cause);
|
|
493
|
+
if (onParseError !== void 0) {
|
|
494
|
+
onParseError(error, filePath2);
|
|
495
|
+
return null;
|
|
496
|
+
}
|
|
497
|
+
throw error;
|
|
498
|
+
}
|
|
499
|
+
var init_syntax_error = __esm({
|
|
500
|
+
"src/canonical/features/syntax-error.ts"() {
|
|
501
|
+
init_errors();
|
|
502
|
+
}
|
|
503
|
+
});
|
|
504
|
+
|
|
468
505
|
// src/canonical/features/mcp.ts
|
|
469
506
|
function parseStringMap(raw) {
|
|
470
507
|
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return {};
|
|
@@ -547,14 +584,14 @@ function stripJsonComments(text) {
|
|
|
547
584
|
}
|
|
548
585
|
return result2;
|
|
549
586
|
}
|
|
550
|
-
async function parseMcp(mcpPath) {
|
|
587
|
+
async function parseMcp(mcpPath, onParseError) {
|
|
551
588
|
const content = await readFileSafe(mcpPath);
|
|
552
589
|
if (!content) return null;
|
|
553
590
|
let parsed;
|
|
554
591
|
try {
|
|
555
592
|
parsed = JSON.parse(stripJsonComments(content));
|
|
556
|
-
} catch {
|
|
557
|
-
return
|
|
593
|
+
} catch (err) {
|
|
594
|
+
return failSyntax(mcpPath, err, onParseError);
|
|
558
595
|
}
|
|
559
596
|
if (!parsed || typeof parsed !== "object") return null;
|
|
560
597
|
const mcpServersRaw = parsed.mcpServers;
|
|
@@ -569,6 +606,7 @@ async function parseMcp(mcpPath) {
|
|
|
569
606
|
}
|
|
570
607
|
var init_mcp = __esm({
|
|
571
608
|
"src/canonical/features/mcp.ts"() {
|
|
609
|
+
init_syntax_error();
|
|
572
610
|
init_fs();
|
|
573
611
|
}
|
|
574
612
|
});
|
|
@@ -598,6 +636,57 @@ var init_hook_command = __esm({
|
|
|
598
636
|
"src/core/hook-command.ts"() {
|
|
599
637
|
}
|
|
600
638
|
});
|
|
639
|
+
function toHookEntry(raw) {
|
|
640
|
+
if (!raw || typeof raw !== "object") return null;
|
|
641
|
+
const obj = raw;
|
|
642
|
+
const matcher = obj.matcher;
|
|
643
|
+
if (typeof matcher !== "string") return null;
|
|
644
|
+
const command = getHookText(obj);
|
|
645
|
+
if (!command) return null;
|
|
646
|
+
const type = typeof obj.type === "string" && VALID_TYPES.includes(obj.type) ? obj.type : void 0;
|
|
647
|
+
const timeout = typeof obj.timeout === "number" && Number.isFinite(obj.timeout) ? obj.timeout : void 0;
|
|
648
|
+
const prompt = getHookPrompt(obj) || void 0;
|
|
649
|
+
return {
|
|
650
|
+
matcher,
|
|
651
|
+
command,
|
|
652
|
+
...timeout !== void 0 && { timeout },
|
|
653
|
+
...type && { type },
|
|
654
|
+
...prompt && { prompt }
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
async function parseHooks(hooksPath, onParseError) {
|
|
658
|
+
const content = await readFileSafe(hooksPath);
|
|
659
|
+
if (content === null) return null;
|
|
660
|
+
if (!content.trim()) return {};
|
|
661
|
+
let parsed;
|
|
662
|
+
try {
|
|
663
|
+
parsed = parse(content);
|
|
664
|
+
} catch (err) {
|
|
665
|
+
return failSyntax(hooksPath, err, onParseError);
|
|
666
|
+
}
|
|
667
|
+
if (!parsed || typeof parsed !== "object") return null;
|
|
668
|
+
const result2 = {};
|
|
669
|
+
const obj = parsed;
|
|
670
|
+
for (const [key, val] of Object.entries(obj)) {
|
|
671
|
+
if (!Array.isArray(val)) continue;
|
|
672
|
+
const entries = [];
|
|
673
|
+
for (const item of val) {
|
|
674
|
+
const entry = toHookEntry(item);
|
|
675
|
+
if (entry) entries.push(entry);
|
|
676
|
+
}
|
|
677
|
+
if (entries.length > 0) result2[key] = entries;
|
|
678
|
+
}
|
|
679
|
+
return result2;
|
|
680
|
+
}
|
|
681
|
+
var VALID_TYPES;
|
|
682
|
+
var init_hooks = __esm({
|
|
683
|
+
"src/canonical/features/hooks.ts"() {
|
|
684
|
+
init_syntax_error();
|
|
685
|
+
init_fs();
|
|
686
|
+
init_hook_command();
|
|
687
|
+
VALID_TYPES = ["command", "prompt"];
|
|
688
|
+
}
|
|
689
|
+
});
|
|
601
690
|
function capabilityLevel(capability) {
|
|
602
691
|
return typeof capability === "string" ? capability : capability.level;
|
|
603
692
|
}
|
|
@@ -665,8 +754,17 @@ var init_target_descriptor_schema = __esm({
|
|
|
665
754
|
managedOutputsSchema = z.object({
|
|
666
755
|
dirs: z.array(z.string()),
|
|
667
756
|
files: z.array(z.string()),
|
|
668
|
-
coOwnedFiles: z.array(z.string()).optional()
|
|
757
|
+
coOwnedFiles: z.array(z.string()).optional(),
|
|
758
|
+
supersededFiles: z.array(z.string()).optional()
|
|
669
759
|
}).passthrough().superRefine((value, ctx) => {
|
|
760
|
+
for (const file of value.supersededFiles ?? []) {
|
|
761
|
+
if (!value.files.includes(file) && !(value.coOwnedFiles ?? []).includes(file)) continue;
|
|
762
|
+
ctx.addIssue({
|
|
763
|
+
code: "custom",
|
|
764
|
+
path: ["supersededFiles"],
|
|
765
|
+
message: `"${file}" is in managedOutputs.supersededFiles and another managedOutputs list.`
|
|
766
|
+
});
|
|
767
|
+
}
|
|
670
768
|
for (const file of value.coOwnedFiles ?? []) {
|
|
671
769
|
if (!value.files.includes(file)) continue;
|
|
672
770
|
ctx.addIssue({
|
|
@@ -1007,11 +1105,25 @@ var init_command_skill = __esm({
|
|
|
1007
1105
|
LEGACY_CODEX_COMMAND_SKILL_PREFIX = "ab-command-";
|
|
1008
1106
|
}
|
|
1009
1107
|
});
|
|
1108
|
+
var RECALL_HOOK_COMMAND;
|
|
1109
|
+
var init_recall_hook_scaffold = __esm({
|
|
1110
|
+
"src/lessons/recall-hook-scaffold.ts"() {
|
|
1111
|
+
RECALL_HOOK_COMMAND = "agentsmesh lessons hook";
|
|
1112
|
+
}
|
|
1113
|
+
});
|
|
1010
1114
|
|
|
1011
1115
|
// src/core/hook-types.ts
|
|
1116
|
+
function isBestEffortHookEvent(event, entries) {
|
|
1117
|
+
if (!BEST_EFFORT_HOOK_EVENTS.has(event)) return false;
|
|
1118
|
+
if (!Array.isArray(entries)) return true;
|
|
1119
|
+
return entries.every(
|
|
1120
|
+
(entry) => typeof entry === "object" && entry !== null && typeof entry.command === "string" && entry.command.includes(RECALL_HOOK_COMMAND)
|
|
1121
|
+
);
|
|
1122
|
+
}
|
|
1012
1123
|
var BEST_EFFORT_HOOK_EVENTS;
|
|
1013
1124
|
var init_hook_types = __esm({
|
|
1014
1125
|
"src/core/hook-types.ts"() {
|
|
1126
|
+
init_recall_hook_scaffold();
|
|
1015
1127
|
BEST_EFFORT_HOOK_EVENTS = /* @__PURE__ */ new Set([
|
|
1016
1128
|
"UserPromptSubmit",
|
|
1017
1129
|
"PostToolUseFailure",
|
|
@@ -1409,6 +1521,7 @@ function extractEmbeddedRules(content) {
|
|
|
1409
1521
|
var ROOT_CONTRACT_START, ROOT_CONTRACT_END, EMBEDDED_RULES_START, EMBEDDED_RULES_END, EMBEDDED_RULE_END, EMBEDDED_RULE_START_PREFIX, EMBEDDED_RULE_START_SUFFIX;
|
|
1410
1522
|
var init_managed_blocks = __esm({
|
|
1411
1523
|
"src/targets/projection/managed-blocks.ts"() {
|
|
1524
|
+
init_markdown();
|
|
1412
1525
|
ROOT_CONTRACT_START = "<!-- agentsmesh:root-generation-contract:start -->";
|
|
1413
1526
|
ROOT_CONTRACT_END = "<!-- agentsmesh:root-generation-contract:end -->";
|
|
1414
1527
|
EMBEDDED_RULES_START = "<!-- agentsmesh:embedded-rules:start -->";
|
|
@@ -1570,10 +1683,17 @@ async function serializeImportedCommandWithFallback(destinationPath, imported, b
|
|
|
1570
1683
|
})();
|
|
1571
1684
|
const description = imported.hasDescription ? imported.description ?? "" : typeof existingFrontmatter.description === "string" ? existingFrontmatter.description : "";
|
|
1572
1685
|
const allowedTools = imported.hasAllowedTools ? imported.allowedTools ?? [] : existingAllowedTools;
|
|
1686
|
+
const {
|
|
1687
|
+
description: _d,
|
|
1688
|
+
"allowed-tools": _a,
|
|
1689
|
+
allowedTools: _c,
|
|
1690
|
+
...preserved
|
|
1691
|
+
} = existingFrontmatter;
|
|
1573
1692
|
return serializeFrontmatter(
|
|
1574
1693
|
{
|
|
1575
1694
|
description,
|
|
1576
|
-
"allowed-tools": allowedTools
|
|
1695
|
+
"allowed-tools": allowedTools,
|
|
1696
|
+
...preserved
|
|
1577
1697
|
},
|
|
1578
1698
|
body.trim() || ""
|
|
1579
1699
|
);
|
|
@@ -2471,6 +2591,26 @@ var init_link_rebaser_resolution = __esm({
|
|
|
2471
2591
|
}
|
|
2472
2592
|
});
|
|
2473
2593
|
|
|
2594
|
+
// src/core/reference/link-uri-encoding.ts
|
|
2595
|
+
function decodeLinkPath(token, role) {
|
|
2596
|
+
if (role !== "markdown-link-dest" || !token.includes("%")) return token;
|
|
2597
|
+
try {
|
|
2598
|
+
return decodeURIComponent(token);
|
|
2599
|
+
} catch {
|
|
2600
|
+
return token;
|
|
2601
|
+
}
|
|
2602
|
+
}
|
|
2603
|
+
function encodeLinkPath(path, enabled) {
|
|
2604
|
+
if (!enabled) return path;
|
|
2605
|
+
return path.split("/").map(
|
|
2606
|
+
(segment) => segment === "" || segment === "." || segment === ".." ? segment : encodeURIComponent(segment)
|
|
2607
|
+
).join("/");
|
|
2608
|
+
}
|
|
2609
|
+
var init_link_uri_encoding = __esm({
|
|
2610
|
+
"src/core/reference/link-uri-encoding.ts"() {
|
|
2611
|
+
}
|
|
2612
|
+
});
|
|
2613
|
+
|
|
2474
2614
|
// src/core/reference/link-token-guards.ts
|
|
2475
2615
|
function isTildeHomeRelativePathToken(fullContent, matchOffset, matchText) {
|
|
2476
2616
|
if (matchOffset >= 2 && fullContent[matchOffset - 2] === "~" && fullContent[matchOffset - 1] === "/") {
|
|
@@ -2600,10 +2740,11 @@ function rewriteFileLinks(input) {
|
|
|
2600
2740
|
const { candidate: punctStripped, suffix } = stripTrailingPunctuation(match);
|
|
2601
2741
|
if (!punctStripped) return match;
|
|
2602
2742
|
const lineNumMatch = LINE_NUMBER_SUFFIX.exec(punctStripped);
|
|
2603
|
-
const
|
|
2743
|
+
const rawCandidate = lineNumMatch ? punctStripped.slice(0, lineNumMatch.index) : punctStripped;
|
|
2604
2744
|
const lineNumSuffix = lineNumMatch ? lineNumMatch[0] : "";
|
|
2605
|
-
if (!
|
|
2606
|
-
const tokenContext = getTokenContext(fullContent, offset, offset +
|
|
2745
|
+
if (!rawCandidate) return match;
|
|
2746
|
+
const tokenContext = getTokenContext(fullContent, offset, offset + rawCandidate.length);
|
|
2747
|
+
const candidate = decodeLinkPath(rawCandidate, tokenContext.role);
|
|
2607
2748
|
if (tokenContext.role !== "markdown-link-dest" && WINDOWS_ABSOLUTE_PATH.test(candidate)) {
|
|
2608
2749
|
return match;
|
|
2609
2750
|
}
|
|
@@ -2673,7 +2814,7 @@ function rewriteFileLinks(input) {
|
|
|
2673
2814
|
const targetTop = targetFromRoot.split("/").filter(Boolean)[0] ?? "";
|
|
2674
2815
|
const tokenIsCanonicalMesh = normalizeSeparators(candidate).startsWith(".agentsmesh/");
|
|
2675
2816
|
const preferRelativeProseInSameSurface = !tokenIsCanonicalMesh && !targetIsDirectory && destTop.length > 0 && destTop === targetTop && destTop.startsWith(".") && destTop !== ".agentsmesh";
|
|
2676
|
-
const forceRelative = preferRelativeProseInSameSurface || tokenContext.role === "markdown-link-dest" || isMarkdownLinkDestinationToken(fullContent, offset,
|
|
2817
|
+
const forceRelative = preferRelativeProseInSameSurface || tokenContext.role === "markdown-link-dest" || isMarkdownLinkDestinationToken(fullContent, offset, rawCandidate);
|
|
2677
2818
|
const rewritten = formatLinkPathForDestination(
|
|
2678
2819
|
input.projectRoot,
|
|
2679
2820
|
input.destinationFile,
|
|
@@ -2690,7 +2831,7 @@ function rewriteFileLinks(input) {
|
|
|
2690
2831
|
}
|
|
2691
2832
|
);
|
|
2692
2833
|
if (!rewritten) return match;
|
|
2693
|
-
return `${rewritten}${lineNumSuffix}${suffix}`;
|
|
2834
|
+
return `${encodeLinkPath(rewritten, candidate !== rawCandidate)}${lineNumSuffix}${suffix}`;
|
|
2694
2835
|
});
|
|
2695
2836
|
return { content, missing: [...missing] };
|
|
2696
2837
|
}
|
|
@@ -2700,6 +2841,7 @@ var init_link_rebaser = __esm({
|
|
|
2700
2841
|
init_link_rebaser_helpers();
|
|
2701
2842
|
init_link_rebaser_output();
|
|
2702
2843
|
init_link_rebaser_resolution();
|
|
2844
|
+
init_link_uri_encoding();
|
|
2703
2845
|
init_link_token_guards();
|
|
2704
2846
|
init_link_token_context();
|
|
2705
2847
|
}
|
|
@@ -3504,7 +3646,7 @@ function unsupportedHookEventNames(hooks, supportedEvents) {
|
|
|
3504
3646
|
if (!hooks) return [];
|
|
3505
3647
|
const supported = new Set(supportedEvents);
|
|
3506
3648
|
return Object.keys(hooks).filter(
|
|
3507
|
-
(event) => !supported.has(event) && !
|
|
3649
|
+
(event) => !supported.has(event) && !isBestEffortHookEvent(event, hooks[event])
|
|
3508
3650
|
);
|
|
3509
3651
|
}
|
|
3510
3652
|
function createUnsupportedHookWarning(event, target34, supportedEvents, options) {
|
|
@@ -8816,10 +8958,10 @@ var init_claude_code2 = __esm({
|
|
|
8816
8958
|
skillDir: ".claude/skills",
|
|
8817
8959
|
managedOutputs: {
|
|
8818
8960
|
dirs: [".claude/agents", ".claude/commands", ".claude/rules", ".claude/skills"],
|
|
8819
|
-
|
|
8820
|
-
//
|
|
8961
|
+
files: [CLAUDE_ROOT, ".claudeignore"],
|
|
8962
|
+
// CLAUDE_NESTED_ROOT is the pre-migration project location: evicted once a run
|
|
8821
8963
|
// writes the root `CLAUDE.md`, so Claude Code never concatenates both into context.
|
|
8822
|
-
|
|
8964
|
+
supersededFiles: [CLAUDE_NESTED_ROOT],
|
|
8823
8965
|
// `.mcp.json` is the shared project MCP file teams hand-commit and
|
|
8824
8966
|
// deepagents-cli writes too; agentsmesh owns only `mcpServers` in it.
|
|
8825
8967
|
// `.claude/settings.json` is co-owned through the `SETTINGS_JSON_PATHS`
|
|
@@ -10050,9 +10192,8 @@ var init_cline2 = __esm({
|
|
|
10050
10192
|
};
|
|
10051
10193
|
}
|
|
10052
10194
|
});
|
|
10053
|
-
|
|
10054
|
-
|
|
10055
|
-
}
|
|
10195
|
+
|
|
10196
|
+
// src/targets/codex-cli/codex-rule-paths.ts
|
|
10056
10197
|
function directoryFromGlob(glob) {
|
|
10057
10198
|
let normalized = glob.trim();
|
|
10058
10199
|
if (normalized.startsWith("./")) normalized = normalized.slice(2);
|
|
@@ -10073,12 +10214,12 @@ function codexRuleDirectory(rule) {
|
|
|
10073
10214
|
const dir = directoryFromGlob(glob);
|
|
10074
10215
|
if (dir) return dir;
|
|
10075
10216
|
}
|
|
10076
|
-
return
|
|
10217
|
+
return null;
|
|
10077
10218
|
}
|
|
10078
10219
|
function codexNestedAgentsPath(rule) {
|
|
10079
10220
|
const dir = codexRuleDirectory(rule);
|
|
10080
10221
|
const filename = rule.codexInstructionVariant === "override" ? "AGENTS.override.md" : "AGENTS.md";
|
|
10081
|
-
return `${dir}/${filename}`;
|
|
10222
|
+
return dir === null ? filename : `${dir}/${filename}`;
|
|
10082
10223
|
}
|
|
10083
10224
|
var GLOB_METACHAR;
|
|
10084
10225
|
var init_codex_rule_paths = __esm({
|
|
@@ -10086,10 +10227,9 @@ var init_codex_rule_paths = __esm({
|
|
|
10086
10227
|
GLOB_METACHAR = /[*?[\]]/;
|
|
10087
10228
|
}
|
|
10088
10229
|
});
|
|
10089
|
-
|
|
10090
|
-
// src/targets/codebuff/rule-paths.ts
|
|
10091
10230
|
function codebuffNestedKnowledgePath(rule) {
|
|
10092
|
-
|
|
10231
|
+
const dir = codexRuleDirectory(rule) ?? basename(rule.source, ".md");
|
|
10232
|
+
return `${dir}/AGENTS.md`;
|
|
10093
10233
|
}
|
|
10094
10234
|
var init_rule_paths = __esm({
|
|
10095
10235
|
"src/targets/codebuff/rule-paths.ts"() {
|
|
@@ -10700,6 +10840,9 @@ function eligibleAdvisoryRules(canonical) {
|
|
|
10700
10840
|
return rule.targets.length === 0 || rule.targets.includes("codex-cli");
|
|
10701
10841
|
});
|
|
10702
10842
|
}
|
|
10843
|
+
function isRootEmbedded(rule) {
|
|
10844
|
+
return codexNestedAgentsPath(rule) === AGENTS_MD;
|
|
10845
|
+
}
|
|
10703
10846
|
function groupByNestedPath2(rules) {
|
|
10704
10847
|
const groups = /* @__PURE__ */ new Map();
|
|
10705
10848
|
for (const rule of rules) {
|
|
@@ -10712,9 +10855,11 @@ function groupByNestedPath2(rules) {
|
|
|
10712
10855
|
}
|
|
10713
10856
|
function generateRules9(canonical) {
|
|
10714
10857
|
const root = canonical.rules.find((r) => r.root);
|
|
10858
|
+
const advisory = eligibleAdvisoryRules(canonical);
|
|
10715
10859
|
const outputs = [];
|
|
10716
10860
|
if (root) {
|
|
10717
|
-
|
|
10861
|
+
const content = appendEmbeddedRulesBlock(root.body.trim(), advisory.filter(isRootEmbedded));
|
|
10862
|
+
outputs.push({ path: AGENTS_MD, content });
|
|
10718
10863
|
}
|
|
10719
10864
|
for (const rule of canonical.rules) {
|
|
10720
10865
|
if (rule.root) continue;
|
|
@@ -10726,7 +10871,8 @@ function generateRules9(canonical) {
|
|
|
10726
10871
|
content: toSafeCodexRulesContent(rule.body)
|
|
10727
10872
|
});
|
|
10728
10873
|
}
|
|
10729
|
-
|
|
10874
|
+
const nested = advisory.filter((rule) => !isRootEmbedded(rule));
|
|
10875
|
+
for (const [path, rules] of groupByNestedPath2(nested)) {
|
|
10730
10876
|
const content = rules.map((rule) => rule.body.trim()).filter((body) => body.length > 0).join("\n\n");
|
|
10731
10877
|
outputs.push({ path, content });
|
|
10732
10878
|
}
|
|
@@ -10953,7 +11099,7 @@ function generateHooks6(canonical) {
|
|
|
10953
11099
|
supportedEvents: CODEX_SUPPORTED_HOOK_EVENTS
|
|
10954
11100
|
});
|
|
10955
11101
|
}
|
|
10956
|
-
var
|
|
11102
|
+
var init_hooks2 = __esm({
|
|
10957
11103
|
"src/targets/codex-cli/generator/hooks.ts"() {
|
|
10958
11104
|
init_wrapped_command_hooks();
|
|
10959
11105
|
init_constants10();
|
|
@@ -11034,7 +11180,7 @@ var init_generator9 = __esm({
|
|
|
11034
11180
|
init_skills();
|
|
11035
11181
|
init_agents();
|
|
11036
11182
|
init_mcp2();
|
|
11037
|
-
|
|
11183
|
+
init_hooks2();
|
|
11038
11184
|
init_permissions();
|
|
11039
11185
|
}
|
|
11040
11186
|
});
|
|
@@ -11551,6 +11697,23 @@ var init_linter9 = __esm({
|
|
|
11551
11697
|
});
|
|
11552
11698
|
|
|
11553
11699
|
// src/targets/codex-cli/lint.ts
|
|
11700
|
+
function lintAgents3(canonical) {
|
|
11701
|
+
const diagnostics = [];
|
|
11702
|
+
for (const agent of canonical.agents) {
|
|
11703
|
+
const dropped = CODEX_DROPPED_AGENT_FIELDS.filter(
|
|
11704
|
+
(field) => hasAgentValue(agent, field)
|
|
11705
|
+
).sort();
|
|
11706
|
+
if (dropped.length === 0) continue;
|
|
11707
|
+
diagnostics.push(
|
|
11708
|
+
createWarning(
|
|
11709
|
+
agent.source,
|
|
11710
|
+
"codex-cli",
|
|
11711
|
+
`Codex agent TOML supports name, description, developer_instructions, model, sandbox_mode and mcp_servers; canonical ${dropped.join(", ")} are not projected to ${CODEX_AGENTS_DIR}/${agent.name}.toml.`
|
|
11712
|
+
)
|
|
11713
|
+
);
|
|
11714
|
+
}
|
|
11715
|
+
return diagnostics;
|
|
11716
|
+
}
|
|
11554
11717
|
function lintMcp4(canonical) {
|
|
11555
11718
|
if (!canonical.mcp || Object.keys(canonical.mcp.mcpServers).length === 0) return [];
|
|
11556
11719
|
const diagnostics = [];
|
|
@@ -11582,11 +11745,21 @@ function lintHooks7(canonical) {
|
|
|
11582
11745
|
(event) => createUnsupportedHookWarning(event, "codex-cli", CODEX_SUPPORTED_HOOK_EVENTS)
|
|
11583
11746
|
);
|
|
11584
11747
|
}
|
|
11748
|
+
var CODEX_DROPPED_AGENT_FIELDS;
|
|
11585
11749
|
var init_lint8 = __esm({
|
|
11586
11750
|
"src/targets/codex-cli/lint.ts"() {
|
|
11587
11751
|
init_helpers();
|
|
11588
11752
|
init_mcp_servers();
|
|
11753
|
+
init_agents_format();
|
|
11589
11754
|
init_constants10();
|
|
11755
|
+
CODEX_DROPPED_AGENT_FIELDS = [
|
|
11756
|
+
"tools",
|
|
11757
|
+
"disallowedTools",
|
|
11758
|
+
"maxTurns",
|
|
11759
|
+
"hooks",
|
|
11760
|
+
"skills",
|
|
11761
|
+
"memory"
|
|
11762
|
+
];
|
|
11590
11763
|
}
|
|
11591
11764
|
});
|
|
11592
11765
|
|
|
@@ -11661,6 +11834,7 @@ var init_codex_cli2 = __esm({
|
|
|
11661
11834
|
generateMcp: generateMcp6,
|
|
11662
11835
|
generateHooks: generateHooks6,
|
|
11663
11836
|
generatePermissions: generatePermissions7,
|
|
11837
|
+
lint: lintAgents3,
|
|
11664
11838
|
importFrom: importFromCodex
|
|
11665
11839
|
};
|
|
11666
11840
|
project6 = {
|
|
@@ -11708,7 +11882,7 @@ var init_codex_cli2 = __esm({
|
|
|
11708
11882
|
},
|
|
11709
11883
|
rewriteGeneratedPath(path) {
|
|
11710
11884
|
if (path === AGENTS_MD) return CODEX_GLOBAL_AGENTS_MD;
|
|
11711
|
-
if (
|
|
11885
|
+
if (/(^|\/)AGENTS(\.override)?\.md$/.test(path)) return null;
|
|
11712
11886
|
if (path.startsWith(`${CODEX_INSTRUCTIONS_DIR}/`)) return null;
|
|
11713
11887
|
return path;
|
|
11714
11888
|
},
|
|
@@ -11975,7 +12149,7 @@ async function importContinueHooks(projectRoot, results) {
|
|
|
11975
12149
|
});
|
|
11976
12150
|
}
|
|
11977
12151
|
var CONTINUE_HOOK_EVENTS, mergeContinueSettings;
|
|
11978
|
-
var
|
|
12152
|
+
var init_hooks3 = __esm({
|
|
11979
12153
|
"src/targets/continue/hooks.ts"() {
|
|
11980
12154
|
init_hooks_format2();
|
|
11981
12155
|
init_settings_helpers2();
|
|
@@ -12243,7 +12417,7 @@ var init_importer10 = __esm({
|
|
|
12243
12417
|
init_shared_import_helpers();
|
|
12244
12418
|
init_constants11();
|
|
12245
12419
|
init_permissions2();
|
|
12246
|
-
|
|
12420
|
+
init_hooks3();
|
|
12247
12421
|
init_continue2();
|
|
12248
12422
|
}
|
|
12249
12423
|
});
|
|
@@ -12364,7 +12538,7 @@ function hasValue(agent, field) {
|
|
|
12364
12538
|
if (value && typeof value === "object") return Object.keys(value).length > 0;
|
|
12365
12539
|
return false;
|
|
12366
12540
|
}
|
|
12367
|
-
function
|
|
12541
|
+
function lintAgents4(canonical) {
|
|
12368
12542
|
const diagnostics = [];
|
|
12369
12543
|
for (const agent of canonical.agents) {
|
|
12370
12544
|
const dropped = DROPPED_FIELDS.filter((field) => hasValue(agent, field)).sort();
|
|
@@ -12384,7 +12558,7 @@ var init_lint9 = __esm({
|
|
|
12384
12558
|
"src/targets/continue/lint.ts"() {
|
|
12385
12559
|
init_helpers();
|
|
12386
12560
|
init_constants11();
|
|
12387
|
-
|
|
12561
|
+
init_hooks3();
|
|
12388
12562
|
DROPPED_FIELDS = [
|
|
12389
12563
|
"disallowedTools",
|
|
12390
12564
|
"permissionMode",
|
|
@@ -12510,7 +12684,7 @@ var target10, descriptor10;
|
|
|
12510
12684
|
var init_continue2 = __esm({
|
|
12511
12685
|
"src/targets/continue/index.ts"() {
|
|
12512
12686
|
init_generator11();
|
|
12513
|
-
|
|
12687
|
+
init_hooks3();
|
|
12514
12688
|
init_config_merge2();
|
|
12515
12689
|
init_capabilities5();
|
|
12516
12690
|
init_layout4();
|
|
@@ -12532,7 +12706,7 @@ var init_continue2 = __esm({
|
|
|
12532
12706
|
generateHooks: generateHooks7,
|
|
12533
12707
|
generateIgnore: generateIgnore8,
|
|
12534
12708
|
// Feature-independent lint hook: agent warnings must not hang off `rules`.
|
|
12535
|
-
lint:
|
|
12709
|
+
lint: lintAgents4,
|
|
12536
12710
|
importFrom: importFromContinue
|
|
12537
12711
|
};
|
|
12538
12712
|
descriptor10 = {
|
|
@@ -12789,7 +12963,7 @@ var init_hook_format = __esm({
|
|
|
12789
12963
|
init_hook_entry();
|
|
12790
12964
|
}
|
|
12791
12965
|
});
|
|
12792
|
-
function
|
|
12966
|
+
function ruleSlug3(source) {
|
|
12793
12967
|
const name = basename(source, ".md");
|
|
12794
12968
|
return name === "_root" ? "root" : name;
|
|
12795
12969
|
}
|
|
@@ -12823,7 +12997,7 @@ function generateRules11(canonical) {
|
|
|
12823
12997
|
if (rule.root) continue;
|
|
12824
12998
|
if (rule.targets.length > 0 && !rule.targets.includes("copilot")) continue;
|
|
12825
12999
|
if (rule.globs.length === 0) continue;
|
|
12826
|
-
const slug =
|
|
13000
|
+
const slug = ruleSlug3(rule.source);
|
|
12827
13001
|
const frontmatter = {
|
|
12828
13002
|
description: rule.description || void 0,
|
|
12829
13003
|
applyTo: rule.globs.length === 1 ? rule.globs[0] : rule.globs
|
|
@@ -14312,13 +14486,18 @@ var init_rules2 = __esm({
|
|
|
14312
14486
|
|
|
14313
14487
|
// src/targets/cursor/generator/commands.ts
|
|
14314
14488
|
function generateCommands13(canonical) {
|
|
14315
|
-
return canonical.commands.map((cmd) =>
|
|
14316
|
-
|
|
14317
|
-
|
|
14318
|
-
|
|
14489
|
+
return canonical.commands.map((cmd) => {
|
|
14490
|
+
const frontmatter = {};
|
|
14491
|
+
if (cmd.description) frontmatter.description = cmd.description;
|
|
14492
|
+
return {
|
|
14493
|
+
path: `${CURSOR_COMMANDS_DIR}/${cmd.name}.md`,
|
|
14494
|
+
content: serializeFrontmatter(frontmatter, cmd.body.trim() || "")
|
|
14495
|
+
};
|
|
14496
|
+
});
|
|
14319
14497
|
}
|
|
14320
14498
|
var init_commands = __esm({
|
|
14321
14499
|
"src/targets/cursor/generator/commands.ts"() {
|
|
14500
|
+
init_markdown();
|
|
14322
14501
|
init_constants13();
|
|
14323
14502
|
}
|
|
14324
14503
|
});
|
|
@@ -14413,7 +14592,7 @@ var init_permissions3 = __esm({
|
|
|
14413
14592
|
// src/targets/cursor/hook-format.ts
|
|
14414
14593
|
function unmappedCursorHookEvents(hooks) {
|
|
14415
14594
|
return Object.keys(hooks).filter(
|
|
14416
|
-
(event) => Array.isArray(hooks[event]) && hooks[event].length > 0 && !(event in CANONICAL_TO_CURSOR) && !
|
|
14595
|
+
(event) => Array.isArray(hooks[event]) && hooks[event].length > 0 && !(event in CANONICAL_TO_CURSOR) && !isBestEffortHookEvent(event, hooks[event])
|
|
14417
14596
|
);
|
|
14418
14597
|
}
|
|
14419
14598
|
function toCursorHooks(hooks) {
|
|
@@ -14488,7 +14667,7 @@ function generateHooks10(canonical) {
|
|
|
14488
14667
|
const content = JSON.stringify({ version: 1, hooks: cursorHooks }, null, 2);
|
|
14489
14668
|
return [{ path: CURSOR_HOOKS, content }];
|
|
14490
14669
|
}
|
|
14491
|
-
var
|
|
14670
|
+
var init_hooks4 = __esm({
|
|
14492
14671
|
"src/targets/cursor/generator/hooks.ts"() {
|
|
14493
14672
|
init_constants13();
|
|
14494
14673
|
init_hook_format2();
|
|
@@ -14516,7 +14695,7 @@ var init_generator14 = __esm({
|
|
|
14516
14695
|
init_skills2();
|
|
14517
14696
|
init_agents2();
|
|
14518
14697
|
init_permissions3();
|
|
14519
|
-
|
|
14698
|
+
init_hooks4();
|
|
14520
14699
|
init_ignore();
|
|
14521
14700
|
}
|
|
14522
14701
|
});
|
|
@@ -14851,14 +15030,11 @@ async function hasGlobalCursorArtifacts(projectRoot) {
|
|
|
14851
15030
|
join(projectRoot, CURSOR_GLOBAL_USER_RULES),
|
|
14852
15031
|
join(projectRoot, CURSOR_MCP),
|
|
14853
15032
|
join(projectRoot, CURSOR_HOOKS),
|
|
14854
|
-
join(projectRoot, CURSOR_IGNORE)
|
|
14855
|
-
join(projectRoot, CURSOR_SKILLS_DIR),
|
|
14856
|
-
join(projectRoot, CURSOR_AGENTS_DIR),
|
|
14857
|
-
join(projectRoot, CURSOR_COMMANDS_DIR)
|
|
15033
|
+
join(projectRoot, CURSOR_IGNORE)
|
|
14858
15034
|
];
|
|
14859
15035
|
for (const p of candidates) {
|
|
14860
|
-
const
|
|
14861
|
-
if (
|
|
15036
|
+
const content = await readFileSafe(p);
|
|
15037
|
+
if (content !== null && content.trim() !== "") return true;
|
|
14862
15038
|
}
|
|
14863
15039
|
const skillFiles = await readDirRecursiveNoSymlinks(join(projectRoot, CURSOR_SKILLS_DIR));
|
|
14864
15040
|
if (skillFiles.some((f) => f.endsWith(".md"))) return true;
|
|
@@ -15145,11 +15321,11 @@ function lintHooks10(canonical) {
|
|
|
15145
15321
|
];
|
|
15146
15322
|
}
|
|
15147
15323
|
function lintCommands6(canonical) {
|
|
15148
|
-
return canonical.commands.filter((command) => command.
|
|
15324
|
+
return canonical.commands.filter((command) => command.allowedTools.length > 0).map(
|
|
15149
15325
|
(command) => createWarning(
|
|
15150
15326
|
command.source,
|
|
15151
15327
|
"cursor",
|
|
15152
|
-
"Cursor command files
|
|
15328
|
+
"Cursor command files project only description frontmatter; allowed-tools metadata is not projected."
|
|
15153
15329
|
)
|
|
15154
15330
|
);
|
|
15155
15331
|
}
|
|
@@ -15482,7 +15658,7 @@ var init_mcp_merge4 = __esm({
|
|
|
15482
15658
|
// src/targets/deepagents-cli/hooks-format.ts
|
|
15483
15659
|
function unmappedDeepagentsHookEvents(hooks) {
|
|
15484
15660
|
return Object.keys(hooks).filter(
|
|
15485
|
-
(event) => Array.isArray(hooks[event]) && hooks[event].length > 0 && !(event in CANONICAL_TO_DEEPAGENTS) && !
|
|
15661
|
+
(event) => Array.isArray(hooks[event]) && hooks[event].length > 0 && !(event in CANONICAL_TO_DEEPAGENTS) && !isBestEffortHookEvent(event, hooks[event])
|
|
15486
15662
|
);
|
|
15487
15663
|
}
|
|
15488
15664
|
function toDeepagentsHooks(hooks) {
|
|
@@ -16050,7 +16226,8 @@ var init_deepagents_cli2 = __esm({
|
|
|
16050
16226
|
}
|
|
16051
16227
|
},
|
|
16052
16228
|
buildImportPaths: buildDeepagentsCliImportPaths,
|
|
16053
|
-
|
|
16229
|
+
// `.mcp.json` is co-owned with claude-code (agentsmesh writes it), so it must not enroll this target.
|
|
16230
|
+
detectionPaths: [DEEPAGENTS_CLI_ROOT_FILE]
|
|
16054
16231
|
};
|
|
16055
16232
|
}
|
|
16056
16233
|
});
|
|
@@ -20028,7 +20205,8 @@ var init_layout8 = __esm({
|
|
|
20028
20205
|
skillDir: KIMI_CODE_SKILLS_DIR,
|
|
20029
20206
|
managedOutputs: {
|
|
20030
20207
|
dirs: [KIMI_CODE_AGENTS_DIR, KIMI_CODE_SKILLS_DIR],
|
|
20031
|
-
files: [KIMI_CODE_ROOT_FILE
|
|
20208
|
+
files: [KIMI_CODE_ROOT_FILE],
|
|
20209
|
+
supersededFiles: [KIMI_CODE_NESTED_ROOT_FILE],
|
|
20032
20210
|
// Kimi Code's own MCP config, in the same directory as the credential-
|
|
20033
20211
|
// bearing config.toml this layout already refuses to delete.
|
|
20034
20212
|
coOwnedFiles: [KIMI_CODE_MCP_FILE]
|
|
@@ -20676,7 +20854,7 @@ function lintMcp9(canonical) {
|
|
|
20676
20854
|
}
|
|
20677
20855
|
return diagnostics;
|
|
20678
20856
|
}
|
|
20679
|
-
function
|
|
20857
|
+
function lintAgents5(canonical) {
|
|
20680
20858
|
return canonical.agents.flatMap((agent) => {
|
|
20681
20859
|
const dropped = DROPPED_AGENT_FIELDS.filter(([, has]) => has(agent)).map(([field]) => field);
|
|
20682
20860
|
if (dropped.length === 0) return [];
|
|
@@ -20767,7 +20945,7 @@ var init_kimi_code2 = __esm({
|
|
|
20767
20945
|
generateHooks: generateHooks14,
|
|
20768
20946
|
generatePermissions: generatePermissions16,
|
|
20769
20947
|
importFrom: importFromKimiCode,
|
|
20770
|
-
lint:
|
|
20948
|
+
lint: lintAgents5
|
|
20771
20949
|
};
|
|
20772
20950
|
capabilities9 = {
|
|
20773
20951
|
rules: "native",
|
|
@@ -23065,7 +23243,7 @@ function lintAgentFields(agent) {
|
|
|
23065
23243
|
)
|
|
23066
23244
|
];
|
|
23067
23245
|
}
|
|
23068
|
-
function
|
|
23246
|
+
function lintAgents6(canonical) {
|
|
23069
23247
|
const diagnostics = [];
|
|
23070
23248
|
for (const agent of canonical.agents) {
|
|
23071
23249
|
diagnostics.push(...lintAgentFields(agent));
|
|
@@ -23127,7 +23305,7 @@ var init_openhands2 = __esm({
|
|
|
23127
23305
|
generatePermissions: generatePermissions19,
|
|
23128
23306
|
importFrom: importFromOpenhands,
|
|
23129
23307
|
// Ungated by feature, so agent-only feature sets still get the warning.
|
|
23130
|
-
lint:
|
|
23308
|
+
lint: lintAgents6
|
|
23131
23309
|
};
|
|
23132
23310
|
descriptor24 = {
|
|
23133
23311
|
id: OPENHANDS_TARGET,
|
|
@@ -26942,7 +27120,7 @@ var init_constants34 = __esm({
|
|
|
26942
27120
|
WINDSURF_GLOBAL_AGENTS_SKILLS_DIR = ".agents/skills";
|
|
26943
27121
|
}
|
|
26944
27122
|
});
|
|
26945
|
-
function
|
|
27123
|
+
function ruleSlug4(source) {
|
|
26946
27124
|
const name = basename(source, ".md");
|
|
26947
27125
|
return name === "_root" ? "root" : name;
|
|
26948
27126
|
}
|
|
@@ -26963,7 +27141,7 @@ function generateRules32(canonical) {
|
|
|
26963
27141
|
for (const rule of canonical.rules) {
|
|
26964
27142
|
if (rule.root) continue;
|
|
26965
27143
|
if (rule.targets.length > 0 && !rule.targets.includes("windsurf")) continue;
|
|
26966
|
-
const slug =
|
|
27144
|
+
const slug = ruleSlug4(rule.source);
|
|
26967
27145
|
const normalizedTrigger = rule.trigger || (rule.globs.length > 0 ? "glob" : void 0);
|
|
26968
27146
|
const frontmatter = {
|
|
26969
27147
|
description: rule.description || void 0,
|
|
@@ -27067,19 +27245,34 @@ var init_mcp4 = __esm({
|
|
|
27067
27245
|
}
|
|
27068
27246
|
});
|
|
27069
27247
|
|
|
27070
|
-
// src/targets/windsurf/
|
|
27248
|
+
// src/targets/windsurf/hook-events.ts
|
|
27071
27249
|
function windsurfEventName(event) {
|
|
27072
|
-
const explicit = {
|
|
27073
|
-
PreToolUse: "pre_tool_use",
|
|
27074
|
-
PostToolUse: "post_tool_use",
|
|
27075
|
-
Notification: "notification",
|
|
27076
|
-
UserPromptSubmit: "user_prompt_submit",
|
|
27077
|
-
SubagentStart: "subagent_start",
|
|
27078
|
-
SubagentStop: "subagent_stop"
|
|
27079
|
-
};
|
|
27080
|
-
if (explicit[event]) return explicit[event];
|
|
27081
27250
|
return event.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[-\s]+/g, "_").toLowerCase();
|
|
27082
27251
|
}
|
|
27252
|
+
function canonicalHookEventName(event) {
|
|
27253
|
+
if (KNOWN_CANONICAL_HOOK_EVENTS.includes(event)) return event;
|
|
27254
|
+
return WINDSURF_TO_CANONICAL.get(event) ?? null;
|
|
27255
|
+
}
|
|
27256
|
+
var KNOWN_CANONICAL_HOOK_EVENTS, WINDSURF_TO_CANONICAL;
|
|
27257
|
+
var init_hook_events = __esm({
|
|
27258
|
+
"src/targets/windsurf/hook-events.ts"() {
|
|
27259
|
+
init_hook_types();
|
|
27260
|
+
KNOWN_CANONICAL_HOOK_EVENTS = [
|
|
27261
|
+
"PreToolUse",
|
|
27262
|
+
"PostToolUse",
|
|
27263
|
+
"Notification",
|
|
27264
|
+
"UserPromptSubmit",
|
|
27265
|
+
"SubagentStart",
|
|
27266
|
+
"SubagentStop",
|
|
27267
|
+
...BEST_EFFORT_HOOK_EVENTS
|
|
27268
|
+
];
|
|
27269
|
+
WINDSURF_TO_CANONICAL = new Map(
|
|
27270
|
+
KNOWN_CANONICAL_HOOK_EVENTS.map((event) => [windsurfEventName(event), event])
|
|
27271
|
+
);
|
|
27272
|
+
}
|
|
27273
|
+
});
|
|
27274
|
+
|
|
27275
|
+
// src/targets/windsurf/generator/hooks.ts
|
|
27083
27276
|
function toWindsurfHooks(hooks) {
|
|
27084
27277
|
const result2 = {};
|
|
27085
27278
|
for (const [event, entries] of Object.entries(hooks)) {
|
|
@@ -27103,10 +27296,11 @@ function generateHooks22(canonical) {
|
|
|
27103
27296
|
if (Object.keys(hooks).length === 0) return [];
|
|
27104
27297
|
return [{ path: WINDSURF_HOOKS_FILE, content: JSON.stringify({ hooks }, null, 2) }];
|
|
27105
27298
|
}
|
|
27106
|
-
var
|
|
27299
|
+
var init_hooks5 = __esm({
|
|
27107
27300
|
"src/targets/windsurf/generator/hooks.ts"() {
|
|
27108
27301
|
init_hook_command();
|
|
27109
27302
|
init_constants34();
|
|
27303
|
+
init_hook_events();
|
|
27110
27304
|
}
|
|
27111
27305
|
});
|
|
27112
27306
|
|
|
@@ -27154,7 +27348,7 @@ var init_generator35 = __esm({
|
|
|
27154
27348
|
init_workflows();
|
|
27155
27349
|
init_agents4();
|
|
27156
27350
|
init_mcp4();
|
|
27157
|
-
|
|
27351
|
+
init_hooks5();
|
|
27158
27352
|
init_skills4();
|
|
27159
27353
|
init_permissions6();
|
|
27160
27354
|
}
|
|
@@ -27245,9 +27439,10 @@ async function importWindsurfHooks(projectRoot, results) {
|
|
|
27245
27439
|
try {
|
|
27246
27440
|
const parsed = JSON.parse(hooksContent);
|
|
27247
27441
|
if (!parsed.hooks || typeof parsed.hooks !== "object" || Array.isArray(parsed.hooks)) return;
|
|
27248
|
-
const canonical = windsurfHooksToCanonical(parsed.hooks);
|
|
27249
|
-
if (Object.keys(canonical).length === 0) return;
|
|
27250
27442
|
const destPath = join(projectRoot, WINDSURF_CANONICAL_HOOKS);
|
|
27443
|
+
const existing = await parseHooks(destPath) ?? {};
|
|
27444
|
+
const canonical = windsurfHooksToCanonical(parsed.hooks, existing);
|
|
27445
|
+
if (Object.keys(canonical).length === 0) return;
|
|
27251
27446
|
await mkdirp(dirname(destPath));
|
|
27252
27447
|
await writeFileAtomic(destPath, stringify(canonical));
|
|
27253
27448
|
results.push({
|
|
@@ -27259,54 +27454,63 @@ async function importWindsurfHooks(projectRoot, results) {
|
|
|
27259
27454
|
} catch {
|
|
27260
27455
|
}
|
|
27261
27456
|
}
|
|
27262
|
-
function
|
|
27263
|
-
const
|
|
27264
|
-
|
|
27265
|
-
post_tool_use: "PostToolUse",
|
|
27266
|
-
notification: "Notification",
|
|
27267
|
-
user_prompt_submit: "UserPromptSubmit",
|
|
27268
|
-
subagent_start: "SubagentStart",
|
|
27269
|
-
subagent_stop: "SubagentStop"
|
|
27270
|
-
};
|
|
27271
|
-
return explicit[event] ?? event;
|
|
27457
|
+
function preservedMatcher(existing, event, command) {
|
|
27458
|
+
const match = existing[event]?.find((entry) => entry.command === command);
|
|
27459
|
+
return match?.matcher ?? WILDCARD_MATCHER;
|
|
27272
27460
|
}
|
|
27273
|
-
function
|
|
27461
|
+
function legacyEntries(entry) {
|
|
27462
|
+
const matcher = typeof entry.matcher === "string" && entry.matcher.trim() ? entry.matcher : WILDCARD_MATCHER;
|
|
27463
|
+
const hooksList = Array.isArray(entry.hooks) ? entry.hooks : [];
|
|
27464
|
+
const out2 = [];
|
|
27465
|
+
for (const item of hooksList) {
|
|
27466
|
+
if (!item || typeof item !== "object") continue;
|
|
27467
|
+
const hook = item;
|
|
27468
|
+
const command = typeof hook.command === "string" ? hook.command : typeof hook.prompt === "string" ? hook.prompt : "";
|
|
27469
|
+
if (!command.trim()) continue;
|
|
27470
|
+
const canonical = {
|
|
27471
|
+
matcher,
|
|
27472
|
+
type: hook.type === "prompt" ? "prompt" : "command",
|
|
27473
|
+
command
|
|
27474
|
+
};
|
|
27475
|
+
if (typeof hook.timeout === "number") canonical.timeout = hook.timeout;
|
|
27476
|
+
out2.push(canonical);
|
|
27477
|
+
}
|
|
27478
|
+
return out2;
|
|
27479
|
+
}
|
|
27480
|
+
function windsurfHooksToCanonical(hooks, existing) {
|
|
27274
27481
|
const result2 = {};
|
|
27275
27482
|
for (const [event, entries] of Object.entries(hooks)) {
|
|
27276
27483
|
if (!Array.isArray(entries)) continue;
|
|
27277
27484
|
const mappedEvent = canonicalHookEventName(event);
|
|
27485
|
+
if (mappedEvent === null) continue;
|
|
27278
27486
|
const canonicalEntries = [];
|
|
27279
27487
|
for (const entry of entries) {
|
|
27280
27488
|
if (!entry || typeof entry !== "object") continue;
|
|
27281
27489
|
const e = entry;
|
|
27282
27490
|
if (typeof e.command === "string" && e.command.trim()) {
|
|
27283
27491
|
canonicalEntries.push({
|
|
27284
|
-
matcher:
|
|
27492
|
+
matcher: preservedMatcher(existing, mappedEvent, e.command),
|
|
27285
27493
|
type: "command",
|
|
27286
27494
|
command: e.command
|
|
27287
27495
|
});
|
|
27288
27496
|
continue;
|
|
27289
27497
|
}
|
|
27290
|
-
|
|
27291
|
-
const hooksList = Array.isArray(e.hooks) ? e.hooks : [];
|
|
27292
|
-
for (const item of hooksList) {
|
|
27293
|
-
if (!item || typeof item !== "object") continue;
|
|
27294
|
-
const hook = item;
|
|
27295
|
-
const command = typeof hook.command === "string" ? hook.command : typeof hook.prompt === "string" ? hook.prompt : "";
|
|
27296
|
-
if (!command.trim()) continue;
|
|
27297
|
-
const canonical = {
|
|
27298
|
-
matcher,
|
|
27299
|
-
type: hook.type === "prompt" ? "prompt" : "command",
|
|
27300
|
-
command
|
|
27301
|
-
};
|
|
27302
|
-
if (typeof hook.timeout === "number") canonical.timeout = hook.timeout;
|
|
27303
|
-
canonicalEntries.push(canonical);
|
|
27304
|
-
}
|
|
27498
|
+
canonicalEntries.push(...legacyEntries(e));
|
|
27305
27499
|
}
|
|
27306
27500
|
if (canonicalEntries.length > 0) result2[mappedEvent] = canonicalEntries;
|
|
27307
27501
|
}
|
|
27308
27502
|
return result2;
|
|
27309
27503
|
}
|
|
27504
|
+
var WILDCARD_MATCHER;
|
|
27505
|
+
var init_importer_hooks2 = __esm({
|
|
27506
|
+
"src/targets/windsurf/importer-hooks.ts"() {
|
|
27507
|
+
init_hooks();
|
|
27508
|
+
init_fs();
|
|
27509
|
+
init_constants34();
|
|
27510
|
+
init_hook_events();
|
|
27511
|
+
WILDCARD_MATCHER = "*";
|
|
27512
|
+
}
|
|
27513
|
+
});
|
|
27310
27514
|
async function importWindsurfMcp(projectRoot, results) {
|
|
27311
27515
|
const sourceCandidates = [WINDSURF_MCP_EXAMPLE_FILE, WINDSURF_MCP_CONFIG_FILE];
|
|
27312
27516
|
for (const relPath of sourceCandidates) {
|
|
@@ -27330,8 +27534,8 @@ async function importWindsurfMcp(projectRoot, results) {
|
|
|
27330
27534
|
}
|
|
27331
27535
|
}
|
|
27332
27536
|
}
|
|
27333
|
-
var
|
|
27334
|
-
"src/targets/windsurf/importer-
|
|
27537
|
+
var init_importer_mcp = __esm({
|
|
27538
|
+
"src/targets/windsurf/importer-mcp.ts"() {
|
|
27335
27539
|
init_fs();
|
|
27336
27540
|
init_constants34();
|
|
27337
27541
|
}
|
|
@@ -27481,7 +27685,8 @@ var init_importer32 = __esm({
|
|
|
27481
27685
|
init_constants34();
|
|
27482
27686
|
init_importer_workflows();
|
|
27483
27687
|
init_skills_adapter5();
|
|
27484
|
-
|
|
27688
|
+
init_importer_hooks2();
|
|
27689
|
+
init_importer_mcp();
|
|
27485
27690
|
}
|
|
27486
27691
|
});
|
|
27487
27692
|
|
|
@@ -27566,9 +27771,28 @@ function lintPermissions22(canonical) {
|
|
|
27566
27771
|
)
|
|
27567
27772
|
];
|
|
27568
27773
|
}
|
|
27774
|
+
function lintHooks23(canonical) {
|
|
27775
|
+
if (!canonical.hooks) return [];
|
|
27776
|
+
const diagnostics = [];
|
|
27777
|
+
for (const [event, entries] of Object.entries(canonical.hooks)) {
|
|
27778
|
+
for (const entry of entries ?? []) {
|
|
27779
|
+
if (WILDCARD_MATCHERS.has(entry.matcher.trim())) continue;
|
|
27780
|
+
diagnostics.push(
|
|
27781
|
+
createWarning(
|
|
27782
|
+
".agentsmesh/hooks.yaml",
|
|
27783
|
+
"windsurf",
|
|
27784
|
+
`Windsurf hooks have no matcher field; ${event} hook "${entry.command}" runs on every ${event} event (matcher "${entry.matcher}" is not projected).`
|
|
27785
|
+
)
|
|
27786
|
+
);
|
|
27787
|
+
}
|
|
27788
|
+
}
|
|
27789
|
+
return diagnostics;
|
|
27790
|
+
}
|
|
27791
|
+
var WILDCARD_MATCHERS;
|
|
27569
27792
|
var init_lint31 = __esm({
|
|
27570
27793
|
"src/targets/windsurf/lint.ts"() {
|
|
27571
27794
|
init_helpers();
|
|
27795
|
+
WILDCARD_MATCHERS = /* @__PURE__ */ new Set(["", "*", ".*"]);
|
|
27572
27796
|
}
|
|
27573
27797
|
});
|
|
27574
27798
|
|
|
@@ -27724,6 +27948,7 @@ var init_windsurf2 = __esm({
|
|
|
27724
27948
|
lintRules: lintRules32,
|
|
27725
27949
|
lint: {
|
|
27726
27950
|
commands: lintCommands10,
|
|
27951
|
+
hooks: lintHooks23,
|
|
27727
27952
|
mcp: lintMcp13,
|
|
27728
27953
|
permissions: lintPermissions22
|
|
27729
27954
|
},
|
|
@@ -29301,24 +29526,14 @@ async function sweepStaleCache(cacheDir, maxAgeMs) {
|
|
|
29301
29526
|
|
|
29302
29527
|
// src/config/remote/remote-fetcher.ts
|
|
29303
29528
|
var MAX_CACHE_KEY_LENGTH = 80;
|
|
29529
|
+
var CACHE_KEY_HASH_LENGTH = 12;
|
|
29304
29530
|
function buildCacheKey(provider, identifier, ref) {
|
|
29305
29531
|
const safe = (value) => value.replace(/[^a-zA-Z0-9_.-]/g, "_").replace(/^\.+/, "_");
|
|
29306
|
-
|
|
29307
|
-
|
|
29308
|
-
|
|
29309
|
-
|
|
29310
|
-
|
|
29311
|
-
} else {
|
|
29312
|
-
key = `${safe(provider)}__${safe(identifier)}__${safe(ref)}`;
|
|
29313
|
-
}
|
|
29314
|
-
} else {
|
|
29315
|
-
key = `${safe(provider)}__${safe(identifier)}__${safe(ref)}`;
|
|
29316
|
-
}
|
|
29317
|
-
if (key.length > MAX_CACHE_KEY_LENGTH) {
|
|
29318
|
-
const hash = createHash("sha256").update(key).digest("hex").slice(0, 16);
|
|
29319
|
-
key = `${key.slice(0, MAX_CACHE_KEY_LENGTH - 18)}--${hash}`;
|
|
29320
|
-
}
|
|
29321
|
-
return key;
|
|
29532
|
+
const [org, repo] = provider === "github" ? identifier.split("/", 2) : [];
|
|
29533
|
+
const readable = org && repo ? `${safe(org)}--${safe(repo)}--${safe(ref)}` : `${safe(provider)}__${safe(identifier)}__${safe(ref)}`;
|
|
29534
|
+
const hash = createHash("sha256").update(`${provider}|${identifier}|${ref}`).digest("hex").slice(0, CACHE_KEY_HASH_LENGTH);
|
|
29535
|
+
const maxReadable = MAX_CACHE_KEY_LENGTH - CACHE_KEY_HASH_LENGTH - 2;
|
|
29536
|
+
return `${readable.slice(0, maxReadable)}--${hash}`;
|
|
29322
29537
|
}
|
|
29323
29538
|
function getCacheDir() {
|
|
29324
29539
|
const env = process.env.AGENTSMESH_CACHE;
|
|
@@ -29430,6 +29645,92 @@ async function resolveExtendPaths(config, configDir, options = {}) {
|
|
|
29430
29645
|
return result2;
|
|
29431
29646
|
}
|
|
29432
29647
|
|
|
29648
|
+
// src/utils/output/color.ts
|
|
29649
|
+
function noColorRequested() {
|
|
29650
|
+
const value = process.env.NO_COLOR;
|
|
29651
|
+
return value !== void 0 && value !== "";
|
|
29652
|
+
}
|
|
29653
|
+
function forceColorRequested() {
|
|
29654
|
+
const value = process.env.FORCE_COLOR;
|
|
29655
|
+
if (value === void 0) return void 0;
|
|
29656
|
+
return value !== "0" && value !== "false";
|
|
29657
|
+
}
|
|
29658
|
+
function colorEnabled(stream = process.stdout) {
|
|
29659
|
+
const forced = forceColorRequested();
|
|
29660
|
+
if (forced !== void 0) return forced;
|
|
29661
|
+
if (noColorRequested()) return false;
|
|
29662
|
+
return stream.isTTY === true;
|
|
29663
|
+
}
|
|
29664
|
+
|
|
29665
|
+
// src/utils/output/logger.ts
|
|
29666
|
+
var C = {
|
|
29667
|
+
green: "\x1B[32m",
|
|
29668
|
+
red: "\x1B[31m",
|
|
29669
|
+
yellow: "\x1B[33m",
|
|
29670
|
+
cyan: "\x1B[36m",
|
|
29671
|
+
reset: "\x1B[0m"
|
|
29672
|
+
};
|
|
29673
|
+
function outStream() {
|
|
29674
|
+
return process.stdout;
|
|
29675
|
+
}
|
|
29676
|
+
function out(text) {
|
|
29677
|
+
outStream().write(text);
|
|
29678
|
+
}
|
|
29679
|
+
function c(code, text, stream) {
|
|
29680
|
+
return colorEnabled(stream) ? `${code}${text}${C.reset}` : text;
|
|
29681
|
+
}
|
|
29682
|
+
function pad(str3, width) {
|
|
29683
|
+
const len = [...str3].length;
|
|
29684
|
+
return str3 + " ".repeat(Math.max(0, width - len));
|
|
29685
|
+
}
|
|
29686
|
+
var logger = {
|
|
29687
|
+
info(msg) {
|
|
29688
|
+
out(c(C.cyan, msg, outStream()) + "\n");
|
|
29689
|
+
},
|
|
29690
|
+
warn(msg) {
|
|
29691
|
+
process.stderr.write(c(C.yellow, "\u26A0 ", process.stderr) + msg + "\n");
|
|
29692
|
+
},
|
|
29693
|
+
error(msg) {
|
|
29694
|
+
process.stderr.write(c(C.red, "\u2717 ", process.stderr) + msg + "\n");
|
|
29695
|
+
},
|
|
29696
|
+
success(msg) {
|
|
29697
|
+
out(c(C.green, "\u2713 ", outStream()) + msg + "\n");
|
|
29698
|
+
},
|
|
29699
|
+
debug(msg) {
|
|
29700
|
+
if (process.env.AGENTSMESH_DEBUG === "1") {
|
|
29701
|
+
out(c(C.cyan, "[debug] ", outStream()) + msg + "\n");
|
|
29702
|
+
}
|
|
29703
|
+
},
|
|
29704
|
+
table(rows) {
|
|
29705
|
+
if (rows.length === 0) return;
|
|
29706
|
+
const cols = rows[0].length;
|
|
29707
|
+
const widths = [];
|
|
29708
|
+
for (let j = 0; j < cols; j++) {
|
|
29709
|
+
let max = 0;
|
|
29710
|
+
for (let i = 0; i < rows.length; i++) {
|
|
29711
|
+
const len = [...rows[i][j]].length;
|
|
29712
|
+
if (len > max) max = len;
|
|
29713
|
+
}
|
|
29714
|
+
widths[j] = max;
|
|
29715
|
+
}
|
|
29716
|
+
const border = "+" + widths.map((w) => "-".repeat(w + 2)).join("+") + "+";
|
|
29717
|
+
out(border + "\n");
|
|
29718
|
+
for (let i = 0; i < rows.length; i++) {
|
|
29719
|
+
const row = rows[i];
|
|
29720
|
+
const line = "| " + row.map((cell, j) => pad(cell, widths[j])).join(" | ") + " |";
|
|
29721
|
+
out(line + "\n");
|
|
29722
|
+
}
|
|
29723
|
+
out(border + "\n");
|
|
29724
|
+
}
|
|
29725
|
+
};
|
|
29726
|
+
|
|
29727
|
+
// src/canonical/features/empty-file.ts
|
|
29728
|
+
function isEmptyCanonicalFile(content, path) {
|
|
29729
|
+
if (content.trim() !== "") return false;
|
|
29730
|
+
logger.warn(`Skipping empty canonical file ${path.replaceAll("\\", "/")}`);
|
|
29731
|
+
return true;
|
|
29732
|
+
}
|
|
29733
|
+
|
|
29433
29734
|
// src/canonical/features/rules.ts
|
|
29434
29735
|
init_fs();
|
|
29435
29736
|
init_markdown();
|
|
@@ -29525,87 +29826,6 @@ function assertNoBasenameCollisions(feature, paths2, stripExt) {
|
|
|
29525
29826
|
seen.set(key, { path: p, slug });
|
|
29526
29827
|
}
|
|
29527
29828
|
}
|
|
29528
|
-
|
|
29529
|
-
// src/utils/output/color.ts
|
|
29530
|
-
function noColorRequested() {
|
|
29531
|
-
const value = process.env.NO_COLOR;
|
|
29532
|
-
return value !== void 0 && value !== "";
|
|
29533
|
-
}
|
|
29534
|
-
function forceColorRequested() {
|
|
29535
|
-
const value = process.env.FORCE_COLOR;
|
|
29536
|
-
if (value === void 0) return void 0;
|
|
29537
|
-
return value !== "0" && value !== "false";
|
|
29538
|
-
}
|
|
29539
|
-
function colorEnabled(stream = process.stdout) {
|
|
29540
|
-
const forced = forceColorRequested();
|
|
29541
|
-
if (forced !== void 0) return forced;
|
|
29542
|
-
if (noColorRequested()) return false;
|
|
29543
|
-
return stream.isTTY === true;
|
|
29544
|
-
}
|
|
29545
|
-
|
|
29546
|
-
// src/utils/output/logger.ts
|
|
29547
|
-
var C = {
|
|
29548
|
-
green: "\x1B[32m",
|
|
29549
|
-
red: "\x1B[31m",
|
|
29550
|
-
yellow: "\x1B[33m",
|
|
29551
|
-
cyan: "\x1B[36m",
|
|
29552
|
-
reset: "\x1B[0m"
|
|
29553
|
-
};
|
|
29554
|
-
function outStream() {
|
|
29555
|
-
return process.stdout;
|
|
29556
|
-
}
|
|
29557
|
-
function out(text) {
|
|
29558
|
-
outStream().write(text);
|
|
29559
|
-
}
|
|
29560
|
-
function c(code, text, stream) {
|
|
29561
|
-
return colorEnabled(stream) ? `${code}${text}${C.reset}` : text;
|
|
29562
|
-
}
|
|
29563
|
-
function pad(str3, width) {
|
|
29564
|
-
const len = [...str3].length;
|
|
29565
|
-
return str3 + " ".repeat(Math.max(0, width - len));
|
|
29566
|
-
}
|
|
29567
|
-
var logger = {
|
|
29568
|
-
info(msg) {
|
|
29569
|
-
out(c(C.cyan, msg, outStream()) + "\n");
|
|
29570
|
-
},
|
|
29571
|
-
warn(msg) {
|
|
29572
|
-
process.stderr.write(c(C.yellow, "\u26A0 ", process.stderr) + msg + "\n");
|
|
29573
|
-
},
|
|
29574
|
-
error(msg) {
|
|
29575
|
-
process.stderr.write(c(C.red, "\u2717 ", process.stderr) + msg + "\n");
|
|
29576
|
-
},
|
|
29577
|
-
success(msg) {
|
|
29578
|
-
out(c(C.green, "\u2713 ", outStream()) + msg + "\n");
|
|
29579
|
-
},
|
|
29580
|
-
debug(msg) {
|
|
29581
|
-
if (process.env.AGENTSMESH_DEBUG === "1") {
|
|
29582
|
-
out(c(C.cyan, "[debug] ", outStream()) + msg + "\n");
|
|
29583
|
-
}
|
|
29584
|
-
},
|
|
29585
|
-
table(rows) {
|
|
29586
|
-
if (rows.length === 0) return;
|
|
29587
|
-
const cols = rows[0].length;
|
|
29588
|
-
const widths = [];
|
|
29589
|
-
for (let j = 0; j < cols; j++) {
|
|
29590
|
-
let max = 0;
|
|
29591
|
-
for (let i = 0; i < rows.length; i++) {
|
|
29592
|
-
const len = [...rows[i][j]].length;
|
|
29593
|
-
if (len > max) max = len;
|
|
29594
|
-
}
|
|
29595
|
-
widths[j] = max;
|
|
29596
|
-
}
|
|
29597
|
-
const border = "+" + widths.map((w) => "-".repeat(w + 2)).join("+") + "+";
|
|
29598
|
-
out(border + "\n");
|
|
29599
|
-
for (let i = 0; i < rows.length; i++) {
|
|
29600
|
-
const row = rows[i];
|
|
29601
|
-
const line = "| " + row.map((cell, j) => pad(cell, widths[j])).join(" | ") + " |";
|
|
29602
|
-
out(line + "\n");
|
|
29603
|
-
}
|
|
29604
|
-
out(border + "\n");
|
|
29605
|
-
}
|
|
29606
|
-
};
|
|
29607
|
-
|
|
29608
|
-
// src/canonical/features/unrecognized-files-warning.ts
|
|
29609
29829
|
var ALTERNATE_RESOURCE_FORMATS = /* @__PURE__ */ new Set([".toml", ".yaml", ".yml", ".json"]);
|
|
29610
29830
|
function warnIfUnrecognizedResourceFormats(featureLabel, dir, allFiles, parsedFiles, opts = {}) {
|
|
29611
29831
|
if (allFiles.length === 0) return;
|
|
@@ -29650,7 +29870,8 @@ async function parseRules(rulesDir, opts = {}) {
|
|
|
29650
29870
|
const rules = [];
|
|
29651
29871
|
for (const path of mdFiles) {
|
|
29652
29872
|
const content = await readFileSafe(path);
|
|
29653
|
-
if (
|
|
29873
|
+
if (content === null) continue;
|
|
29874
|
+
if (isEmptyCanonicalFile(content, path)) continue;
|
|
29654
29875
|
const parsed = parseOrSkipFrontmatter(content, path, opts.onParseError);
|
|
29655
29876
|
if (!parsed) continue;
|
|
29656
29877
|
const { frontmatter, body } = parsed;
|
|
@@ -29704,7 +29925,8 @@ async function parseCommands(commandsDir, opts = {}) {
|
|
|
29704
29925
|
const commands = [];
|
|
29705
29926
|
for (const path of mdFiles) {
|
|
29706
29927
|
const content = await readFileSafe(path);
|
|
29707
|
-
if (
|
|
29928
|
+
if (content === null) continue;
|
|
29929
|
+
if (isEmptyCanonicalFile(content, path)) continue;
|
|
29708
29930
|
const parsed = parseOrSkipFrontmatter(content, path, opts.onParseError);
|
|
29709
29931
|
if (!parsed) continue;
|
|
29710
29932
|
const { frontmatter, body } = parsed;
|
|
@@ -29764,15 +29986,14 @@ async function parseAgents(agentsDir, opts = {}) {
|
|
|
29764
29986
|
const agents = [];
|
|
29765
29987
|
for (const path of mdFiles) {
|
|
29766
29988
|
const content = await readFileSafe(path);
|
|
29767
|
-
if (
|
|
29989
|
+
if (content === null) continue;
|
|
29990
|
+
if (isEmptyCanonicalFile(content, path)) continue;
|
|
29768
29991
|
const parsed = parseOrSkipFrontmatter(content, path, opts.onParseError);
|
|
29769
29992
|
if (!parsed) continue;
|
|
29770
29993
|
const { frontmatter, body } = parsed;
|
|
29771
29994
|
const name = basename(path, ".md");
|
|
29772
29995
|
assertCanonicalName("agent", name);
|
|
29773
|
-
const
|
|
29774
|
-
const toolsKebab = toStrArray2(frontmatter["tools"]);
|
|
29775
|
-
const tools = toolsCamel.length > 0 ? toolsCamel : toolsKebab;
|
|
29996
|
+
const tools = toStrArray2(frontmatter.tools);
|
|
29776
29997
|
const disallowedCamel = toStrArray2(frontmatter.disallowedTools);
|
|
29777
29998
|
const disallowedKebab = toStrArray2(frontmatter["disallowed-tools"]);
|
|
29778
29999
|
const disallowedTools = disallowedCamel.length > 0 ? disallowedCamel : disallowedKebab;
|
|
@@ -29894,20 +30115,21 @@ async function parseSkills(skillsDir, opts = {}) {
|
|
|
29894
30115
|
init_mcp();
|
|
29895
30116
|
|
|
29896
30117
|
// src/canonical/features/permissions.ts
|
|
30118
|
+
init_syntax_error();
|
|
29897
30119
|
init_fs();
|
|
29898
30120
|
function ensureStringArray(val) {
|
|
29899
30121
|
if (!Array.isArray(val)) return [];
|
|
29900
30122
|
return val.filter((x) => typeof x === "string");
|
|
29901
30123
|
}
|
|
29902
|
-
async function parsePermissions(permissionsPath) {
|
|
30124
|
+
async function parsePermissions(permissionsPath, onParseError) {
|
|
29903
30125
|
const content = await readFileSafe(permissionsPath);
|
|
29904
30126
|
if (content === null) return null;
|
|
29905
30127
|
if (!content.trim()) return { allow: [], deny: [], ask: [] };
|
|
29906
30128
|
let parsed;
|
|
29907
30129
|
try {
|
|
29908
30130
|
parsed = parse(content);
|
|
29909
|
-
} catch {
|
|
29910
|
-
return
|
|
30131
|
+
} catch (err) {
|
|
30132
|
+
return failSyntax(permissionsPath, err, onParseError);
|
|
29911
30133
|
}
|
|
29912
30134
|
if (!parsed || typeof parsed !== "object") return null;
|
|
29913
30135
|
const obj = parsed;
|
|
@@ -29917,52 +30139,8 @@ async function parsePermissions(permissionsPath) {
|
|
|
29917
30139
|
return { allow, deny, ask };
|
|
29918
30140
|
}
|
|
29919
30141
|
|
|
29920
|
-
// src/canonical/
|
|
29921
|
-
|
|
29922
|
-
init_hook_command();
|
|
29923
|
-
var VALID_TYPES = ["command", "prompt"];
|
|
29924
|
-
function toHookEntry(raw) {
|
|
29925
|
-
if (!raw || typeof raw !== "object") return null;
|
|
29926
|
-
const obj = raw;
|
|
29927
|
-
const matcher = obj.matcher;
|
|
29928
|
-
if (typeof matcher !== "string") return null;
|
|
29929
|
-
const command = getHookText(obj);
|
|
29930
|
-
if (!command) return null;
|
|
29931
|
-
const type = typeof obj.type === "string" && VALID_TYPES.includes(obj.type) ? obj.type : void 0;
|
|
29932
|
-
const timeout = typeof obj.timeout === "number" && Number.isFinite(obj.timeout) ? obj.timeout : void 0;
|
|
29933
|
-
const prompt = getHookPrompt(obj) || void 0;
|
|
29934
|
-
return {
|
|
29935
|
-
matcher,
|
|
29936
|
-
command,
|
|
29937
|
-
...timeout !== void 0 && { timeout },
|
|
29938
|
-
...type && { type },
|
|
29939
|
-
...prompt && { prompt }
|
|
29940
|
-
};
|
|
29941
|
-
}
|
|
29942
|
-
async function parseHooks(hooksPath) {
|
|
29943
|
-
const content = await readFileSafe(hooksPath);
|
|
29944
|
-
if (content === null) return null;
|
|
29945
|
-
if (!content.trim()) return {};
|
|
29946
|
-
let parsed;
|
|
29947
|
-
try {
|
|
29948
|
-
parsed = parse(content);
|
|
29949
|
-
} catch {
|
|
29950
|
-
return null;
|
|
29951
|
-
}
|
|
29952
|
-
if (!parsed || typeof parsed !== "object") return null;
|
|
29953
|
-
const result2 = {};
|
|
29954
|
-
const obj = parsed;
|
|
29955
|
-
for (const [key, val] of Object.entries(obj)) {
|
|
29956
|
-
if (!Array.isArray(val)) continue;
|
|
29957
|
-
const entries = [];
|
|
29958
|
-
for (const item of val) {
|
|
29959
|
-
const entry = toHookEntry(item);
|
|
29960
|
-
if (entry) entries.push(entry);
|
|
29961
|
-
}
|
|
29962
|
-
if (entries.length > 0) result2[key] = entries;
|
|
29963
|
-
}
|
|
29964
|
-
return result2;
|
|
29965
|
-
}
|
|
30142
|
+
// src/canonical/load/loader.ts
|
|
30143
|
+
init_hooks();
|
|
29966
30144
|
|
|
29967
30145
|
// src/canonical/features/ignore.ts
|
|
29968
30146
|
init_fs();
|
|
@@ -29989,9 +30167,9 @@ async function loadCanonicalFiles(canonicalDirOrProjectRoot, opts = {}) {
|
|
|
29989
30167
|
parseCommands(join(canonicalDir, "commands"), opts),
|
|
29990
30168
|
parseAgents(join(canonicalDir, "agents"), opts),
|
|
29991
30169
|
parseSkills(join(canonicalDir, "skills"), opts),
|
|
29992
|
-
parseMcp(join(canonicalDir, "mcp.json")),
|
|
29993
|
-
parsePermissions(join(canonicalDir, "permissions.yaml")),
|
|
29994
|
-
parseHooks(join(canonicalDir, "hooks.yaml")),
|
|
30170
|
+
parseMcp(join(canonicalDir, "mcp.json"), opts.onParseError),
|
|
30171
|
+
parsePermissions(join(canonicalDir, "permissions.yaml"), opts.onParseError),
|
|
30172
|
+
parseHooks(join(canonicalDir, "hooks.yaml"), opts.onParseError),
|
|
29995
30173
|
parseIgnore(join(canonicalDir, "ignore"))
|
|
29996
30174
|
]);
|
|
29997
30175
|
return {
|
|
@@ -30894,6 +31072,7 @@ function gateExtendElevatedArtifacts(canonical, ext) {
|
|
|
30894
31072
|
});
|
|
30895
31073
|
}
|
|
30896
31074
|
init_mcp();
|
|
31075
|
+
init_hooks();
|
|
30897
31076
|
|
|
30898
31077
|
// src/install/pack/pack-reader.ts
|
|
30899
31078
|
init_fs();
|
|
@@ -31217,8 +31396,46 @@ function mergeLocalConfig(project26, local) {
|
|
|
31217
31396
|
if (Array.isArray(local.extends) && local.extends.length > 0) {
|
|
31218
31397
|
merged.extends = [...project26.extends ?? [], ...local.extends];
|
|
31219
31398
|
}
|
|
31399
|
+
if (Array.isArray(local.plugins)) {
|
|
31400
|
+
merged.plugins = mergeById(project26.plugins, local.plugins);
|
|
31401
|
+
}
|
|
31402
|
+
if (Array.isArray(local.pluginTargets)) {
|
|
31403
|
+
merged.pluginTargets = [.../* @__PURE__ */ new Set([...project26.pluginTargets, ...local.pluginTargets])];
|
|
31404
|
+
}
|
|
31405
|
+
if (typeof local.collaboration === "object" && local.collaboration !== null && !Array.isArray(local.collaboration)) {
|
|
31406
|
+
merged.collaboration = local.collaboration;
|
|
31407
|
+
}
|
|
31408
|
+
warnUnhandledLocalKeys(local);
|
|
31220
31409
|
return merged;
|
|
31221
31410
|
}
|
|
31411
|
+
var LOCAL_KEYS = /* @__PURE__ */ new Set([
|
|
31412
|
+
"version",
|
|
31413
|
+
"targets",
|
|
31414
|
+
"features",
|
|
31415
|
+
"overrides",
|
|
31416
|
+
"conversions",
|
|
31417
|
+
"extends",
|
|
31418
|
+
"plugins",
|
|
31419
|
+
"pluginTargets",
|
|
31420
|
+
"collaboration"
|
|
31421
|
+
]);
|
|
31422
|
+
function warnUnhandledLocalKeys(local) {
|
|
31423
|
+
const unknown = Object.keys(local).filter((key) => !LOCAL_KEYS.has(key));
|
|
31424
|
+
if (unknown.length === 0) return;
|
|
31425
|
+
logger.warn(
|
|
31426
|
+
`agentsmesh.local.yaml: ignoring unknown key(s) ${unknown.join(", ")}; supported keys are ${[...LOCAL_KEYS].join(", ")}.`
|
|
31427
|
+
);
|
|
31428
|
+
}
|
|
31429
|
+
function mergeById(project26, local) {
|
|
31430
|
+
const byId = /* @__PURE__ */ new Map();
|
|
31431
|
+
const anonymous = [];
|
|
31432
|
+
for (const entry of [...project26, ...local]) {
|
|
31433
|
+
const id = typeof entry === "object" && entry !== null && typeof entry.id === "string" ? entry.id : void 0;
|
|
31434
|
+
if (id === void 0) anonymous.push(entry);
|
|
31435
|
+
else byId.set(id, entry);
|
|
31436
|
+
}
|
|
31437
|
+
return [...byId.values(), ...anonymous];
|
|
31438
|
+
}
|
|
31222
31439
|
async function loadConfigFromExactDir(configDir) {
|
|
31223
31440
|
const configPath = join(configDir, CONFIG_FILENAME);
|
|
31224
31441
|
let config = await loadConfig(configPath);
|