skilldex 0.1.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/LICENSE +21 -0
- package/README.md +77 -0
- package/dist/cli/index.js +701 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.cjs +510 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +148 -0
- package/dist/index.d.ts +148 -0
- package/dist/index.js +458 -0
- package/dist/index.js.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/lib/config.ts","../src/lib/constants.ts","../src/lib/scanner.ts","../src/lib/agents.ts","../src/lib/writer.ts","../src/lib/indexer.ts","../src/lib/add.ts","../src/lib/init.ts","../src/lib/list.ts","../src/lib/remove.ts","../src/lib/sync.ts"],"sourcesContent":["// skilldex library entry point\n\nexport { addSkill } from \"./lib/add.js\";\nexport type { AgentSource } from \"./lib/agents.js\";\nexport { AGENT_SOURCES, getAgentDisplayName, getUniqueSkillsDirs } from \"./lib/agents.js\";\nexport { readConfig, writeConfig } from \"./lib/config.js\";\nexport {\n CONFIG_FILENAME,\n CONTEXT_BUDGET_DANGER_KB,\n CONTEXT_BUDGET_WARN_KB,\n compareByNameThenPath,\n END_TAG,\n INDEX_HEADER,\n INDEX_INSTRUCTION,\n SKILL_META_FILE,\n START_TAG,\n TARGET_FILE,\n} from \"./lib/constants.js\";\nexport { generateIndex } from \"./lib/indexer.js\";\nexport { init, initWithSkills } from \"./lib/init.js\";\nexport { listSkills } from \"./lib/list.js\";\nexport { removeSkill } from \"./lib/remove.js\";\nexport { scanForSkills } from \"./lib/scanner.js\";\nexport { syncSkills } from \"./lib/sync.js\";\nexport type {\n AddResult,\n Config,\n DiscoveredSkill,\n InitResult,\n ListResult,\n RemoveResult,\n SkillEntry,\n SkillFile,\n SkillInfo,\n SyncResult,\n TargetFileInfo,\n} from \"./lib/types.js\";\nexport type { RegenerateResult } from \"./lib/writer.js\";\nexport { buildManagedSection, regenerateFromConfig, writeTargetFile } from \"./lib/writer.js\";\n","import { writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { CONFIG_FILENAME, compareByNameThenPath, TARGET_FILE } from \"./constants.js\";\nimport { safeReadFile } from \"./scanner.js\";\nimport type { Config } from \"./types.js\";\n\nfunction getDefaultConfig(): Config {\n return {\n version: 1,\n targets: [TARGET_FILE],\n skills: [],\n };\n}\n\nexport async function readConfig(projectRoot: string): Promise<Config> {\n const configPath = join(projectRoot, CONFIG_FILENAME);\n const content = await safeReadFile(configPath);\n\n if (content === undefined) {\n return getDefaultConfig();\n }\n\n try {\n const parsed = JSON.parse(content) as Config;\n // Validate structure\n if (\n typeof parsed.version !== \"number\" ||\n !Array.isArray(parsed.targets) ||\n !Array.isArray(parsed.skills)\n ) {\n return getDefaultConfig();\n }\n return parsed;\n } catch {\n return getDefaultConfig();\n }\n}\n\nexport async function writeConfig(projectRoot: string, config: Config): Promise<void> {\n const configPath = join(projectRoot, CONFIG_FILENAME);\n const sorted = {\n ...config,\n skills: [...config.skills].sort(compareByNameThenPath),\n };\n const content = JSON.stringify(sorted, null, 2);\n await writeFile(configPath, content, \"utf-8\");\n}\n","export const START_TAG = \"<!-- skilldex:start (auto-generated, do not edit) -->\";\nexport const END_TAG = \"<!-- skilldex:end -->\";\n\nexport const TARGET_FILE = \"AGENTS.md\";\nexport const CONFIG_FILENAME = \"skilldex.config.json\";\nexport const SKILL_META_FILE = \"SKILL.md\";\nexport const SKILLS_DIR_SEGMENTS = [\".agents\", \"skills\"] as const;\nexport const INDEX_HEADER = \"[Skills Index]\";\nexport const INDEX_INSTRUCTION =\n \"IMPORTANT: Prefer retrieval-led reasoning over pre-training-led reasoning for any tasks covered by indexed skills.\";\nexport const CONTEXT_BUDGET_WARN_KB = 20;\nexport const CONTEXT_BUDGET_DANGER_KB = 40;\n\nexport function compareByNameThenPath(\n a: { name: string; path: string },\n b: { name: string; path: string },\n): number {\n return a.name.localeCompare(b.name) || a.path.localeCompare(b.path);\n}\n","import type { Dirent } from \"node:fs\";\nimport { lstat, readdir, readFile } from \"node:fs/promises\";\nimport { join, relative } from \"node:path\";\nimport { getUniqueSkillsDirs } from \"./agents.js\";\nimport { compareByNameThenPath, SKILL_META_FILE } from \"./constants.js\";\nimport type { DiscoveredSkill, SkillFile } from \"./types.js\";\n\n/** Extract key-value pairs from YAML frontmatter (between `---` fences). */\nexport function parseFrontmatter(content: string): Record<string, string> {\n const result: Record<string, string> = {};\n if (!content.startsWith(\"---\")) return result;\n\n const endIndex = content.indexOf(\"\\n---\", 3);\n if (endIndex === -1) return result;\n\n const block = content.slice(4, endIndex);\n for (const line of block.split(\"\\n\")) {\n const colonIndex = line.indexOf(\":\");\n if (colonIndex === -1) continue;\n const key = line.slice(0, colonIndex).trim();\n const value = line.slice(colonIndex + 1).trim();\n if (key) result[key] = value;\n }\n return result;\n}\n\nasync function safeReaddir(dir: string): Promise<Dirent[]> {\n try {\n return await readdir(dir, { withFileTypes: true });\n } catch {\n return [];\n }\n}\n\nexport async function safeReadFile(path: string): Promise<string | undefined> {\n try {\n return await readFile(path, \"utf-8\");\n } catch {\n return undefined;\n }\n}\n\nasync function collectMdFiles(dir: string, skillRoot: string): Promise<SkillFile[]> {\n const entries = await safeReaddir(dir);\n const files: SkillFile[] = [];\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n const nested = await collectMdFiles(fullPath, skillRoot);\n files.push(...nested);\n } else if (entry.isFile() && entry.name.endsWith(\".md\") && entry.name !== SKILL_META_FILE) {\n files.push({\n relativePath: relative(skillRoot, fullPath),\n name: entry.name.replace(/\\.md$/, \"\"),\n });\n }\n }\n return files;\n}\n\nasync function isSymlink(path: string): Promise<boolean> {\n try {\n const stats = await lstat(path);\n return stats.isSymbolicLink();\n } catch {\n return false;\n }\n}\n\n/** Scan a single skills directory and return discovered skills. */\nasync function scanDirectory(dir: string, projectRoot: string): Promise<DiscoveredSkill[]> {\n const entries = await safeReaddir(dir);\n const skills: DiscoveredSkill[] = [];\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n\n const skillPath = join(dir, entry.name);\n\n if (await isSymlink(skillPath)) continue;\n\n let description = \"\";\n const skillMd = await safeReadFile(join(skillPath, SKILL_META_FILE));\n if (skillMd !== undefined) {\n const frontmatter = parseFrontmatter(skillMd);\n description = frontmatter.description ?? \"\";\n }\n\n const files = await collectMdFiles(skillPath, skillPath);\n skills.push({\n name: entry.name,\n description,\n path: skillPath,\n relativePath: relative(projectRoot, skillPath),\n files,\n });\n }\n return skills;\n}\n\n/** Scan all agent source directories for skills. Same-named skills in different directories are all included. */\nexport async function scanForSkills(projectRoot: string): Promise<DiscoveredSkill[]> {\n const results = await Promise.all(\n getUniqueSkillsDirs().map((d) => scanDirectory(join(projectRoot, d), projectRoot)),\n );\n return results.flat().sort(compareByNameThenPath);\n}\n","export interface AgentSource {\n /** Agent identifier, e.g. \"claude-code\" */\n name: string;\n /** Human-readable name, e.g. \"Claude Code\" */\n displayName: string;\n /** Skills directory relative to project root, e.g. \".claude/skills\" */\n skillsDir: string;\n}\n\n/**\n * Known agent source directories (project-scoped).\n * Sourced from the Vercel Skills CLI agent conventions.\n */\nexport const AGENT_SOURCES: AgentSource[] = [\n { name: \"universal\", displayName: \"Universal\", skillsDir: \".agents/skills\" },\n { name: \"antigravity\", displayName: \"Antigravity\", skillsDir: \".agent/skills\" },\n { name: \"claude-code\", displayName: \"Claude Code\", skillsDir: \".claude/skills\" },\n { name: \"codex\", displayName: \"Codex\", skillsDir: \".agents/skills\" },\n { name: \"cursor\", displayName: \"Cursor\", skillsDir: \".cursor/skills\" },\n { name: \"github-copilot\", displayName: \"GitHub Copilot\", skillsDir: \".agents/skills\" },\n { name: \"opencode\", displayName: \"OpenCode\", skillsDir: \".agents/skills\" },\n { name: \"openclaw\", displayName: \"OpenClaw\", skillsDir: \"skills\" },\n { name: \"windsurf\", displayName: \"Windsurf\", skillsDir: \".windsurf/skills\" },\n];\n\n/** Unique skills directories to scan (deduplicates agents sharing the same dir). */\nexport function getUniqueSkillsDirs(): string[] {\n return [...new Set(AGENT_SOURCES.map((a) => a.skillsDir))];\n}\n\n/** Maps a skill's relative path to the first matching agent's display name. */\nexport function getAgentDisplayName(relativePath: string): string | undefined {\n for (const agent of AGENT_SOURCES) {\n if (relativePath.startsWith(`${agent.skillsDir}/`) || relativePath === agent.skillsDir) {\n return agent.displayName;\n }\n }\n return undefined;\n}\n","import { stat, writeFile } from \"node:fs/promises\";\nimport { basename, join } from \"node:path\";\nimport { readConfig } from \"./config.js\";\nimport { END_TAG, START_TAG, TARGET_FILE } from \"./constants.js\";\nimport { generateIndex } from \"./indexer.js\";\nimport { safeReadFile, scanForSkills } from \"./scanner.js\";\nimport type { InitResult, TargetFileInfo } from \"./types.js\";\n\nexport async function getTargetInfos(\n projectRoot: string,\n targets: string[],\n): Promise<TargetFileInfo[]> {\n return Promise.all(\n targets.map(async (t) => {\n const p = join(projectRoot, t);\n const s = await stat(p);\n return { file: basename(t), path: p, totalSize: s.size };\n }),\n );\n}\n\nexport function buildManagedSection(indexContent: string): string {\n return `${START_TAG}\\n${indexContent}\\n${END_TAG}`;\n}\n\n/** Write or update the managed skilldex section in a target file. Creates, appends, or replaces as needed. Returns the written file content. */\nexport async function writeTargetFile(\n projectRoot: string,\n indexContent: string,\n targetFile: string = TARGET_FILE,\n): Promise<string> {\n const targetPath = join(projectRoot, targetFile);\n const section = buildManagedSection(indexContent);\n\n const existing = await safeReadFile(targetPath);\n\n let output: string;\n if (existing === undefined) {\n output = `${section}\\n`;\n } else if (existing.includes(START_TAG) && existing.includes(END_TAG)) {\n const startIdx = existing.indexOf(START_TAG);\n const endIdx = existing.indexOf(END_TAG) + END_TAG.length;\n output = existing.slice(0, startIdx) + section + existing.slice(endIdx);\n } else {\n output = `${existing.trimEnd()}\\n\\n${section}\\n`;\n }\n\n await writeFile(targetPath, output, \"utf-8\");\n return output;\n}\n\nexport interface RegenerateResult extends InitResult {\n /** Map of target file path → written content */\n writtenContent: Map<string, string>;\n}\n\n/** Regenerate all target files from config (reads config, scans indexed skills, writes targets). */\nexport async function regenerateFromConfig(projectRoot: string): Promise<RegenerateResult> {\n const config = await readConfig(projectRoot);\n const allSkills = await scanForSkills(projectRoot);\n\n // Map skill paths from config to DiscoveredSkill objects\n const skillMap = new Map(allSkills.map((s) => [s.relativePath, s]));\n const skills = config.skills\n .map((entry) => skillMap.get(entry.path))\n .filter((s) => s !== undefined);\n\n const index = generateIndex(skills);\n\n const writtenContent = new Map<string, string>();\n for (const target of config.targets) {\n const content = await writeTargetFile(projectRoot, index, target);\n writtenContent.set(join(projectRoot, target), content);\n }\n\n const managedSize = Buffer.byteLength(buildManagedSection(index));\n const targets = await getTargetInfos(projectRoot, config.targets);\n\n return {\n skillCount: skills.length,\n managedSize,\n targets,\n writtenContent,\n };\n}\n","import { dirname } from \"node:path\";\nimport { INDEX_HEADER, INDEX_INSTRUCTION } from \"./constants.js\";\nimport type { DiscoveredSkill } from \"./types.js\";\n\nfunction groupFilesBySubdir(\n files: { relativePath: string; name: string }[],\n): Map<string, string[]> {\n const groups = new Map<string, string[]>();\n for (const file of files) {\n const dir = dirname(file.relativePath);\n const key = dir === \".\" ? \"\" : dir;\n const existing = groups.get(key);\n if (existing) {\n existing.push(`${file.name}.md`);\n } else {\n groups.set(key, [`${file.name}.md`]);\n }\n }\n return groups;\n}\n\nexport function generateIndex(skills: DiscoveredSkill[]): string {\n const segments: string[] = [INDEX_HEADER, INDEX_INSTRUCTION];\n\n for (const skill of skills) {\n segments.push(`[${skill.name}]`);\n segments.push(`root:./${skill.relativePath}`);\n\n if (skill.description) {\n segments.push(`desc:${skill.description}`);\n }\n\n const groups = groupFilesBySubdir(skill.files);\n for (const [subdir, fileNames] of groups) {\n const fileList = `{${fileNames.join(\",\")}}`;\n if (subdir) {\n segments.push(`${subdir}:${fileList}`);\n } else {\n segments.push(fileList);\n }\n }\n }\n\n return segments.join(\"|\");\n}\n","import { readConfig, writeConfig } from \"./config.js\";\nimport { scanForSkills } from \"./scanner.js\";\nimport type { AddResult, DiscoveredSkill } from \"./types.js\";\nimport { regenerateFromConfig } from \"./writer.js\";\n\nexport async function addSkill(projectRoot: string, skillName: string): Promise<AddResult> {\n const config = await readConfig(projectRoot);\n const allSkills = await scanForSkills(projectRoot);\n\n const isPath = skillName.includes(\"/\");\n\n let targetSkill: DiscoveredSkill | undefined;\n\n if (isPath) {\n // Path-based lookup for disambiguation\n targetSkill = allSkills.find((s) => s.relativePath === skillName);\n if (!targetSkill) {\n throw new Error(`Skill \"${skillName}\" not found. Did you create the skill directory?`);\n }\n } else {\n // Name-based lookup\n const matches = allSkills.filter((s) => s.name === skillName);\n if (matches.length === 0) {\n throw new Error(`Skill \"${skillName}\" not found. Did you create the skill directory?`);\n }\n if (matches.length > 1) {\n const paths = matches.map((s) => ` ${s.relativePath}`).join(\"\\n\");\n throw new Error(`Multiple skills named \"${skillName}\" found. Specify the path:\\n${paths}`);\n }\n targetSkill = matches[0];\n }\n\n if (config.skills.some((s) => s.path === targetSkill.relativePath)) {\n throw new Error(`Skill \"${targetSkill.relativePath}\" is already indexed`);\n }\n\n config.skills.push({\n name: targetSkill.name,\n path: targetSkill.relativePath,\n });\n\n await writeConfig(projectRoot, config);\n\n const result = await regenerateFromConfig(projectRoot);\n\n return {\n skillName: targetSkill.name,\n managedSize: result.managedSize,\n targets: result.targets,\n };\n}\n","import { writeConfig } from \"./config.js\";\nimport { TARGET_FILE } from \"./constants.js\";\nimport { scanForSkills } from \"./scanner.js\";\nimport type { DiscoveredSkill, InitResult } from \"./types.js\";\nimport { regenerateFromConfig } from \"./writer.js\";\n\n/** Scan for skills, filter by selection, and write the index to target files. */\nexport async function init(options: {\n projectRoot: string;\n selectedSkills?: string[];\n yes?: boolean;\n}): Promise<InitResult> {\n const { projectRoot, selectedSkills } = options;\n\n const discovered = await scanForSkills(projectRoot);\n\n let skills: DiscoveredSkill[];\n if (selectedSkills) {\n const selected = new Set(selectedSkills);\n skills = discovered.filter((s) => selected.has(s.name) || selected.has(s.relativePath));\n } else {\n skills = discovered;\n }\n\n return initWithSkills(projectRoot, skills);\n}\n\n/** Index a specific set of skills and write to target file(s). */\nexport async function initWithSkills(\n projectRoot: string,\n skills: DiscoveredSkill[],\n targets: string[] = [TARGET_FILE],\n): Promise<InitResult> {\n const config = {\n version: 1 as const,\n targets,\n skills: skills.map((skill) => ({\n name: skill.name,\n path: skill.relativePath,\n })),\n };\n await writeConfig(projectRoot, config);\n\n return regenerateFromConfig(projectRoot);\n}\n","import { readConfig } from \"./config.js\";\nimport { scanForSkills } from \"./scanner.js\";\nimport type { ListResult, SkillInfo } from \"./types.js\";\n\nexport async function listSkills(projectRoot: string): Promise<ListResult> {\n const config = await readConfig(projectRoot);\n const allSkills = await scanForSkills(projectRoot);\n\n const indexedPaths = new Set(config.skills.map((s) => s.path));\n const skillMap = new Map(allSkills.map((s) => [s.relativePath, s]));\n\n const indexed: SkillInfo[] = config.skills\n .map((entry) => {\n const discovered = skillMap.get(entry.path);\n if (!discovered) return undefined;\n return {\n name: entry.name,\n path: entry.path,\n description: discovered.description,\n };\n })\n .filter((s) => s !== undefined);\n\n const available: SkillInfo[] = allSkills\n .filter((s) => !indexedPaths.has(s.relativePath))\n .map((s) => ({\n name: s.name,\n description: s.description,\n path: s.relativePath,\n }));\n\n return { indexed, available };\n}\n","import { rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { readConfig, writeConfig } from \"./config.js\";\nimport type { RemoveResult } from \"./types.js\";\nimport { regenerateFromConfig } from \"./writer.js\";\n\nexport async function removeSkill(\n projectRoot: string,\n skillName: string,\n deleteFiles = false,\n): Promise<RemoveResult> {\n const config = await readConfig(projectRoot);\n\n const isPath = skillName.includes(\"/\");\n\n let skillIndex: number;\n\n if (isPath) {\n skillIndex = config.skills.findIndex((s) => s.path === skillName);\n if (skillIndex === -1) {\n throw new Error(`Skill \"${skillName}\" is not indexed`);\n }\n } else {\n const matches = config.skills\n .map((s, i) => ({ entry: s, index: i }))\n .filter(({ entry }) => entry.name === skillName);\n\n if (matches.length === 0) {\n throw new Error(`Skill \"${skillName}\" is not indexed`);\n }\n if (matches.length > 1) {\n const paths = matches.map(({ entry }) => ` ${entry.path}`).join(\"\\n\");\n throw new Error(`Multiple skills named \"${skillName}\" indexed. Specify the path:\\n${paths}`);\n }\n skillIndex = matches[0].index;\n }\n\n const entry = config.skills[skillIndex];\n const skillPath = join(projectRoot, entry.path);\n\n config.skills.splice(skillIndex, 1);\n await writeConfig(projectRoot, config);\n\n if (deleteFiles) {\n await rm(skillPath, { recursive: true, force: true });\n }\n\n const result = await regenerateFromConfig(projectRoot);\n\n return {\n skillName: entry.name,\n wasDeleted: deleteFiles,\n managedSize: result.managedSize,\n targets: result.targets,\n };\n}\n","import { join } from \"node:path\";\nimport { readConfig, writeConfig } from \"./config.js\";\nimport { safeReadFile, scanForSkills } from \"./scanner.js\";\nimport type { SyncResult } from \"./types.js\";\nimport { regenerateFromConfig } from \"./writer.js\";\n\nexport async function syncSkills(projectRoot: string): Promise<SyncResult> {\n const config = await readConfig(projectRoot);\n const onDisk = await scanForSkills(projectRoot);\n const diskPaths = new Set(onDisk.map((s) => s.relativePath));\n\n // Find stale entries: in config but not on disk\n const stale = config.skills.filter((s) => !diskPaths.has(s.path));\n const removed = stale.map((s) => s.name);\n\n if (stale.length > 0) {\n const stalePaths = new Set(stale.map((s) => s.path));\n config.skills = config.skills.filter((s) => !stalePaths.has(s.path));\n await writeConfig(projectRoot, config);\n }\n\n const targetPaths = config.targets.map((t) => join(projectRoot, t));\n\n // Read before-state for all targets\n const beforeMap = new Map<string, string | undefined>();\n for (const targetPath of targetPaths) {\n beforeMap.set(targetPath, await safeReadFile(targetPath));\n }\n\n // Nothing to do if no skills indexed and no target files exist\n if (config.skills.length === 0 && [...beforeMap.values()].every((v) => v === undefined)) {\n return { removed, changed: false, managedSize: 0, targets: [] };\n }\n\n const result = await regenerateFromConfig(projectRoot);\n\n // Check if ANY target changed using the written content from regeneration\n let changed = false;\n for (const targetPath of targetPaths) {\n const after = result.writtenContent.get(targetPath);\n if (beforeMap.get(targetPath) !== after) {\n changed = true;\n break;\n }\n }\n\n return {\n removed,\n changed,\n managedSize: result.managedSize,\n targets: result.targets,\n };\n}\n"],"mappings":"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","names":["import_promises","import_node_path","import_promises","import_node_path","import_node_path","import_promises","import_node_path","entry","import_node_path"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
interface SkillFile {
|
|
2
|
+
/** Relative path within the skill directory, e.g. "patterns/hooks.md" */
|
|
3
|
+
relativePath: string;
|
|
4
|
+
/** Filename without extension, e.g. "hooks" */
|
|
5
|
+
name: string;
|
|
6
|
+
}
|
|
7
|
+
interface DiscoveredSkill {
|
|
8
|
+
/** Directory name, e.g. "react-best-practices" */
|
|
9
|
+
name: string;
|
|
10
|
+
/** From SKILL.md frontmatter description field; empty string if not found */
|
|
11
|
+
description: string;
|
|
12
|
+
/** Absolute path to skill directory */
|
|
13
|
+
path: string;
|
|
14
|
+
/** Relative path from project root, e.g. ".agents/skills/react-best-practices" */
|
|
15
|
+
relativePath: string;
|
|
16
|
+
/** .md files in the skill (excluding SKILL.md) */
|
|
17
|
+
files: SkillFile[];
|
|
18
|
+
}
|
|
19
|
+
interface TargetFileInfo {
|
|
20
|
+
/** Target filename (e.g. "AGENTS.md") */
|
|
21
|
+
file: string;
|
|
22
|
+
/** Absolute path */
|
|
23
|
+
path: string;
|
|
24
|
+
/** Total file size in bytes */
|
|
25
|
+
totalSize: number;
|
|
26
|
+
}
|
|
27
|
+
interface InitResult {
|
|
28
|
+
skillCount: number;
|
|
29
|
+
/** Size of the managed section in bytes */
|
|
30
|
+
managedSize: number;
|
|
31
|
+
/** Per-target file details */
|
|
32
|
+
targets: TargetFileInfo[];
|
|
33
|
+
}
|
|
34
|
+
interface SkillEntry {
|
|
35
|
+
/** Skill name (e.g., "react-best-practices") */
|
|
36
|
+
name: string;
|
|
37
|
+
/** Relative path from project root (e.g., ".agents/skills/react-best-practices") */
|
|
38
|
+
path: string;
|
|
39
|
+
}
|
|
40
|
+
interface Config {
|
|
41
|
+
version: 1;
|
|
42
|
+
/** Which files to write the index to (e.g., ["AGENTS.md", "CLAUDE.md"]) */
|
|
43
|
+
targets: string[];
|
|
44
|
+
/** List of indexed skills */
|
|
45
|
+
skills: SkillEntry[];
|
|
46
|
+
}
|
|
47
|
+
interface AddResult {
|
|
48
|
+
skillName: string;
|
|
49
|
+
managedSize: number;
|
|
50
|
+
targets: TargetFileInfo[];
|
|
51
|
+
}
|
|
52
|
+
interface RemoveResult {
|
|
53
|
+
skillName: string;
|
|
54
|
+
/** true if skill files were deleted from disk */
|
|
55
|
+
wasDeleted: boolean;
|
|
56
|
+
managedSize: number;
|
|
57
|
+
targets: TargetFileInfo[];
|
|
58
|
+
}
|
|
59
|
+
interface SkillInfo {
|
|
60
|
+
name: string;
|
|
61
|
+
/** Relative path from project root */
|
|
62
|
+
path: string;
|
|
63
|
+
description: string;
|
|
64
|
+
}
|
|
65
|
+
interface ListResult {
|
|
66
|
+
indexed: SkillInfo[];
|
|
67
|
+
available: SkillInfo[];
|
|
68
|
+
}
|
|
69
|
+
interface SyncResult {
|
|
70
|
+
/** Skills that were in config but missing from disk (removed) */
|
|
71
|
+
removed: string[];
|
|
72
|
+
/** Whether any target file content actually changed after regeneration */
|
|
73
|
+
changed: boolean;
|
|
74
|
+
managedSize: number;
|
|
75
|
+
targets: TargetFileInfo[];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
declare function addSkill(projectRoot: string, skillName: string): Promise<AddResult>;
|
|
79
|
+
|
|
80
|
+
interface AgentSource {
|
|
81
|
+
/** Agent identifier, e.g. "claude-code" */
|
|
82
|
+
name: string;
|
|
83
|
+
/** Human-readable name, e.g. "Claude Code" */
|
|
84
|
+
displayName: string;
|
|
85
|
+
/** Skills directory relative to project root, e.g. ".claude/skills" */
|
|
86
|
+
skillsDir: string;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Known agent source directories (project-scoped).
|
|
90
|
+
* Sourced from the Vercel Skills CLI agent conventions.
|
|
91
|
+
*/
|
|
92
|
+
declare const AGENT_SOURCES: AgentSource[];
|
|
93
|
+
/** Unique skills directories to scan (deduplicates agents sharing the same dir). */
|
|
94
|
+
declare function getUniqueSkillsDirs(): string[];
|
|
95
|
+
/** Maps a skill's relative path to the first matching agent's display name. */
|
|
96
|
+
declare function getAgentDisplayName(relativePath: string): string | undefined;
|
|
97
|
+
|
|
98
|
+
declare function readConfig(projectRoot: string): Promise<Config>;
|
|
99
|
+
declare function writeConfig(projectRoot: string, config: Config): Promise<void>;
|
|
100
|
+
|
|
101
|
+
declare const START_TAG = "<!-- skilldex:start (auto-generated, do not edit) -->";
|
|
102
|
+
declare const END_TAG = "<!-- skilldex:end -->";
|
|
103
|
+
declare const TARGET_FILE = "AGENTS.md";
|
|
104
|
+
declare const CONFIG_FILENAME = "skilldex.config.json";
|
|
105
|
+
declare const SKILL_META_FILE = "SKILL.md";
|
|
106
|
+
declare const INDEX_HEADER = "[Skills Index]";
|
|
107
|
+
declare const INDEX_INSTRUCTION = "IMPORTANT: Prefer retrieval-led reasoning over pre-training-led reasoning for any tasks covered by indexed skills.";
|
|
108
|
+
declare const CONTEXT_BUDGET_WARN_KB = 20;
|
|
109
|
+
declare const CONTEXT_BUDGET_DANGER_KB = 40;
|
|
110
|
+
declare function compareByNameThenPath(a: {
|
|
111
|
+
name: string;
|
|
112
|
+
path: string;
|
|
113
|
+
}, b: {
|
|
114
|
+
name: string;
|
|
115
|
+
path: string;
|
|
116
|
+
}): number;
|
|
117
|
+
|
|
118
|
+
declare function generateIndex(skills: DiscoveredSkill[]): string;
|
|
119
|
+
|
|
120
|
+
/** Scan for skills, filter by selection, and write the index to target files. */
|
|
121
|
+
declare function init(options: {
|
|
122
|
+
projectRoot: string;
|
|
123
|
+
selectedSkills?: string[];
|
|
124
|
+
yes?: boolean;
|
|
125
|
+
}): Promise<InitResult>;
|
|
126
|
+
/** Index a specific set of skills and write to target file(s). */
|
|
127
|
+
declare function initWithSkills(projectRoot: string, skills: DiscoveredSkill[], targets?: string[]): Promise<InitResult>;
|
|
128
|
+
|
|
129
|
+
declare function listSkills(projectRoot: string): Promise<ListResult>;
|
|
130
|
+
|
|
131
|
+
declare function removeSkill(projectRoot: string, skillName: string, deleteFiles?: boolean): Promise<RemoveResult>;
|
|
132
|
+
|
|
133
|
+
/** Scan all agent source directories for skills. Same-named skills in different directories are all included. */
|
|
134
|
+
declare function scanForSkills(projectRoot: string): Promise<DiscoveredSkill[]>;
|
|
135
|
+
|
|
136
|
+
declare function syncSkills(projectRoot: string): Promise<SyncResult>;
|
|
137
|
+
|
|
138
|
+
declare function buildManagedSection(indexContent: string): string;
|
|
139
|
+
/** Write or update the managed skilldex section in a target file. Creates, appends, or replaces as needed. Returns the written file content. */
|
|
140
|
+
declare function writeTargetFile(projectRoot: string, indexContent: string, targetFile?: string): Promise<string>;
|
|
141
|
+
interface RegenerateResult extends InitResult {
|
|
142
|
+
/** Map of target file path → written content */
|
|
143
|
+
writtenContent: Map<string, string>;
|
|
144
|
+
}
|
|
145
|
+
/** Regenerate all target files from config (reads config, scans indexed skills, writes targets). */
|
|
146
|
+
declare function regenerateFromConfig(projectRoot: string): Promise<RegenerateResult>;
|
|
147
|
+
|
|
148
|
+
export { AGENT_SOURCES, type AddResult, type AgentSource, CONFIG_FILENAME, CONTEXT_BUDGET_DANGER_KB, CONTEXT_BUDGET_WARN_KB, type Config, type DiscoveredSkill, END_TAG, INDEX_HEADER, INDEX_INSTRUCTION, type InitResult, type ListResult, type RegenerateResult, type RemoveResult, SKILL_META_FILE, START_TAG, type SkillEntry, type SkillFile, type SkillInfo, type SyncResult, TARGET_FILE, type TargetFileInfo, addSkill, buildManagedSection, compareByNameThenPath, generateIndex, getAgentDisplayName, getUniqueSkillsDirs, init, initWithSkills, listSkills, readConfig, regenerateFromConfig, removeSkill, scanForSkills, syncSkills, writeConfig, writeTargetFile };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
interface SkillFile {
|
|
2
|
+
/** Relative path within the skill directory, e.g. "patterns/hooks.md" */
|
|
3
|
+
relativePath: string;
|
|
4
|
+
/** Filename without extension, e.g. "hooks" */
|
|
5
|
+
name: string;
|
|
6
|
+
}
|
|
7
|
+
interface DiscoveredSkill {
|
|
8
|
+
/** Directory name, e.g. "react-best-practices" */
|
|
9
|
+
name: string;
|
|
10
|
+
/** From SKILL.md frontmatter description field; empty string if not found */
|
|
11
|
+
description: string;
|
|
12
|
+
/** Absolute path to skill directory */
|
|
13
|
+
path: string;
|
|
14
|
+
/** Relative path from project root, e.g. ".agents/skills/react-best-practices" */
|
|
15
|
+
relativePath: string;
|
|
16
|
+
/** .md files in the skill (excluding SKILL.md) */
|
|
17
|
+
files: SkillFile[];
|
|
18
|
+
}
|
|
19
|
+
interface TargetFileInfo {
|
|
20
|
+
/** Target filename (e.g. "AGENTS.md") */
|
|
21
|
+
file: string;
|
|
22
|
+
/** Absolute path */
|
|
23
|
+
path: string;
|
|
24
|
+
/** Total file size in bytes */
|
|
25
|
+
totalSize: number;
|
|
26
|
+
}
|
|
27
|
+
interface InitResult {
|
|
28
|
+
skillCount: number;
|
|
29
|
+
/** Size of the managed section in bytes */
|
|
30
|
+
managedSize: number;
|
|
31
|
+
/** Per-target file details */
|
|
32
|
+
targets: TargetFileInfo[];
|
|
33
|
+
}
|
|
34
|
+
interface SkillEntry {
|
|
35
|
+
/** Skill name (e.g., "react-best-practices") */
|
|
36
|
+
name: string;
|
|
37
|
+
/** Relative path from project root (e.g., ".agents/skills/react-best-practices") */
|
|
38
|
+
path: string;
|
|
39
|
+
}
|
|
40
|
+
interface Config {
|
|
41
|
+
version: 1;
|
|
42
|
+
/** Which files to write the index to (e.g., ["AGENTS.md", "CLAUDE.md"]) */
|
|
43
|
+
targets: string[];
|
|
44
|
+
/** List of indexed skills */
|
|
45
|
+
skills: SkillEntry[];
|
|
46
|
+
}
|
|
47
|
+
interface AddResult {
|
|
48
|
+
skillName: string;
|
|
49
|
+
managedSize: number;
|
|
50
|
+
targets: TargetFileInfo[];
|
|
51
|
+
}
|
|
52
|
+
interface RemoveResult {
|
|
53
|
+
skillName: string;
|
|
54
|
+
/** true if skill files were deleted from disk */
|
|
55
|
+
wasDeleted: boolean;
|
|
56
|
+
managedSize: number;
|
|
57
|
+
targets: TargetFileInfo[];
|
|
58
|
+
}
|
|
59
|
+
interface SkillInfo {
|
|
60
|
+
name: string;
|
|
61
|
+
/** Relative path from project root */
|
|
62
|
+
path: string;
|
|
63
|
+
description: string;
|
|
64
|
+
}
|
|
65
|
+
interface ListResult {
|
|
66
|
+
indexed: SkillInfo[];
|
|
67
|
+
available: SkillInfo[];
|
|
68
|
+
}
|
|
69
|
+
interface SyncResult {
|
|
70
|
+
/** Skills that were in config but missing from disk (removed) */
|
|
71
|
+
removed: string[];
|
|
72
|
+
/** Whether any target file content actually changed after regeneration */
|
|
73
|
+
changed: boolean;
|
|
74
|
+
managedSize: number;
|
|
75
|
+
targets: TargetFileInfo[];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
declare function addSkill(projectRoot: string, skillName: string): Promise<AddResult>;
|
|
79
|
+
|
|
80
|
+
interface AgentSource {
|
|
81
|
+
/** Agent identifier, e.g. "claude-code" */
|
|
82
|
+
name: string;
|
|
83
|
+
/** Human-readable name, e.g. "Claude Code" */
|
|
84
|
+
displayName: string;
|
|
85
|
+
/** Skills directory relative to project root, e.g. ".claude/skills" */
|
|
86
|
+
skillsDir: string;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Known agent source directories (project-scoped).
|
|
90
|
+
* Sourced from the Vercel Skills CLI agent conventions.
|
|
91
|
+
*/
|
|
92
|
+
declare const AGENT_SOURCES: AgentSource[];
|
|
93
|
+
/** Unique skills directories to scan (deduplicates agents sharing the same dir). */
|
|
94
|
+
declare function getUniqueSkillsDirs(): string[];
|
|
95
|
+
/** Maps a skill's relative path to the first matching agent's display name. */
|
|
96
|
+
declare function getAgentDisplayName(relativePath: string): string | undefined;
|
|
97
|
+
|
|
98
|
+
declare function readConfig(projectRoot: string): Promise<Config>;
|
|
99
|
+
declare function writeConfig(projectRoot: string, config: Config): Promise<void>;
|
|
100
|
+
|
|
101
|
+
declare const START_TAG = "<!-- skilldex:start (auto-generated, do not edit) -->";
|
|
102
|
+
declare const END_TAG = "<!-- skilldex:end -->";
|
|
103
|
+
declare const TARGET_FILE = "AGENTS.md";
|
|
104
|
+
declare const CONFIG_FILENAME = "skilldex.config.json";
|
|
105
|
+
declare const SKILL_META_FILE = "SKILL.md";
|
|
106
|
+
declare const INDEX_HEADER = "[Skills Index]";
|
|
107
|
+
declare const INDEX_INSTRUCTION = "IMPORTANT: Prefer retrieval-led reasoning over pre-training-led reasoning for any tasks covered by indexed skills.";
|
|
108
|
+
declare const CONTEXT_BUDGET_WARN_KB = 20;
|
|
109
|
+
declare const CONTEXT_BUDGET_DANGER_KB = 40;
|
|
110
|
+
declare function compareByNameThenPath(a: {
|
|
111
|
+
name: string;
|
|
112
|
+
path: string;
|
|
113
|
+
}, b: {
|
|
114
|
+
name: string;
|
|
115
|
+
path: string;
|
|
116
|
+
}): number;
|
|
117
|
+
|
|
118
|
+
declare function generateIndex(skills: DiscoveredSkill[]): string;
|
|
119
|
+
|
|
120
|
+
/** Scan for skills, filter by selection, and write the index to target files. */
|
|
121
|
+
declare function init(options: {
|
|
122
|
+
projectRoot: string;
|
|
123
|
+
selectedSkills?: string[];
|
|
124
|
+
yes?: boolean;
|
|
125
|
+
}): Promise<InitResult>;
|
|
126
|
+
/** Index a specific set of skills and write to target file(s). */
|
|
127
|
+
declare function initWithSkills(projectRoot: string, skills: DiscoveredSkill[], targets?: string[]): Promise<InitResult>;
|
|
128
|
+
|
|
129
|
+
declare function listSkills(projectRoot: string): Promise<ListResult>;
|
|
130
|
+
|
|
131
|
+
declare function removeSkill(projectRoot: string, skillName: string, deleteFiles?: boolean): Promise<RemoveResult>;
|
|
132
|
+
|
|
133
|
+
/** Scan all agent source directories for skills. Same-named skills in different directories are all included. */
|
|
134
|
+
declare function scanForSkills(projectRoot: string): Promise<DiscoveredSkill[]>;
|
|
135
|
+
|
|
136
|
+
declare function syncSkills(projectRoot: string): Promise<SyncResult>;
|
|
137
|
+
|
|
138
|
+
declare function buildManagedSection(indexContent: string): string;
|
|
139
|
+
/** Write or update the managed skilldex section in a target file. Creates, appends, or replaces as needed. Returns the written file content. */
|
|
140
|
+
declare function writeTargetFile(projectRoot: string, indexContent: string, targetFile?: string): Promise<string>;
|
|
141
|
+
interface RegenerateResult extends InitResult {
|
|
142
|
+
/** Map of target file path → written content */
|
|
143
|
+
writtenContent: Map<string, string>;
|
|
144
|
+
}
|
|
145
|
+
/** Regenerate all target files from config (reads config, scans indexed skills, writes targets). */
|
|
146
|
+
declare function regenerateFromConfig(projectRoot: string): Promise<RegenerateResult>;
|
|
147
|
+
|
|
148
|
+
export { AGENT_SOURCES, type AddResult, type AgentSource, CONFIG_FILENAME, CONTEXT_BUDGET_DANGER_KB, CONTEXT_BUDGET_WARN_KB, type Config, type DiscoveredSkill, END_TAG, INDEX_HEADER, INDEX_INSTRUCTION, type InitResult, type ListResult, type RegenerateResult, type RemoveResult, SKILL_META_FILE, START_TAG, type SkillEntry, type SkillFile, type SkillInfo, type SyncResult, TARGET_FILE, type TargetFileInfo, addSkill, buildManagedSection, compareByNameThenPath, generateIndex, getAgentDisplayName, getUniqueSkillsDirs, init, initWithSkills, listSkills, readConfig, regenerateFromConfig, removeSkill, scanForSkills, syncSkills, writeConfig, writeTargetFile };
|