@polka-codes/core 0.10.11 → 0.10.16

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.
Files changed (250) hide show
  1. package/dist/Agent/backoff.d.ts +7 -0
  2. package/dist/Agent/backoff.js +21 -0
  3. package/dist/Agent/backoff.js.map +1 -0
  4. package/dist/Agent/index.d.ts +2 -0
  5. package/dist/Agent/index.js +3 -0
  6. package/dist/Agent/index.js.map +1 -0
  7. package/dist/Agent/parseJsonFromMarkdown.d.ts +8 -0
  8. package/dist/Agent/parseJsonFromMarkdown.js +34 -0
  9. package/dist/Agent/parseJsonFromMarkdown.js.map +1 -0
  10. package/dist/Agent/parseJsonFromMarkdown.test.d.ts +1 -0
  11. package/dist/Agent/parseJsonFromMarkdown.test.js +70 -0
  12. package/dist/Agent/parseJsonFromMarkdown.test.js.map +1 -0
  13. package/dist/Agent/prompts.d.ts +9 -0
  14. package/dist/Agent/prompts.js +107 -0
  15. package/dist/Agent/prompts.js.map +1 -0
  16. package/dist/UsageMeter.d.ts +101 -0
  17. package/dist/UsageMeter.js +299 -0
  18. package/dist/UsageMeter.js.map +1 -0
  19. package/dist/UsageMeter.test.d.ts +4 -0
  20. package/dist/UsageMeter.test.js +556 -0
  21. package/dist/UsageMeter.test.js.map +1 -0
  22. package/dist/config/base.d.ts +68 -0
  23. package/dist/config/base.js +56 -0
  24. package/dist/config/base.js.map +1 -0
  25. package/dist/config/memory.d.ts +24 -0
  26. package/dist/config/memory.js +36 -0
  27. package/dist/config/memory.js.map +1 -0
  28. package/dist/config.d.ts +236 -0
  29. package/dist/config.js +184 -0
  30. package/dist/config.js.map +1 -0
  31. package/dist/errors/base.d.ts +31 -0
  32. package/dist/errors/base.js +60 -0
  33. package/dist/errors/base.js.map +1 -0
  34. package/dist/errors/index.d.ts +1 -0
  35. package/dist/errors/index.js +3 -0
  36. package/dist/errors/index.js.map +1 -0
  37. package/dist/fs/index.d.ts +2 -0
  38. package/dist/fs/index.js +3 -0
  39. package/dist/fs/index.js.map +1 -0
  40. package/dist/fs/node-provider.d.ts +16 -0
  41. package/dist/fs/node-provider.js +47 -0
  42. package/dist/fs/node-provider.js.map +1 -0
  43. package/dist/fs/provider.d.ts +61 -0
  44. package/dist/fs/provider.js +3 -0
  45. package/dist/fs/provider.js.map +1 -0
  46. package/dist/index.d.ts +20 -191
  47. package/dist/index.js +21 -4123
  48. package/dist/index.js.map +1 -0
  49. package/dist/memory/index.d.ts +1 -0
  50. package/dist/memory/index.js +2 -0
  51. package/dist/memory/index.js.map +1 -0
  52. package/dist/memory/types.d.ts +136 -0
  53. package/dist/memory/types.js +2 -0
  54. package/dist/memory/types.js.map +1 -0
  55. package/dist/path.d.ts +9 -0
  56. package/dist/path.js +68 -0
  57. package/dist/path.js.map +1 -0
  58. package/dist/path.test.d.ts +1 -0
  59. package/dist/path.test.js +82 -0
  60. package/dist/path.test.js.map +1 -0
  61. package/dist/pricing/converter.d.ts +6 -0
  62. package/dist/pricing/converter.js +13 -0
  63. package/dist/pricing/converter.js.map +1 -0
  64. package/dist/pricing/converter.test.d.ts +1 -0
  65. package/dist/pricing/converter.test.js +54 -0
  66. package/dist/pricing/converter.test.js.map +1 -0
  67. package/dist/pricing/index.d.ts +2 -0
  68. package/dist/pricing/index.js +2 -0
  69. package/dist/pricing/index.js.map +1 -0
  70. package/dist/pricing/portkey-client.d.ts +2 -0
  71. package/dist/pricing/portkey-client.js +57 -0
  72. package/dist/pricing/portkey-client.js.map +1 -0
  73. package/dist/pricing/pricing-service.d.ts +6 -0
  74. package/dist/pricing/pricing-service.js +125 -0
  75. package/dist/pricing/pricing-service.js.map +1 -0
  76. package/dist/pricing/pricing-service.test.d.ts +1 -0
  77. package/dist/pricing/pricing-service.test.js +141 -0
  78. package/dist/pricing/pricing-service.test.js.map +1 -0
  79. package/dist/pricing/types.d.ts +24 -0
  80. package/dist/pricing/types.js +2 -0
  81. package/dist/pricing/types.js.map +1 -0
  82. package/dist/skills/__tests__/discovery.test.d.ts +1 -0
  83. package/dist/skills/__tests__/discovery.test.js +254 -0
  84. package/dist/skills/__tests__/discovery.test.js.map +1 -0
  85. package/dist/skills/__tests__/validation.test.d.ts +1 -0
  86. package/dist/skills/__tests__/validation.test.js +221 -0
  87. package/dist/skills/__tests__/validation.test.js.map +1 -0
  88. package/dist/skills/constants.d.ts +32 -0
  89. package/dist/skills/constants.js +50 -0
  90. package/dist/skills/constants.js.map +1 -0
  91. package/dist/skills/discovery.d.ts +56 -0
  92. package/dist/skills/discovery.js +392 -0
  93. package/dist/skills/discovery.js.map +1 -0
  94. package/dist/skills/index.d.ts +4 -0
  95. package/dist/skills/index.js +6 -0
  96. package/dist/skills/index.js.map +1 -0
  97. package/dist/skills/tools/index.d.ts +3 -0
  98. package/dist/skills/tools/index.js +5 -0
  99. package/dist/skills/tools/index.js.map +1 -0
  100. package/dist/skills/tools/listSkills.d.ts +54 -0
  101. package/dist/skills/tools/listSkills.js +52 -0
  102. package/dist/skills/tools/listSkills.js.map +1 -0
  103. package/dist/skills/tools/loadSkill.d.ts +52 -0
  104. package/dist/skills/tools/loadSkill.js +86 -0
  105. package/dist/skills/tools/loadSkill.js.map +1 -0
  106. package/dist/skills/tools/readSkillFile.d.ts +43 -0
  107. package/dist/skills/tools/readSkillFile.js +68 -0
  108. package/dist/skills/tools/readSkillFile.js.map +1 -0
  109. package/dist/skills/types.d.ts +83 -0
  110. package/dist/skills/types.js +42 -0
  111. package/dist/skills/types.js.map +1 -0
  112. package/dist/skills/validation.d.ts +30 -0
  113. package/dist/skills/validation.js +133 -0
  114. package/dist/skills/validation.js.map +1 -0
  115. package/dist/tool.d.ts +51 -0
  116. package/dist/tool.js +2 -0
  117. package/dist/tool.js.map +1 -0
  118. package/dist/tools/askFollowupQuestion.d.ts +35 -0
  119. package/dist/tools/askFollowupQuestion.js +105 -0
  120. package/dist/tools/askFollowupQuestion.js.map +1 -0
  121. package/dist/tools/askFollowupQuestion.test.d.ts +1 -0
  122. package/dist/tools/askFollowupQuestion.test.js +80 -0
  123. package/dist/tools/askFollowupQuestion.test.js.map +1 -0
  124. package/dist/tools/executeCommand.d.ts +29 -0
  125. package/dist/tools/executeCommand.js +82 -0
  126. package/dist/tools/executeCommand.js.map +1 -0
  127. package/dist/tools/executeCommand.test.d.ts +1 -0
  128. package/dist/tools/executeCommand.test.js +60 -0
  129. package/dist/tools/executeCommand.test.js.map +1 -0
  130. package/dist/tools/fetchUrl.d.ts +26 -0
  131. package/dist/tools/fetchUrl.js +85 -0
  132. package/dist/tools/fetchUrl.js.map +1 -0
  133. package/dist/tools/index.d.ts +15 -0
  134. package/dist/tools/index.js +17 -0
  135. package/dist/tools/index.js.map +1 -0
  136. package/dist/tools/listFiles.d.ts +35 -0
  137. package/dist/tools/listFiles.js +61 -0
  138. package/dist/tools/listFiles.js.map +1 -0
  139. package/dist/tools/listFiles.test.d.ts +1 -0
  140. package/dist/tools/listFiles.test.js +59 -0
  141. package/dist/tools/listFiles.test.js.map +1 -0
  142. package/dist/tools/provider.d.ts +76 -0
  143. package/dist/tools/provider.js +60 -0
  144. package/dist/tools/provider.js.map +1 -0
  145. package/dist/tools/readBinaryFile.d.ts +26 -0
  146. package/dist/tools/readBinaryFile.js +52 -0
  147. package/dist/tools/readBinaryFile.js.map +1 -0
  148. package/dist/tools/readFile.d.ts +35 -0
  149. package/dist/tools/readFile.js +128 -0
  150. package/dist/tools/readFile.js.map +1 -0
  151. package/dist/tools/readFile.test.d.ts +1 -0
  152. package/dist/tools/readFile.test.js +37 -0
  153. package/dist/tools/readFile.test.js.map +1 -0
  154. package/dist/tools/removeFile.d.ts +26 -0
  155. package/dist/tools/removeFile.js +49 -0
  156. package/dist/tools/removeFile.js.map +1 -0
  157. package/dist/tools/removeFile.test.d.ts +1 -0
  158. package/dist/tools/removeFile.test.js +32 -0
  159. package/dist/tools/removeFile.test.js.map +1 -0
  160. package/dist/tools/renameFile.d.ts +29 -0
  161. package/dist/tools/renameFile.js +48 -0
  162. package/dist/tools/renameFile.js.map +1 -0
  163. package/dist/tools/renameFile.test.d.ts +1 -0
  164. package/dist/tools/renameFile.test.js +53 -0
  165. package/dist/tools/renameFile.test.js.map +1 -0
  166. package/dist/tools/replaceInFile.d.ts +29 -0
  167. package/dist/tools/replaceInFile.js +233 -0
  168. package/dist/tools/replaceInFile.js.map +1 -0
  169. package/dist/tools/replaceInFile.test.d.ts +1 -0
  170. package/dist/tools/replaceInFile.test.js +79 -0
  171. package/dist/tools/replaceInFile.test.js.map +1 -0
  172. package/dist/tools/response-builders.d.ts +64 -0
  173. package/dist/tools/response-builders.js +88 -0
  174. package/dist/tools/response-builders.js.map +1 -0
  175. package/dist/tools/search.d.ts +26 -0
  176. package/dist/tools/search.js +56 -0
  177. package/dist/tools/search.js.map +1 -0
  178. package/dist/tools/search.test.d.ts +1 -0
  179. package/dist/tools/search.test.js +22 -0
  180. package/dist/tools/search.test.js.map +1 -0
  181. package/dist/tools/searchFiles.d.ts +32 -0
  182. package/dist/tools/searchFiles.js +86 -0
  183. package/dist/tools/searchFiles.js.map +1 -0
  184. package/dist/tools/todo.d.ts +37 -0
  185. package/dist/tools/todo.js +41 -0
  186. package/dist/tools/todo.js.map +1 -0
  187. package/dist/tools/utils/index.d.ts +1 -0
  188. package/dist/tools/utils/index.js +2 -0
  189. package/dist/tools/utils/index.js.map +1 -0
  190. package/dist/tools/utils/replaceInFile.d.ts +7 -0
  191. package/dist/tools/utils/replaceInFile.js +133 -0
  192. package/dist/tools/utils/replaceInFile.js.map +1 -0
  193. package/dist/tools/utils/replaceInFile.test.d.ts +1 -0
  194. package/dist/tools/utils/replaceInFile.test.js +308 -0
  195. package/dist/tools/utils/replaceInFile.test.js.map +1 -0
  196. package/dist/tools/utils.d.ts +10 -0
  197. package/dist/tools/utils.js +27 -0
  198. package/dist/tools/utils.js.map +1 -0
  199. package/dist/tools/writeToFile.d.ts +29 -0
  200. package/dist/tools/writeToFile.js +85 -0
  201. package/dist/tools/writeToFile.js.map +1 -0
  202. package/dist/tools/writeToFile.test.d.ts +1 -0
  203. package/dist/tools/writeToFile.test.js +46 -0
  204. package/dist/tools/writeToFile.test.js.map +1 -0
  205. package/dist/utils/index.d.ts +1 -0
  206. package/dist/utils/index.js +3 -0
  207. package/dist/utils/index.js.map +1 -0
  208. package/dist/utils/merge.d.ts +26 -0
  209. package/dist/utils/merge.js +45 -0
  210. package/dist/utils/merge.js.map +1 -0
  211. package/dist/workflow/agent.workflow.d.ts +39 -0
  212. package/dist/workflow/agent.workflow.js +166 -0
  213. package/dist/workflow/agent.workflow.js.map +1 -0
  214. package/dist/workflow/agent.workflow.test.d.ts +1 -0
  215. package/dist/workflow/agent.workflow.test.js +175 -0
  216. package/dist/workflow/agent.workflow.test.js.map +1 -0
  217. package/dist/workflow/control-flow.test.d.ts +1 -0
  218. package/dist/workflow/control-flow.test.js +323 -0
  219. package/dist/workflow/control-flow.test.js.map +1 -0
  220. package/dist/workflow/dynamic-edge-cases.test.d.ts +1 -0
  221. package/dist/workflow/dynamic-edge-cases.test.js +486 -0
  222. package/dist/workflow/dynamic-edge-cases.test.js.map +1 -0
  223. package/dist/workflow/dynamic-types.d.ts +124 -0
  224. package/dist/workflow/dynamic-types.js +105 -0
  225. package/dist/workflow/dynamic-types.js.map +1 -0
  226. package/dist/workflow/dynamic.d.ts +118 -0
  227. package/dist/workflow/dynamic.js +999 -0
  228. package/dist/workflow/dynamic.js.map +1 -0
  229. package/dist/workflow/index.d.ts +6 -0
  230. package/dist/workflow/index.js +8 -0
  231. package/dist/workflow/index.js.map +1 -0
  232. package/dist/workflow/json-ai-types.d.ts +122 -0
  233. package/dist/workflow/json-ai-types.js +144 -0
  234. package/dist/workflow/json-ai-types.js.map +1 -0
  235. package/dist/workflow/json-schema-conversion.test.d.ts +1 -0
  236. package/dist/workflow/json-schema-conversion.test.js +371 -0
  237. package/dist/workflow/json-schema-conversion.test.js.map +1 -0
  238. package/dist/workflow/try-catch.test.d.ts +1 -0
  239. package/dist/workflow/try-catch.test.js +443 -0
  240. package/dist/workflow/try-catch.test.js.map +1 -0
  241. package/dist/workflow/types.d.ts +103 -0
  242. package/dist/workflow/types.js +17 -0
  243. package/dist/workflow/types.js.map +1 -0
  244. package/dist/workflow/workflow.d.ts +29 -0
  245. package/dist/workflow/workflow.js +57 -0
  246. package/dist/workflow/workflow.js.map +1 -0
  247. package/dist/workflow/workflow.test.d.ts +1 -0
  248. package/dist/workflow/workflow.test.js +189 -0
  249. package/dist/workflow/workflow.test.js.map +1 -0
  250. package/package.json +9 -1
@@ -0,0 +1,392 @@
1
+ // generated by polka.codes
2
+ import { homedir } from 'node:os';
3
+ import { parse } from 'yaml';
4
+ import { ZodError } from 'zod';
5
+ import { NodeFileSystemProvider } from '../fs';
6
+ import { IGNORED_DIRECTORIES, SKILL_ERROR_MESSAGES, SKILL_LIMITS } from './constants';
7
+ import { SkillDiscoveryError, skillMetadataSchema } from './types';
8
+ /**
9
+ * PERFORMANCE CONSIDERATION
10
+ *
11
+ * The current implementation eagerly loads all skill files into memory during
12
+ * discovery. This means every CLI command reads the full content of all skills
13
+ * from disk, which can cause performance degradation with many skills.
14
+ *
15
+ * Future optimization: Implement lazy loading where discoverAll() only reads
16
+ * SKILL.md metadata, and full skill content is loaded on-demand when the loadSkill
17
+ * tool is called. This would significantly improve CLI startup time.
18
+ */
19
+ /**
20
+ * List of binary file extensions that should not be loaded as text
21
+ */
22
+ const BINARY_EXTENSIONS = [
23
+ '.png',
24
+ '.jpg',
25
+ '.jpeg',
26
+ '.gif',
27
+ '.bmp',
28
+ '.ico',
29
+ '.webp',
30
+ '.pdf',
31
+ '.zip',
32
+ '.tar',
33
+ '.gz',
34
+ '.exe',
35
+ '.dll',
36
+ '.so',
37
+ '.dylib',
38
+ '.bin',
39
+ '.dat',
40
+ '.db',
41
+ '.sqlite',
42
+ '.woff',
43
+ '.woff2',
44
+ '.ttf',
45
+ '.eot',
46
+ ];
47
+ /**
48
+ * Check if a file is likely binary based on its extension.
49
+ *
50
+ * For performance, this is a fast check based on known binary extensions.
51
+ * Files without known extensions are assumed to be text and will be read.
52
+ * If reading fails with encoding errors, the file will be skipped.
53
+ *
54
+ * @param filename - The filename to check
55
+ * @returns true if the file has a known binary extension
56
+ */
57
+ function isBinaryFile(filename) {
58
+ const ext = filename.toLowerCase().slice(filename.lastIndexOf('.'));
59
+ return BINARY_EXTENSIONS.includes(ext);
60
+ }
61
+ /**
62
+ * Check if a buffer contains binary content by looking for null bytes.
63
+ * This is a simple heuristic that works for most binary files.
64
+ *
65
+ * @param buffer - The buffer to check
66
+ * @returns true if the buffer appears to contain binary data
67
+ */
68
+ function isBinaryContent(buffer) {
69
+ // Check for null bytes in the first 8KB (common in binary files)
70
+ const checkLength = Math.min(buffer.length, 8192);
71
+ for (let i = 0; i < checkLength; i++) {
72
+ if (buffer[i] === 0) {
73
+ return true;
74
+ }
75
+ }
76
+ return false;
77
+ }
78
+ /**
79
+ * Try to read a file as UTF-8 text, returning null if it appears to be binary.
80
+ * This handles binary files that don't have known extensions by checking content.
81
+ *
82
+ * @param filePath - The path to the file to read
83
+ * @returns The file content as a string, or null if it appears to be binary
84
+ */
85
+ async function tryReadTextFile(filePath, fs) {
86
+ try {
87
+ // First, read as a buffer to check for binary content
88
+ const buffer = await fs.readFileAsBuffer(filePath);
89
+ // Check if the file contains binary content
90
+ if (isBinaryContent(buffer)) {
91
+ return null;
92
+ }
93
+ // If not binary, decode as UTF-8 with fatal mode to catch invalid UTF-8 sequences
94
+ // This ensures binary files that pass the null-byte check are still detected
95
+ try {
96
+ return new TextDecoder('utf-8', { fatal: true }).decode(buffer);
97
+ }
98
+ catch (_decodeError) {
99
+ // Invalid UTF-8 sequence detected, treat as binary
100
+ return null;
101
+ }
102
+ }
103
+ catch (error) {
104
+ // If reading fails (e.g., directory), skip it
105
+ if (error && typeof error === 'object' && 'code' in error && (error.code === 'EINVAL' || error.code === 'EISDIR')) {
106
+ return null;
107
+ }
108
+ throw error;
109
+ }
110
+ }
111
+ /**
112
+ * Service for discovering and loading Agent Skills from filesystem
113
+ *
114
+ * Skills are discovered from three sources with priority:
115
+ * 1. Project skills at .claude/skills/ (highest priority)
116
+ * 2. Personal skills at ~/.claude/skills/
117
+ * 3. Plugin skills at node_modules (lowest priority)
118
+ */
119
+ export class SkillDiscoveryService {
120
+ fs;
121
+ personalSkillsDir;
122
+ projectSkillsDir;
123
+ pluginSkillsDirs;
124
+ constructor(options) {
125
+ this.fs = options.fs ?? new NodeFileSystemProvider();
126
+ this.personalSkillsDir = options.personalSkillsDir ?? this.fs.join(homedir(), '.claude', 'skills');
127
+ this.projectSkillsDir = this.fs.join(options.cwd, '.claude', 'skills');
128
+ this.pluginSkillsDirs = options.pluginSkillsDirs ?? [];
129
+ }
130
+ /**
131
+ * Discover all available skills from all sources
132
+ * Removes duplicates (project skills take priority over personal/plugin)
133
+ */
134
+ async discoverAll() {
135
+ const skills = [];
136
+ // Load in parallel but handle failures gracefully
137
+ const results = await Promise.allSettled([
138
+ this.discoverInDirectory(this.projectSkillsDir, 'project'),
139
+ this.discoverInDirectory(this.personalSkillsDir, 'personal'),
140
+ this.discoverPlugins(),
141
+ ]);
142
+ // Extract successful results
143
+ const projectSkills = results[0].status === 'fulfilled' ? results[0].value : [];
144
+ const personalSkills = results[1].status === 'fulfilled' ? results[1].value : [];
145
+ const pluginSkills = results[2].status === 'fulfilled' ? results[2].value : [];
146
+ // Log errors if any failed
147
+ if (results[0].status === 'rejected') {
148
+ console.warn(`Failed to load project skills: ${results[0].reason}`);
149
+ }
150
+ if (results[1].status === 'rejected') {
151
+ console.warn(`Failed to load personal skills: ${results[1].reason}`);
152
+ }
153
+ if (results[2].status === 'rejected') {
154
+ console.warn(`Failed to load plugin skills: ${results[2].reason}`);
155
+ }
156
+ // Filter out duplicates (project skills take priority)
157
+ const seenNames = new Set();
158
+ const allSkills = [...projectSkills, ...personalSkills, ...pluginSkills];
159
+ for (const skill of allSkills) {
160
+ if (!seenNames.has(skill.metadata.name)) {
161
+ seenNames.add(skill.metadata.name);
162
+ skills.push(skill);
163
+ }
164
+ }
165
+ return skills;
166
+ }
167
+ /**
168
+ * Discover skills in a specific directory
169
+ */
170
+ async discoverInDirectory(dir, source) {
171
+ const exists = typeof this.fs.exists === 'boolean' ? this.fs.exists(dir) : await this.fs.exists(dir);
172
+ if (!exists) {
173
+ return [];
174
+ }
175
+ const skills = [];
176
+ const entries = await this.fs.readdir(dir);
177
+ for (const entry of entries) {
178
+ if (!entry.isDirectory) {
179
+ continue;
180
+ }
181
+ const skillPath = this.fs.join(dir, entry.name);
182
+ const skillMdPath = this.fs.join(skillPath, 'SKILL.md');
183
+ const skillMdExists = typeof this.fs.exists === 'boolean' ? this.fs.exists(skillMdPath) : await this.fs.exists(skillMdPath);
184
+ if (!skillMdExists) {
185
+ continue;
186
+ }
187
+ try {
188
+ // Only load metadata
189
+ const content = await this.fs.readFile(skillMdPath);
190
+ const { metadata } = this.parseSkillMd(content);
191
+ skills.push({
192
+ metadata,
193
+ path: skillPath,
194
+ source,
195
+ });
196
+ }
197
+ catch (error) {
198
+ // Log all errors and continue to discover other skills
199
+ let message = 'Unknown error';
200
+ let path = skillPath;
201
+ if (error instanceof SkillDiscoveryError) {
202
+ message = error.message;
203
+ path = error.path;
204
+ }
205
+ else if (error instanceof ZodError) {
206
+ message = error.issues[0]?.message ?? 'Invalid skill metadata';
207
+ }
208
+ else if (error instanceof Error) {
209
+ message = error.message;
210
+ }
211
+ console.warn(`Warning: Failed to load skill at ${path}: ${message}`);
212
+ }
213
+ }
214
+ return skills;
215
+ }
216
+ /**
217
+ * Discover skills from plugin directories (node_modules)
218
+ */
219
+ async discoverPlugins() {
220
+ const skills = [];
221
+ for (const pluginDir of this.pluginSkillsDirs) {
222
+ const exists = typeof this.fs.exists === 'boolean' ? this.fs.exists(pluginDir) : await this.fs.exists(pluginDir);
223
+ if (!exists) {
224
+ continue;
225
+ }
226
+ const pluginSkills = await this.discoverInDirectory(pluginDir, 'plugin');
227
+ skills.push(...pluginSkills);
228
+ }
229
+ return skills;
230
+ }
231
+ /**
232
+ * Load a single skill from its directory
233
+ */
234
+ async loadSkill(skillPath, source) {
235
+ const skillMdPath = this.fs.join(skillPath, 'SKILL.md');
236
+ const skillMdExists = typeof this.fs.exists === 'boolean' ? this.fs.exists(skillMdPath) : await this.fs.exists(skillMdPath);
237
+ if (!skillMdExists) {
238
+ throw new SkillDiscoveryError('SKILL.md not found', skillPath);
239
+ }
240
+ const content = await this.fs.readFile(skillMdPath);
241
+ const { metadata, content: instructions } = this.parseSkillMd(content);
242
+ // Load additional files
243
+ const files = new Map();
244
+ let totalSize = 0;
245
+ const entries = await this.fs.readdir(skillPath);
246
+ for (const entry of entries) {
247
+ if (entry.name === 'SKILL.md') {
248
+ continue;
249
+ }
250
+ const filePath = this.fs.join(skillPath, entry.name);
251
+ if (entry.isFile) {
252
+ // Skip binary files to avoid corruption
253
+ if (isBinaryFile(entry.name)) {
254
+ continue;
255
+ }
256
+ // Check file size before reading to prevent OOM
257
+ const fileStats = await this.fs.stat(filePath);
258
+ const fileSize = fileStats.size;
259
+ if (fileSize > SKILL_LIMITS.MAX_FILE_SIZE) {
260
+ throw new SkillDiscoveryError(`File size exceeds limit (${fileSize} > ${SKILL_LIMITS.MAX_FILE_SIZE}): ${entry.name}`, skillPath);
261
+ }
262
+ // Check if we would exceed the total skill size limit
263
+ if (totalSize + fileSize > SKILL_LIMITS.MAX_SKILL_SIZE) {
264
+ throw new SkillDiscoveryError(`Total skill size exceeds limit (${totalSize + fileSize} > ${SKILL_LIMITS.MAX_SKILL_SIZE}): ${skillPath}`, skillPath);
265
+ }
266
+ const fileContent = await tryReadTextFile(filePath, this.fs);
267
+ if (fileContent === null) {
268
+ // Skip binary files - don't count them towards total size
269
+ continue;
270
+ }
271
+ // Track cumulative size to prevent resource exhaustion
272
+ totalSize += fileSize;
273
+ files.set(entry.name, fileContent);
274
+ }
275
+ else if (entry.isDirectory) {
276
+ // Recursively load directory contents and update total size
277
+ totalSize = await this.loadDirectoryFiles(filePath, entry.name, files, 0, totalSize);
278
+ }
279
+ }
280
+ return {
281
+ metadata,
282
+ content: instructions,
283
+ files,
284
+ path: skillPath,
285
+ source,
286
+ };
287
+ }
288
+ /**
289
+ * Parse SKILL.md content and extract frontmatter
290
+ */
291
+ parseSkillMd(content) {
292
+ // Use \r?\n to support both LF and CRLF line endings
293
+ // Use \s* to allow optional trailing spaces after ---
294
+ const frontmatterRegex = /^---\r?\n([\s\S]+?)\r?\n---\r?\n([\s\S]*)$/;
295
+ const match = content.match(frontmatterRegex);
296
+ if (!match || match.length < 3) {
297
+ throw new SkillDiscoveryError(SKILL_ERROR_MESSAGES.MISSING_FRONTMATTER, '');
298
+ }
299
+ const frontmatter = match[1] ?? '';
300
+ const instructions = match[2] ?? '';
301
+ const metadata = this.parseMetadata(frontmatter);
302
+ return { metadata, content: instructions };
303
+ }
304
+ /**
305
+ * Parse and validate YAML frontmatter
306
+ */
307
+ parseMetadata(frontmatter) {
308
+ const parsed = parse(frontmatter);
309
+ return skillMetadataSchema.parse(parsed);
310
+ }
311
+ /**
312
+ * Recursively load files from a directory into the files map
313
+ * @returns The total size of all files loaded (in bytes)
314
+ */
315
+ async loadDirectoryFiles(dirPath, prefix, files, depth = 0, currentTotal = 0) {
316
+ const { MAX_DEPTH, MAX_FILES } = SKILL_LIMITS;
317
+ let totalSize = currentTotal;
318
+ // Prevent stack overflow from deep recursion
319
+ if (depth > MAX_DEPTH) {
320
+ return totalSize;
321
+ }
322
+ // Prevent memory exhaustion from too many files
323
+ if (files.size >= MAX_FILES) {
324
+ return totalSize;
325
+ }
326
+ // Check if the current directory (from prefix) should be ignored
327
+ const currentDirName = prefix.split('/').pop() ?? prefix;
328
+ if (IGNORED_DIRECTORIES.includes(currentDirName)) {
329
+ return totalSize;
330
+ }
331
+ const entries = await this.fs.readdir(dirPath);
332
+ for (const entry of entries) {
333
+ // Check file count limit before processing each entry
334
+ if (files.size >= MAX_FILES) {
335
+ break;
336
+ }
337
+ const filePath = this.fs.join(dirPath, entry.name);
338
+ // Normalize key to avoid double slashes
339
+ const key = `${prefix}/${entry.name}`.replace(/\/+/g, '/');
340
+ if (entry.isFile) {
341
+ // Skip binary files to avoid corruption
342
+ if (isBinaryFile(entry.name)) {
343
+ continue;
344
+ }
345
+ // Check file size before reading to prevent OOM
346
+ const fileStats = await this.fs.stat(filePath);
347
+ const fileSize = fileStats.size;
348
+ if (fileSize > SKILL_LIMITS.MAX_FILE_SIZE) {
349
+ throw new SkillDiscoveryError(`File size exceeds limit (${fileSize} > ${SKILL_LIMITS.MAX_FILE_SIZE}): ${key}`, dirPath);
350
+ }
351
+ // Check if we would exceed the total skill size limit
352
+ if (totalSize + fileSize > SKILL_LIMITS.MAX_SKILL_SIZE) {
353
+ throw new SkillDiscoveryError(`Total skill size exceeds limit (${totalSize + fileSize} > ${SKILL_LIMITS.MAX_SKILL_SIZE}): ${dirPath}`, dirPath);
354
+ }
355
+ const content = await tryReadTextFile(filePath, this.fs);
356
+ if (content === null) {
357
+ // Skip binary files - don't count them towards total size
358
+ continue;
359
+ }
360
+ // Track cumulative size to prevent resource exhaustion
361
+ totalSize += fileSize;
362
+ files.set(key, content);
363
+ }
364
+ else if (entry.isDirectory) {
365
+ // Skip ignored directories
366
+ if (IGNORED_DIRECTORIES.includes(entry.name)) {
367
+ continue;
368
+ }
369
+ totalSize = await this.loadDirectoryFiles(filePath, key, files, depth + 1, totalSize);
370
+ }
371
+ }
372
+ return totalSize;
373
+ }
374
+ /**
375
+ * Create an initial skill context object
376
+ */
377
+ async createContext() {
378
+ const availableSkills = await this.discoverAll();
379
+ return {
380
+ activeSkill: null,
381
+ availableSkills,
382
+ skillLoadingHistory: [],
383
+ loadSkill: async (name) => {
384
+ const ref = availableSkills.find((s) => s.metadata.name === name);
385
+ if (!ref)
386
+ return null;
387
+ return this.loadSkill(ref.path, ref.source);
388
+ },
389
+ };
390
+ }
391
+ }
392
+ //# sourceMappingURL=discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/skills/discovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export * from './constants';
2
+ export * from './discovery';
3
+ export * from './types';
4
+ export * from './validation';
@@ -0,0 +1,6 @@
1
+ // generated by polka.codes
2
+ export * from './constants';
3
+ export * from './discovery';
4
+ export * from './types';
5
+ export * from './validation';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/skills/index.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAE3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,SAAS,CAAA;AACvB,cAAc,cAAc,CAAA"}
@@ -0,0 +1,3 @@
1
+ export * from './listSkills';
2
+ export * from './loadSkill';
3
+ export * from './readSkillFile';
@@ -0,0 +1,5 @@
1
+ // generated by polka.codes
2
+ export * from './listSkills';
3
+ export * from './loadSkill';
4
+ export * from './readSkillFile';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/skills/tools/index.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAE3B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,iBAAiB,CAAA"}
@@ -0,0 +1,54 @@
1
+ import { z } from 'zod';
2
+ import type { SkillContext } from '../types';
3
+ /**
4
+ * Tool input parameters for listing skills
5
+ */
6
+ export declare const ListSkillsInputSchema: z.ZodObject<{
7
+ filter: z.ZodOptional<z.ZodString>;
8
+ }, z.core.$strip>;
9
+ export type ListSkillsInput = z.infer<typeof ListSkillsInputSchema>;
10
+ /**
11
+ * Tool output for listing skills
12
+ */
13
+ export declare const ListSkillsOutputSchema: z.ZodObject<{
14
+ skills: z.ZodArray<z.ZodObject<{
15
+ name: z.ZodString;
16
+ description: z.ZodString;
17
+ source: z.ZodEnum<{
18
+ project: "project";
19
+ personal: "personal";
20
+ plugin: "plugin";
21
+ }>;
22
+ }, z.core.$strip>>;
23
+ total: z.ZodNumber;
24
+ }, z.core.$strip>;
25
+ export type ListSkillsOutput = z.infer<typeof ListSkillsOutputSchema>;
26
+ /**
27
+ * List all available skills with their descriptions
28
+ *
29
+ * This tool enables agents to discover what specialized capabilities
30
+ * are available based on task context.
31
+ */
32
+ export declare function listSkills(input: ListSkillsInput, context: SkillContext): Promise<ListSkillsOutput>;
33
+ /**
34
+ * Tool info for listSkills (used in agent workflow)
35
+ */
36
+ export declare const listSkillsToolInfo: {
37
+ readonly name: "listSkills";
38
+ readonly description: "List all available skills with their descriptions. Use this to discover what specialized capabilities are available.";
39
+ readonly parameters: z.ZodObject<{
40
+ filter: z.ZodOptional<z.ZodString>;
41
+ }, z.core.$strip>;
42
+ readonly returns: z.ZodObject<{
43
+ skills: z.ZodArray<z.ZodObject<{
44
+ name: z.ZodString;
45
+ description: z.ZodString;
46
+ source: z.ZodEnum<{
47
+ project: "project";
48
+ personal: "personal";
49
+ plugin: "plugin";
50
+ }>;
51
+ }, z.core.$strip>>;
52
+ total: z.ZodNumber;
53
+ }, z.core.$strip>;
54
+ };
@@ -0,0 +1,52 @@
1
+ // generated by polka.codes
2
+ import { z } from 'zod';
3
+ /**
4
+ * Tool input parameters for listing skills
5
+ */
6
+ export const ListSkillsInputSchema = z.object({
7
+ filter: z.string().optional().describe('Optional filter string to match against skill names and descriptions'),
8
+ });
9
+ /**
10
+ * Tool output for listing skills
11
+ */
12
+ export const ListSkillsOutputSchema = z.object({
13
+ skills: z.array(z.object({
14
+ name: z.string(),
15
+ description: z.string(),
16
+ source: z.enum(['personal', 'project', 'plugin']),
17
+ })),
18
+ total: z.number(),
19
+ });
20
+ /**
21
+ * List all available skills with their descriptions
22
+ *
23
+ * This tool enables agents to discover what specialized capabilities
24
+ * are available based on task context.
25
+ */
26
+ export async function listSkills(input, context) {
27
+ const { filter } = input;
28
+ let skills = context.availableSkills;
29
+ // Apply filter if provided
30
+ if (filter) {
31
+ const filterLower = filter.toLowerCase();
32
+ skills = skills.filter((s) => s.metadata.name.includes(filterLower) || s.metadata.description.toLowerCase().includes(filterLower));
33
+ }
34
+ return {
35
+ skills: skills.map((s) => ({
36
+ name: s.metadata.name,
37
+ description: s.metadata.description,
38
+ source: s.source,
39
+ })),
40
+ total: skills.length,
41
+ };
42
+ }
43
+ /**
44
+ * Tool info for listSkills (used in agent workflow)
45
+ */
46
+ export const listSkillsToolInfo = {
47
+ name: 'listSkills',
48
+ description: 'List all available skills with their descriptions. Use this to discover what specialized capabilities are available.',
49
+ parameters: ListSkillsInputSchema,
50
+ returns: ListSkillsOutputSchema,
51
+ };
52
+ //# sourceMappingURL=listSkills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listSkills.js","sourceRoot":"","sources":["../../../src/skills/tools/listSkills.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sEAAsE,CAAC;CAC/G,CAAC,CAAA;AAIF;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,MAAM,EAAE,CAAC,CAAC,KAAK,CACb,CAAC,CAAC,MAAM,CAAC;QACP,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;QACvB,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;KAClD,CAAC,CACH;IACD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;CAClB,CAAC,CAAA;AAIF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,KAAsB,EAAE,OAAqB;IAC5E,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAA;IACxB,IAAI,MAAM,GAAG,OAAO,CAAC,eAAe,CAAA;IAEpC,2BAA2B;IAC3B,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,EAAE,CAAA;QACxC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAA;IACpI,CAAC;IAED,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACzB,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI;YACrB,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW;YACnC,MAAM,EAAE,CAAC,CAAC,MAAM;SACjB,CAAC,CAAC;QACH,KAAK,EAAE,MAAM,CAAC,MAAM;KACrB,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,IAAI,EAAE,YAAY;IAClB,WAAW,EAAE,sHAAsH;IACnI,UAAU,EAAE,qBAAqB;IACjC,OAAO,EAAE,sBAAsB;CACvB,CAAA"}
@@ -0,0 +1,52 @@
1
+ import { z } from 'zod';
2
+ import type { SkillContext } from '../types';
3
+ /**
4
+ * Tool input parameters for loading a skill
5
+ */
6
+ export declare const LoadSkillInputSchema: z.ZodObject<{
7
+ skillName: z.ZodString;
8
+ }, z.core.$strip>;
9
+ export type LoadSkillInput = z.infer<typeof LoadSkillInputSchema>;
10
+ /**
11
+ * Tool output for loading a skill
12
+ */
13
+ export declare const LoadSkillOutputSchema: z.ZodObject<{
14
+ success: z.ZodBoolean;
15
+ skill: z.ZodOptional<z.ZodObject<{
16
+ name: z.ZodString;
17
+ description: z.ZodString;
18
+ content: z.ZodString;
19
+ availableFiles: z.ZodArray<z.ZodString>;
20
+ }, z.core.$strip>>;
21
+ error: z.ZodOptional<z.ZodString>;
22
+ warnings: z.ZodOptional<z.ZodArray<z.ZodString>>;
23
+ }, z.core.$strip>;
24
+ export type LoadSkillOutput = z.infer<typeof LoadSkillOutputSchema>;
25
+ /**
26
+ * Load a skill by name to access its instructions and resources
27
+ *
28
+ * This tool enables agents to autonomously load specialized knowledge
29
+ * and capabilities based on task context.
30
+ */
31
+ export declare function loadSkill(input: LoadSkillInput, context: SkillContext): Promise<LoadSkillOutput>;
32
+ /**
33
+ * Tool info for loadSkill (used in agent workflow)
34
+ */
35
+ export declare const loadSkillToolInfo: {
36
+ readonly name: "loadSkill";
37
+ readonly description: "Load a skill by name to access its instructions and resources. Use this when you need specialized knowledge or capabilities for a specific task.";
38
+ readonly parameters: z.ZodObject<{
39
+ skillName: z.ZodString;
40
+ }, z.core.$strip>;
41
+ readonly returns: z.ZodObject<{
42
+ success: z.ZodBoolean;
43
+ skill: z.ZodOptional<z.ZodObject<{
44
+ name: z.ZodString;
45
+ description: z.ZodString;
46
+ content: z.ZodString;
47
+ availableFiles: z.ZodArray<z.ZodString>;
48
+ }, z.core.$strip>>;
49
+ error: z.ZodOptional<z.ZodString>;
50
+ warnings: z.ZodOptional<z.ZodArray<z.ZodString>>;
51
+ }, z.core.$strip>;
52
+ };