@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
|
@@ -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
|
package/docs/PLUGINS.md
ADDED
|
@@ -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
|
+
```
|