





















@@ -65,12 +65,14 @@ function resolveCompactHomePrefixes(): string[] {
6565const realHomes = resolvedHomes
6666.map((home) => tryRealpath(home))
6767.filter((home): home is string => !!home);
68-return uniqueStrings([...resolvedHomes, ...realHomes]).sort((a, b) => b.length - a.length);
68+return uniqueStrings([...resolvedHomes, ...realHomes]).toSorted((a, b) => b.length - a.length);
6969}
70707171function compactSkillPaths(skills: Skill[]): Skill[] {
7272const homes = resolveCompactHomePrefixes();
73-if (homes.length === 0) return skills;
73+if (homes.length === 0) {
74+return skills;
75+}
7476return skills.map((s) => ({
7577 ...s,
7678filePath: compactHomePath(s.filePath, homes),
@@ -106,12 +108,12 @@ function compactPathForConsoleMessage(filePath: string): string {
106108107109function isSkillVisibleInAvailableSkillsPrompt(entry: SkillEntry): boolean {
108110if (entry.exposure) {
109-return entry.exposure.includeInAvailableSkillsPrompt !== false;
111+return entry.exposure.includeInAvailableSkillsPrompt ?? true;
110112}
111113if (entry.invocation) {
112-return entry.invocation.disableModelInvocation !== true;
114+return !entry.invocation.disableModelInvocation;
113115}
114-return entry.skill.disableModelInvocation !== true;
116+return !entry.skill.disableModelInvocation;
115117}
116118117119function filterSkillEntries(
@@ -839,8 +841,7 @@ function loadGeneratedPluginSkillRecords(params: {
839841840842if (loadedSkills.length > maxSkillsLoadedPerSource) {
841843return loadedSkills
842-.slice()
843-.sort((a, b) => a.skill.name.localeCompare(b.skill.name, "en"))
844+.toSorted((a, b) => a.skill.name.localeCompare(b.skill.name, "en"))
844845.slice(0, maxSkillsLoadedPerSource);
845846}
846847return loadedSkills;
@@ -1107,8 +1108,7 @@ function loadSkillEntries(
1107110811081109if (loadedSkills.length > maxSkillsLoadedPerSource) {
11091110return loadedSkills
1110-.slice()
1111-.sort((a, b) => a.skill.name.localeCompare(b.skill.name, "en"))
1111+.toSorted((a, b) => a.skill.name.localeCompare(b.skill.name, "en"))
11121112.slice(0, maxSkillsLoadedPerSource);
11131113}
11141114@@ -1193,7 +1193,7 @@ function loadSkillEntries(
11931193}
1194119411951195const skillEntries: SkillEntry[] = Array.from(merged.values())
1196-.sort((a, b) => a.skill.name.localeCompare(b.skill.name, "en"))
1196+.toSorted((a, b) => a.skill.name.localeCompare(b.skill.name, "en"))
11971197.map((record) => {
11981198const skill = record.skill;
11991199const frontmatter =
@@ -1205,22 +1205,27 @@ function loadSkillEntries(
12051205}) ??
12061206({} as ParsedSkillFrontmatter);
12071207const invocation = resolveSkillInvocationPolicy(frontmatter);
1208-return {
1208+const entry: SkillEntry = {
12091209 skill,
12101210 frontmatter,
12111211metadata: resolveSkillEntryMetadata({ frontmatter, skillDir: skill.baseDir }),
12121212 invocation,
1213- ...(record.syncSourceDir !== undefined ? { syncSourceDir: record.syncSourceDir } : {}),
1214- ...(record.syncDirName !== undefined ? { syncDirName: record.syncDirName } : {}),
12151213exposure: {
12161214includeInRuntimeRegistry: true,
12171215// Freshly loaded entries preserve the documented disable-model-invocation
12181216// contract, while legacy entries without exposure metadata still use the
12191217// fallback in isSkillVisibleInAvailableSkillsPrompt().
1220-includeInAvailableSkillsPrompt: invocation.disableModelInvocation !== true,
1221-userInvocable: invocation.userInvocable !== false,
1218+includeInAvailableSkillsPrompt: !invocation.disableModelInvocation,
1219+userInvocable: invocation.userInvocable ?? true,
12221220},
12231221};
1222+if (record.syncSourceDir !== undefined) {
1223+entry.syncSourceDir = record.syncSourceDir;
1224+}
1225+if (record.syncDirName !== undefined) {
1226+entry.syncDirName = record.syncDirName;
1227+}
1228+return entry;
12241229});
12251230return skillEntries;
12261231}
@@ -1240,7 +1245,9 @@ function escapeXml(str: string): string {
12401245 * preserving awareness of all skills before resorting to dropping.
12411246 */
12421247export function formatSkillsCompact(skills: Skill[]): string {
1243-if (skills.length === 0) return "";
1248+if (skills.length === 0) {
1249+return "";
1250+}
12441251const lines = [
12451252"\n\nThe following skills provide specialized instructions for specific tasks.",
12461253"Use the read tool to load a skill's file when the task matches its name.",
@@ -1392,9 +1399,9 @@ function resolveWorkspaceSkillPromptState(
13921399// Budget checks and final render both use this same representation so the
13931400// tier decision is based on the exact strings that end up in the prompt.
13941401// resolvedSkills keeps canonical paths for snapshot / runtime consumers.
1395-const promptSkills = compactSkillPaths(resolvedSkills)
1396-.slice()
1397- .sort((a, b) => a.name.localeCompare(b.name, "en"));
1402+const promptSkills = compactSkillPaths(resolvedSkills).toSorted((a, b) =>
1403+a.name.localeCompare(b.name, "en"),
1404+);
13981405const { skillsForPrompt, truncated, compact } = applySkillsPromptLimits({
13991406skills: promptSkills,
14001407config: opts?.config,
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。