zidane 1.8.0 → 2.0.1
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/dist/{agent-CWQ5XOw6.d.ts → agent-D-ZFMbSd.d.ts} +371 -21
- package/dist/{chunk-FFFDQHMA.js → chunk-7JTBBZ2U.js} +21 -0
- package/dist/chunk-BCXXXJ3G.js +779 -0
- package/dist/{chunk-WQBKOZVI.js → chunk-FRNFVKWW.js} +50 -12
- package/dist/{chunk-EC7IRWVS.js → chunk-LN4LLLHA.js} +101 -7
- package/dist/chunk-LVC7NQUZ.js +22 -0
- package/dist/chunk-MYWDHD7C.js +14 -0
- package/dist/{chunk-3RJOWJOJ.js → chunk-OVQ4N64O.js} +1 -1
- package/dist/{chunk-4N5ADW7A.js → chunk-PASFWG7S.js} +343 -32
- package/dist/{chunk-TBC6MSVK.js → chunk-PJUUYBKF.js} +53 -4
- package/dist/{chunk-2IB4XBQE.js → chunk-VG2E6YK3.js} +0 -97
- package/dist/harnesses.d.ts +1 -2
- package/dist/harnesses.js +5 -5
- package/dist/index.d.ts +5 -6
- package/dist/index.js +42 -12
- package/dist/mcp.d.ts +1 -2
- package/dist/mcp.js +3 -1
- package/dist/providers.d.ts +1 -2
- package/dist/providers.js +3 -3
- package/dist/session/sqlite.d.ts +16 -0
- package/dist/session/sqlite.js +98 -0
- package/dist/session.d.ts +1 -2
- package/dist/session.js +3 -5
- package/dist/skills-use-C4KFVla0.d.ts +66 -0
- package/dist/skills.d.ts +215 -30
- package/dist/skills.js +21 -2
- package/dist/{spawn-EEv1Johs.d.ts → spawn-RoqpjYLZ.d.ts} +1 -1
- package/dist/tools.d.ts +3 -4
- package/dist/tools.js +10 -4
- package/dist/types.d.ts +2 -3
- package/dist/types.js +8 -2
- package/package.json +12 -3
- package/dist/chunk-4C6Y56CC.js +0 -390
- package/dist/chunk-CFLC2I7D.js +0 -8
- package/dist/glob-j9gbk6xm.d.ts +0 -5
- package/dist/types-CDI8Kmve.d.ts +0 -64
package/dist/chunk-4C6Y56CC.js
DELETED
|
@@ -1,390 +0,0 @@
|
|
|
1
|
-
// src/skills/catalog.ts
|
|
2
|
-
function buildCatalog(skills, readToolName = "read_file") {
|
|
3
|
-
if (skills.length === 0)
|
|
4
|
-
return "";
|
|
5
|
-
const entries = skills.map((skill) => {
|
|
6
|
-
const locationLine = skill.location ? `
|
|
7
|
-
<location>${escapeXml(skill.location)}</location>` : "";
|
|
8
|
-
return ` <skill>
|
|
9
|
-
<name>${escapeXml(skill.name)}</name>
|
|
10
|
-
<description>${escapeXml(skill.description)}</description>${locationLine}
|
|
11
|
-
</skill>`;
|
|
12
|
-
}).join("\n");
|
|
13
|
-
const hasFsSkills = skills.some((s) => s.location);
|
|
14
|
-
const hasInlineSkills = skills.some((s) => !s.location);
|
|
15
|
-
const behavioralParts = [];
|
|
16
|
-
behavioralParts.push(
|
|
17
|
-
"The following skills provide specialized instructions for specific tasks.",
|
|
18
|
-
"When a task matches a skill's description, activate the skill to load its full instructions before proceeding."
|
|
19
|
-
);
|
|
20
|
-
if (hasFsSkills) {
|
|
21
|
-
behavioralParts.push(
|
|
22
|
-
`For skills with a <location>, use the ${readToolName} tool to read the SKILL.md file at that path.`,
|
|
23
|
-
"When a skill references relative paths, resolve them against the skill's directory (the parent of SKILL.md) and use absolute paths in tool calls."
|
|
24
|
-
);
|
|
25
|
-
}
|
|
26
|
-
if (hasInlineSkills) {
|
|
27
|
-
behavioralParts.push(
|
|
28
|
-
"Skills without a <location> have their instructions included directly in <instructions> tags below."
|
|
29
|
-
);
|
|
30
|
-
}
|
|
31
|
-
const parts = [
|
|
32
|
-
behavioralParts.join("\n"),
|
|
33
|
-
"",
|
|
34
|
-
"<available_skills>",
|
|
35
|
-
entries,
|
|
36
|
-
"</available_skills>"
|
|
37
|
-
];
|
|
38
|
-
if (hasInlineSkills) {
|
|
39
|
-
parts.push("");
|
|
40
|
-
for (const skill of skills) {
|
|
41
|
-
if (!skill.location && skill.instructions) {
|
|
42
|
-
parts.push(`<skill_instructions name="${escapeXml(skill.name)}">`);
|
|
43
|
-
parts.push(skill.instructions);
|
|
44
|
-
if (skill.resources && skill.resources.length > 0) {
|
|
45
|
-
parts.push("");
|
|
46
|
-
parts.push("<skill_resources>");
|
|
47
|
-
for (const res of skill.resources) {
|
|
48
|
-
parts.push(` <file type="${res.type}">${escapeXml(res.path)}</file>`);
|
|
49
|
-
}
|
|
50
|
-
parts.push("</skill_resources>");
|
|
51
|
-
}
|
|
52
|
-
parts.push("</skill_instructions>");
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
return parts.join("\n");
|
|
57
|
-
}
|
|
58
|
-
var RE_AMP = /&/g;
|
|
59
|
-
var RE_LT = /</g;
|
|
60
|
-
var RE_GT = />/g;
|
|
61
|
-
var RE_QUOT = /"/g;
|
|
62
|
-
function escapeXml(str) {
|
|
63
|
-
return str.replace(RE_AMP, "&").replace(RE_LT, "<").replace(RE_GT, ">").replace(RE_QUOT, """);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// src/skills/interpolate.ts
|
|
67
|
-
var SHELL_INTERPOLATION_RE = /!`([^`]+)`/g;
|
|
68
|
-
async function interpolateShellCommands(instructions, execution, handle) {
|
|
69
|
-
const matches = [...instructions.matchAll(SHELL_INTERPOLATION_RE)];
|
|
70
|
-
if (matches.length === 0)
|
|
71
|
-
return instructions;
|
|
72
|
-
const replacements = [];
|
|
73
|
-
for (const match of matches) {
|
|
74
|
-
const command = match[1];
|
|
75
|
-
const index = match.index;
|
|
76
|
-
const length = match[0].length;
|
|
77
|
-
try {
|
|
78
|
-
const result2 = await execution.exec(handle, command, { timeout: 30 });
|
|
79
|
-
const output = result2.exitCode === 0 ? result2.stdout.trim() : `[command failed (exit ${result2.exitCode}): ${result2.stderr.trim() || result2.stdout.trim()}]`;
|
|
80
|
-
replacements.push({ index, length, output });
|
|
81
|
-
} catch (err) {
|
|
82
|
-
replacements.push({ index, length, output: `[command error: ${err.message}]` });
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
let result = instructions;
|
|
86
|
-
for (let i = replacements.length - 1; i >= 0; i--) {
|
|
87
|
-
const { index, length, output } = replacements[i];
|
|
88
|
-
result = result.slice(0, index) + output + result.slice(index + length);
|
|
89
|
-
}
|
|
90
|
-
return result;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// src/skills/discovery.ts
|
|
94
|
-
import { existsSync, readdirSync, readFileSync, statSync } from "fs";
|
|
95
|
-
import { homedir } from "os";
|
|
96
|
-
import { basename, dirname, join, resolve } from "path";
|
|
97
|
-
var SKILL_NAME_RE = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
|
|
98
|
-
var FRONTMATTER_RE = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/;
|
|
99
|
-
var INDENT_RE = /^[ \t]{2,}/;
|
|
100
|
-
var KV_RE = /^([^:]+):(.*)$/;
|
|
101
|
-
var QUOTE_RE = /^(['"])(.*)\1$/;
|
|
102
|
-
var WHITESPACE_SPLIT_RE = /\s+/;
|
|
103
|
-
var PARAGRAPH_SPLIT_RE = /\n\n/;
|
|
104
|
-
var COMMA_OR_SPACE_RE = /[,\s]+/;
|
|
105
|
-
function validateSkillName(name) {
|
|
106
|
-
if (name.length < 1 || name.length > 64)
|
|
107
|
-
return false;
|
|
108
|
-
if (name.includes("--"))
|
|
109
|
-
return false;
|
|
110
|
-
return SKILL_NAME_RE.test(name);
|
|
111
|
-
}
|
|
112
|
-
function parseFrontmatter(content) {
|
|
113
|
-
const match = content.match(FRONTMATTER_RE);
|
|
114
|
-
if (!match) {
|
|
115
|
-
return { frontmatter: {}, body: content.trim() };
|
|
116
|
-
}
|
|
117
|
-
const yamlBlock = match[1];
|
|
118
|
-
const body = match[2].trim();
|
|
119
|
-
const frontmatter = {};
|
|
120
|
-
let currentKey = null;
|
|
121
|
-
let currentMap = null;
|
|
122
|
-
for (const line of yamlBlock.split("\n")) {
|
|
123
|
-
if (!line.trim() || line.trim().startsWith("#"))
|
|
124
|
-
continue;
|
|
125
|
-
if (currentKey && currentMap && INDENT_RE.test(line)) {
|
|
126
|
-
const nestedMatch = line.trim().match(KV_RE);
|
|
127
|
-
if (nestedMatch) {
|
|
128
|
-
const val = nestedMatch[2].trim();
|
|
129
|
-
currentMap[nestedMatch[1].trim()] = unquoteYaml(val);
|
|
130
|
-
}
|
|
131
|
-
continue;
|
|
132
|
-
}
|
|
133
|
-
if (currentKey && currentMap) {
|
|
134
|
-
frontmatter[currentKey] = currentMap;
|
|
135
|
-
currentKey = null;
|
|
136
|
-
currentMap = null;
|
|
137
|
-
}
|
|
138
|
-
const kvMatch = line.match(KV_RE);
|
|
139
|
-
if (!kvMatch)
|
|
140
|
-
continue;
|
|
141
|
-
const key = kvMatch[1].trim();
|
|
142
|
-
const value = kvMatch[2].trim();
|
|
143
|
-
if (!value) {
|
|
144
|
-
currentKey = key;
|
|
145
|
-
currentMap = {};
|
|
146
|
-
} else {
|
|
147
|
-
frontmatter[key] = unquoteYaml(value);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
if (currentKey && currentMap) {
|
|
151
|
-
frontmatter[currentKey] = currentMap;
|
|
152
|
-
}
|
|
153
|
-
return { frontmatter, body };
|
|
154
|
-
}
|
|
155
|
-
function unquoteYaml(val) {
|
|
156
|
-
const m = val.match(QUOTE_RE);
|
|
157
|
-
if (m)
|
|
158
|
-
return m[2];
|
|
159
|
-
return val;
|
|
160
|
-
}
|
|
161
|
-
var RESOURCE_DIRS = {
|
|
162
|
-
scripts: "script",
|
|
163
|
-
references: "reference",
|
|
164
|
-
assets: "asset"
|
|
165
|
-
};
|
|
166
|
-
function enumerateResources(baseDir) {
|
|
167
|
-
const resources = [];
|
|
168
|
-
for (const [dir, type] of Object.entries(RESOURCE_DIRS)) {
|
|
169
|
-
const dirPath = join(baseDir, dir);
|
|
170
|
-
if (!existsSync(dirPath) || !statSync(dirPath).isDirectory())
|
|
171
|
-
continue;
|
|
172
|
-
try {
|
|
173
|
-
const files = readdirSync(dirPath, { recursive: true });
|
|
174
|
-
for (const file of files) {
|
|
175
|
-
const fullPath = join(dirPath, file);
|
|
176
|
-
if (statSync(fullPath).isFile()) {
|
|
177
|
-
resources.push({ path: join(dir, file), type });
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
} catch {
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
try {
|
|
184
|
-
for (const entry of readdirSync(baseDir)) {
|
|
185
|
-
if (entry === "SKILL.md")
|
|
186
|
-
continue;
|
|
187
|
-
const entryPath = join(baseDir, entry);
|
|
188
|
-
if (statSync(entryPath).isFile()) {
|
|
189
|
-
resources.push({ path: entry, type: "other" });
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
} catch {
|
|
193
|
-
}
|
|
194
|
-
return resources;
|
|
195
|
-
}
|
|
196
|
-
async function parseSkillFile(filePath) {
|
|
197
|
-
const absPath = resolve(filePath);
|
|
198
|
-
if (!existsSync(absPath))
|
|
199
|
-
return null;
|
|
200
|
-
const content = readFileSync(absPath, "utf-8");
|
|
201
|
-
const { frontmatter, body } = parseFrontmatter(content);
|
|
202
|
-
const name = frontmatter.name;
|
|
203
|
-
let description = frontmatter.description;
|
|
204
|
-
if (!description && body) {
|
|
205
|
-
const firstParagraph = body.split(PARAGRAPH_SPLIT_RE)[0]?.trim();
|
|
206
|
-
if (firstParagraph)
|
|
207
|
-
description = firstParagraph;
|
|
208
|
-
}
|
|
209
|
-
if (!description)
|
|
210
|
-
return null;
|
|
211
|
-
const baseDir = dirname(absPath);
|
|
212
|
-
const dirName = basename(baseDir);
|
|
213
|
-
const skillName = name || dirName;
|
|
214
|
-
const config = {
|
|
215
|
-
name: skillName,
|
|
216
|
-
description,
|
|
217
|
-
instructions: body,
|
|
218
|
-
location: absPath,
|
|
219
|
-
baseDir,
|
|
220
|
-
resources: enumerateResources(baseDir)
|
|
221
|
-
};
|
|
222
|
-
if (frontmatter.license)
|
|
223
|
-
config.license = frontmatter.license;
|
|
224
|
-
if (frontmatter.compatibility)
|
|
225
|
-
config.compatibility = frontmatter.compatibility;
|
|
226
|
-
if (frontmatter.metadata && typeof frontmatter.metadata === "object")
|
|
227
|
-
config.metadata = frontmatter.metadata;
|
|
228
|
-
if (frontmatter["allowed-tools"])
|
|
229
|
-
config.allowedTools = frontmatter["allowed-tools"].split(WHITESPACE_SPLIT_RE);
|
|
230
|
-
if (frontmatter.model)
|
|
231
|
-
config.model = frontmatter.model;
|
|
232
|
-
const thinkingValue = frontmatter.thinking ?? frontmatter.effort;
|
|
233
|
-
if (thinkingValue)
|
|
234
|
-
config.thinking = thinkingValue;
|
|
235
|
-
if (frontmatter.paths) {
|
|
236
|
-
const raw = frontmatter.paths;
|
|
237
|
-
config.paths = raw.split(COMMA_OR_SPACE_RE).filter(Boolean);
|
|
238
|
-
}
|
|
239
|
-
return config;
|
|
240
|
-
}
|
|
241
|
-
var SKIP_DIRS = /* @__PURE__ */ new Set([".git", "node_modules", ".DS_Store", "dist", "build"]);
|
|
242
|
-
function findSkillDirs(root, maxDepth = 4, _depth = 0) {
|
|
243
|
-
if (_depth > maxDepth)
|
|
244
|
-
return [];
|
|
245
|
-
if (!existsSync(root) || !statSync(root).isDirectory())
|
|
246
|
-
return [];
|
|
247
|
-
const results = [];
|
|
248
|
-
try {
|
|
249
|
-
for (const entry of readdirSync(root)) {
|
|
250
|
-
if (SKIP_DIRS.has(entry))
|
|
251
|
-
continue;
|
|
252
|
-
const entryPath = join(root, entry);
|
|
253
|
-
if (!statSync(entryPath).isDirectory())
|
|
254
|
-
continue;
|
|
255
|
-
const skillFile = join(entryPath, "SKILL.md");
|
|
256
|
-
if (existsSync(skillFile) && statSync(skillFile).isFile()) {
|
|
257
|
-
results.push(skillFile);
|
|
258
|
-
} else {
|
|
259
|
-
results.push(...findSkillDirs(entryPath, maxDepth, _depth + 1));
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
} catch {
|
|
263
|
-
}
|
|
264
|
-
return results;
|
|
265
|
-
}
|
|
266
|
-
function getDefaultScanPaths() {
|
|
267
|
-
const home = homedir();
|
|
268
|
-
const cwd = process.cwd();
|
|
269
|
-
return [
|
|
270
|
-
// Project-level (higher priority)
|
|
271
|
-
join(cwd, ".agents", "skills"),
|
|
272
|
-
join(cwd, ".zidane", "skills"),
|
|
273
|
-
// User-level (lower priority)
|
|
274
|
-
join(home, ".agents", "skills"),
|
|
275
|
-
join(home, ".zidane", "skills")
|
|
276
|
-
];
|
|
277
|
-
}
|
|
278
|
-
async function discoverSkills(paths) {
|
|
279
|
-
const skillsByName = /* @__PURE__ */ new Map();
|
|
280
|
-
for (const scanPath of paths) {
|
|
281
|
-
const skillFiles = findSkillDirs(resolve(scanPath));
|
|
282
|
-
for (const file of skillFiles) {
|
|
283
|
-
const skill = await parseSkillFile(file);
|
|
284
|
-
if (skill && !skillsByName.has(skill.name)) {
|
|
285
|
-
skillsByName.set(skill.name, skill);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
return [...skillsByName.values()];
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
// src/skills/writer.ts
|
|
293
|
-
import { mkdirSync, writeFileSync } from "fs";
|
|
294
|
-
import { join as join2 } from "path";
|
|
295
|
-
function serializeFrontmatter(skill) {
|
|
296
|
-
const lines = ["---"];
|
|
297
|
-
lines.push(`name: ${skill.name}`);
|
|
298
|
-
lines.push(`description: ${skill.description}`);
|
|
299
|
-
if (skill.license)
|
|
300
|
-
lines.push(`license: ${skill.license}`);
|
|
301
|
-
if (skill.compatibility)
|
|
302
|
-
lines.push(`compatibility: ${skill.compatibility}`);
|
|
303
|
-
if (skill.allowedTools?.length)
|
|
304
|
-
lines.push(`allowed-tools: ${skill.allowedTools.join(" ")}`);
|
|
305
|
-
if (skill.model)
|
|
306
|
-
lines.push(`model: ${skill.model}`);
|
|
307
|
-
if (skill.thinking)
|
|
308
|
-
lines.push(`thinking: ${skill.thinking}`);
|
|
309
|
-
if (skill.paths?.length)
|
|
310
|
-
lines.push(`paths: ${skill.paths.join(", ")}`);
|
|
311
|
-
if (skill.metadata && Object.keys(skill.metadata).length > 0) {
|
|
312
|
-
lines.push("metadata:");
|
|
313
|
-
for (const [key, value] of Object.entries(skill.metadata)) {
|
|
314
|
-
lines.push(` ${key}: "${value}"`);
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
lines.push("---");
|
|
318
|
-
return lines.join("\n");
|
|
319
|
-
}
|
|
320
|
-
function writeSkillToDisk(skill, targetDir) {
|
|
321
|
-
const skillDir = join2(targetDir, skill.name);
|
|
322
|
-
mkdirSync(skillDir, { recursive: true });
|
|
323
|
-
const frontmatter = serializeFrontmatter(skill);
|
|
324
|
-
const body = skill.instructions ? `
|
|
325
|
-
${skill.instructions}` : "";
|
|
326
|
-
const content = `${frontmatter}
|
|
327
|
-
${body}
|
|
328
|
-
`;
|
|
329
|
-
const skillPath = join2(skillDir, "SKILL.md");
|
|
330
|
-
writeFileSync(skillPath, content);
|
|
331
|
-
return skillPath;
|
|
332
|
-
}
|
|
333
|
-
function writeSkillsToDisk(skills, targetDir) {
|
|
334
|
-
mkdirSync(targetDir, { recursive: true });
|
|
335
|
-
for (const skill of skills) {
|
|
336
|
-
writeSkillToDisk(skill, targetDir);
|
|
337
|
-
}
|
|
338
|
-
return targetDir;
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
// src/skills/resolve.ts
|
|
342
|
-
import { mkdtempSync } from "fs";
|
|
343
|
-
import { tmpdir } from "os";
|
|
344
|
-
import { join as join3 } from "path";
|
|
345
|
-
async function resolveSkills(config) {
|
|
346
|
-
const scanPaths = config.skipDefaultPaths ? [...config.scan ?? []] : [...getDefaultScanPaths(), ...config.scan ?? []];
|
|
347
|
-
if (config.write?.length) {
|
|
348
|
-
const writeDir = mkdtempSync(join3(tmpdir(), "zidane-skills-"));
|
|
349
|
-
writeSkillsToDisk(config.write, writeDir);
|
|
350
|
-
scanPaths.push(writeDir);
|
|
351
|
-
}
|
|
352
|
-
const skills = await discoverSkills(scanPaths);
|
|
353
|
-
const exclude = new Set(config.exclude ?? []);
|
|
354
|
-
let filtered = skills.filter((s) => !exclude.has(s.name));
|
|
355
|
-
if (Array.isArray(config.enabled)) {
|
|
356
|
-
const allowlist = new Set(config.enabled);
|
|
357
|
-
filtered = filtered.filter((s) => allowlist.has(s.name));
|
|
358
|
-
}
|
|
359
|
-
return filtered;
|
|
360
|
-
}
|
|
361
|
-
function mergeSkillsConfig(harness, agent) {
|
|
362
|
-
if (!harness && !agent)
|
|
363
|
-
return void 0;
|
|
364
|
-
if (!harness)
|
|
365
|
-
return agent;
|
|
366
|
-
if (!agent)
|
|
367
|
-
return harness;
|
|
368
|
-
return {
|
|
369
|
-
// Agent-level enabled takes precedence when explicitly set
|
|
370
|
-
enabled: agent.enabled !== void 0 ? agent.enabled : harness.enabled,
|
|
371
|
-
scan: [...harness.scan ?? [], ...agent.scan ?? []],
|
|
372
|
-
write: [...harness.write ?? [], ...agent.write ?? []],
|
|
373
|
-
readToolName: agent.readToolName ?? harness.readToolName,
|
|
374
|
-
exclude: [.../* @__PURE__ */ new Set([...harness.exclude ?? [], ...agent.exclude ?? []])]
|
|
375
|
-
};
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
export {
|
|
379
|
-
buildCatalog,
|
|
380
|
-
interpolateShellCommands,
|
|
381
|
-
validateSkillName,
|
|
382
|
-
parseFrontmatter,
|
|
383
|
-
parseSkillFile,
|
|
384
|
-
getDefaultScanPaths,
|
|
385
|
-
discoverSkills,
|
|
386
|
-
writeSkillToDisk,
|
|
387
|
-
writeSkillsToDisk,
|
|
388
|
-
resolveSkills,
|
|
389
|
-
mergeSkillsConfig
|
|
390
|
-
};
|
package/dist/chunk-CFLC2I7D.js
DELETED
package/dist/glob-j9gbk6xm.d.ts
DELETED
package/dist/types-CDI8Kmve.d.ts
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Types for the Agent Skills system.
|
|
3
|
-
*
|
|
4
|
-
* Follows the Agent Skills open standard (agentskills.io/specification).
|
|
5
|
-
*/
|
|
6
|
-
interface SkillResource {
|
|
7
|
-
/** Relative path from skill directory */
|
|
8
|
-
path: string;
|
|
9
|
-
/** Resource type inferred from directory */
|
|
10
|
-
type: 'script' | 'reference' | 'asset' | 'other';
|
|
11
|
-
}
|
|
12
|
-
interface SkillConfig {
|
|
13
|
-
/** Skill name: 1-64 chars, lowercase alphanumeric + hyphens */
|
|
14
|
-
name: string;
|
|
15
|
-
/** What the skill does and when to use it (1-1024 chars) */
|
|
16
|
-
description: string;
|
|
17
|
-
/** The SKILL.md body content (after YAML frontmatter) */
|
|
18
|
-
instructions: string;
|
|
19
|
-
/** Absolute path to SKILL.md (undefined for inline skills) */
|
|
20
|
-
location?: string;
|
|
21
|
-
/** Skill directory path for resolving relative references */
|
|
22
|
-
baseDir?: string;
|
|
23
|
-
/** License identifier or reference */
|
|
24
|
-
license?: string;
|
|
25
|
-
/** Environment requirements */
|
|
26
|
-
compatibility?: string;
|
|
27
|
-
/** Arbitrary key-value metadata */
|
|
28
|
-
metadata?: Record<string, string>;
|
|
29
|
-
/** Pre-approved tool names (experimental) */
|
|
30
|
-
allowedTools?: string[];
|
|
31
|
-
/** Bundled resource files discovered in the skill directory */
|
|
32
|
-
resources?: SkillResource[];
|
|
33
|
-
/** Model override when this skill is active */
|
|
34
|
-
model?: string;
|
|
35
|
-
/** Thinking/reasoning level override when this skill is active */
|
|
36
|
-
thinking?: 'off' | 'minimal' | 'low' | 'medium' | 'high';
|
|
37
|
-
/**
|
|
38
|
-
* Glob patterns that limit when this skill auto-activates.
|
|
39
|
-
* Parsed and stored per the Agent Skills spec, but not yet
|
|
40
|
-
* enforced at runtime — all skills are included in the catalog.
|
|
41
|
-
*/
|
|
42
|
-
paths?: string[];
|
|
43
|
-
}
|
|
44
|
-
interface SkillsConfig {
|
|
45
|
-
/**
|
|
46
|
-
* Control which skills are active.
|
|
47
|
-
* - `true` (default): all discovered skills are enabled
|
|
48
|
-
* - `false` or `[]`: fully disable the skills system (no resolution, no catalog, no hooks)
|
|
49
|
-
* - `string[]`: allowlist — only skills with matching names are enabled
|
|
50
|
-
*/
|
|
51
|
-
enabled?: boolean | string[];
|
|
52
|
-
/** Directories to scan for SKILL.md files */
|
|
53
|
-
scan?: string[];
|
|
54
|
-
/** Dynamic skills written to disk at agent start, then loaded normally */
|
|
55
|
-
write?: SkillConfig[];
|
|
56
|
-
/** Tool name the agent should use to read skill files (default: 'read_file') */
|
|
57
|
-
readToolName?: string;
|
|
58
|
-
/** Skill names to exclude from the catalog */
|
|
59
|
-
exclude?: string[];
|
|
60
|
-
/** Skip default scan paths (~/.agents/skills, .zidane/skills, etc.) */
|
|
61
|
-
skipDefaultPaths?: boolean;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export type { SkillConfig as S, SkillResource as a, SkillsConfig as b };
|