matimo 0.1.0-alpha.8 → 0.1.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/package.json +10 -8
- package/packages/cli/dist/bin.d.ts +3 -0
- package/packages/cli/dist/bin.d.ts.map +1 -0
- package/packages/cli/dist/bin.js +50 -0
- package/packages/cli/dist/bin.js.map +1 -0
- package/packages/cli/dist/cli.d.ts.map +1 -1
- package/packages/cli/dist/cli.js +64 -2
- package/packages/cli/dist/cli.js.map +1 -1
- package/packages/cli/dist/commands/doctor.d.ts +2 -0
- package/packages/cli/dist/commands/doctor.d.ts.map +1 -0
- package/packages/cli/dist/commands/doctor.js +174 -0
- package/packages/cli/dist/commands/doctor.js.map +1 -0
- package/packages/cli/dist/commands/mcp-setup.d.ts +9 -0
- package/packages/cli/dist/commands/mcp-setup.d.ts.map +1 -0
- package/packages/cli/dist/commands/mcp-setup.js +106 -0
- package/packages/cli/dist/commands/mcp-setup.js.map +1 -0
- package/packages/cli/dist/commands/mcp.d.ts +17 -0
- package/packages/cli/dist/commands/mcp.d.ts.map +1 -0
- package/packages/cli/dist/commands/mcp.js +228 -0
- package/packages/cli/dist/commands/mcp.js.map +1 -0
- package/packages/cli/dist/commands/review.d.ts +10 -0
- package/packages/cli/dist/commands/review.d.ts.map +1 -0
- package/packages/cli/dist/commands/review.js +176 -0
- package/packages/cli/dist/commands/review.js.map +1 -0
- package/packages/core/dist/approval/approval-handler.d.ts +5 -1
- package/packages/core/dist/approval/approval-handler.d.ts.map +1 -1
- package/packages/core/dist/approval/approval-handler.js +6 -0
- package/packages/core/dist/approval/approval-handler.js.map +1 -1
- package/packages/core/dist/core/schema.d.ts +41 -10
- package/packages/core/dist/core/schema.d.ts.map +1 -1
- package/packages/core/dist/core/schema.js +40 -4
- package/packages/core/dist/core/schema.js.map +1 -1
- package/packages/core/dist/core/skill-content-parser.d.ts +91 -0
- package/packages/core/dist/core/skill-content-parser.d.ts.map +1 -0
- package/packages/core/dist/core/skill-content-parser.js +248 -0
- package/packages/core/dist/core/skill-content-parser.js.map +1 -0
- package/packages/core/dist/core/skill-loader.d.ts +46 -0
- package/packages/core/dist/core/skill-loader.d.ts.map +1 -0
- package/packages/core/dist/core/skill-loader.js +310 -0
- package/packages/core/dist/core/skill-loader.js.map +1 -0
- package/packages/core/dist/core/skill-registry.d.ts +131 -0
- package/packages/core/dist/core/skill-registry.d.ts.map +1 -0
- package/packages/core/dist/core/skill-registry.js +316 -0
- package/packages/core/dist/core/skill-registry.js.map +1 -0
- package/packages/core/dist/core/tfidf-embedding.d.ts +45 -0
- package/packages/core/dist/core/tfidf-embedding.d.ts.map +1 -0
- package/packages/core/dist/core/tfidf-embedding.js +199 -0
- package/packages/core/dist/core/tfidf-embedding.js.map +1 -0
- package/packages/core/dist/core/tool-loader.d.ts +3 -1
- package/packages/core/dist/core/tool-loader.d.ts.map +1 -1
- package/packages/core/dist/core/tool-loader.js +33 -10
- package/packages/core/dist/core/tool-loader.js.map +1 -1
- package/packages/core/dist/core/types.d.ts +203 -6
- package/packages/core/dist/core/types.d.ts.map +1 -1
- package/packages/core/dist/encodings/parameter-encoding.d.ts +1 -1
- package/packages/core/dist/encodings/parameter-encoding.d.ts.map +1 -1
- package/packages/core/dist/encodings/parameter-encoding.js +9 -4
- package/packages/core/dist/encodings/parameter-encoding.js.map +1 -1
- package/packages/core/dist/errors/matimo-error.d.ts +11 -2
- package/packages/core/dist/errors/matimo-error.d.ts.map +1 -1
- package/packages/core/dist/errors/matimo-error.js +25 -1
- package/packages/core/dist/errors/matimo-error.js.map +1 -1
- package/packages/core/dist/executors/command-executor.d.ts +9 -2
- package/packages/core/dist/executors/command-executor.d.ts.map +1 -1
- package/packages/core/dist/executors/command-executor.js +29 -5
- package/packages/core/dist/executors/command-executor.js.map +1 -1
- package/packages/core/dist/executors/function-executor.d.ts +10 -3
- package/packages/core/dist/executors/function-executor.d.ts.map +1 -1
- package/packages/core/dist/executors/function-executor.js +44 -24
- package/packages/core/dist/executors/function-executor.js.map +1 -1
- package/packages/core/dist/executors/http-executor.d.ts +79 -4
- package/packages/core/dist/executors/http-executor.d.ts.map +1 -1
- package/packages/core/dist/executors/http-executor.js +232 -28
- package/packages/core/dist/executors/http-executor.js.map +1 -1
- package/packages/core/dist/index.d.ts +25 -3
- package/packages/core/dist/index.d.ts.map +1 -1
- package/packages/core/dist/index.js +19 -1
- package/packages/core/dist/index.js.map +1 -1
- package/packages/core/dist/integrations/langchain.d.ts +55 -0
- package/packages/core/dist/integrations/langchain.d.ts.map +1 -1
- package/packages/core/dist/integrations/langchain.js +71 -4
- package/packages/core/dist/integrations/langchain.js.map +1 -1
- package/packages/core/dist/logging/logger.d.ts +8 -2
- package/packages/core/dist/logging/logger.d.ts.map +1 -1
- package/packages/core/dist/logging/logger.js.map +1 -1
- package/packages/core/dist/logging/winston-logger.d.ts.map +1 -1
- package/packages/core/dist/logging/winston-logger.js +9 -1
- package/packages/core/dist/logging/winston-logger.js.map +1 -1
- package/packages/core/dist/matimo-instance.d.ts +230 -18
- package/packages/core/dist/matimo-instance.d.ts.map +1 -1
- package/packages/core/dist/matimo-instance.js +739 -40
- package/packages/core/dist/matimo-instance.js.map +1 -1
- package/packages/core/dist/mcp/index.d.ts +18 -0
- package/packages/core/dist/mcp/index.d.ts.map +1 -0
- package/packages/core/dist/mcp/index.js +24 -0
- package/packages/core/dist/mcp/index.js.map +1 -0
- package/packages/core/dist/mcp/mcp-server.d.ts +141 -0
- package/packages/core/dist/mcp/mcp-server.d.ts.map +1 -0
- package/packages/core/dist/mcp/mcp-server.js +754 -0
- package/packages/core/dist/mcp/mcp-server.js.map +1 -0
- package/packages/core/dist/mcp/secrets/aws-resolver.d.ts +41 -0
- package/packages/core/dist/mcp/secrets/aws-resolver.d.ts.map +1 -0
- package/packages/core/dist/mcp/secrets/aws-resolver.js +141 -0
- package/packages/core/dist/mcp/secrets/aws-resolver.js.map +1 -0
- package/packages/core/dist/mcp/secrets/dotenv-resolver.d.ts +23 -0
- package/packages/core/dist/mcp/secrets/dotenv-resolver.d.ts.map +1 -0
- package/packages/core/dist/mcp/secrets/dotenv-resolver.js +94 -0
- package/packages/core/dist/mcp/secrets/dotenv-resolver.js.map +1 -0
- package/packages/core/dist/mcp/secrets/env-resolver.d.ts +14 -0
- package/packages/core/dist/mcp/secrets/env-resolver.d.ts.map +1 -0
- package/packages/core/dist/mcp/secrets/env-resolver.js +27 -0
- package/packages/core/dist/mcp/secrets/env-resolver.js.map +1 -0
- package/packages/core/dist/mcp/secrets/index.d.ts +14 -0
- package/packages/core/dist/mcp/secrets/index.d.ts.map +1 -0
- package/packages/core/dist/mcp/secrets/index.js +13 -0
- package/packages/core/dist/mcp/secrets/index.js.map +1 -0
- package/packages/core/dist/mcp/secrets/resolver-chain.d.ts +34 -0
- package/packages/core/dist/mcp/secrets/resolver-chain.d.ts.map +1 -0
- package/packages/core/dist/mcp/secrets/resolver-chain.js +141 -0
- package/packages/core/dist/mcp/secrets/resolver-chain.js.map +1 -0
- package/packages/core/dist/mcp/secrets/types.d.ts +73 -0
- package/packages/core/dist/mcp/secrets/types.d.ts.map +1 -0
- package/packages/core/dist/mcp/secrets/types.js +8 -0
- package/packages/core/dist/mcp/secrets/types.js.map +1 -0
- package/packages/core/dist/mcp/secrets/vault-resolver.d.ts +43 -0
- package/packages/core/dist/mcp/secrets/vault-resolver.d.ts.map +1 -0
- package/packages/core/dist/mcp/secrets/vault-resolver.js +127 -0
- package/packages/core/dist/mcp/secrets/vault-resolver.js.map +1 -0
- package/packages/core/dist/mcp/tool-converter.d.ts +40 -0
- package/packages/core/dist/mcp/tool-converter.d.ts.map +1 -0
- package/packages/core/dist/mcp/tool-converter.js +185 -0
- package/packages/core/dist/mcp/tool-converter.js.map +1 -0
- package/packages/core/dist/policy/approval-manifest.d.ts +76 -0
- package/packages/core/dist/policy/approval-manifest.d.ts.map +1 -0
- package/packages/core/dist/policy/approval-manifest.js +197 -0
- package/packages/core/dist/policy/approval-manifest.js.map +1 -0
- package/packages/core/dist/policy/content-validator.d.ts +19 -0
- package/packages/core/dist/policy/content-validator.d.ts.map +1 -0
- package/packages/core/dist/policy/content-validator.js +196 -0
- package/packages/core/dist/policy/content-validator.js.map +1 -0
- package/packages/core/dist/policy/default-policy.d.ts +46 -0
- package/packages/core/dist/policy/default-policy.d.ts.map +1 -0
- package/packages/core/dist/policy/default-policy.js +241 -0
- package/packages/core/dist/policy/default-policy.js.map +1 -0
- package/packages/core/dist/policy/events.d.ts +71 -0
- package/packages/core/dist/policy/events.d.ts.map +1 -0
- package/packages/core/dist/policy/events.js +8 -0
- package/packages/core/dist/policy/events.js.map +1 -0
- package/packages/core/dist/policy/index.d.ts +13 -0
- package/packages/core/dist/policy/index.d.ts.map +1 -0
- package/packages/core/dist/policy/index.js +9 -0
- package/packages/core/dist/policy/index.js.map +1 -0
- package/packages/core/dist/policy/integrity-tracker.d.ts +62 -0
- package/packages/core/dist/policy/integrity-tracker.d.ts.map +1 -0
- package/packages/core/dist/policy/integrity-tracker.js +79 -0
- package/packages/core/dist/policy/integrity-tracker.js.map +1 -0
- package/packages/core/dist/policy/policy-loader.d.ts +58 -0
- package/packages/core/dist/policy/policy-loader.d.ts.map +1 -0
- package/packages/core/dist/policy/policy-loader.js +156 -0
- package/packages/core/dist/policy/policy-loader.js.map +1 -0
- package/packages/core/dist/policy/risk-classifier.d.ts +18 -0
- package/packages/core/dist/policy/risk-classifier.d.ts.map +1 -0
- package/packages/core/dist/policy/risk-classifier.js +47 -0
- package/packages/core/dist/policy/risk-classifier.js.map +1 -0
- package/packages/core/dist/policy/types.d.ts +131 -0
- package/packages/core/dist/policy/types.d.ts.map +1 -0
- package/packages/core/dist/policy/types.js +8 -0
- package/packages/core/dist/policy/types.js.map +1 -0
- package/LICENSE +0 -21
- package/README.md +0 -243
- package/packages/cli/bin/matimo.cjs +0 -26
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill Loader — loads and validates skills from multiple sources
|
|
3
|
+
*
|
|
4
|
+
* Implements agentskills.io specification with proper YAML parsing and Zod validation.
|
|
5
|
+
*
|
|
6
|
+
* @see https://agentskills.io/specification
|
|
7
|
+
*/
|
|
8
|
+
import fs from 'fs';
|
|
9
|
+
import path from 'path';
|
|
10
|
+
import YAML from 'js-yaml';
|
|
11
|
+
import { z } from 'zod';
|
|
12
|
+
import { parseSkillSections } from './skill-content-parser';
|
|
13
|
+
import { getGlobalMatimoLogger } from '../logging';
|
|
14
|
+
import { MatimoError, ErrorCode } from '../errors/matimo-error';
|
|
15
|
+
// ─── Name Validation ─────────────────────────────────────────────────────────
|
|
16
|
+
const VALID_NAME_PATTERN = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/;
|
|
17
|
+
const CONSECUTIVE_HYPHENS = /--/;
|
|
18
|
+
const MAX_NAME_LENGTH = 64;
|
|
19
|
+
function validateSkillName(name) {
|
|
20
|
+
if (!name || name.trim().length === 0) {
|
|
21
|
+
return { valid: false, error: 'Skill name is required' };
|
|
22
|
+
}
|
|
23
|
+
if (name.length > MAX_NAME_LENGTH) {
|
|
24
|
+
return {
|
|
25
|
+
valid: false,
|
|
26
|
+
error: `Skill name must be at most ${MAX_NAME_LENGTH} characters`,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
if (!VALID_NAME_PATTERN.test(name)) {
|
|
30
|
+
return {
|
|
31
|
+
valid: false,
|
|
32
|
+
error: 'Skill name must contain only lowercase letters, numbers, and hyphens, and must not start or end with a hyphen',
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
if (CONSECUTIVE_HYPHENS.test(name)) {
|
|
36
|
+
return { valid: false, error: 'Skill name must not contain consecutive hyphens' };
|
|
37
|
+
}
|
|
38
|
+
return { valid: true };
|
|
39
|
+
}
|
|
40
|
+
// ─── YAML Parser & Validation ──────────────────────────────────────────────
|
|
41
|
+
/**
|
|
42
|
+
* Parser schema for skill frontmatter (using Zod for runtime validation)
|
|
43
|
+
*/
|
|
44
|
+
const FrontmatterSchema = z.object({
|
|
45
|
+
name: z.string().min(1, 'name is required'),
|
|
46
|
+
description: z.string().min(1, 'description is required').max(1024),
|
|
47
|
+
version: z.string().optional(),
|
|
48
|
+
license: z.string().optional(),
|
|
49
|
+
compatibility: z.string().max(500).optional(),
|
|
50
|
+
'allowed-tools': z.union([z.string(), z.array(z.string())]).optional(),
|
|
51
|
+
metadata: z.record(z.string(), z.string()).optional(),
|
|
52
|
+
});
|
|
53
|
+
/**
|
|
54
|
+
* Helper: Extract and validate YAML frontmatter
|
|
55
|
+
* @returns { frontmatter, body, error }
|
|
56
|
+
*/
|
|
57
|
+
function extractFrontmatter(content) {
|
|
58
|
+
if (!content?.startsWith('---')) {
|
|
59
|
+
return { error: 'Skill content must start with YAML frontmatter (---)' };
|
|
60
|
+
}
|
|
61
|
+
const endIndex = content.indexOf('---', 3);
|
|
62
|
+
if (endIndex === -1) {
|
|
63
|
+
return { error: 'Skill content must have closing YAML frontmatter (---)' };
|
|
64
|
+
}
|
|
65
|
+
const frontmatterBlock = content.substring(3, endIndex).trim();
|
|
66
|
+
const body = content.substring(endIndex + 3).trim();
|
|
67
|
+
let parsed;
|
|
68
|
+
try {
|
|
69
|
+
parsed = YAML.load(frontmatterBlock) || {};
|
|
70
|
+
}
|
|
71
|
+
catch (e) {
|
|
72
|
+
return { error: `Failed to parse YAML frontmatter: ${e.message}` };
|
|
73
|
+
}
|
|
74
|
+
// Normalize allowed-tools: convert space-delimited string to array
|
|
75
|
+
if (parsed['allowed-tools'] && typeof parsed['allowed-tools'] === 'string') {
|
|
76
|
+
parsed['allowed-tools'] = parsed['allowed-tools'].split(/\s+/);
|
|
77
|
+
}
|
|
78
|
+
// Validate with Zod
|
|
79
|
+
const validationResult = FrontmatterSchema.safeParse(parsed);
|
|
80
|
+
if (!validationResult.success) {
|
|
81
|
+
const errors = validationResult.error.issues
|
|
82
|
+
.map((e) => `${e.path.join('.')}: ${e.message}`)
|
|
83
|
+
.join('; ');
|
|
84
|
+
return { error: `Frontmatter validation failed: ${errors}` };
|
|
85
|
+
}
|
|
86
|
+
const frontmatter = {
|
|
87
|
+
name: validationResult.data.name,
|
|
88
|
+
description: validationResult.data.description,
|
|
89
|
+
version: validationResult.data.version,
|
|
90
|
+
license: validationResult.data.license,
|
|
91
|
+
compatibility: validationResult.data.compatibility,
|
|
92
|
+
'allowed-tools': validationResult.data['allowed-tools'],
|
|
93
|
+
metadata: validationResult.data.metadata,
|
|
94
|
+
};
|
|
95
|
+
return { frontmatter, body };
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Parse YAML frontmatter from SKILL.md content
|
|
99
|
+
*/
|
|
100
|
+
export function parseSkillContent(content) {
|
|
101
|
+
const { frontmatter, body, error } = extractFrontmatter(content);
|
|
102
|
+
if (error) {
|
|
103
|
+
return {
|
|
104
|
+
error,
|
|
105
|
+
frontmatter: { name: '', description: '' },
|
|
106
|
+
body: content.substring(content.indexOf('---', 3) + 3).trim() || '',
|
|
107
|
+
raw: content,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
// Parse body into structured sections for selective context loading
|
|
111
|
+
const parsedContent = parseSkillSections(body);
|
|
112
|
+
return {
|
|
113
|
+
frontmatter: frontmatter,
|
|
114
|
+
body: body,
|
|
115
|
+
raw: content,
|
|
116
|
+
sections: parsedContent.sections,
|
|
117
|
+
totalTokens: parsedContent.totalTokens,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Extract ONLY metadata from SKILL.md without parsing body/sections.
|
|
122
|
+
*
|
|
123
|
+
* Optimized for matimo_list_skills — reads YAML frontmatter only.
|
|
124
|
+
* This avoids the overhead of parsing sections and body content.
|
|
125
|
+
*
|
|
126
|
+
* Returns SkillSummary: name, description, version, license, metadata, source.
|
|
127
|
+
*/
|
|
128
|
+
export function extractSkillMetadata(content, source = 'user') {
|
|
129
|
+
const { frontmatter, error } = extractFrontmatter(content);
|
|
130
|
+
if (error) {
|
|
131
|
+
return { success: false, error };
|
|
132
|
+
}
|
|
133
|
+
// Return only metadata fields (no body, sections, or body content)
|
|
134
|
+
return {
|
|
135
|
+
success: true,
|
|
136
|
+
metadata: {
|
|
137
|
+
name: frontmatter.name,
|
|
138
|
+
description: frontmatter.description,
|
|
139
|
+
version: frontmatter.version,
|
|
140
|
+
license: frontmatter.license,
|
|
141
|
+
metadata: frontmatter.metadata,
|
|
142
|
+
source,
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
// ─── Bundled Resources Discovery ───────────────────────────────────────────
|
|
147
|
+
function listBundledResources(skillDir) {
|
|
148
|
+
const resources = {
|
|
149
|
+
scripts: [],
|
|
150
|
+
references: [],
|
|
151
|
+
assets: [],
|
|
152
|
+
other: [],
|
|
153
|
+
};
|
|
154
|
+
if (!fs.existsSync(skillDir))
|
|
155
|
+
return resources;
|
|
156
|
+
const KNOWN_DIRS = {
|
|
157
|
+
scripts: 'scripts',
|
|
158
|
+
references: 'references',
|
|
159
|
+
assets: 'assets',
|
|
160
|
+
};
|
|
161
|
+
const entries = fs.readdirSync(skillDir, { withFileTypes: true });
|
|
162
|
+
for (const entry of entries) {
|
|
163
|
+
if (entry.name === 'SKILL.md')
|
|
164
|
+
continue;
|
|
165
|
+
if (entry.isDirectory()) {
|
|
166
|
+
const category = KNOWN_DIRS[entry.name];
|
|
167
|
+
if (category) {
|
|
168
|
+
const subDir = path.join(skillDir, entry.name);
|
|
169
|
+
const subEntries = fs.readdirSync(subDir);
|
|
170
|
+
for (const sub of subEntries) {
|
|
171
|
+
resources[category].push(`${entry.name}/${sub}`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
const subDir = path.join(skillDir, entry.name);
|
|
176
|
+
const subEntries = fs.readdirSync(subDir);
|
|
177
|
+
for (const sub of subEntries) {
|
|
178
|
+
resources.other.push(`${entry.name}/${sub}`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
resources.other.push(entry.name);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return resources;
|
|
187
|
+
}
|
|
188
|
+
// ─── SkillLoader ──────────────────────────────────────────────────────────
|
|
189
|
+
/**
|
|
190
|
+
* SkillLoader reads and validates skills from directories
|
|
191
|
+
*/
|
|
192
|
+
export class SkillLoader {
|
|
193
|
+
constructor() {
|
|
194
|
+
this.logger = getGlobalMatimoLogger();
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Load all skills from a directory
|
|
198
|
+
*/
|
|
199
|
+
loadSkillsFromDirectory(skillsDir, source = 'user') {
|
|
200
|
+
const skills = [];
|
|
201
|
+
if (!fs.existsSync(skillsDir)) {
|
|
202
|
+
return skills;
|
|
203
|
+
}
|
|
204
|
+
const entries = fs.readdirSync(skillsDir, { withFileTypes: true });
|
|
205
|
+
for (const entry of entries) {
|
|
206
|
+
if (!entry.isDirectory())
|
|
207
|
+
continue;
|
|
208
|
+
const skillPath = path.join(skillsDir, entry.name, 'SKILL.md');
|
|
209
|
+
if (!fs.existsSync(skillPath))
|
|
210
|
+
continue;
|
|
211
|
+
try {
|
|
212
|
+
this.logger.debug('SkillLoader: attempting to load skill', {
|
|
213
|
+
name: entry.name,
|
|
214
|
+
skillPath,
|
|
215
|
+
});
|
|
216
|
+
const skill = this.loadSkill(entry.name, skillsDir, source);
|
|
217
|
+
if (skill) {
|
|
218
|
+
skills.push(skill);
|
|
219
|
+
this.logger.debug('SkillLoader: successfully loaded skill', {
|
|
220
|
+
name: skill.name,
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
this.logger.warn('SkillLoader: loadSkill returned null', {
|
|
225
|
+
name: entry.name,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
catch (err) {
|
|
230
|
+
this.logger.error('SkillLoader: failed to load skill', {
|
|
231
|
+
dir: entry.name,
|
|
232
|
+
error: err.message,
|
|
233
|
+
stack: err.stack,
|
|
234
|
+
skillsDir,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return skills;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Load a single skill by name
|
|
242
|
+
*/
|
|
243
|
+
loadSkill(name, skillsDir, source = 'user') {
|
|
244
|
+
// Validate name
|
|
245
|
+
const nameValidation = validateSkillName(name);
|
|
246
|
+
if (!nameValidation.valid) {
|
|
247
|
+
throw new MatimoError(`Invalid skill name: ${nameValidation.error}`, ErrorCode.INVALID_SCHEMA);
|
|
248
|
+
}
|
|
249
|
+
const skillDir = path.join(skillsDir, name);
|
|
250
|
+
const skillPath = path.join(skillDir, 'SKILL.md');
|
|
251
|
+
if (!fs.existsSync(skillPath)) {
|
|
252
|
+
throw new MatimoError(`Skill not found: ${skillPath}`, ErrorCode.TOOL_NOT_FOUND);
|
|
253
|
+
}
|
|
254
|
+
const content = fs.readFileSync(skillPath, 'utf-8');
|
|
255
|
+
const parsed = parseSkillContent(content);
|
|
256
|
+
if (parsed.error) {
|
|
257
|
+
throw new MatimoError(`Failed to parse skill: ${parsed.error}`, ErrorCode.INVALID_SCHEMA);
|
|
258
|
+
}
|
|
259
|
+
const { frontmatter } = parsed;
|
|
260
|
+
// Verify frontmatter name matches directory name
|
|
261
|
+
if (frontmatter.name !== name) {
|
|
262
|
+
throw new MatimoError(`Skill name "${frontmatter.name}" must match directory name "${name}"`, ErrorCode.INVALID_SCHEMA);
|
|
263
|
+
}
|
|
264
|
+
const resources = listBundledResources(skillDir);
|
|
265
|
+
const skill = {
|
|
266
|
+
name: frontmatter.name,
|
|
267
|
+
description: frontmatter.description,
|
|
268
|
+
version: frontmatter.version,
|
|
269
|
+
license: frontmatter.license,
|
|
270
|
+
compatibility: frontmatter.compatibility,
|
|
271
|
+
allowedTools: frontmatter['allowed-tools'],
|
|
272
|
+
metadata: frontmatter.metadata,
|
|
273
|
+
body: parsed.body,
|
|
274
|
+
sections: parsed.sections,
|
|
275
|
+
totalTokens: parsed.totalTokens,
|
|
276
|
+
resources,
|
|
277
|
+
source,
|
|
278
|
+
_path: skillDir,
|
|
279
|
+
};
|
|
280
|
+
return skill;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Load a skill resource file (scripts/, references/, assets/)
|
|
284
|
+
*/
|
|
285
|
+
loadSkillResource(skillName, skillsDir, resourcePath) {
|
|
286
|
+
// Validate resource path (prevent traversal)
|
|
287
|
+
if (/\.\.|\\/u.test(resourcePath) || /[\x00-\x1f]/.test(resourcePath)) {
|
|
288
|
+
throw new MatimoError('Resource path contains invalid characters', ErrorCode.INVALID_SCHEMA);
|
|
289
|
+
}
|
|
290
|
+
const skillDir = path.join(skillsDir, skillName);
|
|
291
|
+
const resourceFullPath = path.join(skillDir, resourcePath);
|
|
292
|
+
// Verify path stays within skill directory
|
|
293
|
+
const resolvedPath = path.resolve(resourceFullPath);
|
|
294
|
+
const resolvedSkillDir = path.resolve(skillDir);
|
|
295
|
+
if (!resolvedPath.startsWith(resolvedSkillDir + path.sep) &&
|
|
296
|
+
resolvedPath !== resolvedSkillDir) {
|
|
297
|
+
throw new MatimoError('Resource path escapes the skill directory', ErrorCode.INVALID_SCHEMA);
|
|
298
|
+
}
|
|
299
|
+
if (!fs.existsSync(resourceFullPath)) {
|
|
300
|
+
throw new MatimoError(`Resource file not found: ${resourcePath}`, ErrorCode.TOOL_NOT_FOUND);
|
|
301
|
+
}
|
|
302
|
+
try {
|
|
303
|
+
return fs.readFileSync(resourceFullPath, 'utf-8');
|
|
304
|
+
}
|
|
305
|
+
catch (err) {
|
|
306
|
+
throw new MatimoError(`Failed to read resource file: ${err.message}`, ErrorCode.EXECUTION_FAILED);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
//# sourceMappingURL=skill-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-loader.js","sourceRoot":"","sources":["../../src/core/skill-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill Registry — in-memory store and search for skills
|
|
3
|
+
*
|
|
4
|
+
* Mirrors ToolRegistry but for skills. Provides discovery, search, and filtering.
|
|
5
|
+
* Supports both substring matching (default) and semantic search via pluggable embeddings.
|
|
6
|
+
*/
|
|
7
|
+
import { SkillDefinition, SkillSummary, SearchSkillsOptions, EmbeddingProvider, SkillContentOptions } from './types';
|
|
8
|
+
/**
|
|
9
|
+
* Semantic search result with relevance score.
|
|
10
|
+
*/
|
|
11
|
+
export interface SemanticSearchResult {
|
|
12
|
+
skill: SkillSummary;
|
|
13
|
+
/** Cosine similarity score (0–1, higher = more relevant) */
|
|
14
|
+
score: number;
|
|
15
|
+
}
|
|
16
|
+
export declare class SkillRegistry {
|
|
17
|
+
private logger;
|
|
18
|
+
private skills;
|
|
19
|
+
/** Pluggable embedding provider for semantic search */
|
|
20
|
+
private embeddingProvider;
|
|
21
|
+
/** Cached embeddings: skill name → vector */
|
|
22
|
+
private embeddings;
|
|
23
|
+
/** Whether embeddings need rebuilding */
|
|
24
|
+
private embeddingsDirty;
|
|
25
|
+
/** Cached parsed content for selective loading */
|
|
26
|
+
private parsedContent;
|
|
27
|
+
/**
|
|
28
|
+
* Set a custom embedding provider (OpenAI, Cohere, etc.).
|
|
29
|
+
* If not set, a built-in TF-IDF provider is used as fallback.
|
|
30
|
+
*/
|
|
31
|
+
setEmbeddingProvider(provider: EmbeddingProvider): void;
|
|
32
|
+
/**
|
|
33
|
+
* Register a single skill
|
|
34
|
+
*/
|
|
35
|
+
register(skill: SkillDefinition): void;
|
|
36
|
+
/**
|
|
37
|
+
* Register multiple skills
|
|
38
|
+
*/
|
|
39
|
+
registerAll(skills: SkillDefinition[]): void;
|
|
40
|
+
/**
|
|
41
|
+
* Get a single skill by name
|
|
42
|
+
*/
|
|
43
|
+
get(name: string): SkillDefinition | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* Get a single skill by name (throws if not found)
|
|
46
|
+
*/
|
|
47
|
+
getRequired(name: string): SkillDefinition;
|
|
48
|
+
/**
|
|
49
|
+
* Get selective skill content — only the sections an agent needs.
|
|
50
|
+
* This prevents dumping entire SKILL.md files into the LLM context.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* // Get only the error handling section, max 500 tokens
|
|
54
|
+
* registry.getSkillContent('postgres-query-operations', {
|
|
55
|
+
* sections: ['Error Handling'],
|
|
56
|
+
* maxTokens: 500,
|
|
57
|
+
* })
|
|
58
|
+
*/
|
|
59
|
+
getSkillContent(name: string, options?: SkillContentOptions): string | null;
|
|
60
|
+
/**
|
|
61
|
+
* List all sections of a skill with their token costs.
|
|
62
|
+
* Agents use this to decide which sections to load.
|
|
63
|
+
*/
|
|
64
|
+
getSkillSections(name: string): Array<{
|
|
65
|
+
path: string;
|
|
66
|
+
level: number;
|
|
67
|
+
tokenEstimate: number;
|
|
68
|
+
}> | null;
|
|
69
|
+
/**
|
|
70
|
+
* List all skills (Level 1 discovery — minimal context)
|
|
71
|
+
*/
|
|
72
|
+
list(): SkillSummary[];
|
|
73
|
+
/**
|
|
74
|
+
* Search skills by keyword, category, difficulty, etc.
|
|
75
|
+
*
|
|
76
|
+
* When `options.semantic` is true, uses embedding-based similarity ranking
|
|
77
|
+
* instead of substring matching. Falls back to built-in TF-IDF if no
|
|
78
|
+
* external embedding provider is configured.
|
|
79
|
+
*/
|
|
80
|
+
search(options?: SearchSkillsOptions): SkillSummary[];
|
|
81
|
+
/**
|
|
82
|
+
* Semantic search with relevance scores.
|
|
83
|
+
* Returns ranked results with cosine similarity scores.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* const results = await registry.semanticSearch('How do I handle Postgres connection pooling?');
|
|
87
|
+
* // → [{ skill: { name: 'postgres-query-operations', ... }, score: 0.82 }]
|
|
88
|
+
*/
|
|
89
|
+
semanticSearch(query: string, options?: {
|
|
90
|
+
limit?: number;
|
|
91
|
+
minScore?: number;
|
|
92
|
+
}): Promise<SemanticSearchResult[]>;
|
|
93
|
+
/**
|
|
94
|
+
* Get all skills (full definitions)
|
|
95
|
+
*/
|
|
96
|
+
getAll(): SkillDefinition[];
|
|
97
|
+
/**
|
|
98
|
+
* Check if a skill exists
|
|
99
|
+
*/
|
|
100
|
+
has(name: string): boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Get the count of registered skills
|
|
103
|
+
*/
|
|
104
|
+
count(): number;
|
|
105
|
+
/**
|
|
106
|
+
* Clear all skills
|
|
107
|
+
*/
|
|
108
|
+
clear(): void;
|
|
109
|
+
/**
|
|
110
|
+
* Remove a skill
|
|
111
|
+
*/
|
|
112
|
+
remove(name: string): boolean;
|
|
113
|
+
/**
|
|
114
|
+
* Ensure embeddings are computed and up-to-date.
|
|
115
|
+
*/
|
|
116
|
+
private ensureEmbeddings;
|
|
117
|
+
/**
|
|
118
|
+
* Synchronous ranking using TF-IDF (for the non-async search() method).
|
|
119
|
+
*/
|
|
120
|
+
private rankBySimilarity;
|
|
121
|
+
/**
|
|
122
|
+
* Get or create the default TF-IDF provider.
|
|
123
|
+
*/
|
|
124
|
+
private defaultProvider;
|
|
125
|
+
private getDefaultProvider;
|
|
126
|
+
/**
|
|
127
|
+
* Convert a skill into a searchable text string for embedding.
|
|
128
|
+
*/
|
|
129
|
+
private skillToText;
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=skill-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-registry.d.ts","sourceRoot":"","sources":["../../src/core/skill-registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,SAAS,CAAC;AAOjB;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,YAAY,CAAC;IACpB,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,MAAM,CAAsC;IAEpD,uDAAuD;IACvD,OAAO,CAAC,iBAAiB,CAAkC;IAC3D,6CAA6C;IAC7C,OAAO,CAAC,UAAU,CAA+B;IACjD,yCAAyC;IACzC,OAAO,CAAC,eAAe,CAAQ;IAC/B,kDAAkD;IAClD,OAAO,CAAC,aAAa,CAAyC;IAE9D;;;OAGG;IACH,oBAAoB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI;IAMvD;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAetC;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,IAAI;IAM5C;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAI9C;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe;IAQ1C;;;;;;;;;;OAUG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,MAAM,GAAG,IAAI;IAM3E;;;OAGG;IACH,gBAAgB,CACd,IAAI,EAAE,MAAM,GACX,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI;IAMvE;;OAEG;IACH,IAAI,IAAI,YAAY,EAAE;IAWtB;;;;;;OAMG;IACH,MAAM,CAAC,OAAO,GAAE,mBAAwB,GAAG,YAAY,EAAE;IAmEzD;;;;;;;OAOG;IACG,cAAc,CAClB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAO,GAClD,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAgClC;;OAEG;IACH,MAAM,IAAI,eAAe,EAAE;IAI3B;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B;;OAEG;IACH,KAAK,IAAI,MAAM;IAIf;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAS7B;;OAEG;YACW,gBAAgB;IAwB9B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAyBxB;;OAEG;IACH,OAAO,CAAC,eAAe,CAAuC;IAC9D,OAAO,CAAC,kBAAkB;IAO1B;;OAEG;IACH,OAAO,CAAC,WAAW;CAOpB"}
|