zidane 1.3.1 → 1.4.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.
@@ -1,87 +1,11 @@
1
1
  import { Hookable } from 'hookable';
2
+ import { E as ExecutionContext, c as ExecutionHandle, f as SkillsConfig, d as SkillConfig } from './types-D8fzooXc.js';
2
3
  import Anthropic from '@anthropic-ai/sdk';
3
4
  import { M as McpServerConfig, e as TurnUsage, b as SessionMessage, C as ChildRunStats, a as AgentStats, A as AgentRunOptions, c as SessionTurn, d as ToolExecutionMode } from './types-CLRMCak3.js';
4
5
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
5
6
  import { Provider, StreamOptions } from './providers.js';
6
7
  import { Session } from './session.js';
7
8
 
8
- /**
9
- * Execution context types.
10
- *
11
- * An execution context defines *where* and *how* an agent's tools run.
12
- * The agent loop and tools interact through this interface without knowing
13
- * whether they're running in-process, in a Docker container, or in a
14
- * remote sandbox.
15
- */
16
- interface ContextCapabilities {
17
- /** Can execute shell commands */
18
- shell: boolean;
19
- /** Can read/write files in a workspace */
20
- filesystem: boolean;
21
- /** Can make outbound network requests */
22
- network: boolean;
23
- /** Has GPU access */
24
- gpu: boolean;
25
- }
26
- /** Opaque handle to a running execution context instance */
27
- interface ExecutionHandle {
28
- id: string;
29
- type: ContextType;
30
- /** Working directory within the context */
31
- cwd: string;
32
- }
33
- interface ExecResult {
34
- stdout: string;
35
- stderr: string;
36
- exitCode: number;
37
- }
38
- interface SpawnConfig {
39
- /** Working directory (created if it doesn't exist) */
40
- cwd?: string;
41
- /** Environment variables */
42
- env?: Record<string, string>;
43
- /** Docker image (only for 'docker' context) */
44
- image?: string;
45
- /** Resource limits */
46
- limits?: {
47
- /** Memory limit in MB */
48
- memory?: number;
49
- /** CPU limit (e.g. '1.0' = 1 core) */
50
- cpu?: string;
51
- /** Timeout in seconds for the entire context lifetime */
52
- timeout?: number;
53
- };
54
- /** Sandbox provider config (only for 'sandbox' context) */
55
- sandbox?: {
56
- provider: string;
57
- apiKey?: string;
58
- [key: string]: unknown;
59
- };
60
- }
61
- type ContextType = 'process' | 'docker' | 'sandbox';
62
- interface ExecutionContext {
63
- /** Context type identifier */
64
- readonly type: ContextType;
65
- /** What this context supports */
66
- readonly capabilities: ContextCapabilities;
67
- /** Spawn a new execution environment */
68
- spawn: (config?: SpawnConfig) => Promise<ExecutionHandle>;
69
- /** Execute a shell command in the context */
70
- exec: (handle: ExecutionHandle, command: string, options?: {
71
- cwd?: string;
72
- env?: Record<string, string>;
73
- timeout?: number;
74
- }) => Promise<ExecResult>;
75
- /** Read a file from the context's filesystem */
76
- readFile: (handle: ExecutionHandle, path: string) => Promise<string>;
77
- /** Write a file to the context's filesystem */
78
- writeFile: (handle: ExecutionHandle, path: string, content: string) => Promise<void>;
79
- /** List files in a directory */
80
- listFiles: (handle: ExecutionHandle, path: string) => Promise<string[]>;
81
- /** Destroy the execution environment and clean up resources */
82
- destroy: (handle: ExecutionHandle) => Promise<void>;
83
- }
84
-
85
9
  /** Core tools available in every basic harness (without spawn) */
86
10
  declare const basicTools: {
87
11
  shell: ToolDef;
@@ -123,12 +47,19 @@ interface HarnessConfig {
123
47
  tools: Record<string, ToolDef>;
124
48
  /** MCP servers to connect and expose as tools */
125
49
  mcpServers?: McpServerConfig[];
50
+ /** Skills configuration at the harness level */
51
+ skills?: SkillsConfig;
126
52
  }
127
53
  /**
128
54
  * Define a harness with a name, optional system prompt, and tools.
129
55
  */
130
56
  declare function defineHarness(config: HarnessConfig): HarnessConfig;
131
57
  type Harness = HarnessConfig;
58
+ /**
59
+ * A harness with no tools — for pure chat mode.
60
+ * Use with `enableTools: false` or when no tool access is needed.
61
+ */
62
+ declare const noTools: HarnessConfig;
132
63
 
133
64
  /**
134
65
  * MCP (Model Context Protocol) server support.
@@ -258,6 +189,16 @@ interface AgentHooks {
258
189
  input: Record<string, unknown>;
259
190
  error: Error;
260
191
  }) => void;
192
+ 'skills:resolve': (ctx: {
193
+ skills: SkillConfig[];
194
+ }) => void;
195
+ 'skills:catalog': (ctx: {
196
+ catalog: string;
197
+ skills: SkillConfig[];
198
+ }) => void;
199
+ 'skills:activate': (ctx: {
200
+ skill: SkillConfig;
201
+ }) => void;
261
202
  'agent:abort': (ctx: object) => void;
262
203
  'agent:done': (ctx: AgentStats) => void;
263
204
  'session:start': (ctx: {
@@ -284,16 +225,21 @@ interface AgentHooks {
284
225
  }) => void;
285
226
  }
286
227
  interface AgentOptions {
287
- harness: HarnessConfig;
228
+ /** Harness (tools + system prompt). Defaults to a no-tools harness if omitted. */
229
+ harness?: HarnessConfig;
288
230
  provider: Provider;
289
231
  /** Tool execution mode: 'sequential' (default) or 'parallel' */
290
232
  toolExecution?: ToolExecutionMode;
233
+ /** Enable tool use. When false, no tools are sent to the provider (pure chat mode). Default: true. */
234
+ enableTools?: boolean;
291
235
  /** Execution context: where tools run. Defaults to in-process. */
292
236
  execution?: ExecutionContext;
293
237
  /** MCP servers to connect and expose as tools */
294
238
  mcpServers?: McpServerConfig[];
295
239
  /** Session for identity, turn persistence, and run tracking */
296
240
  session?: Session;
241
+ /** Skills configuration (merged with harness-level skills, agent takes precedence) */
242
+ skills?: SkillsConfig;
297
243
  /** @internal */
298
244
  _mcpConnector?: (configs: McpServerConfig[]) => Promise<McpConnection>;
299
245
  }
@@ -314,6 +260,6 @@ interface Agent {
314
260
  readonly session: Session | null;
315
261
  meta: Record<string, unknown>;
316
262
  }
317
- declare function createAgent({ harness, provider, toolExecution, execution, mcpServers, session, _mcpConnector }: AgentOptions): Agent;
263
+ declare function createAgent({ harness: harnessOption, provider, toolExecution, enableTools, execution, mcpServers, session, skills: agentSkills, _mcpConnector }: AgentOptions): Agent;
318
264
 
319
- export { type Agent as A, type ContextCapabilities as C, type ExecutionContext as E, type Harness as H, type McpConnection as M, type SpawnConfig as S, type ToolContext as T, _default as _, type ExecResult as a, type AgentHooks as b, type AgentOptions as c, type ContextType as d, type ExecutionHandle as e, type HarnessConfig as f, type ToolDef as g, type ToolMap as h, connectMcpServers as i, createAgent as j, defineHarness as k, basicTools as l, resultToString as r };
265
+ export { type Agent as A, type Harness as H, type McpConnection as M, type ToolContext as T, _default as _, type AgentHooks as a, type AgentOptions as b, type HarnessConfig as c, type ToolDef as d, type ToolMap as e, connectMcpServers as f, createAgent as g, defineHarness as h, basicTools as i, noTools as n, resultToString as r };
@@ -0,0 +1,430 @@
1
+ import {
2
+ __esm
3
+ } from "./chunk-PNKVD2UK.js";
4
+
5
+ // src/skills/catalog.ts
6
+ function buildCatalog(skills, readToolName = "read_file") {
7
+ if (skills.length === 0)
8
+ return "";
9
+ const entries = skills.map((skill) => {
10
+ const locationLine = skill.location ? `
11
+ <location>${escapeXml(skill.location)}</location>` : "";
12
+ return ` <skill>
13
+ <name>${escapeXml(skill.name)}</name>
14
+ <description>${escapeXml(skill.description)}</description>${locationLine}
15
+ </skill>`;
16
+ }).join("\n");
17
+ const hasFsSkills = skills.some((s) => s.location);
18
+ const hasInlineSkills = skills.some((s) => !s.location);
19
+ const behavioralParts = [];
20
+ behavioralParts.push(
21
+ "The following skills provide specialized instructions for specific tasks.",
22
+ "When a task matches a skill's description, activate the skill to load its full instructions before proceeding."
23
+ );
24
+ if (hasFsSkills) {
25
+ behavioralParts.push(
26
+ `For skills with a <location>, use the ${readToolName} tool to read the SKILL.md file at that path.`,
27
+ "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."
28
+ );
29
+ }
30
+ if (hasInlineSkills) {
31
+ behavioralParts.push(
32
+ "Skills without a <location> have their instructions included directly in <instructions> tags below."
33
+ );
34
+ }
35
+ const parts = [
36
+ behavioralParts.join("\n"),
37
+ "",
38
+ "<available_skills>",
39
+ entries,
40
+ "</available_skills>"
41
+ ];
42
+ if (hasInlineSkills) {
43
+ parts.push("");
44
+ for (const skill of skills) {
45
+ if (!skill.location && skill.instructions) {
46
+ parts.push(`<skill_instructions name="${escapeXml(skill.name)}">`);
47
+ parts.push(skill.instructions);
48
+ if (skill.resources && skill.resources.length > 0) {
49
+ parts.push("");
50
+ parts.push("<skill_resources>");
51
+ for (const res of skill.resources) {
52
+ parts.push(` <file type="${res.type}">${escapeXml(res.path)}</file>`);
53
+ }
54
+ parts.push("</skill_resources>");
55
+ }
56
+ parts.push("</skill_instructions>");
57
+ }
58
+ }
59
+ }
60
+ return parts.join("\n");
61
+ }
62
+ function escapeXml(str) {
63
+ return str.replace(RE_AMP, "&amp;").replace(RE_LT, "&lt;").replace(RE_GT, "&gt;").replace(RE_QUOT, "&quot;");
64
+ }
65
+ var RE_AMP, RE_LT, RE_GT, RE_QUOT;
66
+ var init_catalog = __esm({
67
+ "src/skills/catalog.ts"() {
68
+ "use strict";
69
+ RE_AMP = /&/g;
70
+ RE_LT = /</g;
71
+ RE_GT = />/g;
72
+ RE_QUOT = /"/g;
73
+ }
74
+ });
75
+
76
+ // src/skills/interpolate.ts
77
+ async function interpolateShellCommands(instructions, execution, handle) {
78
+ const matches = [...instructions.matchAll(SHELL_INTERPOLATION_RE)];
79
+ if (matches.length === 0)
80
+ return instructions;
81
+ const replacements = [];
82
+ for (const match of matches) {
83
+ const command = match[1];
84
+ const index = match.index;
85
+ const length = match[0].length;
86
+ try {
87
+ const result2 = await execution.exec(handle, command, { timeout: 30 });
88
+ const output = result2.exitCode === 0 ? result2.stdout.trim() : `[command failed (exit ${result2.exitCode}): ${result2.stderr.trim() || result2.stdout.trim()}]`;
89
+ replacements.push({ index, length, output });
90
+ } catch (err) {
91
+ replacements.push({ index, length, output: `[command error: ${err.message}]` });
92
+ }
93
+ }
94
+ let result = instructions;
95
+ for (let i = replacements.length - 1; i >= 0; i--) {
96
+ const { index, length, output } = replacements[i];
97
+ result = result.slice(0, index) + output + result.slice(index + length);
98
+ }
99
+ return result;
100
+ }
101
+ var SHELL_INTERPOLATION_RE;
102
+ var init_interpolate = __esm({
103
+ "src/skills/interpolate.ts"() {
104
+ "use strict";
105
+ SHELL_INTERPOLATION_RE = /!`([^`]+)`/g;
106
+ }
107
+ });
108
+
109
+ // src/skills/discovery.ts
110
+ import { existsSync, readdirSync, readFileSync, statSync } from "fs";
111
+ import { homedir } from "os";
112
+ import { basename, dirname, join, resolve } from "path";
113
+ function validateSkillName(name) {
114
+ if (name.length < 1 || name.length > 64)
115
+ return false;
116
+ if (name.includes("--"))
117
+ return false;
118
+ return SKILL_NAME_RE.test(name);
119
+ }
120
+ function parseFrontmatter(content) {
121
+ const match = content.match(FRONTMATTER_RE);
122
+ if (!match) {
123
+ return { frontmatter: {}, body: content.trim() };
124
+ }
125
+ const yamlBlock = match[1];
126
+ const body = match[2].trim();
127
+ const frontmatter = {};
128
+ let currentKey = null;
129
+ let currentMap = null;
130
+ for (const line of yamlBlock.split("\n")) {
131
+ if (!line.trim() || line.trim().startsWith("#"))
132
+ continue;
133
+ if (currentKey && currentMap && INDENT_RE.test(line)) {
134
+ const nestedMatch = line.trim().match(KV_RE);
135
+ if (nestedMatch) {
136
+ const val = nestedMatch[2].trim();
137
+ currentMap[nestedMatch[1].trim()] = unquoteYaml(val);
138
+ }
139
+ continue;
140
+ }
141
+ if (currentKey && currentMap) {
142
+ frontmatter[currentKey] = currentMap;
143
+ currentKey = null;
144
+ currentMap = null;
145
+ }
146
+ const kvMatch = line.match(KV_RE);
147
+ if (!kvMatch)
148
+ continue;
149
+ const key = kvMatch[1].trim();
150
+ const value = kvMatch[2].trim();
151
+ if (!value) {
152
+ currentKey = key;
153
+ currentMap = {};
154
+ } else {
155
+ frontmatter[key] = unquoteYaml(value);
156
+ }
157
+ }
158
+ if (currentKey && currentMap) {
159
+ frontmatter[currentKey] = currentMap;
160
+ }
161
+ return { frontmatter, body };
162
+ }
163
+ function unquoteYaml(val) {
164
+ const m = val.match(QUOTE_RE);
165
+ if (m)
166
+ return m[2];
167
+ return val;
168
+ }
169
+ function enumerateResources(baseDir) {
170
+ const resources = [];
171
+ for (const [dir, type] of Object.entries(RESOURCE_DIRS)) {
172
+ const dirPath = join(baseDir, dir);
173
+ if (!existsSync(dirPath) || !statSync(dirPath).isDirectory())
174
+ continue;
175
+ try {
176
+ const files = readdirSync(dirPath, { recursive: true });
177
+ for (const file of files) {
178
+ const fullPath = join(dirPath, file);
179
+ if (statSync(fullPath).isFile()) {
180
+ resources.push({ path: join(dir, file), type });
181
+ }
182
+ }
183
+ } catch {
184
+ }
185
+ }
186
+ try {
187
+ for (const entry of readdirSync(baseDir)) {
188
+ if (entry === "SKILL.md")
189
+ continue;
190
+ const entryPath = join(baseDir, entry);
191
+ if (statSync(entryPath).isFile()) {
192
+ resources.push({ path: entry, type: "other" });
193
+ }
194
+ }
195
+ } catch {
196
+ }
197
+ return resources;
198
+ }
199
+ async function parseSkillFile(filePath) {
200
+ const absPath = resolve(filePath);
201
+ if (!existsSync(absPath))
202
+ return null;
203
+ const content = readFileSync(absPath, "utf-8");
204
+ const { frontmatter, body } = parseFrontmatter(content);
205
+ const name = frontmatter.name;
206
+ let description = frontmatter.description;
207
+ if (!description && body) {
208
+ const firstParagraph = body.split(PARAGRAPH_SPLIT_RE)[0]?.trim();
209
+ if (firstParagraph)
210
+ description = firstParagraph;
211
+ }
212
+ if (!description)
213
+ return null;
214
+ const baseDir = dirname(absPath);
215
+ const dirName = basename(baseDir);
216
+ const skillName = name || dirName;
217
+ const config = {
218
+ name: skillName,
219
+ description,
220
+ instructions: body,
221
+ location: absPath,
222
+ baseDir,
223
+ resources: enumerateResources(baseDir)
224
+ };
225
+ if (frontmatter.license)
226
+ config.license = frontmatter.license;
227
+ if (frontmatter.compatibility)
228
+ config.compatibility = frontmatter.compatibility;
229
+ if (frontmatter.metadata && typeof frontmatter.metadata === "object")
230
+ config.metadata = frontmatter.metadata;
231
+ if (frontmatter["allowed-tools"])
232
+ config.allowedTools = frontmatter["allowed-tools"].split(WHITESPACE_SPLIT_RE);
233
+ if (frontmatter.model)
234
+ config.model = frontmatter.model;
235
+ if (frontmatter.thinking)
236
+ config.thinking = frontmatter.thinking;
237
+ if (frontmatter.effort)
238
+ config.thinking = frontmatter.effort;
239
+ if (frontmatter.paths) {
240
+ const raw = frontmatter.paths;
241
+ config.paths = raw.split(COMMA_OR_SPACE_RE).filter(Boolean);
242
+ }
243
+ return config;
244
+ }
245
+ function findSkillDirs(root, maxDepth = 4, _depth = 0) {
246
+ if (_depth > maxDepth)
247
+ return [];
248
+ if (!existsSync(root) || !statSync(root).isDirectory())
249
+ return [];
250
+ const results = [];
251
+ try {
252
+ for (const entry of readdirSync(root)) {
253
+ if (SKIP_DIRS.has(entry))
254
+ continue;
255
+ const entryPath = join(root, entry);
256
+ if (!statSync(entryPath).isDirectory())
257
+ continue;
258
+ const skillFile = join(entryPath, "SKILL.md");
259
+ if (existsSync(skillFile) && statSync(skillFile).isFile()) {
260
+ results.push(skillFile);
261
+ } else {
262
+ results.push(...findSkillDirs(entryPath, maxDepth, _depth + 1));
263
+ }
264
+ }
265
+ } catch {
266
+ }
267
+ return results;
268
+ }
269
+ function getDefaultScanPaths() {
270
+ const home = homedir();
271
+ const cwd = process.cwd();
272
+ return [
273
+ // Project-level (higher priority)
274
+ join(cwd, ".agents", "skills"),
275
+ join(cwd, ".zidane", "skills"),
276
+ // User-level (lower priority)
277
+ join(home, ".agents", "skills"),
278
+ join(home, ".zidane", "skills")
279
+ ];
280
+ }
281
+ async function discoverSkills(paths) {
282
+ const skillsByName = /* @__PURE__ */ new Map();
283
+ for (const scanPath of paths) {
284
+ const skillFiles = findSkillDirs(resolve(scanPath));
285
+ for (const file of skillFiles) {
286
+ const skill = await parseSkillFile(file);
287
+ if (skill && !skillsByName.has(skill.name)) {
288
+ skillsByName.set(skill.name, skill);
289
+ }
290
+ }
291
+ }
292
+ return [...skillsByName.values()];
293
+ }
294
+ var SKILL_NAME_RE, FRONTMATTER_RE, INDENT_RE, KV_RE, QUOTE_RE, WHITESPACE_SPLIT_RE, PARAGRAPH_SPLIT_RE, COMMA_OR_SPACE_RE, RESOURCE_DIRS, SKIP_DIRS;
295
+ var init_discovery = __esm({
296
+ "src/skills/discovery.ts"() {
297
+ "use strict";
298
+ SKILL_NAME_RE = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
299
+ FRONTMATTER_RE = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/;
300
+ INDENT_RE = /^[ \t]{2,}/;
301
+ KV_RE = /^([^:]+):(.*)$/;
302
+ QUOTE_RE = /^(['"])(.*)\1$/;
303
+ WHITESPACE_SPLIT_RE = /\s+/;
304
+ PARAGRAPH_SPLIT_RE = /\n\n/;
305
+ COMMA_OR_SPACE_RE = /[,\s]+/;
306
+ RESOURCE_DIRS = {
307
+ scripts: "script",
308
+ references: "reference",
309
+ assets: "asset"
310
+ };
311
+ SKIP_DIRS = /* @__PURE__ */ new Set([".git", "node_modules", ".DS_Store", "dist", "build"]);
312
+ }
313
+ });
314
+
315
+ // src/skills/writer.ts
316
+ import { mkdirSync, writeFileSync } from "fs";
317
+ import { join as join2 } from "path";
318
+ function serializeFrontmatter(skill) {
319
+ const lines = ["---"];
320
+ lines.push(`name: ${skill.name}`);
321
+ lines.push(`description: ${skill.description}`);
322
+ if (skill.license)
323
+ lines.push(`license: ${skill.license}`);
324
+ if (skill.compatibility)
325
+ lines.push(`compatibility: ${skill.compatibility}`);
326
+ if (skill.allowedTools?.length)
327
+ lines.push(`allowed-tools: ${skill.allowedTools.join(" ")}`);
328
+ if (skill.model)
329
+ lines.push(`model: ${skill.model}`);
330
+ if (skill.thinking)
331
+ lines.push(`thinking: ${skill.thinking}`);
332
+ if (skill.paths?.length)
333
+ lines.push(`paths: ${skill.paths.join(", ")}`);
334
+ if (skill.metadata && Object.keys(skill.metadata).length > 0) {
335
+ lines.push("metadata:");
336
+ for (const [key, value] of Object.entries(skill.metadata)) {
337
+ lines.push(` ${key}: "${value}"`);
338
+ }
339
+ }
340
+ lines.push("---");
341
+ return lines.join("\n");
342
+ }
343
+ function writeSkillToDisk(skill, targetDir) {
344
+ const skillDir = join2(targetDir, skill.name);
345
+ mkdirSync(skillDir, { recursive: true });
346
+ const frontmatter = serializeFrontmatter(skill);
347
+ const body = skill.instructions ? `
348
+ ${skill.instructions}` : "";
349
+ const content = `${frontmatter}
350
+ ${body}
351
+ `;
352
+ const skillPath = join2(skillDir, "SKILL.md");
353
+ writeFileSync(skillPath, content);
354
+ return skillPath;
355
+ }
356
+ function writeSkillsToDisk(skills, targetDir) {
357
+ mkdirSync(targetDir, { recursive: true });
358
+ for (const skill of skills) {
359
+ writeSkillToDisk(skill, targetDir);
360
+ }
361
+ return targetDir;
362
+ }
363
+ var init_writer = __esm({
364
+ "src/skills/writer.ts"() {
365
+ "use strict";
366
+ }
367
+ });
368
+
369
+ // src/skills/resolve.ts
370
+ import { mkdtempSync } from "fs";
371
+ import { tmpdir } from "os";
372
+ import { join as join3 } from "path";
373
+ async function resolveSkills(config) {
374
+ const scanPaths = config.skipDefaultPaths ? [...config.scan ?? []] : [...getDefaultScanPaths(), ...config.scan ?? []];
375
+ if (config.write?.length) {
376
+ const writeDir = mkdtempSync(join3(tmpdir(), "zidane-skills-"));
377
+ writeSkillsToDisk(config.write, writeDir);
378
+ scanPaths.push(writeDir);
379
+ }
380
+ const skills = await discoverSkills(scanPaths);
381
+ const exclude = new Set(config.exclude ?? []);
382
+ let filtered = skills.filter((s) => !exclude.has(s.name));
383
+ if (Array.isArray(config.enabled)) {
384
+ const allowlist = new Set(config.enabled);
385
+ filtered = filtered.filter((s) => allowlist.has(s.name));
386
+ }
387
+ return filtered;
388
+ }
389
+ function mergeSkillsConfig(harness, agent) {
390
+ if (!harness && !agent)
391
+ return void 0;
392
+ if (!harness)
393
+ return agent;
394
+ if (!agent)
395
+ return harness;
396
+ return {
397
+ // Agent-level enabled takes precedence when explicitly set
398
+ enabled: agent.enabled !== void 0 ? agent.enabled : harness.enabled,
399
+ scan: [...harness.scan ?? [], ...agent.scan ?? []],
400
+ write: [...harness.write ?? [], ...agent.write ?? []],
401
+ readToolName: agent.readToolName ?? harness.readToolName,
402
+ exclude: [.../* @__PURE__ */ new Set([...harness.exclude ?? [], ...agent.exclude ?? []])]
403
+ };
404
+ }
405
+ var init_resolve = __esm({
406
+ "src/skills/resolve.ts"() {
407
+ "use strict";
408
+ init_discovery();
409
+ init_writer();
410
+ }
411
+ });
412
+
413
+ export {
414
+ buildCatalog,
415
+ init_catalog,
416
+ interpolateShellCommands,
417
+ init_interpolate,
418
+ validateSkillName,
419
+ parseFrontmatter,
420
+ parseSkillFile,
421
+ getDefaultScanPaths,
422
+ discoverSkills,
423
+ init_discovery,
424
+ writeSkillToDisk,
425
+ writeSkillsToDisk,
426
+ init_writer,
427
+ resolveSkills,
428
+ mergeSkillsConfig,
429
+ init_resolve
430
+ };
@@ -0,0 +1,21 @@
1
+ import {
2
+ init_catalog,
3
+ init_discovery,
4
+ init_interpolate,
5
+ init_resolve,
6
+ init_writer
7
+ } from "./chunk-PRNQ7DXE.js";
8
+
9
+ // src/skills/index.ts
10
+ init_catalog();
11
+ init_discovery();
12
+ init_interpolate();
13
+ init_resolve();
14
+ init_writer();
15
+ function defineSkill(config) {
16
+ return config;
17
+ }
18
+
19
+ export {
20
+ defineSkill
21
+ };