@majkapp/plugin-kit 3.7.3 → 3.7.4
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/bin/promptable-cli.js +88 -0
- package/docs/AGENTS.md +641 -0
- package/docs/AUTH.md +248 -0
- package/docs/BATCH.md +256 -0
- package/docs/CONFIG_API.md +206 -0
- package/docs/CONVERSATIONS_API.md +283 -0
- package/docs/DELEGATION.md +196 -0
- package/docs/INDEX.md +38 -0
- package/docs/KNOWLEDGE.md +225 -0
- package/docs/PLUGINS.md +356 -0
- package/docs/REPORTS.md +271 -0
- package/docs/SCRIPTING.md +231 -0
- package/docs/SECRETS.md +412 -0
- package/docs/SKILLS.md +514 -0
- package/docs/TASKS.md +622 -0
- package/docs/TOOL_DISCOVERY.md +240 -0
- package/package.json +1 -1
package/docs/SKILLS.md
ADDED
|
@@ -0,0 +1,514 @@
|
|
|
1
|
+
# Skills API - Task Instructions with Tools
|
|
2
|
+
|
|
3
|
+
The Skills API provides a way to manage skills - instructions on how to accomplish tasks using tools. Skills can be database-persisted or runtime-registered with optional setup/teardown functions.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { definePlugin } from '@majkapp/plugin-kit';
|
|
9
|
+
|
|
10
|
+
// Access skills from plugin context
|
|
11
|
+
.function('enableCodeReview', {
|
|
12
|
+
description: 'Enable code review mode',
|
|
13
|
+
input: { type: 'object', properties: {}, additionalProperties: false },
|
|
14
|
+
output: { type: 'object', properties: { instructions: { type: 'string' } } },
|
|
15
|
+
handler: async (input, ctx) => {
|
|
16
|
+
const result = await ctx.majk.skills.enable(ctx, {
|
|
17
|
+
skill: 'code-review-mode'
|
|
18
|
+
});
|
|
19
|
+
return { instructions: result.instructions };
|
|
20
|
+
}
|
|
21
|
+
})
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Interface Overview
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
export interface SkillsAPI {
|
|
28
|
+
// Discovery
|
|
29
|
+
list(conversationId?: string, includeDisabled?: boolean): Promise<ListSkillsResult>;
|
|
30
|
+
search(conversationId: string | undefined, input: SearchSkillsInput): Promise<SearchSkillsResult>;
|
|
31
|
+
getById(skillId: string): Promise<Skill | null>;
|
|
32
|
+
|
|
33
|
+
// Database skills
|
|
34
|
+
add(conversationId: string | undefined, input: AddSkillInput): Promise<AddSkillResult>;
|
|
35
|
+
update(input: UpdateSkillInput): Promise<UpdateSkillResult>;
|
|
36
|
+
delete(input: DeleteSkillInput): Promise<boolean>;
|
|
37
|
+
|
|
38
|
+
// Activation
|
|
39
|
+
enable(context: SkillContext, input: EnableSkillInput): Promise<EnableSkillResult>;
|
|
40
|
+
disable(conversationId: string, input: DisableSkillInput): Promise<boolean>;
|
|
41
|
+
|
|
42
|
+
// Runtime skills
|
|
43
|
+
registerRuntime(skill: RuntimeSkill): Promise<void>;
|
|
44
|
+
unregisterRuntime(skillId: string): Promise<boolean>;
|
|
45
|
+
getRuntime(skillId: string): Promise<RuntimeSkill | undefined>;
|
|
46
|
+
|
|
47
|
+
// Events
|
|
48
|
+
on(eventType: SkillEventType, handler: (event: SkillEvent) => void): Promise<Unsubscribe>;
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Core Concepts
|
|
53
|
+
|
|
54
|
+
### Skill Types
|
|
55
|
+
|
|
56
|
+
1. **Database Skills** - Persisted skills created via `add()`
|
|
57
|
+
2. **Runtime Skills** - Memory-only skills with setup/teardown functions
|
|
58
|
+
|
|
59
|
+
### Skill Definition
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
interface SkillDefinition {
|
|
63
|
+
id: string; // Unique identifier
|
|
64
|
+
name: string; // Display name
|
|
65
|
+
description: string; // One-sentence description
|
|
66
|
+
instructions: string; // Full task instructions
|
|
67
|
+
tags?: string[]; // Optional categorization
|
|
68
|
+
enabled: boolean; // Whether currently active
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Discovery Operations
|
|
73
|
+
|
|
74
|
+
### List Skills
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
// List all skills
|
|
78
|
+
const { skills, total } = await ctx.majk.skills.list();
|
|
79
|
+
|
|
80
|
+
// Include disabled skills
|
|
81
|
+
const all = await ctx.majk.skills.list(undefined, true);
|
|
82
|
+
|
|
83
|
+
// List conversation-specific skills
|
|
84
|
+
const conversationSkills = await ctx.majk.skills.list(conversationId);
|
|
85
|
+
|
|
86
|
+
console.log(`Found ${skills.length} skills out of ${total} total`);
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Search Skills
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
const results = await ctx.majk.skills.search(conversationId, {
|
|
93
|
+
query: 'code review',
|
|
94
|
+
limit: 10,
|
|
95
|
+
includeDisabled: false
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
console.log('Well-matching skills:', results.matching);
|
|
99
|
+
console.log('Related skills:', results.related);
|
|
100
|
+
console.log('Total found:', results.total);
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Get Skill by ID
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
const skill = await ctx.majk.skills.getById('code-review-mode');
|
|
107
|
+
if (skill) {
|
|
108
|
+
console.log('Skill:', skill.name);
|
|
109
|
+
console.log('Instructions:', skill.instructions);
|
|
110
|
+
console.log('Source:', skill.source); // 'database' | 'runtime'
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Database Skills Management
|
|
115
|
+
|
|
116
|
+
### Adding Skills
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
const result = await ctx.majk.skills.add(conversationId, {
|
|
120
|
+
id: 'custom-reviewer', // Optional - auto-generated if not provided
|
|
121
|
+
name: 'Custom Code Reviewer',
|
|
122
|
+
description: 'Reviews code with custom standards',
|
|
123
|
+
instructions: `You are now in Custom Code Review Mode.
|
|
124
|
+
|
|
125
|
+
When reviewing code:
|
|
126
|
+
1. Check for our company coding standards
|
|
127
|
+
2. Look for security vulnerabilities
|
|
128
|
+
3. Suggest performance improvements
|
|
129
|
+
4. Verify test coverage
|
|
130
|
+
|
|
131
|
+
Use these tools:
|
|
132
|
+
- Static analysis tools
|
|
133
|
+
- Security scanners
|
|
134
|
+
- Test coverage reports`,
|
|
135
|
+
tags: ['review', 'code-quality', 'security'],
|
|
136
|
+
enabled: true
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
console.log(`Created skill: ${result.name} (${result.id})`);
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Updating Skills
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
const result = await ctx.majk.skills.update({
|
|
146
|
+
id: 'custom-reviewer',
|
|
147
|
+
name: 'Enhanced Code Reviewer',
|
|
148
|
+
description: 'Reviews code with enhanced AI analysis',
|
|
149
|
+
instructions: 'Updated instructions here...',
|
|
150
|
+
tags: ['review', 'ai', 'enhanced']
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
console.log(`Updated: ${result.name}, Success: ${result.updated}`);
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Deleting Skills
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
const deleted = await ctx.majk.skills.delete({ id: 'custom-reviewer' });
|
|
160
|
+
console.log('Skill deleted:', deleted);
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Skill Activation
|
|
164
|
+
|
|
165
|
+
### Enabling Skills
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
// Basic skill enablement
|
|
169
|
+
const result = await ctx.majk.skills.enable(ctx, { skill: 'code-review-mode' });
|
|
170
|
+
console.log('Skill enabled:', result.name);
|
|
171
|
+
console.log('Instructions to follow:', result.instructions);
|
|
172
|
+
|
|
173
|
+
// The instructions returned include:
|
|
174
|
+
// - Base skill instructions
|
|
175
|
+
// - Additional context from setup function (if any)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Disabling Skills
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
const disabled = await ctx.majk.skills.disable(conversationId, {
|
|
182
|
+
skill: 'code-review-mode'
|
|
183
|
+
});
|
|
184
|
+
console.log('Skill disabled:', disabled);
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Runtime Skills
|
|
188
|
+
|
|
189
|
+
Runtime skills exist only in memory and can have setup/teardown functions for dynamic behavior.
|
|
190
|
+
|
|
191
|
+
### Registering Runtime Skills
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
await ctx.majk.skills.registerRuntime({
|
|
195
|
+
id: 'dynamic-analyzer',
|
|
196
|
+
name: 'Dynamic Code Analyzer',
|
|
197
|
+
description: 'Analyzes code with runtime context',
|
|
198
|
+
instructions: 'Base instructions for dynamic analysis...',
|
|
199
|
+
enabled: true,
|
|
200
|
+
|
|
201
|
+
// Optional setup function - called when skill is enabled
|
|
202
|
+
setup: async (context: SkillContext) => {
|
|
203
|
+
// Perform setup logic
|
|
204
|
+
console.log(`Setting up for teammate: ${context.teammateId}`);
|
|
205
|
+
console.log(`In conversation: ${context.conversationId}`);
|
|
206
|
+
|
|
207
|
+
// Initialize tools, connect to services, etc.
|
|
208
|
+
const projectPath = process.cwd();
|
|
209
|
+
const config = await loadProjectConfig(projectPath);
|
|
210
|
+
|
|
211
|
+
// Return additional instructions to prepend
|
|
212
|
+
return `Project configuration loaded from ${projectPath}.
|
|
213
|
+
Using ${config.language} with ${config.framework} framework.`;
|
|
214
|
+
},
|
|
215
|
+
|
|
216
|
+
// Optional teardown function - called when skill is disabled
|
|
217
|
+
teardown: async (context: SkillContext) => {
|
|
218
|
+
// Cleanup logic
|
|
219
|
+
console.log(`Cleaning up dynamic analyzer for ${context.teammateId}`);
|
|
220
|
+
await cleanupTempFiles();
|
|
221
|
+
await disconnectServices();
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Managing Runtime Skills
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
// Get runtime skill
|
|
230
|
+
const runtimeSkill = await ctx.majk.skills.getRuntime('dynamic-analyzer');
|
|
231
|
+
if (runtimeSkill) {
|
|
232
|
+
console.log('Runtime skill found:', runtimeSkill.name);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Unregister runtime skill
|
|
236
|
+
const removed = await ctx.majk.skills.unregisterRuntime('dynamic-analyzer');
|
|
237
|
+
console.log('Runtime skill removed:', removed);
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Event Handling
|
|
241
|
+
|
|
242
|
+
Subscribe to skill-related events:
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
// Subscribe to all skill events
|
|
246
|
+
const unsubscribe = await ctx.majk.skills.on('skill_enabled', (event) => {
|
|
247
|
+
console.log(`Skill ${event.skillId} enabled at ${event.timestamp}`);
|
|
248
|
+
console.log('Event data:', event.data);
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
// Subscribe to specific events
|
|
252
|
+
await ctx.majk.skills.on('skill_added', (event) => {
|
|
253
|
+
console.log('New skill added:', event.skillId);
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
await ctx.majk.skills.on('skill_deleted', (event) => {
|
|
257
|
+
console.log('Skill deleted:', event.skillId);
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
// Clean up subscription
|
|
261
|
+
await unsubscribe();
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Event types:
|
|
265
|
+
- `skill_added` - New skill created
|
|
266
|
+
- `skill_updated` - Skill modified
|
|
267
|
+
- `skill_deleted` - Skill removed
|
|
268
|
+
- `skill_enabled` - Skill activated
|
|
269
|
+
- `skill_disabled` - Skill deactivated
|
|
270
|
+
|
|
271
|
+
## Plugin Integration
|
|
272
|
+
|
|
273
|
+
### Declaring Skills in Plugins
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
import { definePlugin } from '@majkapp/plugin-kit';
|
|
277
|
+
|
|
278
|
+
const plugin = definePlugin('code-tools', 'Code Analysis Tools', '1.0.0')
|
|
279
|
+
|
|
280
|
+
// Declare a skill capability
|
|
281
|
+
.skill({
|
|
282
|
+
id: 'advanced-reviewer',
|
|
283
|
+
name: 'Advanced Code Reviewer',
|
|
284
|
+
description: 'Performs deep code analysis with AI',
|
|
285
|
+
instructions: `You are now in Advanced Code Review Mode.
|
|
286
|
+
|
|
287
|
+
Perform comprehensive analysis including:
|
|
288
|
+
- Architecture patterns
|
|
289
|
+
- Performance bottlenecks
|
|
290
|
+
- Security vulnerabilities
|
|
291
|
+
- Maintainability issues`,
|
|
292
|
+
tags: ['review', 'ai', 'advanced']
|
|
293
|
+
})
|
|
294
|
+
|
|
295
|
+
.build();
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
## Complete Example
|
|
299
|
+
|
|
300
|
+
Here's a comprehensive example showing database skills, runtime skills, and event handling:
|
|
301
|
+
|
|
302
|
+
```typescript
|
|
303
|
+
.function('setupCodeReviewWorkflow', {
|
|
304
|
+
description: 'Set up complete code review workflow',
|
|
305
|
+
input: {
|
|
306
|
+
type: 'object',
|
|
307
|
+
properties: {
|
|
308
|
+
projectType: { type: 'string', enum: ['web', 'api', 'mobile'] }
|
|
309
|
+
},
|
|
310
|
+
required: ['projectType'],
|
|
311
|
+
additionalProperties: false
|
|
312
|
+
},
|
|
313
|
+
output: {
|
|
314
|
+
type: 'object',
|
|
315
|
+
properties: {
|
|
316
|
+
skillsEnabled: { type: 'array', items: { type: 'string' } },
|
|
317
|
+
instructions: { type: 'string' }
|
|
318
|
+
}
|
|
319
|
+
},
|
|
320
|
+
handler: async (input, ctx) => {
|
|
321
|
+
const skillsEnabled = [];
|
|
322
|
+
|
|
323
|
+
// 1. Add a persistent skill for this project type
|
|
324
|
+
const projectSkill = await ctx.majk.skills.add(ctx.conversationId, {
|
|
325
|
+
name: `${input.projectType.toUpperCase()} Code Reviewer`,
|
|
326
|
+
description: `Specialized reviewer for ${input.projectType} projects`,
|
|
327
|
+
instructions: `You are reviewing ${input.projectType} code.
|
|
328
|
+
Focus on ${input.projectType}-specific best practices and patterns.`,
|
|
329
|
+
tags: ['review', input.projectType],
|
|
330
|
+
enabled: false
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
// 2. Register a runtime skill with dynamic setup
|
|
334
|
+
await ctx.majk.skills.registerRuntime({
|
|
335
|
+
id: 'project-context-analyzer',
|
|
336
|
+
name: 'Project Context Analyzer',
|
|
337
|
+
description: 'Analyzes project-specific context',
|
|
338
|
+
instructions: 'Analyze code within project context...',
|
|
339
|
+
enabled: true,
|
|
340
|
+
|
|
341
|
+
setup: async (context) => {
|
|
342
|
+
// Analyze project structure
|
|
343
|
+
const analysis = await analyzeProjectStructure(input.projectType);
|
|
344
|
+
return `Project analysis complete: ${analysis.summary}`;
|
|
345
|
+
},
|
|
346
|
+
|
|
347
|
+
teardown: async (context) => {
|
|
348
|
+
await cleanupAnalysisCache();
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
// 3. Enable both skills
|
|
353
|
+
const result1 = await ctx.majk.skills.enable(ctx, {
|
|
354
|
+
skill: projectSkill.id
|
|
355
|
+
});
|
|
356
|
+
skillsEnabled.push(result1.name);
|
|
357
|
+
|
|
358
|
+
const result2 = await ctx.majk.skills.enable(ctx, {
|
|
359
|
+
skill: 'project-context-analyzer'
|
|
360
|
+
});
|
|
361
|
+
skillsEnabled.push(result2.name);
|
|
362
|
+
|
|
363
|
+
// 4. Subscribe to skill events
|
|
364
|
+
await ctx.majk.skills.on('skill_disabled', async (event) => {
|
|
365
|
+
ctx.logger.info(`Skill disabled: ${event.skillId}`);
|
|
366
|
+
// Cleanup if needed
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
return {
|
|
370
|
+
skillsEnabled,
|
|
371
|
+
instructions: `Code review workflow active for ${input.projectType} project.
|
|
372
|
+
${result1.instructions}
|
|
373
|
+
|
|
374
|
+
${result2.instructions}`
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
})
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
## Types Reference
|
|
381
|
+
|
|
382
|
+
### Input Types
|
|
383
|
+
|
|
384
|
+
```typescript
|
|
385
|
+
interface AddSkillInput {
|
|
386
|
+
id?: string; // Auto-generated if not provided
|
|
387
|
+
name: string;
|
|
388
|
+
description: string;
|
|
389
|
+
instructions: string;
|
|
390
|
+
tags?: string[];
|
|
391
|
+
enabled: boolean;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
interface UpdateSkillInput {
|
|
395
|
+
id: string;
|
|
396
|
+
name?: string;
|
|
397
|
+
description?: string;
|
|
398
|
+
instructions?: string;
|
|
399
|
+
tags?: string[];
|
|
400
|
+
enabled?: boolean;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
interface SearchSkillsInput {
|
|
404
|
+
query: string;
|
|
405
|
+
limit?: number;
|
|
406
|
+
includeDisabled?: boolean;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
interface EnableSkillInput {
|
|
410
|
+
skill: string; // ID or name
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
interface DisableSkillInput {
|
|
414
|
+
skill: string; // ID or name
|
|
415
|
+
}
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### Output Types
|
|
419
|
+
|
|
420
|
+
```typescript
|
|
421
|
+
interface ListSkillsResult {
|
|
422
|
+
skills: SkillSummary[];
|
|
423
|
+
total: number;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
interface SearchSkillsResult {
|
|
427
|
+
matching: SkillSummary[];
|
|
428
|
+
related: SkillSummary[];
|
|
429
|
+
total: number;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
interface EnableSkillResult {
|
|
433
|
+
id: string;
|
|
434
|
+
name: string;
|
|
435
|
+
instructions: string; // Includes setup additions
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
interface SkillSummary {
|
|
439
|
+
id: string;
|
|
440
|
+
name: string;
|
|
441
|
+
description: string;
|
|
442
|
+
enabled: boolean;
|
|
443
|
+
source: 'database' | 'runtime';
|
|
444
|
+
tags?: string[];
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
interface Skill extends SkillDefinition {
|
|
448
|
+
persisted: boolean;
|
|
449
|
+
hasSetup: boolean;
|
|
450
|
+
hasTeardown: boolean;
|
|
451
|
+
source: 'database' | 'runtime';
|
|
452
|
+
}
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
### Context and Functions
|
|
456
|
+
|
|
457
|
+
```typescript
|
|
458
|
+
interface SkillContext {
|
|
459
|
+
teammateId: string;
|
|
460
|
+
conversationId: string;
|
|
461
|
+
projectRoot: string;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
type SkillSetupFn = (context: SkillContext) => Promise<string | void>;
|
|
465
|
+
type SkillTeardownFn = (context: SkillContext) => Promise<void>;
|
|
466
|
+
|
|
467
|
+
interface RuntimeSkill extends SkillDefinition {
|
|
468
|
+
setup?: SkillSetupFn;
|
|
469
|
+
teardown?: SkillTeardownFn;
|
|
470
|
+
}
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
## Best Practices
|
|
474
|
+
|
|
475
|
+
1. **Use descriptive IDs** - Make skill IDs meaningful and unique
|
|
476
|
+
2. **Write clear instructions** - Provide step-by-step guidance
|
|
477
|
+
3. **Tag appropriately** - Use consistent tags for discoverability
|
|
478
|
+
4. **Handle setup/teardown** - Clean up resources in teardown functions
|
|
479
|
+
5. **Subscribe to events** - Monitor skill state changes
|
|
480
|
+
6. **Conversation scoping** - Use conversation IDs when appropriate
|
|
481
|
+
7. **Error handling** - Skills operations can fail, handle gracefully
|
|
482
|
+
|
|
483
|
+
## Common Patterns
|
|
484
|
+
|
|
485
|
+
### Conditional Skills
|
|
486
|
+
|
|
487
|
+
```typescript
|
|
488
|
+
// Enable different skills based on context
|
|
489
|
+
const projectType = await detectProjectType();
|
|
490
|
+
const skillId = `${projectType}-expert`;
|
|
491
|
+
await ctx.majk.skills.enable(ctx, { skill: skillId });
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
### Skill Chains
|
|
495
|
+
|
|
496
|
+
```typescript
|
|
497
|
+
// Enable multiple related skills in sequence
|
|
498
|
+
const skills = ['basic-reviewer', 'security-scanner', 'performance-analyzer'];
|
|
499
|
+
for (const skillId of skills) {
|
|
500
|
+
await ctx.majk.skills.enable(ctx, { skill: skillId });
|
|
501
|
+
}
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
### Dynamic Instructions
|
|
505
|
+
|
|
506
|
+
```typescript
|
|
507
|
+
// Use setup to provide context-aware instructions
|
|
508
|
+
setup: async (context) => {
|
|
509
|
+
const codebase = await analyzeCodebase(context.projectRoot);
|
|
510
|
+
return `Codebase uses ${codebase.languages.join(', ')}.
|
|
511
|
+
Primary framework: ${codebase.framework}.
|
|
512
|
+
Focus on ${codebase.framework}-specific patterns.`;
|
|
513
|
+
}
|
|
514
|
+
```
|