diff options
Diffstat (limited to 'packages/skills/src/pure.ts')
| -rw-r--r-- | packages/skills/src/pure.ts | 106 |
1 files changed, 53 insertions, 53 deletions
diff --git a/packages/skills/src/pure.ts b/packages/skills/src/pure.ts index 2800967..4cc8e5c 100644 --- a/packages/skills/src/pure.ts +++ b/packages/skills/src/pure.ts @@ -5,14 +5,14 @@ /** A discovered skill entry (name + optional summary from metadata). */ export interface SkillEntry { - readonly name: string; - readonly summary?: string | undefined; + readonly name: string; + readonly summary?: string | undefined; } /** Result of parsing a skill file's metadata. */ export interface SkillMeta { - readonly summary?: string | undefined; - readonly hasMeta: boolean; + readonly summary?: string | undefined; + readonly hasMeta: boolean; } /** @@ -22,16 +22,16 @@ export interface SkillMeta { * Returns `{ hasMeta: false }` when line 2 is not `---` (malformed). */ export function parseSkillMeta(content: string): SkillMeta { - const lines = content.split("\n"); - if (lines.length < 2) { - return { hasMeta: false }; - } - const line2 = lines[1]; - if (line2 === undefined || line2.trim() !== "---") { - return { hasMeta: false }; - } - const summary = lines[0]; - return { hasMeta: true, summary: summary?.trim() === "" ? undefined : summary }; + const lines = content.split("\n"); + if (lines.length < 2) { + return { hasMeta: false }; + } + const line2 = lines[1]; + if (line2 === undefined || line2.trim() !== "---") { + return { hasMeta: false }; + } + const summary = lines[0]; + return { hasMeta: true, summary: summary?.trim() === "" ? undefined : summary }; } /** @@ -40,11 +40,11 @@ export function parseSkillMeta(content: string): SkillMeta { * When hasMeta is false, returns the whole file unchanged. */ export function stripLoadedBody(content: string, hasMeta: boolean): string { - if (!hasMeta) { - return content; - } - const lines = content.split("\n"); - return lines.slice(2).join("\n"); + if (!hasMeta) { + return content; + } + const lines = content.split("\n"); + return lines.slice(2).join("\n"); } /** @@ -52,17 +52,17 @@ export function stripLoadedBody(content: string, hasMeta: boolean): string { * Returns a deduplicated array sorted by name. */ export function mergeCatalog( - homeEntries: readonly SkillEntry[], - cwdEntries: readonly SkillEntry[], + homeEntries: readonly SkillEntry[], + cwdEntries: readonly SkillEntry[], ): readonly SkillEntry[] { - const map = new Map<string, SkillEntry>(); - for (const entry of homeEntries) { - map.set(entry.name, entry); - } - for (const entry of cwdEntries) { - map.set(entry.name, entry); - } - return [...map.values()].sort((a, b) => a.name.localeCompare(b.name)); + const map = new Map<string, SkillEntry>(); + for (const entry of homeEntries) { + map.set(entry.name, entry); + } + for (const entry of cwdEntries) { + map.set(entry.name, entry); + } + return [...map.values()].sort((a, b) => a.name.localeCompare(b.name)); } /** @@ -70,18 +70,18 @@ export function mergeCatalog( * Lists all skills by name; appends summary only for skills with valid metadata. */ export function renderDescription(catalog: readonly SkillEntry[]): string { - if (catalog.length === 0) { - return "Load a skill by name. No skills are currently available."; - } - const lines = ["Load a skill by name. Available skills:"]; - for (const entry of catalog) { - if (entry.summary !== undefined) { - lines.push(`- ${entry.name}: ${entry.summary}`); - } else { - lines.push(`- ${entry.name}`); - } - } - return lines.join("\n"); + if (catalog.length === 0) { + return "Load a skill by name. No skills are currently available."; + } + const lines = ["Load a skill by name. Available skills:"]; + for (const entry of catalog) { + if (entry.summary !== undefined) { + lines.push(`- ${entry.name}: ${entry.summary}`); + } else { + lines.push(`- ${entry.name}`); + } + } + return lines.join("\n"); } /** @@ -89,16 +89,16 @@ export function renderDescription(catalog: readonly SkillEntry[]): string { * Returns true if the name is safe, false if it contains `/`, `\`, `..`, or is empty. */ export function isValidSkillName(name: unknown): name is string { - if (typeof name !== "string" || name.length === 0) { - return false; - } - if (name.includes("/") || name.includes("\\")) { - return false; - } - if (name.includes("..")) { - return false; - } - return true; + if (typeof name !== "string" || name.length === 0) { + return false; + } + if (name.includes("/") || name.includes("\\")) { + return false; + } + if (name.includes("..")) { + return false; + } + return true; } /** @@ -106,6 +106,6 @@ export function isValidSkillName(name: unknown): name is string { * Prefix check — catches `..` traversal and absolute paths outside base. */ export function isPathWithinDir(resolvedPath: string, base: string): boolean { - const normalizedBase = base.endsWith("/") ? base : `${base}/`; - return resolvedPath === base || resolvedPath.startsWith(normalizedBase); + const normalizedBase = base.endsWith("/") ? base : `${base}/`; + return resolvedPath === base || resolvedPath.startsWith(normalizedBase); } |
