@openplaybooks/agentfn 0.2.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.
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Prompt enhancement and injection module.
3
+ *
4
+ * Handles general prompt manipulation, including:
5
+ * - Skill/agent reference enhancement
6
+ * - Prompt templating and injection
7
+ * - Context augmentation
8
+ *
9
+ * Note: The enhancePrompt function uses legacy auto-detection.
10
+ * New code should use discoverSkills/loadSkill from skills.ts directly
11
+ * and format prompts at the application level.
12
+ */
13
+ import { listSkills, listAgents, legacyGetSkillPath, legacyGetAgentPath, getSkillMeta, getAgentMeta, } from "./skills.js";
14
+ /**
15
+ * Extract @agent references from prompt
16
+ * Matches: @agent-name, @agent_name, @AgentName
17
+ */
18
+ function extractAgentRefs(prompt) {
19
+ const refs = [];
20
+ const regex = /@([a-zA-Z0-9_-]+)/g;
21
+ let match;
22
+ while ((match = regex.exec(prompt)) !== null) {
23
+ refs.push(match[1].toLowerCase());
24
+ }
25
+ return [...new Set(refs)];
26
+ }
27
+ /**
28
+ * Extract /skill commands from prompt
29
+ * Matches: /skill-name, /skill_name
30
+ */
31
+ function extractSkillRefs(prompt) {
32
+ const refs = [];
33
+ const regex = /\/([a-zA-Z0-9_-]+)/g;
34
+ let match;
35
+ while ((match = regex.exec(prompt)) !== null) {
36
+ refs.push(match[1].toLowerCase());
37
+ }
38
+ return [...new Set(refs)];
39
+ }
40
+ /**
41
+ * @deprecated Application-level prompt formatting should be done by the caller.
42
+ * This function uses legacy auto-detection of .converge/ directories.
43
+ *
44
+ * Enhance a prompt by adding footnote references to skills and agents.
45
+ *
46
+ * - /skill refs point to .converge/{name}/SKILL.md
47
+ * - @agent refs point to .converge/{name}/AGENT.md or .converge/{name}.md (fallback to SKILL.md)
48
+ *
49
+ * Returns the enhanced prompt with skill/agent footnotes.
50
+ * The AI can load these files on-demand when needed.
51
+ */
52
+ export function enhancePrompt(prompt, options) {
53
+ const cwd = options?.cwd;
54
+ const skillRefs = extractSkillRefs(prompt);
55
+ const agentRefs = extractAgentRefs(prompt);
56
+ const footnotes = [];
57
+ // Collect /skill references (capabilities)
58
+ for (const ref of skillRefs) {
59
+ const skillPath = legacyGetSkillPath(ref, cwd);
60
+ if (skillPath) {
61
+ const meta = getSkillMeta(skillPath);
62
+ const desc = meta?.description || "No description";
63
+ footnotes.push(`[^skill:${ref}]: **${meta?.name || ref}** — ${desc} [Load: ${skillPath}]`);
64
+ }
65
+ }
66
+ // Collect @agent references (try agent first, fallback to skill)
67
+ for (const ref of agentRefs) {
68
+ let agentPath = legacyGetAgentPath(ref, cwd);
69
+ let meta = null;
70
+ let footnoteType = "agent";
71
+ if (agentPath) {
72
+ meta = getAgentMeta(agentPath);
73
+ footnoteType = "agent";
74
+ }
75
+ // Fallback to skill if no agent found
76
+ if (!agentPath) {
77
+ agentPath = legacyGetSkillPath(ref, cwd);
78
+ if (agentPath) {
79
+ meta = getSkillMeta(agentPath);
80
+ footnoteType = "skill";
81
+ }
82
+ }
83
+ if (agentPath && meta) {
84
+ footnotes.push(`[^${footnoteType}:${ref}]: **${meta?.name || ref}** — ${meta?.description || "No description"} [Load: ${agentPath}]`);
85
+ }
86
+ }
87
+ if (footnotes.length === 0) {
88
+ return prompt;
89
+ }
90
+ // Build enhanced prompt
91
+ const parts = [];
92
+ parts.push("<!-- REFERENCED SKILLS/AGENTS -->");
93
+ parts.push("The following skills/agents are referenced. Load the file if you need the full instructions:");
94
+ parts.push("");
95
+ parts.push(...footnotes);
96
+ parts.push("");
97
+ parts.push("<!-- USER PROMPT -->");
98
+ parts.push(prompt);
99
+ return parts.join("\n");
100
+ }
101
+ // Re-export skill listing functions for convenience (legacy)
102
+ export { listSkills, listAgents };
103
+ //# sourceMappingURL=prompting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompting.js","sourceRoot":"","sources":["../src/prompting.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { Provider } from "./types.js";
2
+ /** Get the current default provider */
3
+ export declare function getDefaultProvider(): Provider;
4
+ /** Set the default provider used when no provider is specified */
5
+ export declare function setDefaultProvider(provider: Provider): void;
6
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAI3C,uCAAuC;AACvC,wBAAgB,kBAAkB,IAAI,QAAQ,CAE7C;AAED,kEAAkE;AAClE,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAE3D"}
@@ -0,0 +1,10 @@
1
+ let _defaultProvider = "claude";
2
+ /** Get the current default provider */
3
+ export function getDefaultProvider() {
4
+ return _defaultProvider;
5
+ }
6
+ /** Set the default provider used when no provider is specified */
7
+ export function setDefaultProvider(provider) {
8
+ _defaultProvider = provider;
9
+ }
10
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAEA,IAAI,gBAAgB,GAAa,QAAQ,CAAC;AAE1C,uCAAuC;AACvC,MAAM,UAAU,kBAAkB;IAChC,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,kBAAkB,CAAC,QAAkB;IACnD,gBAAgB,GAAG,QAAQ,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Skill and agent loading utilities.
3
+ *
4
+ * All functions take explicit paths — no hardcoded .converge/ or project root detection.
5
+ * The caller decides where skills live and which ones to activate.
6
+ *
7
+ * Handles:
8
+ * - Discovering skills in a directory (folders with SKILL.md)
9
+ * - Loading skill/agent metadata (YAML frontmatter)
10
+ * - Creating/cleaning symlinks for Claude Code and OpenCode native skill discovery locations
11
+ */
12
+ /** Info about a discovered skill */
13
+ export interface SkillInfo {
14
+ /** Directory name (e.g. "page-build") */
15
+ dirName: string;
16
+ /** Name from frontmatter, or directory name if missing */
17
+ name: string;
18
+ /** Description from frontmatter */
19
+ description: string;
20
+ /** Absolute path to the SKILL.md file */
21
+ path: string;
22
+ }
23
+ /** Loaded skill content */
24
+ export interface SkillContent {
25
+ /** Parsed frontmatter key-value pairs */
26
+ meta: Record<string, string>;
27
+ /** Markdown body (frontmatter stripped) */
28
+ body: string;
29
+ /** Absolute path to the SKILL.md file */
30
+ path: string;
31
+ }
32
+ /** Parse YAML frontmatter from markdown content */
33
+ export declare function parseFrontmatter(content: string): Record<string, string>;
34
+ /** Strip frontmatter from markdown content, return body only */
35
+ export declare function stripFrontmatter(content: string): string;
36
+ /**
37
+ * Discover skills in a directory.
38
+ * Scans for subdirectories containing SKILL.md.
39
+ *
40
+ * @param skillsRoot - Absolute path to the skills directory (e.g. "/project/.converge/skills")
41
+ */
42
+ export declare function discoverSkills(skillsRoot: string): SkillInfo[];
43
+ /**
44
+ * Load a skill's content from a skills root directory.
45
+ *
46
+ * @param skillsRoot - Absolute path to the skills directory
47
+ * @param name - Skill name (directory name)
48
+ */
49
+ export declare function loadSkill(skillsRoot: string, name: string): SkillContent | null;
50
+ /**
51
+ * Load a skill from multiple root directories (first match wins).
52
+ *
53
+ * @param roots - Array of absolute paths to search
54
+ * @param name - Skill name (directory name)
55
+ */
56
+ export declare function loadSkillFromRoots(roots: string[], name: string): SkillContent | null;
57
+ /**
58
+ * Get the absolute path to a skill file, searching multiple roots.
59
+ *
60
+ * @param roots - Array of absolute paths to search
61
+ * @param name - Skill name (directory name)
62
+ */
63
+ export declare function getSkillPath(roots: string[], name: string): string | null;
64
+ /**
65
+ * Get skill metadata from a SKILL.md file path.
66
+ */
67
+ export declare function getSkillMeta(path: string): Record<string, string> | null;
68
+ /**
69
+ * Discover agents in a directory.
70
+ * Looks for {name}/AGENT.md or {name}.md files.
71
+ *
72
+ * @param agentsRoot - Absolute path to agents directory
73
+ */
74
+ export declare function discoverAgents(agentsRoot: string): string[];
75
+ /**
76
+ * Get the absolute path to an agent file.
77
+ *
78
+ * @param agentsRoot - Absolute path to agents directory
79
+ * @param name - Agent name
80
+ */
81
+ export declare function getAgentPath(agentsRoot: string, name: string): string | null;
82
+ /**
83
+ * Get agent metadata from an AGENT.md file path.
84
+ */
85
+ export declare function getAgentMeta(path: string): Record<string, string> | null;
86
+ export interface SymlinkOptions {
87
+ /** Only create symlinks for these skill names. If omitted, symlinks all discovered skills. */
88
+ skills?: string[];
89
+ /** Target directory for symlinks (e.g. "/project/.claude/skills") */
90
+ targetRoot?: string;
91
+ }
92
+ /**
93
+ * Create symlinks in targetRoot pointing to skillsRoot/{name}.
94
+ * Only creates symlinks for skills that don't already have an entry in targetRoot.
95
+ *
96
+ * @param skillsRoot - Absolute path to the source skills directory
97
+ * @param opts - Options for filtering and target directory
98
+ * @returns Array of symlink names created (for cleanup)
99
+ */
100
+ export declare function ensureSkillSymlinks(skillsRoot: string, opts?: SymlinkOptions): string[];
101
+ /**
102
+ * Remove symlinks by name from a target directory.
103
+ * Only removes symlinks (not real directories).
104
+ *
105
+ * @param names - Symlink names to remove
106
+ * @param targetRoot - Directory containing the symlinks
107
+ */
108
+ export declare function cleanupSkillSymlinks(names: string[], targetRoot: string): void;
109
+ /**
110
+ * @deprecated Use discoverSkills(skillsRoot) instead.
111
+ * Lists skills under <projectRoot>/.claude/skills and <projectRoot>/.converge.
112
+ */
113
+ export declare function listSkills(cwd?: string): string[];
114
+ /**
115
+ * @deprecated Use discoverAgents(agentsRoot) instead.
116
+ * Lists agents under <projectRoot>/.converge.
117
+ */
118
+ export declare function listAgents(cwd?: string): string[];
119
+ /**
120
+ * @deprecated Use getSkillPath(roots, name) instead.
121
+ */
122
+ export declare function legacyGetSkillPath(name: string, cwd?: string): string | null;
123
+ /**
124
+ * @deprecated Use getAgentPath(agentsRoot, name) instead.
125
+ */
126
+ export declare function legacyGetAgentPath(name: string, cwd?: string): string | null;
127
+ /**
128
+ * Resolve <projectRoot>/.converge/, honoring CONVERGE_PATH override.
129
+ * @internal
130
+ */
131
+ export declare function _getConvergeDir(cwd?: string): string | null;
132
+ //# sourceMappingURL=skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../src/skills.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAoBH,oCAAoC;AACpC,MAAM,WAAW,SAAS;IACxB,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,2BAA2B;AAC3B,MAAM,WAAW,YAAY;IAC3B,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;CACd;AAMD,mDAAmD;AACnD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAsBxE;AAED,gEAAgE;AAChE,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD;AAMD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,CA2B9D;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CACvB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,GACX,YAAY,GAAG,IAAI,CAcrB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EAAE,EACf,IAAI,EAAE,MAAM,GACX,YAAY,GAAG,IAAI,CAMrB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMzE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAOxE;AAMD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAgB3D;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM5E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAOxE;AAMD,MAAM,WAAW,cAAc;IAC7B,8FAA8F;IAC9F,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE,cAAc,GACpB,MAAM,EAAE,CAsCV;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,GACjB,IAAI,CA6BN;AAWD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAYjD;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAIjD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ5E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI5E;AAMD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK3D"}
package/dist/skills.js ADDED
@@ -0,0 +1,354 @@
1
+ /**
2
+ * Skill and agent loading utilities.
3
+ *
4
+ * All functions take explicit paths — no hardcoded .converge/ or project root detection.
5
+ * The caller decides where skills live and which ones to activate.
6
+ *
7
+ * Handles:
8
+ * - Discovering skills in a directory (folders with SKILL.md)
9
+ * - Loading skill/agent metadata (YAML frontmatter)
10
+ * - Creating/cleaning symlinks for Claude Code and OpenCode native skill discovery locations
11
+ */
12
+ import { existsSync, readdirSync, readFileSync, mkdirSync, symlinkSync, lstatSync, unlinkSync, rmdirSync, } from "node:fs";
13
+ import { join, resolve, relative } from "node:path";
14
+ import { platform } from "node:os";
15
+ import { findConvergeRoot } from "./find-converge-root.js";
16
+ /* ------------------------------------------------------------------ */
17
+ /* Frontmatter Parsing */
18
+ /* ------------------------------------------------------------------ */
19
+ /** Parse YAML frontmatter from markdown content */
20
+ export function parseFrontmatter(content) {
21
+ const result = {};
22
+ const match = content.match(/^---\n([\s\S]*?)\n---/);
23
+ if (!match)
24
+ return result;
25
+ const yaml = match[1];
26
+ for (const line of yaml.split("\n")) {
27
+ const colonIndex = line.indexOf(":");
28
+ if (colonIndex > 0) {
29
+ const key = line.slice(0, colonIndex).trim();
30
+ let value = line.slice(colonIndex + 1).trim();
31
+ // Strip surrounding quotes
32
+ if ((value.startsWith('"') && value.endsWith('"')) ||
33
+ (value.startsWith("'") && value.endsWith("'"))) {
34
+ value = value.slice(1, -1);
35
+ }
36
+ result[key] = value;
37
+ }
38
+ }
39
+ return result;
40
+ }
41
+ /** Strip frontmatter from markdown content, return body only */
42
+ export function stripFrontmatter(content) {
43
+ return content.replace(/^---\n[\s\S]*?\n---\n*/, "").trim();
44
+ }
45
+ /* ------------------------------------------------------------------ */
46
+ /* Skill Discovery & Loading */
47
+ /* ------------------------------------------------------------------ */
48
+ /**
49
+ * Discover skills in a directory.
50
+ * Scans for subdirectories containing SKILL.md.
51
+ *
52
+ * @param skillsRoot - Absolute path to the skills directory (e.g. "/project/.converge/skills")
53
+ */
54
+ export function discoverSkills(skillsRoot) {
55
+ if (!existsSync(skillsRoot))
56
+ return [];
57
+ const results = [];
58
+ try {
59
+ const entries = readdirSync(skillsRoot, { withFileTypes: true });
60
+ for (const d of entries) {
61
+ if (!d.isDirectory())
62
+ continue;
63
+ const skillFile = join(skillsRoot, d.name, "SKILL.md");
64
+ if (!existsSync(skillFile))
65
+ continue;
66
+ const content = readFileSync(skillFile, "utf-8");
67
+ const meta = parseFrontmatter(content);
68
+ results.push({
69
+ dirName: d.name,
70
+ name: meta.name || d.name,
71
+ description: meta.description || "",
72
+ path: skillFile,
73
+ });
74
+ }
75
+ }
76
+ catch {
77
+ /* directory read failed */
78
+ }
79
+ return results;
80
+ }
81
+ /**
82
+ * Load a skill's content from a skills root directory.
83
+ *
84
+ * @param skillsRoot - Absolute path to the skills directory
85
+ * @param name - Skill name (directory name)
86
+ */
87
+ export function loadSkill(skillsRoot, name) {
88
+ const skillFile = join(skillsRoot, name, "SKILL.md");
89
+ if (!existsSync(skillFile))
90
+ return null;
91
+ try {
92
+ const content = readFileSync(skillFile, "utf-8");
93
+ return {
94
+ meta: parseFrontmatter(content),
95
+ body: stripFrontmatter(content),
96
+ path: skillFile,
97
+ };
98
+ }
99
+ catch {
100
+ return null;
101
+ }
102
+ }
103
+ /**
104
+ * Load a skill from multiple root directories (first match wins).
105
+ *
106
+ * @param roots - Array of absolute paths to search
107
+ * @param name - Skill name (directory name)
108
+ */
109
+ export function loadSkillFromRoots(roots, name) {
110
+ for (const root of roots) {
111
+ const result = loadSkill(root, name);
112
+ if (result)
113
+ return result;
114
+ }
115
+ return null;
116
+ }
117
+ /**
118
+ * Get the absolute path to a skill file, searching multiple roots.
119
+ *
120
+ * @param roots - Array of absolute paths to search
121
+ * @param name - Skill name (directory name)
122
+ */
123
+ export function getSkillPath(roots, name) {
124
+ for (const root of roots) {
125
+ const skillFile = join(root, name, "SKILL.md");
126
+ if (existsSync(skillFile))
127
+ return skillFile;
128
+ }
129
+ return null;
130
+ }
131
+ /**
132
+ * Get skill metadata from a SKILL.md file path.
133
+ */
134
+ export function getSkillMeta(path) {
135
+ try {
136
+ const content = readFileSync(path, "utf-8");
137
+ return parseFrontmatter(content);
138
+ }
139
+ catch {
140
+ return null;
141
+ }
142
+ }
143
+ /* ------------------------------------------------------------------ */
144
+ /* Agent Discovery & Loading */
145
+ /* ------------------------------------------------------------------ */
146
+ /**
147
+ * Discover agents in a directory.
148
+ * Looks for {name}/AGENT.md or {name}.md files.
149
+ *
150
+ * @param agentsRoot - Absolute path to agents directory
151
+ */
152
+ export function discoverAgents(agentsRoot) {
153
+ if (!existsSync(agentsRoot))
154
+ return [];
155
+ try {
156
+ const entries = readdirSync(agentsRoot, { withFileTypes: true });
157
+ const dirs = entries
158
+ .filter((d) => d.isDirectory())
159
+ .map((d) => d.name)
160
+ .filter((name) => existsSync(join(agentsRoot, name, "AGENT.md")));
161
+ const files = entries
162
+ .filter((d) => d.isFile() && d.name.endsWith(".md"))
163
+ .map((d) => d.name.replace(".md", ""));
164
+ return [...new Set([...dirs, ...files])];
165
+ }
166
+ catch {
167
+ return [];
168
+ }
169
+ }
170
+ /**
171
+ * Get the absolute path to an agent file.
172
+ *
173
+ * @param agentsRoot - Absolute path to agents directory
174
+ * @param name - Agent name
175
+ */
176
+ export function getAgentPath(agentsRoot, name) {
177
+ const path1 = join(agentsRoot, `${name}.md`);
178
+ const path2 = join(agentsRoot, name, "AGENT.md");
179
+ if (existsSync(path1))
180
+ return path1;
181
+ if (existsSync(path2))
182
+ return path2;
183
+ return null;
184
+ }
185
+ /**
186
+ * Get agent metadata from an AGENT.md file path.
187
+ */
188
+ export function getAgentMeta(path) {
189
+ try {
190
+ const content = readFileSync(path, "utf-8");
191
+ return parseFrontmatter(content);
192
+ }
193
+ catch {
194
+ return null;
195
+ }
196
+ }
197
+ /**
198
+ * Create symlinks in targetRoot pointing to skillsRoot/{name}.
199
+ * Only creates symlinks for skills that don't already have an entry in targetRoot.
200
+ *
201
+ * @param skillsRoot - Absolute path to the source skills directory
202
+ * @param opts - Options for filtering and target directory
203
+ * @returns Array of symlink names created (for cleanup)
204
+ */
205
+ export function ensureSkillSymlinks(skillsRoot, opts) {
206
+ if (!existsSync(skillsRoot))
207
+ return [];
208
+ if (!opts?.targetRoot)
209
+ return [];
210
+ const targetRoot = opts.targetRoot;
211
+ const created = [];
212
+ try {
213
+ const entries = readdirSync(skillsRoot, { withFileTypes: true });
214
+ for (const d of entries) {
215
+ if (!d.isDirectory())
216
+ continue;
217
+ if (!existsSync(join(skillsRoot, d.name, "SKILL.md")))
218
+ continue;
219
+ if (opts.skills && !opts.skills.includes(d.name))
220
+ continue;
221
+ const linkPath = join(targetRoot, d.name);
222
+ // Skip if already exists (symlink or real dir)
223
+ try {
224
+ lstatSync(linkPath);
225
+ continue;
226
+ }
227
+ catch {
228
+ /* doesn't exist, create it */
229
+ }
230
+ mkdirSync(targetRoot, { recursive: true });
231
+ const absTarget = resolve(join(skillsRoot, d.name));
232
+ if (platform() === "win32") {
233
+ symlinkSync(absTarget, linkPath, "junction");
234
+ }
235
+ else {
236
+ symlinkSync(relative(targetRoot, absTarget), linkPath);
237
+ }
238
+ created.push(d.name);
239
+ }
240
+ }
241
+ catch {
242
+ /* ignore */
243
+ }
244
+ return created;
245
+ }
246
+ /**
247
+ * Remove symlinks by name from a target directory.
248
+ * Only removes symlinks (not real directories).
249
+ *
250
+ * @param names - Symlink names to remove
251
+ * @param targetRoot - Directory containing the symlinks
252
+ */
253
+ export function cleanupSkillSymlinks(names, targetRoot) {
254
+ if (names.length === 0)
255
+ return;
256
+ for (const name of names) {
257
+ const linkPath = join(targetRoot, name);
258
+ try {
259
+ if (lstatSync(linkPath).isSymbolicLink()) {
260
+ if (platform() === "win32") {
261
+ // Windows junctions are reported as symlinks but must be removed with rmdirSync
262
+ try {
263
+ rmdirSync(linkPath);
264
+ }
265
+ catch {
266
+ unlinkSync(linkPath);
267
+ }
268
+ }
269
+ else {
270
+ unlinkSync(linkPath);
271
+ }
272
+ }
273
+ }
274
+ catch {
275
+ /* already gone */
276
+ }
277
+ }
278
+ // Remove dir if empty
279
+ try {
280
+ rmdirSync(targetRoot);
281
+ }
282
+ catch {
283
+ /* not empty */
284
+ }
285
+ }
286
+ /* ------------------------------------------------------------------ */
287
+ /* Legacy Compat (deprecated — used by prompting.ts and external */
288
+ /* callers that haven't migrated to discoverSkills/getSkillPath) */
289
+ /* */
290
+ /* All resolution flows through findConvergeRoot — the single */
291
+ /* source of truth for "where is the project". Project root = */
292
+ /* nearest ancestor (or self) containing .converge/. */
293
+ /* ------------------------------------------------------------------ */
294
+ /**
295
+ * @deprecated Use discoverSkills(skillsRoot) instead.
296
+ * Lists skills under <projectRoot>/.claude/skills and <projectRoot>/.converge.
297
+ */
298
+ export function listSkills(cwd) {
299
+ const root = findConvergeRoot(cwd ?? process.cwd());
300
+ if (!root)
301
+ return [];
302
+ const skills = new Set();
303
+ for (const info of discoverSkills(join(root, ".claude", "skills"))) {
304
+ skills.add(info.dirName);
305
+ }
306
+ for (const info of discoverSkills(join(root, ".converge"))) {
307
+ skills.add(info.dirName);
308
+ }
309
+ return [...skills];
310
+ }
311
+ /**
312
+ * @deprecated Use discoverAgents(agentsRoot) instead.
313
+ * Lists agents under <projectRoot>/.converge.
314
+ */
315
+ export function listAgents(cwd) {
316
+ const convergeDir = _getConvergeDir(cwd);
317
+ if (!convergeDir)
318
+ return [];
319
+ return discoverAgents(convergeDir);
320
+ }
321
+ /**
322
+ * @deprecated Use getSkillPath(roots, name) instead.
323
+ */
324
+ export function legacyGetSkillPath(name, cwd) {
325
+ const root = findConvergeRoot(cwd ?? process.cwd());
326
+ if (!root)
327
+ return null;
328
+ return getSkillPath([join(root, ".claude", "skills"), join(root, ".converge")], name);
329
+ }
330
+ /**
331
+ * @deprecated Use getAgentPath(agentsRoot, name) instead.
332
+ */
333
+ export function legacyGetAgentPath(name, cwd) {
334
+ const convergeDir = _getConvergeDir(cwd);
335
+ if (!convergeDir)
336
+ return null;
337
+ return getAgentPath(convergeDir, name);
338
+ }
339
+ /* ------------------------------------------------------------------ */
340
+ /* Internal helpers */
341
+ /* ------------------------------------------------------------------ */
342
+ /**
343
+ * Resolve <projectRoot>/.converge/, honoring CONVERGE_PATH override.
344
+ * @internal
345
+ */
346
+ export function _getConvergeDir(cwd) {
347
+ if (process.env.CONVERGE_PATH)
348
+ return process.env.CONVERGE_PATH;
349
+ const root = findConvergeRoot(cwd ?? process.cwd());
350
+ if (!root)
351
+ return null;
352
+ return join(root, ".converge");
353
+ }
354
+ //# sourceMappingURL=skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.js","sourceRoot":"","sources":["../src/skills.ts"],"names":[],"mappings":"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"}