@majkapp/plugin-kit 3.7.2 → 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.
@@ -0,0 +1,225 @@
1
+ # Knowledge API
2
+
3
+ Store and search knowledge nodes organized into trees with reference tracking.
4
+
5
+ ## Quick Start
6
+
7
+ ```typescript
8
+ handler: async (input, ctx) => {
9
+ // Add knowledge
10
+ await ctx.majk.knowledge.add({
11
+ conversationId: 'conv-123',
12
+ title: 'API Design Decision',
13
+ content: 'We decided to use REST over GraphQL because...',
14
+ references: ['file:src/api/routes.ts#L10-50'],
15
+ tree: 'decisions'
16
+ });
17
+
18
+ // Search knowledge
19
+ const nodes = await ctx.majk.knowledge.search('REST API', {
20
+ conversationId: 'conv-123'
21
+ });
22
+
23
+ return { found: nodes.length };
24
+ }
25
+ ```
26
+
27
+ ## API Reference
28
+
29
+ ### add(input)
30
+
31
+ Add a knowledge node.
32
+
33
+ ```typescript
34
+ await ctx.majk.knowledge.add({
35
+ conversationId: string, // Conversation to associate with
36
+ title: string, // Node title
37
+ content: string, // Knowledge content
38
+ references?: string[], // Reference links (files, URLs, etc.)
39
+ tree?: string // Tree name (default: 'default')
40
+ });
41
+ ```
42
+
43
+ ### search(query, options?)
44
+
45
+ Search knowledge by text.
46
+
47
+ ```typescript
48
+ const nodes = await ctx.majk.knowledge.search(query, {
49
+ conversationId?: string, // Filter by conversation
50
+ tree?: string, // Filter by tree
51
+ limit?: number // Max results
52
+ });
53
+ // Returns: KnowledgeNode[]
54
+ ```
55
+
56
+ ### getByReference(ref)
57
+
58
+ Find nodes that reference a specific resource.
59
+
60
+ ```typescript
61
+ const nodes = await ctx.majk.knowledge.getByReference('file:src/api.ts');
62
+ // Returns: KnowledgeNode[]
63
+ ```
64
+
65
+ ### getTree(conversationId, treeName)
66
+
67
+ Get all nodes in a tree.
68
+
69
+ ```typescript
70
+ const tree = await ctx.majk.knowledge.getTree('conv-123', 'decisions');
71
+ // Returns: { name, conversationId, nodes: KnowledgeNode[] }
72
+ ```
73
+
74
+ ### listTrees(conversationId)
75
+
76
+ List all trees in a conversation.
77
+
78
+ ```typescript
79
+ const trees = await ctx.majk.knowledge.listTrees('conv-123');
80
+ // Returns: string[] (tree names)
81
+ ```
82
+
83
+ ## Types
84
+
85
+ ```typescript
86
+ interface KnowledgeNode {
87
+ id: string;
88
+ title: string;
89
+ content: string;
90
+ references: string[];
91
+ conversationId: string;
92
+ tree: string;
93
+ createdAt: Date;
94
+ }
95
+
96
+ interface KnowledgeTree {
97
+ name: string;
98
+ conversationId: string;
99
+ nodes: KnowledgeNode[];
100
+ }
101
+ ```
102
+
103
+ ## Reference Patterns
104
+
105
+ Use consistent reference formats:
106
+
107
+ ```typescript
108
+ // File references
109
+ 'file:src/api/routes.ts'
110
+ 'file:src/api/routes.ts#L10-50'
111
+
112
+ // URL references
113
+ 'url:https://docs.example.com/api'
114
+
115
+ // Function references
116
+ 'function:createUser'
117
+ 'function:src/api.ts:createUser'
118
+
119
+ // Commit references
120
+ 'commit:abc123'
121
+
122
+ // Issue/PR references
123
+ 'issue:42'
124
+ 'pr:123'
125
+ ```
126
+
127
+ ## Common Patterns
128
+
129
+ ### Organize by Topic
130
+
131
+ ```typescript
132
+ // Add to different trees
133
+ await ctx.majk.knowledge.add({
134
+ conversationId,
135
+ title: 'Auth Flow Decision',
136
+ content: 'Using JWT tokens...',
137
+ tree: 'architecture'
138
+ });
139
+
140
+ await ctx.majk.knowledge.add({
141
+ conversationId,
142
+ title: 'JWT Security Concern',
143
+ content: 'Token expiry handling...',
144
+ tree: 'security'
145
+ });
146
+
147
+ // Query specific tree
148
+ const archNodes = await ctx.majk.knowledge.getTree(conversationId, 'architecture');
149
+ ```
150
+
151
+ ### Track Code References
152
+
153
+ ```typescript
154
+ // Add knowledge about code
155
+ await ctx.majk.knowledge.add({
156
+ conversationId,
157
+ title: 'Rate Limiter Implementation',
158
+ content: 'The rate limiter uses a sliding window algorithm...',
159
+ references: [
160
+ 'file:src/middleware/rateLimiter.ts',
161
+ 'file:src/config/limits.ts#L5-20',
162
+ 'url:https://en.wikipedia.org/wiki/Sliding_window_protocol'
163
+ ],
164
+ tree: 'implementation'
165
+ });
166
+
167
+ // Later, find all knowledge about a file
168
+ const related = await ctx.majk.knowledge.getByReference('file:src/middleware/rateLimiter.ts');
169
+ ```
170
+
171
+ ### Build Context for Analysis
172
+
173
+ ```typescript
174
+ async function getProjectContext(conversationId: string) {
175
+ const trees = await ctx.majk.knowledge.listTrees(conversationId);
176
+
177
+ const context = {};
178
+ for (const treeName of trees) {
179
+ const tree = await ctx.majk.knowledge.getTree(conversationId, treeName);
180
+ context[treeName] = tree.nodes.map(n => ({
181
+ title: n.title,
182
+ summary: n.content.slice(0, 200)
183
+ }));
184
+ }
185
+
186
+ return context;
187
+ }
188
+ ```
189
+
190
+ ### Search Across Everything
191
+
192
+ ```typescript
193
+ // Broad search
194
+ const results = await ctx.majk.knowledge.search('authentication');
195
+
196
+ // Filtered search
197
+ const securityResults = await ctx.majk.knowledge.search('authentication', {
198
+ conversationId,
199
+ tree: 'security',
200
+ limit: 5
201
+ });
202
+ ```
203
+
204
+ ## Best Practices
205
+
206
+ 1. **Use meaningful titles** - Clear, searchable node titles
207
+ 2. **Consistent tree names** - Standardize tree names across conversations
208
+ 3. **Rich references** - Link to files, URLs, commits for traceability
209
+ 4. **Structured content** - Use markdown for formatted content
210
+ 5. **Search-friendly content** - Include keywords that users might search for
211
+
212
+ ## Tree Organization Examples
213
+
214
+ ```
215
+ decisions/ - Architecture and design decisions
216
+ security/ - Security considerations and findings
217
+ implementation/ - How things are implemented
218
+ bugs/ - Known issues and their context
219
+ research/ - Background research and findings
220
+ ```
221
+
222
+ ## Next Steps
223
+
224
+ Run `npx @majkapp/plugin-kit --reports` - Reports and knowledge base
225
+ Run `npx @majkapp/plugin-kit --context` - Context API overview
@@ -0,0 +1,356 @@
1
+ # Plugin Management API
2
+
3
+ The `ctx.majk.plugins` API provides comprehensive plugin lifecycle management, health monitoring, and administration capabilities.
4
+
5
+ ## Overview
6
+
7
+ ```typescript
8
+ // Access the plugin management API
9
+ const pluginAPI = ctx.majk.plugins;
10
+
11
+ // Install a plugin
12
+ await pluginAPI.install('my-plugin@1.0.0');
13
+
14
+ // Start/stop plugin lifecycle
15
+ await pluginAPI.start('my-plugin');
16
+ await pluginAPI.stop('my-plugin');
17
+
18
+ // Monitor health and logs
19
+ const health = await pluginAPI.getHealth('my-plugin');
20
+ const logs = await pluginAPI.getLogs('my-plugin');
21
+ ```
22
+
23
+ ## Installation Management
24
+
25
+ ### install(identifier, options?)
26
+ Install a plugin from various sources.
27
+
28
+ ```typescript
29
+ // Install from npm
30
+ await ctx.majk.plugins.install('my-plugin@1.0.0');
31
+
32
+ // Install from local path
33
+ await ctx.majk.plugins.install('/path/to/plugin');
34
+
35
+ // Install with options
36
+ await ctx.majk.plugins.install('my-plugin', {
37
+ force: true, // Force reinstall
38
+ dev: true, // Install as development dependency
39
+ registry: 'custom' // Use custom registry
40
+ });
41
+ ```
42
+
43
+ **Returns:** `InstallPluginResult` with installation details and any errors.
44
+
45
+ ### uninstall(pluginId)
46
+ Remove a plugin completely.
47
+
48
+ ```typescript
49
+ const success = await ctx.majk.plugins.uninstall('my-plugin');
50
+ console.log(success ? 'Uninstalled' : 'Failed to uninstall');
51
+ ```
52
+
53
+ **Returns:** `boolean` indicating success.
54
+
55
+ ## Plugin Discovery
56
+
57
+ ### list()
58
+ Get all installed plugins.
59
+
60
+ ```typescript
61
+ const plugins = await ctx.majk.plugins.list();
62
+ plugins.forEach(plugin => {
63
+ console.log(`${plugin.name} v${plugin.version} - ${plugin.status}`);
64
+ });
65
+ ```
66
+
67
+ **Returns:** `PluginInfo[]` with plugin metadata and status.
68
+
69
+ ### get(pluginId)
70
+ Get detailed information about a specific plugin.
71
+
72
+ ```typescript
73
+ const plugin = await ctx.majk.plugins.get('my-plugin');
74
+ if (plugin) {
75
+ console.log(`Plugin: ${plugin.name}`);
76
+ console.log(`Status: ${plugin.status}`);
77
+ console.log(`Capabilities: ${plugin.capabilities?.length || 0}`);
78
+ }
79
+ ```
80
+
81
+ **Returns:** `PluginInfo | null` if plugin exists.
82
+
83
+ ## Lifecycle Management
84
+
85
+ ### start(pluginId)
86
+ Start a stopped plugin.
87
+
88
+ ```typescript
89
+ await ctx.majk.plugins.start('my-plugin');
90
+ console.log('Plugin started');
91
+ ```
92
+
93
+ ### stop(pluginId)
94
+ Stop a running plugin gracefully.
95
+
96
+ ```typescript
97
+ await ctx.majk.plugins.stop('my-plugin');
98
+ console.log('Plugin stopped');
99
+ ```
100
+
101
+ ### restart(pluginId)
102
+ Stop and start a plugin.
103
+
104
+ ```typescript
105
+ await ctx.majk.plugins.restart('my-plugin');
106
+ console.log('Plugin restarted');
107
+ ```
108
+
109
+ ### reload(pluginId)
110
+ Reload plugin code without stopping (hot reload).
111
+
112
+ ```typescript
113
+ await ctx.majk.plugins.reload('my-plugin');
114
+ console.log('Plugin code reloaded');
115
+ ```
116
+
117
+ ### enable(pluginId) / disable(pluginId)
118
+ Enable or disable a plugin.
119
+
120
+ ```typescript
121
+ // Disable plugin (stops and prevents auto-start)
122
+ await ctx.majk.plugins.disable('my-plugin');
123
+
124
+ // Re-enable plugin
125
+ await ctx.majk.plugins.enable('my-plugin');
126
+ ```
127
+
128
+ ### isRunning(pluginId)
129
+ Check if plugin is currently running.
130
+
131
+ ```typescript
132
+ if (ctx.majk.plugins.isRunning('my-plugin')) {
133
+ console.log('Plugin is active');
134
+ } else {
135
+ console.log('Plugin is stopped');
136
+ }
137
+ ```
138
+
139
+ **Returns:** `boolean` - synchronous check.
140
+
141
+ ## Health Monitoring
142
+
143
+ ### getHealth(pluginId)
144
+ Get plugin health status and diagnostics.
145
+
146
+ ```typescript
147
+ const health = await ctx.majk.plugins.getHealth('my-plugin');
148
+ if (health) {
149
+ console.log(`Status: ${health.status}`);
150
+ console.log(`Memory: ${health.memoryUsage}MB`);
151
+ console.log(`Uptime: ${health.uptime}ms`);
152
+
153
+ if (health.errors?.length > 0) {
154
+ console.log('Recent errors:', health.errors);
155
+ }
156
+ }
157
+ ```
158
+
159
+ **Returns:** `PluginHealth | null` with performance metrics and error information.
160
+
161
+ ### getCapabilities(pluginId)
162
+ Get plugin's registered capabilities (functions, screens, services).
163
+
164
+ ```typescript
165
+ const capabilities = await ctx.majk.plugins.getCapabilities('my-plugin');
166
+ capabilities.forEach(cap => {
167
+ console.log(`${cap.type}: ${cap.name} - ${cap.description}`);
168
+ });
169
+ ```
170
+
171
+ **Returns:** `PluginCapabilityInfo[]` listing all plugin capabilities.
172
+
173
+ ## Logging
174
+
175
+ ### getLogs(pluginId, options?)
176
+ Retrieve plugin logs for debugging.
177
+
178
+ ```typescript
179
+ // Get recent logs
180
+ const logs = await ctx.majk.plugins.getLogs('my-plugin');
181
+
182
+ // Get logs with filters
183
+ const errorLogs = await ctx.majk.plugins.getLogs('my-plugin', {
184
+ level: 'error', // Filter by log level
185
+ since: Date.now() - 3600000, // Last hour
186
+ limit: 100 // Max entries
187
+ });
188
+
189
+ logs.forEach(log => {
190
+ console.log(`[${log.timestamp}] ${log.level}: ${log.message}`);
191
+ });
192
+ ```
193
+
194
+ **Returns:** `PluginLog[]` with timestamped log entries.
195
+
196
+ ### clearLogs(pluginId)
197
+ Clear plugin's log history.
198
+
199
+ ```typescript
200
+ await ctx.majk.plugins.clearLogs('my-plugin');
201
+ console.log('Logs cleared');
202
+ ```
203
+
204
+ ## Development Tools
205
+
206
+ ### setHotReload(pluginId, enabled)
207
+ Enable/disable hot reload for development.
208
+
209
+ ```typescript
210
+ // Enable hot reload for development
211
+ await ctx.majk.plugins.setHotReload('my-plugin', true);
212
+
213
+ // Disable for production
214
+ await ctx.majk.plugins.setHotReload('my-plugin', false);
215
+ ```
216
+
217
+ ### isHotReloadEnabled(pluginId)
218
+ Check hot reload status.
219
+
220
+ ```typescript
221
+ const hotReloadEnabled = await ctx.majk.plugins.isHotReloadEnabled('my-plugin');
222
+ console.log(`Hot reload: ${hotReloadEnabled ? 'ON' : 'OFF'}`);
223
+ ```
224
+
225
+ ## URL Generation
226
+
227
+ ### getPluginExternalUrl(pluginId, options?)
228
+ Get external URL for plugin access.
229
+
230
+ ```typescript
231
+ const url = await ctx.majk.plugins.getPluginExternalUrl('my-plugin');
232
+ console.log(`Plugin accessible at: ${url}`);
233
+
234
+ // With custom options
235
+ const customUrl = await ctx.majk.plugins.getPluginExternalUrl('my-plugin', {
236
+ path: '/api/status',
237
+ port: 8080
238
+ });
239
+ ```
240
+
241
+ **Returns:** `string` - External URL for plugin access.
242
+
243
+ ### getPluginScreenUrl(pluginId, options?)
244
+ Get URL for plugin's UI screens.
245
+
246
+ ```typescript
247
+ const screenUrl = await ctx.majk.plugins.getPluginScreenUrl('my-plugin');
248
+ console.log(`Plugin UI at: ${screenUrl}`);
249
+
250
+ // For specific screen
251
+ const specificScreen = await ctx.majk.plugins.getPluginScreenUrl('my-plugin', {
252
+ screen: 'dashboard',
253
+ params: { view: 'admin' }
254
+ });
255
+ ```
256
+
257
+ **Returns:** `string` - URL for plugin UI screens.
258
+
259
+ ## Common Patterns
260
+
261
+ ### Plugin Health Check
262
+ ```typescript
263
+ async function checkPluginHealth(pluginId: string) {
264
+ if (!ctx.majk.plugins.isRunning(pluginId)) {
265
+ console.log(`Plugin ${pluginId} is not running`);
266
+ return;
267
+ }
268
+
269
+ const health = await ctx.majk.plugins.getHealth(pluginId);
270
+ if (health?.status === 'unhealthy') {
271
+ console.log(`Plugin ${pluginId} is unhealthy:`, health.errors);
272
+ // Consider restarting
273
+ await ctx.majk.plugins.restart(pluginId);
274
+ }
275
+ }
276
+ ```
277
+
278
+ ### Plugin Lifecycle with Error Handling
279
+ ```typescript
280
+ async function safePluginOperation(pluginId: string, operation: 'start' | 'stop' | 'restart') {
281
+ try {
282
+ await ctx.majk.plugins[operation](pluginId);
283
+ console.log(`Plugin ${pluginId} ${operation} successful`);
284
+ } catch (error) {
285
+ console.error(`Failed to ${operation} plugin ${pluginId}:`, error);
286
+
287
+ // Check logs for more details
288
+ const logs = await ctx.majk.plugins.getLogs(pluginId, {
289
+ level: 'error',
290
+ limit: 5
291
+ });
292
+ console.log('Recent errors:', logs);
293
+ }
294
+ }
295
+ ```
296
+
297
+ ### Development Workflow
298
+ ```typescript
299
+ async function setupDevelopment(pluginId: string) {
300
+ // Enable hot reload for development
301
+ await ctx.majk.plugins.setHotReload(pluginId, true);
302
+
303
+ // Start the plugin
304
+ await ctx.majk.plugins.start(pluginId);
305
+
306
+ // Get development URLs
307
+ const externalUrl = await ctx.majk.plugins.getPluginExternalUrl(pluginId);
308
+ const screenUrl = await ctx.majk.plugins.getPluginScreenUrl(pluginId);
309
+
310
+ console.log('Development setup complete:');
311
+ console.log(`- Plugin API: ${externalUrl}`);
312
+ console.log(`- Plugin UI: ${screenUrl}`);
313
+ console.log('- Hot reload: ENABLED');
314
+ }
315
+ ```
316
+
317
+ ## Type Definitions
318
+
319
+ ```typescript
320
+ interface PluginInfo {
321
+ id: string;
322
+ name: string;
323
+ version: string;
324
+ status: 'running' | 'stopped' | 'error' | 'disabled';
325
+ description?: string;
326
+ author?: string;
327
+ capabilities?: PluginCapabilityInfo[];
328
+ }
329
+
330
+ interface PluginHealth {
331
+ status: 'healthy' | 'unhealthy' | 'unknown';
332
+ uptime: number;
333
+ memoryUsage: number;
334
+ errors?: string[];
335
+ lastCheck: number;
336
+ }
337
+
338
+ interface PluginLog {
339
+ timestamp: number;
340
+ level: 'debug' | 'info' | 'warn' | 'error';
341
+ message: string;
342
+ context?: any;
343
+ }
344
+
345
+ interface InstallPluginOptions {
346
+ force?: boolean;
347
+ dev?: boolean;
348
+ registry?: string;
349
+ }
350
+
351
+ interface GetLogsOptions {
352
+ level?: 'debug' | 'info' | 'warn' | 'error';
353
+ since?: number;
354
+ limit?: number;
355
+ }
356
+ ```