mcp-agent-foundry 1.3.1 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +265 -2
- package/dist/background/index.d.ts +33 -0
- package/dist/background/index.d.ts.map +1 -0
- package/dist/background/index.js +33 -0
- package/dist/background/index.js.map +1 -0
- package/dist/background/task-runner.d.ts +177 -0
- package/dist/background/task-runner.d.ts.map +1 -0
- package/dist/background/task-runner.js +551 -0
- package/dist/background/task-runner.js.map +1 -0
- package/dist/background/types.d.ts +135 -0
- package/dist/background/types.d.ts.map +1 -0
- package/dist/background/types.js +8 -0
- package/dist/background/types.js.map +1 -0
- package/dist/config/validator.d.ts +2 -2
- package/dist/config/validator.d.ts.map +1 -1
- package/dist/config/validator.js +2 -2
- package/dist/config/validator.js.map +1 -1
- package/dist/failover/health-tracker.d.ts +81 -1
- package/dist/failover/health-tracker.d.ts.map +1 -1
- package/dist/failover/health-tracker.js +229 -1
- package/dist/failover/health-tracker.js.map +1 -1
- package/dist/failover/orchestrator.d.ts.map +1 -1
- package/dist/failover/orchestrator.js +12 -2
- package/dist/failover/orchestrator.js.map +1 -1
- package/dist/hooks/hook-executor.d.ts +77 -0
- package/dist/hooks/hook-executor.d.ts.map +1 -0
- package/dist/hooks/hook-executor.js +308 -0
- package/dist/hooks/hook-executor.js.map +1 -0
- package/dist/hooks/hook-manager.d.ts +140 -0
- package/dist/hooks/hook-manager.d.ts.map +1 -0
- package/dist/hooks/hook-manager.js +520 -0
- package/dist/hooks/hook-manager.js.map +1 -0
- package/dist/hooks/index.d.ts +10 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +10 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/types.d.ts +221 -0
- package/dist/hooks/types.d.ts.map +1 -0
- package/dist/hooks/types.js +31 -0
- package/dist/hooks/types.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/mcp/auto-mode.d.ts +221 -0
- package/dist/mcp/auto-mode.d.ts.map +1 -0
- package/dist/mcp/auto-mode.js +436 -0
- package/dist/mcp/auto-mode.js.map +1 -0
- package/dist/mcp/index.d.ts +14 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +22 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/tools/critique-plan.d.ts.map +1 -1
- package/dist/mcp/tools/critique-plan.js +57 -4
- package/dist/mcp/tools/critique-plan.js.map +1 -1
- package/dist/mcp/tools/design-feedback.d.ts.map +1 -1
- package/dist/mcp/tools/design-feedback.js +58 -4
- package/dist/mcp/tools/design-feedback.js.map +1 -1
- package/dist/mcp/tools/invoke-agent.d.ts.map +1 -1
- package/dist/mcp/tools/invoke-agent.js +64 -1
- package/dist/mcp/tools/invoke-agent.js.map +1 -1
- package/dist/mcp/tools/review-code.d.ts.map +1 -1
- package/dist/mcp/tools/review-code.js +57 -4
- package/dist/mcp/tools/review-code.js.map +1 -1
- package/dist/mcp/tools/tasks/delete-task.d.ts +25 -0
- package/dist/mcp/tools/tasks/delete-task.d.ts.map +1 -0
- package/dist/mcp/tools/tasks/delete-task.js +148 -0
- package/dist/mcp/tools/tasks/delete-task.js.map +1 -0
- package/dist/mcp/tools/tasks/execute-task.d.ts.map +1 -1
- package/dist/mcp/tools/tasks/execute-task.js +74 -5
- package/dist/mcp/tools/tasks/execute-task.js.map +1 -1
- package/dist/mcp/tools/tasks/index.d.ts +2 -0
- package/dist/mcp/tools/tasks/index.d.ts.map +1 -1
- package/dist/mcp/tools/tasks/index.js +6 -0
- package/dist/mcp/tools/tasks/index.js.map +1 -1
- package/dist/observability/debug-logger.d.ts +209 -0
- package/dist/observability/debug-logger.d.ts.map +1 -0
- package/dist/observability/debug-logger.js +430 -0
- package/dist/observability/debug-logger.js.map +1 -0
- package/dist/observability/index.d.ts +12 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +12 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/logger.d.ts +180 -0
- package/dist/observability/logger.d.ts.map +1 -1
- package/dist/observability/logger.js +158 -0
- package/dist/observability/logger.js.map +1 -1
- package/dist/providers/anthropic.d.ts +40 -6
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +120 -8
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/base.d.ts +6 -3
- package/dist/providers/base.d.ts.map +1 -1
- package/dist/providers/base.js.map +1 -1
- package/dist/router/context-manager.d.ts +214 -1
- package/dist/router/context-manager.d.ts.map +1 -1
- package/dist/router/context-manager.js +759 -2
- package/dist/router/context-manager.js.map +1 -1
- package/dist/router/context-types.d.ts +182 -0
- package/dist/router/context-types.d.ts.map +1 -0
- package/dist/router/context-types.js +8 -0
- package/dist/router/context-types.js.map +1 -0
- package/dist/router/engine.d.ts +3 -3
- package/dist/router/engine.d.ts.map +1 -1
- package/dist/router/engine.js +32 -4
- package/dist/router/engine.js.map +1 -1
- package/dist/router/pattern-executor.d.ts.map +1 -1
- package/dist/router/pattern-executor.js +38 -7
- package/dist/router/pattern-executor.js.map +1 -1
- package/dist/server.d.ts +41 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +165 -0
- package/dist/server.js.map +1 -1
- package/dist/skills/hot-reloader.d.ts +104 -0
- package/dist/skills/hot-reloader.d.ts.map +1 -0
- package/dist/skills/hot-reloader.js +314 -0
- package/dist/skills/hot-reloader.js.map +1 -0
- package/dist/skills/index.d.ts +14 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +16 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/skill-executor.d.ts +96 -0
- package/dist/skills/skill-executor.d.ts.map +1 -0
- package/dist/skills/skill-executor.js +289 -0
- package/dist/skills/skill-executor.js.map +1 -0
- package/dist/skills/skill-loader.d.ts +147 -0
- package/dist/skills/skill-loader.d.ts.map +1 -0
- package/dist/skills/skill-loader.js +579 -0
- package/dist/skills/skill-loader.js.map +1 -0
- package/dist/skills/types.d.ts +198 -0
- package/dist/skills/types.d.ts.map +1 -0
- package/dist/skills/types.js +21 -0
- package/dist/skills/types.js.map +1 -0
- package/dist/tasks/coordinator.d.ts +22 -1
- package/dist/tasks/coordinator.d.ts.map +1 -1
- package/dist/tasks/coordinator.js +83 -0
- package/dist/tasks/coordinator.js.map +1 -1
- package/dist/tasks/state-coordinator.d.ts +19 -0
- package/dist/tasks/state-coordinator.d.ts.map +1 -1
- package/dist/tasks/state-coordinator.js +40 -0
- package/dist/tasks/state-coordinator.js.map +1 -1
- package/dist/types.d.ts +39 -7
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,579 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill Loader
|
|
3
|
+
*
|
|
4
|
+
* Loads and manages skill definitions from YAML/JSON files.
|
|
5
|
+
* Handles file discovery, parsing, validation, and registration.
|
|
6
|
+
*/
|
|
7
|
+
import { promises as fs } from 'fs';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import os from 'os';
|
|
10
|
+
import { parse as parseYaml } from 'yaml';
|
|
11
|
+
import { DEFAULT_SKILLS_CONFIG } from './types.js';
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// Skill Loader Class
|
|
14
|
+
// ============================================================================
|
|
15
|
+
/**
|
|
16
|
+
* Loads and manages skill definitions from files.
|
|
17
|
+
* Provides methods for discovery, parsing, validation, and querying.
|
|
18
|
+
*/
|
|
19
|
+
export class SkillLoader {
|
|
20
|
+
skills = new Map();
|
|
21
|
+
config;
|
|
22
|
+
logger;
|
|
23
|
+
cooldownTracker = new Map(); // skill name -> last trigger timestamp
|
|
24
|
+
constructor(config, logger) {
|
|
25
|
+
this.config = { ...DEFAULT_SKILLS_CONFIG, ...config };
|
|
26
|
+
this.logger = logger.child({ component: 'SkillLoader' });
|
|
27
|
+
this.logger.debug('SkillLoader initialized', {
|
|
28
|
+
enabled: this.config.enabled,
|
|
29
|
+
searchPaths: this.config.searchPaths,
|
|
30
|
+
filePatterns: this.config.filePatterns,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
// ==========================================================================
|
|
34
|
+
// Loading Methods
|
|
35
|
+
// ==========================================================================
|
|
36
|
+
/**
|
|
37
|
+
* Load all skills from configured search paths.
|
|
38
|
+
* Searches each path in order and registers found skills.
|
|
39
|
+
*/
|
|
40
|
+
async loadAll() {
|
|
41
|
+
if (!this.config.enabled) {
|
|
42
|
+
this.logger.debug('Skills system disabled, skipping load');
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
this.logger.info('Loading skills from configured paths', {
|
|
46
|
+
paths: this.config.searchPaths,
|
|
47
|
+
});
|
|
48
|
+
let totalLoaded = 0;
|
|
49
|
+
for (const searchPath of this.config.searchPaths) {
|
|
50
|
+
try {
|
|
51
|
+
const expandedPath = this.expandPath(searchPath);
|
|
52
|
+
const skills = await this.loadFromDirectory(expandedPath);
|
|
53
|
+
totalLoaded += skills.length;
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
// Directory may not exist, which is fine
|
|
57
|
+
if (error.code !== 'ENOENT') {
|
|
58
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
59
|
+
this.logger.warn('Failed to load skills from path', {
|
|
60
|
+
path: searchPath,
|
|
61
|
+
error: errorMessage,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
this.logger.info('Skills loading complete', {
|
|
67
|
+
totalLoaded,
|
|
68
|
+
totalRegistered: this.skills.size,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Load skills from a specific directory.
|
|
73
|
+
* Returns array of successfully loaded skill definitions.
|
|
74
|
+
*
|
|
75
|
+
* @param dirPath - Directory path to search
|
|
76
|
+
* @returns Array of loaded skill definitions
|
|
77
|
+
*/
|
|
78
|
+
async loadFromDirectory(dirPath) {
|
|
79
|
+
const expandedPath = this.expandPath(dirPath);
|
|
80
|
+
const loadedSkills = [];
|
|
81
|
+
try {
|
|
82
|
+
const stat = await fs.stat(expandedPath);
|
|
83
|
+
if (!stat.isDirectory()) {
|
|
84
|
+
this.logger.warn('Path is not a directory', { path: expandedPath });
|
|
85
|
+
return loadedSkills;
|
|
86
|
+
}
|
|
87
|
+
const entries = await fs.readdir(expandedPath, { withFileTypes: true });
|
|
88
|
+
for (const entry of entries) {
|
|
89
|
+
if (entry.isFile() && this.isSkillFile(entry.name)) {
|
|
90
|
+
const filePath = path.join(expandedPath, entry.name);
|
|
91
|
+
const skill = await this.loadSkillFile(filePath);
|
|
92
|
+
if (skill) {
|
|
93
|
+
loadedSkills.push(skill);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else if (entry.isDirectory()) {
|
|
97
|
+
// Recursively load from subdirectories
|
|
98
|
+
const subDirPath = path.join(expandedPath, entry.name);
|
|
99
|
+
const subSkills = await this.loadFromDirectory(subDirPath);
|
|
100
|
+
loadedSkills.push(...subSkills);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
this.logger.debug('Loaded skills from directory', {
|
|
104
|
+
path: expandedPath,
|
|
105
|
+
count: loadedSkills.length,
|
|
106
|
+
});
|
|
107
|
+
return loadedSkills;
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
if (error.code === 'ENOENT') {
|
|
111
|
+
this.logger.debug('Skills directory does not exist', { path: expandedPath });
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
throw error;
|
|
115
|
+
}
|
|
116
|
+
return loadedSkills;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Load a single skill file.
|
|
121
|
+
* Parses, validates, and registers the skill.
|
|
122
|
+
*
|
|
123
|
+
* @param filePath - Path to the skill file
|
|
124
|
+
* @returns Loaded skill definition or null if failed
|
|
125
|
+
*/
|
|
126
|
+
async loadSkillFile(filePath) {
|
|
127
|
+
try {
|
|
128
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
129
|
+
const stat = await fs.stat(filePath);
|
|
130
|
+
const skill = this.parseSkill(content, filePath);
|
|
131
|
+
// Add metadata
|
|
132
|
+
skill.sourcePath = filePath;
|
|
133
|
+
skill.lastModified = stat.mtime;
|
|
134
|
+
// Validate
|
|
135
|
+
const validation = this.validateSkill(skill);
|
|
136
|
+
if (!validation.valid) {
|
|
137
|
+
this.logger.warn('Skill validation failed', {
|
|
138
|
+
path: filePath,
|
|
139
|
+
errors: validation.errors.map((e) => e.message),
|
|
140
|
+
});
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
if (validation.warnings.length > 0) {
|
|
144
|
+
this.logger.debug('Skill validation warnings', {
|
|
145
|
+
path: filePath,
|
|
146
|
+
warnings: validation.warnings.map((e) => e.message),
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
// Register
|
|
150
|
+
this.register(skill);
|
|
151
|
+
this.logger.debug('Skill loaded', {
|
|
152
|
+
name: skill.name,
|
|
153
|
+
path: filePath,
|
|
154
|
+
enabled: skill.enabled !== false,
|
|
155
|
+
});
|
|
156
|
+
return skill;
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
160
|
+
this.logger.warn('Failed to load skill file', {
|
|
161
|
+
path: filePath,
|
|
162
|
+
error: errorMessage,
|
|
163
|
+
});
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// ==========================================================================
|
|
168
|
+
// Parsing Methods
|
|
169
|
+
// ==========================================================================
|
|
170
|
+
/**
|
|
171
|
+
* Parse skill definition from file content.
|
|
172
|
+
* Supports YAML and JSON formats.
|
|
173
|
+
*
|
|
174
|
+
* @param content - File content
|
|
175
|
+
* @param filePath - Path to file (for error messages and format detection)
|
|
176
|
+
* @returns Parsed skill definition
|
|
177
|
+
*/
|
|
178
|
+
parseSkill(content, filePath) {
|
|
179
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
180
|
+
try {
|
|
181
|
+
let parsed;
|
|
182
|
+
if (ext === '.json') {
|
|
183
|
+
parsed = JSON.parse(content);
|
|
184
|
+
}
|
|
185
|
+
else if (ext === '.yaml' || ext === '.yml') {
|
|
186
|
+
parsed = parseYaml(content);
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
// Try YAML first, then JSON
|
|
190
|
+
try {
|
|
191
|
+
parsed = parseYaml(content);
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
parsed = JSON.parse(content);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
198
|
+
throw new Error('Skill definition must be an object');
|
|
199
|
+
}
|
|
200
|
+
return this.normalizeSkill(parsed, filePath);
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
204
|
+
throw new Error(`Failed to parse skill file ${filePath}: ${errorMessage}`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Normalize parsed skill object to SkillDefinition.
|
|
209
|
+
* Applies defaults and type coercion.
|
|
210
|
+
*/
|
|
211
|
+
normalizeSkill(parsed, filePath) {
|
|
212
|
+
// Extract name from filename if not provided
|
|
213
|
+
const defaultName = path.basename(filePath, path.extname(filePath));
|
|
214
|
+
return {
|
|
215
|
+
name: String(parsed['name'] ?? defaultName),
|
|
216
|
+
displayName: parsed['displayName'] ? String(parsed['displayName']) : undefined,
|
|
217
|
+
description: String(parsed['description'] ?? ''),
|
|
218
|
+
version: parsed['version'] ? String(parsed['version']) : undefined,
|
|
219
|
+
author: parsed['author'] ? String(parsed['author']) : undefined,
|
|
220
|
+
keywords: Array.isArray(parsed['keywords'])
|
|
221
|
+
? parsed['keywords'].map(String)
|
|
222
|
+
: undefined,
|
|
223
|
+
triggers: this.parseTriggers(parsed['triggers']),
|
|
224
|
+
role: parsed['role'] ? String(parsed['role']) : undefined,
|
|
225
|
+
provider: parsed['provider'] ? String(parsed['provider']) : undefined,
|
|
226
|
+
model: parsed['model'] ? String(parsed['model']) : undefined,
|
|
227
|
+
systemPrompt: parsed['systemPrompt'] ? String(parsed['systemPrompt']) : undefined,
|
|
228
|
+
context: this.parseContextMode(parsed['context']),
|
|
229
|
+
allowedTools: Array.isArray(parsed['allowedTools'])
|
|
230
|
+
? parsed['allowedTools'].map(String)
|
|
231
|
+
: undefined,
|
|
232
|
+
internal: parsed['internal'] === true,
|
|
233
|
+
enabled: parsed['enabled'] !== false,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Parse triggers array from raw data.
|
|
238
|
+
*/
|
|
239
|
+
parseTriggers(raw) {
|
|
240
|
+
if (!Array.isArray(raw)) {
|
|
241
|
+
return undefined;
|
|
242
|
+
}
|
|
243
|
+
return raw.map((t) => {
|
|
244
|
+
if (typeof t !== 'object' || t === null) {
|
|
245
|
+
return {};
|
|
246
|
+
}
|
|
247
|
+
const trigger = t;
|
|
248
|
+
return {
|
|
249
|
+
keywords: Array.isArray(trigger['keywords'])
|
|
250
|
+
? trigger['keywords'].map(String)
|
|
251
|
+
: undefined,
|
|
252
|
+
patterns: Array.isArray(trigger['patterns'])
|
|
253
|
+
? trigger['patterns'].map(String)
|
|
254
|
+
: undefined,
|
|
255
|
+
events: Array.isArray(trigger['events'])
|
|
256
|
+
? trigger['events'].map(String)
|
|
257
|
+
: undefined,
|
|
258
|
+
confidence: typeof trigger['confidence'] === 'number' ? trigger['confidence'] : undefined,
|
|
259
|
+
cooldownMs: typeof trigger['cooldownMs'] === 'number' ? trigger['cooldownMs'] : undefined,
|
|
260
|
+
};
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Parse context mode from raw value.
|
|
265
|
+
*/
|
|
266
|
+
parseContextMode(raw) {
|
|
267
|
+
if (raw === 'inherit' || raw === 'fork' || raw === 'isolated') {
|
|
268
|
+
return raw;
|
|
269
|
+
}
|
|
270
|
+
return undefined;
|
|
271
|
+
}
|
|
272
|
+
// ==========================================================================
|
|
273
|
+
// Validation Methods
|
|
274
|
+
// ==========================================================================
|
|
275
|
+
/**
|
|
276
|
+
* Validate a skill definition.
|
|
277
|
+
* Returns validation result with errors and warnings.
|
|
278
|
+
*
|
|
279
|
+
* @param skill - Skill definition to validate
|
|
280
|
+
* @returns Validation result
|
|
281
|
+
*/
|
|
282
|
+
validateSkill(skill) {
|
|
283
|
+
const errors = [];
|
|
284
|
+
const warnings = [];
|
|
285
|
+
// Required fields
|
|
286
|
+
if (!skill.name || skill.name.trim() === '') {
|
|
287
|
+
errors.push({
|
|
288
|
+
field: 'name',
|
|
289
|
+
message: 'Skill name is required',
|
|
290
|
+
severity: 'error',
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
else if (!/^[a-zA-Z0-9_-]+$/.test(skill.name)) {
|
|
294
|
+
errors.push({
|
|
295
|
+
field: 'name',
|
|
296
|
+
message: 'Skill name must contain only alphanumeric characters, underscores, and hyphens',
|
|
297
|
+
severity: 'error',
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
if (!skill.description || skill.description.trim() === '') {
|
|
301
|
+
warnings.push({
|
|
302
|
+
field: 'description',
|
|
303
|
+
message: 'Skill description is recommended',
|
|
304
|
+
severity: 'warning',
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
// Validate triggers
|
|
308
|
+
if (skill.triggers) {
|
|
309
|
+
for (let i = 0; i < skill.triggers.length; i++) {
|
|
310
|
+
const trigger = skill.triggers[i];
|
|
311
|
+
if (trigger && trigger.confidence !== undefined) {
|
|
312
|
+
if (trigger.confidence < 0 || trigger.confidence > 1) {
|
|
313
|
+
errors.push({
|
|
314
|
+
field: `triggers[${i}].confidence`,
|
|
315
|
+
message: 'Confidence must be between 0 and 1',
|
|
316
|
+
severity: 'error',
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
if (trigger && trigger.cooldownMs !== undefined && trigger.cooldownMs < 0) {
|
|
321
|
+
errors.push({
|
|
322
|
+
field: `triggers[${i}].cooldownMs`,
|
|
323
|
+
message: 'Cooldown must be non-negative',
|
|
324
|
+
severity: 'error',
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
// Validate patterns are valid regex
|
|
328
|
+
if (trigger?.patterns) {
|
|
329
|
+
for (let j = 0; j < trigger.patterns.length; j++) {
|
|
330
|
+
try {
|
|
331
|
+
new RegExp(trigger.patterns[j] ?? '');
|
|
332
|
+
}
|
|
333
|
+
catch {
|
|
334
|
+
errors.push({
|
|
335
|
+
field: `triggers[${i}].patterns[${j}]`,
|
|
336
|
+
message: `Invalid regular expression: ${trigger.patterns[j]}`,
|
|
337
|
+
severity: 'error',
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
// Context mode validation
|
|
345
|
+
if (skill.context &&
|
|
346
|
+
!['inherit', 'fork', 'isolated'].includes(skill.context)) {
|
|
347
|
+
errors.push({
|
|
348
|
+
field: 'context',
|
|
349
|
+
message: "Context must be 'inherit', 'fork', or 'isolated'",
|
|
350
|
+
severity: 'error',
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
// Version format (semver)
|
|
354
|
+
if (skill.version && !/^\d+\.\d+\.\d+/.test(skill.version)) {
|
|
355
|
+
warnings.push({
|
|
356
|
+
field: 'version',
|
|
357
|
+
message: 'Version should follow semver format (e.g., 1.0.0)',
|
|
358
|
+
severity: 'warning',
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
return {
|
|
362
|
+
valid: errors.length === 0,
|
|
363
|
+
errors,
|
|
364
|
+
warnings,
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
// ==========================================================================
|
|
368
|
+
// Registration Methods
|
|
369
|
+
// ==========================================================================
|
|
370
|
+
/**
|
|
371
|
+
* Register a skill programmatically.
|
|
372
|
+
* Overwrites existing skill with same name.
|
|
373
|
+
*
|
|
374
|
+
* @param skill - Skill definition to register
|
|
375
|
+
*/
|
|
376
|
+
register(skill) {
|
|
377
|
+
const existing = this.skills.get(skill.name);
|
|
378
|
+
if (existing) {
|
|
379
|
+
this.logger.debug('Overwriting existing skill', { name: skill.name });
|
|
380
|
+
}
|
|
381
|
+
this.skills.set(skill.name, skill);
|
|
382
|
+
this.logger.debug('Skill registered', {
|
|
383
|
+
name: skill.name,
|
|
384
|
+
displayName: skill.displayName,
|
|
385
|
+
enabled: skill.enabled !== false,
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Unregister a skill by name.
|
|
390
|
+
*
|
|
391
|
+
* @param name - Skill name to unregister
|
|
392
|
+
* @returns True if skill was found and removed
|
|
393
|
+
*/
|
|
394
|
+
unregister(name) {
|
|
395
|
+
const existed = this.skills.delete(name);
|
|
396
|
+
if (existed) {
|
|
397
|
+
this.cooldownTracker.delete(name);
|
|
398
|
+
this.logger.debug('Skill unregistered', { name });
|
|
399
|
+
}
|
|
400
|
+
return existed;
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Check if a skill exists.
|
|
404
|
+
*
|
|
405
|
+
* @param name - Skill name
|
|
406
|
+
* @returns True if skill is registered
|
|
407
|
+
*/
|
|
408
|
+
has(name) {
|
|
409
|
+
return this.skills.has(name);
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Clear all loaded skills.
|
|
413
|
+
*/
|
|
414
|
+
clear() {
|
|
415
|
+
this.skills.clear();
|
|
416
|
+
this.cooldownTracker.clear();
|
|
417
|
+
this.logger.debug('All skills cleared');
|
|
418
|
+
}
|
|
419
|
+
// ==========================================================================
|
|
420
|
+
// Query Methods
|
|
421
|
+
// ==========================================================================
|
|
422
|
+
/**
|
|
423
|
+
* Get all loaded skills.
|
|
424
|
+
*
|
|
425
|
+
* @returns Array of all skill definitions
|
|
426
|
+
*/
|
|
427
|
+
getAllSkills() {
|
|
428
|
+
return Array.from(this.skills.values());
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Get skill by name.
|
|
432
|
+
*
|
|
433
|
+
* @param name - Skill name
|
|
434
|
+
* @returns Skill definition or undefined if not found
|
|
435
|
+
*/
|
|
436
|
+
getSkill(name) {
|
|
437
|
+
return this.skills.get(name);
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Get the file path for a skill.
|
|
441
|
+
*
|
|
442
|
+
* @param name - Skill name
|
|
443
|
+
* @returns Source file path or undefined
|
|
444
|
+
*/
|
|
445
|
+
getSkillPath(name) {
|
|
446
|
+
return this.skills.get(name)?.sourcePath;
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Get skills matching trigger conditions.
|
|
450
|
+
* Returns skills sorted by confidence score (highest first).
|
|
451
|
+
*
|
|
452
|
+
* @param context - Trigger context to match against
|
|
453
|
+
* @returns Array of matching skills with confidence scores
|
|
454
|
+
*/
|
|
455
|
+
getMatchingSkills(context) {
|
|
456
|
+
const matches = [];
|
|
457
|
+
const now = Date.now();
|
|
458
|
+
for (const skill of this.skills.values()) {
|
|
459
|
+
// Skip disabled or internal skills
|
|
460
|
+
if (skill.enabled === false || skill.internal) {
|
|
461
|
+
continue;
|
|
462
|
+
}
|
|
463
|
+
// Skip skills without triggers
|
|
464
|
+
if (!skill.triggers || skill.triggers.length === 0) {
|
|
465
|
+
continue;
|
|
466
|
+
}
|
|
467
|
+
// Check each trigger
|
|
468
|
+
for (const trigger of skill.triggers) {
|
|
469
|
+
const match = this.matchTrigger(skill, trigger, context, now);
|
|
470
|
+
if (match) {
|
|
471
|
+
matches.push(match);
|
|
472
|
+
break; // Only match once per skill
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
// Sort by confidence (highest first)
|
|
477
|
+
matches.sort((a, b) => b.confidence - a.confidence);
|
|
478
|
+
return matches;
|
|
479
|
+
}
|
|
480
|
+
// ==========================================================================
|
|
481
|
+
// Reload Methods
|
|
482
|
+
// ==========================================================================
|
|
483
|
+
/**
|
|
484
|
+
* Reload a specific skill from its source file.
|
|
485
|
+
*
|
|
486
|
+
* @param name - Skill name to reload
|
|
487
|
+
* @returns True if skill was successfully reloaded
|
|
488
|
+
*/
|
|
489
|
+
async reloadSkill(name) {
|
|
490
|
+
const existing = this.skills.get(name);
|
|
491
|
+
if (!existing?.sourcePath) {
|
|
492
|
+
this.logger.warn('Cannot reload skill without source path', { name });
|
|
493
|
+
return false;
|
|
494
|
+
}
|
|
495
|
+
const reloaded = await this.loadSkillFile(existing.sourcePath);
|
|
496
|
+
return reloaded !== null;
|
|
497
|
+
}
|
|
498
|
+
// ==========================================================================
|
|
499
|
+
// Private Methods
|
|
500
|
+
// ==========================================================================
|
|
501
|
+
/**
|
|
502
|
+
* Expand ~ in paths to home directory.
|
|
503
|
+
*/
|
|
504
|
+
expandPath(p) {
|
|
505
|
+
if (p.startsWith('~')) {
|
|
506
|
+
return path.join(os.homedir(), p.slice(1));
|
|
507
|
+
}
|
|
508
|
+
return p;
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Check if filename matches skill file patterns.
|
|
512
|
+
*/
|
|
513
|
+
isSkillFile(filename) {
|
|
514
|
+
const ext = path.extname(filename).toLowerCase();
|
|
515
|
+
return ['.yaml', '.yml', '.json'].includes(ext);
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Match a trigger against the provided context.
|
|
519
|
+
*/
|
|
520
|
+
matchTrigger(skill, trigger, context, now) {
|
|
521
|
+
// Check cooldown
|
|
522
|
+
if (trigger.cooldownMs) {
|
|
523
|
+
const lastTrigger = this.cooldownTracker.get(skill.name);
|
|
524
|
+
if (lastTrigger && now - lastTrigger < trigger.cooldownMs) {
|
|
525
|
+
return null;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
let matched = false;
|
|
529
|
+
let confidence = trigger.confidence ?? 1.0;
|
|
530
|
+
const match = {
|
|
531
|
+
skill,
|
|
532
|
+
confidence: 0,
|
|
533
|
+
matchedTrigger: trigger,
|
|
534
|
+
};
|
|
535
|
+
// Check event match
|
|
536
|
+
if (trigger.events && context.event) {
|
|
537
|
+
if (trigger.events.includes(context.event)) {
|
|
538
|
+
matched = true;
|
|
539
|
+
match.matchedEvent = context.event;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
// Check keyword match
|
|
543
|
+
if (trigger.keywords && context.keywords) {
|
|
544
|
+
const matchedKeywords = trigger.keywords.filter((kw) => context.keywords.some((ckw) => ckw.toLowerCase().includes(kw.toLowerCase())));
|
|
545
|
+
if (matchedKeywords.length > 0) {
|
|
546
|
+
matched = true;
|
|
547
|
+
match.matchedKeywords = matchedKeywords;
|
|
548
|
+
// Adjust confidence based on match ratio
|
|
549
|
+
confidence *= matchedKeywords.length / trigger.keywords.length;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
// Check pattern match against text
|
|
553
|
+
if (trigger.patterns && context.text) {
|
|
554
|
+
for (const pattern of trigger.patterns) {
|
|
555
|
+
try {
|
|
556
|
+
const regex = new RegExp(pattern, 'i');
|
|
557
|
+
if (regex.test(context.text)) {
|
|
558
|
+
matched = true;
|
|
559
|
+
match.matchedPattern = pattern;
|
|
560
|
+
break;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
catch {
|
|
564
|
+
// Invalid regex, skip
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
if (matched) {
|
|
569
|
+
match.confidence = confidence;
|
|
570
|
+
// Update cooldown tracker
|
|
571
|
+
if (trigger.cooldownMs) {
|
|
572
|
+
this.cooldownTracker.set(skill.name, now);
|
|
573
|
+
}
|
|
574
|
+
return match;
|
|
575
|
+
}
|
|
576
|
+
return null;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
//# sourceMappingURL=skill-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-loader.js","sourceRoot":"","sources":["../../src/skills/skill-loader.ts"],"names":[],"mappings":"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"}
|