skill-tree 0.0.1 → 0.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 CHANGED
@@ -1 +1,324 @@
1
- # skill-trees
1
+ # skill-tree
2
+
3
+ A TypeScript library for managing agent skill versions and evolution. Extract, iterate, and adapt skills from agent trajectories.
4
+
5
+ ## Overview
6
+
7
+ skill-tree helps you build and maintain a library of reusable skills for AI agents by:
8
+
9
+ - **Extracting skills** from agent sessions/trajectories (manual or automatic)
10
+ - **Storing skills** in a versioned, searchable format (OpenSkills-compatible)
11
+ - **Evolving skills** through versioning, forking, and merging
12
+ - **Quality gates** to ensure extracted skills are reusable and non-trivial
13
+
14
+ Inspired by research on skill libraries ([arXiv:2512.17102](https://arxiv.org/abs/2512.17102)), [Claudeception](https://github.com/blader/Claudeception), and [OpenSkills](https://github.com/numman-ali/openskills).
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install skill-tree
20
+ ```
21
+
22
+ ## Quick Start
23
+
24
+ ```typescript
25
+ import { createSkillBank } from 'skill-tree';
26
+
27
+ // Create a skill bank with filesystem storage
28
+ const skillBank = createSkillBank({
29
+ storage: {
30
+ type: 'filesystem',
31
+ basePath: './skills',
32
+ openSkillsCompatible: true,
33
+ },
34
+ });
35
+
36
+ await skillBank.initialize();
37
+
38
+ // Parse a Claude Code session
39
+ const trajectory = await skillBank.parseSession(sessionContent);
40
+
41
+ // Extract a skill manually
42
+ const result = await skillBank.extractManual(trajectory, {
43
+ suggestedName: 'typescript-import-fix',
44
+ description: 'Fix TypeScript ES module import errors',
45
+ tags: ['typescript', 'imports'],
46
+ });
47
+
48
+ if (result.success) {
49
+ console.log('Extracted skill:', result.skill.name);
50
+ }
51
+
52
+ // Search for skills
53
+ const skills = await skillBank.searchSkills('typescript error');
54
+
55
+ // Create a new version
56
+ const updated = await skillBank.createVersion('typescript-import-fix', {
57
+ solution: 'Updated solution...',
58
+ }, { bumpType: 'minor' });
59
+ ```
60
+
61
+ ## Core Concepts
62
+
63
+ ### Skills
64
+
65
+ A skill represents a reusable piece of knowledge extracted from agent interactions:
66
+
67
+ ```typescript
68
+ interface Skill {
69
+ id: string; // Unique identifier
70
+ name: string; // Human-readable name
71
+ version: string; // Semantic version
72
+ description: string; // For semantic matching
73
+ problem: string; // What problem this solves
74
+ triggerConditions: TriggerCondition[]; // When to apply
75
+ solution: string; // Step-by-step solution
76
+ verification: string; // How to verify it worked
77
+ examples: SkillExample[]; // Usage examples
78
+ // ... metadata, metrics, lineage
79
+ }
80
+ ```
81
+
82
+ ### Trajectories
83
+
84
+ Agent sessions are parsed into trajectories:
85
+
86
+ ```typescript
87
+ interface Trajectory {
88
+ sessionId: string;
89
+ turns: Turn[]; // User/assistant/tool interactions
90
+ metadata: TrajectoryMetadata;
91
+ outcome?: TrajectoryOutcome;
92
+ }
93
+ ```
94
+
95
+ ### Quality Gates
96
+
97
+ Extraction includes quality gates (inspired by Claudeception) to ensure skills are:
98
+
99
+ - **Reusable**: Applicable across multiple future tasks
100
+ - **Non-trivial**: Involves discovery beyond documentation lookup
101
+ - **Specific**: Has clear trigger conditions
102
+ - **Verified**: Solution demonstrably works
103
+
104
+ ## Features
105
+
106
+ ### Session Adapters
107
+
108
+ Parse different agent session formats:
109
+
110
+ ```typescript
111
+ // Built-in: Claude Code JSONL
112
+ const trajectory = await skillBank.parseSession(jsonlContent);
113
+
114
+ // Register custom adapters
115
+ skillBank.registerAdapter(myCustomAdapter);
116
+ ```
117
+
118
+ ### Extraction Modes
119
+
120
+ **Manual extraction** with user guidance:
121
+
122
+ ```typescript
123
+ const result = await skillBank.extractManual(trajectory, {
124
+ turnRange: [5, 15], // Extract specific turns
125
+ suggestedName: 'my-skill',
126
+ tags: ['debugging'],
127
+ });
128
+ ```
129
+
130
+ **Automatic extraction** using LLM:
131
+
132
+ ```typescript
133
+ skillBank.setLLMProvider(myLLMProvider);
134
+
135
+ const results = await skillBank.extractAutomatic(trajectory, {
136
+ minConfidence: 0.7,
137
+ });
138
+ ```
139
+
140
+ ### Storage
141
+
142
+ **Filesystem storage** (OpenSkills-compatible):
143
+
144
+ ```typescript
145
+ const skillBank = createSkillBank({
146
+ storage: {
147
+ type: 'filesystem',
148
+ basePath: '~/.skills',
149
+ openSkillsCompatible: true, // YAML frontmatter + Markdown
150
+ },
151
+ });
152
+ ```
153
+
154
+ **Memory storage** (for testing):
155
+
156
+ ```typescript
157
+ const skillBank = createSkillBank({
158
+ storage: { type: 'memory' },
159
+ });
160
+ ```
161
+
162
+ Skills are stored in the OpenSkills format:
163
+
164
+ ```
165
+ skills/
166
+ ├── my-skill/
167
+ │ ├── SKILL.md # Skill content (YAML + Markdown)
168
+ │ └── .skilltree.json # Metadata and lineage
169
+ └── .versions/
170
+ └── my-skill/
171
+ ├── 1.0.0.json # Version snapshots
172
+ └── 1.1.0.json
173
+ ```
174
+
175
+ ### Versioning
176
+
177
+ Semantic versioning with full lineage tracking:
178
+
179
+ ```typescript
180
+ // Create new version
181
+ const v2 = await skillBank.createVersion('my-skill', updates, {
182
+ bumpType: 'minor',
183
+ changelog: 'Added alternative solution',
184
+ });
185
+
186
+ // Get version history
187
+ const history = await skillBank.getVersionHistory('my-skill');
188
+
189
+ // Rollback to previous version
190
+ const restored = await skillBank.rollbackSkill('my-skill', '1.0.0');
191
+
192
+ // Compare versions
193
+ const diff = await skillBank.compareVersions('my-skill', '1.0.0', '2.0.0');
194
+ ```
195
+
196
+ ### Skill Evolution
197
+
198
+ Fork and merge skills:
199
+
200
+ ```typescript
201
+ // Fork for a specialized use case
202
+ const forked = await skillBank.forkSkill('my-skill', {
203
+ newId: 'my-skill-react',
204
+ newName: 'My Skill (React variant)',
205
+ reason: 'Specialized for React projects',
206
+ });
207
+
208
+ // Merge improvements back
209
+ const merged = await skillBank.lineageTracker.mergeSkill(
210
+ 'my-skill',
211
+ 'my-skill-react',
212
+ { fields: ['solution', 'examples'] }
213
+ );
214
+ ```
215
+
216
+ ### Events
217
+
218
+ Subscribe to skill bank events:
219
+
220
+ ```typescript
221
+ const unsubscribe = skillBank.on((event) => {
222
+ switch (event.type) {
223
+ case 'skill:created':
224
+ console.log('New skill:', event.skill.name);
225
+ break;
226
+ case 'extraction:completed':
227
+ console.log('Extraction confidence:', event.result.confidence);
228
+ break;
229
+ }
230
+ });
231
+ ```
232
+
233
+ ## API Reference
234
+
235
+ ### SkillBank
236
+
237
+ Main orchestrator class.
238
+
239
+ | Method | Description |
240
+ |--------|-------------|
241
+ | `initialize()` | Initialize storage (required before use) |
242
+ | `parseSession(content, adapter?)` | Parse session into trajectory |
243
+ | `extractManual(trajectory, options?)` | Extract skill with guidance |
244
+ | `extractAutomatic(trajectory, options?)` | Extract skills using LLM |
245
+ | `getSkill(id, version?)` | Get skill by ID |
246
+ | `listSkills(filter?)` | List skills with optional filter |
247
+ | `searchSkills(query)` | Search skills by text |
248
+ | `saveSkill(skill)` | Save or update a skill |
249
+ | `deleteSkill(id, version?)` | Delete a skill |
250
+ | `createVersion(id, updates, options?)` | Create new version |
251
+ | `forkSkill(id, options)` | Fork a skill |
252
+ | `getVersionHistory(id)` | Get version history |
253
+ | `rollbackSkill(id, version)` | Rollback to version |
254
+ | `on(handler)` | Subscribe to events |
255
+
256
+ ### Versioning Utilities
257
+
258
+ ```typescript
259
+ import {
260
+ parseVersion,
261
+ compareVersions,
262
+ bumpVersion,
263
+ satisfiesRange,
264
+ } from 'skill-tree';
265
+
266
+ bumpVersion('1.2.3', 'minor'); // '1.3.0'
267
+ satisfiesRange('1.5.0', '^1.2.0'); // true
268
+ ```
269
+
270
+ ## Skill Format
271
+
272
+ Skills use YAML frontmatter + Markdown (OpenSkills-compatible):
273
+
274
+ ```markdown
275
+ ---
276
+ name: typescript-esm-import-fix
277
+ description: |
278
+ Fix TypeScript ES module import errors by adding .js extension
279
+ version: 1.0.0
280
+ author: extracted
281
+ status: active
282
+ date: 2024-01-15
283
+ tags:
284
+ - typescript
285
+ - esm
286
+ - imports
287
+ ---
288
+
289
+ ## Problem
290
+
291
+ TypeScript with ES modules requires explicit .js extensions in imports.
292
+
293
+ ## Trigger Conditions
294
+
295
+ - **error**: `Cannot find module './utils'`
296
+ - **pattern**: `import .* from '\./[^']+(?<!\.js)'`
297
+
298
+ ## Solution
299
+
300
+ 1. Add `.js` extension to relative imports
301
+ 2. Even for `.ts` files, use `.js` in the import path
302
+
303
+ ## Verification
304
+
305
+ Run `tsc` and verify no module resolution errors.
306
+
307
+ ## Examples
308
+
309
+ ### Basic import fix
310
+
311
+ **Before:**
312
+ ```typescript
313
+ import { helper } from './utils'
314
+ ```
315
+
316
+ **After:**
317
+ ```typescript
318
+ import { helper } from './utils.js'
319
+ ```
320
+ ```
321
+
322
+ ## License
323
+
324
+ MIT