@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/docs/TASKS.md ADDED
@@ -0,0 +1,622 @@
1
+ # Task API
2
+
3
+ The Task API provides asynchronous task execution with real-time progress monitoring, completion tracking, and event handling. Perfect for delegating work to agents or team members, managing long-running operations, and orchestrating multi-step workflows.
4
+
5
+ ## Quick Start
6
+
7
+ ```typescript
8
+ import { definePlugin } from '@majkapp/plugin-kit';
9
+
10
+ const plugin = definePlugin('task-example', 'Task Example', '1.0.0')
11
+ .pluginRoot(__dirname)
12
+
13
+ .function('analyzeCode', {
14
+ description: 'Start code analysis task and monitor progress',
15
+ input: { type: 'object', properties: {}, additionalProperties: false },
16
+ output: { type: 'object', properties: { taskId: { type: 'string' }, result: { type: 'string' } } },
17
+ handler: async (_, ctx) => {
18
+ // Start a new task
19
+ const task = await ctx.majk.tasks.start({
20
+ title: 'Code Analysis',
21
+ message: 'Analyze the codebase for security issues and performance problems',
22
+ agentId: 'security-analyzer',
23
+ workingDirectory: './src',
24
+ taskType: 'analysis',
25
+ context: {
26
+ scope: 'security,performance',
27
+ depth: 'thorough'
28
+ }
29
+ });
30
+
31
+ // Monitor progress with event handlers
32
+ await task.onProgress(progress => {
33
+ console.log(`Progress: ${progress.stage} - ${progress.message}`);
34
+ if (progress.percentage) {
35
+ console.log(`${progress.percentage}% complete`);
36
+ }
37
+ });
38
+
39
+ // Wait for completion with timeout
40
+ const result = await task.waitForCompletion(300000); // 5 minutes
41
+
42
+ return {
43
+ taskId: task.id,
44
+ result: result.success ? 'Analysis completed successfully' : 'Analysis failed'
45
+ };
46
+ }
47
+ })
48
+
49
+ .build();
50
+ ```
51
+
52
+ ## Core Concepts
53
+
54
+ ### Task Lifecycle
55
+
56
+ Tasks progress through these states:
57
+ - **pending**: Task created but not yet started
58
+ - **running**: Task is actively being executed
59
+ - **completed**: Task finished successfully
60
+ - **failed**: Task encountered an error and stopped
61
+
62
+ ### Task Types
63
+
64
+ The API supports different task categories:
65
+ - `code-project`: Development and coding tasks
66
+ - `automation`: Automated workflows and scripts
67
+ - `analysis`: Data analysis and research tasks
68
+ - `chat`: Conversational interactions
69
+ - `research`: Information gathering and investigation
70
+
71
+ ### Working with Task Handles
72
+
73
+ Task handles provide a rich interface for monitoring and controlling task execution:
74
+
75
+ ```typescript
76
+ // Get task status without blocking
77
+ const status = await task.getStatus();
78
+ console.log('Current status:', status);
79
+
80
+ // Check if task is complete
81
+ const isComplete = await task.isComplete();
82
+
83
+ // Send additional instructions
84
+ await task.send('Please also check for SQL injection vulnerabilities');
85
+
86
+ // Send follow-up messages
87
+ await task.sendFollowup('Focus on the authentication module');
88
+
89
+ // Stop a running task
90
+ await task.stop();
91
+ ```
92
+
93
+ ## API Reference
94
+
95
+ ### TaskAPI Interface
96
+
97
+ ```typescript
98
+ interface TaskAPI {
99
+ start(request: StartTaskRequest): Promise<TaskHandle>;
100
+ get(taskId: string): Promise<TaskHandle | null>;
101
+ list(filter?: TaskFilter): Promise<TaskHandle[]>;
102
+ onTaskStarted(handler: TaskEventHandler): Promise<Unsubscribe>;
103
+ onTaskCompleted(handler: TaskEventHandler): Promise<Unsubscribe>;
104
+ onTaskFailed(handler: TaskEventHandler): Promise<Unsubscribe>;
105
+ }
106
+ ```
107
+
108
+ ### Starting Tasks
109
+
110
+ ```typescript
111
+ interface StartTaskRequest {
112
+ title: string; // Human-readable task title
113
+ message: string; // Initial instruction/prompt
114
+ agentId?: string; // Specific agent to use
115
+ teamMemberId?: string; // Team member to assign to
116
+ workingDirectory?: string; // Directory context
117
+ context?: Record<string, any>; // Additional context data
118
+ triggerImmediately?: boolean; // Start immediately (default: true)
119
+ taskType?: 'code-project' | 'automation' | 'analysis' | 'chat' | 'research';
120
+ }
121
+ ```
122
+
123
+ ### Task Handle Interface
124
+
125
+ ```typescript
126
+ interface TaskHandle {
127
+ readonly id: string;
128
+ readonly conversationId: string;
129
+ readonly title: string;
130
+ readonly status: 'pending' | 'running' | 'completed' | 'failed'; // Deprecated - use getStatus()
131
+ readonly agentId: string;
132
+ readonly teamMemberId?: string;
133
+ readonly startedAt: Date;
134
+ readonly completedAt?: Date;
135
+
136
+ // Communication
137
+ send(message: string): Promise<void>;
138
+ sendFollowup(message: string): Promise<void>;
139
+
140
+ // Status and Control
141
+ getStatus(): Promise<'pending' | 'running' | 'completed' | 'failed'>;
142
+ isComplete(): Promise<boolean>;
143
+ waitForCompletion(timeout?: number): Promise<TaskResult>;
144
+ stop(): Promise<void>;
145
+
146
+ // Event Handling
147
+ onMessage(handler: (message: TaskMessage) => void): Promise<Unsubscribe>;
148
+ onProgress(handler: (progress: TaskProgress) => void): Promise<Unsubscribe>;
149
+ onComplete(handler: (result: TaskResult) => void): Promise<Unsubscribe>;
150
+ onError(handler: (error: TaskError) => void): Promise<Unsubscribe>;
151
+
152
+ // Data Access
153
+ getMessages(): Promise<TaskMessage[]>;
154
+ getConversation(): Promise<Conversation>;
155
+ }
156
+ ```
157
+
158
+ ## Common Patterns
159
+
160
+ ### Fire and Forget
161
+
162
+ Start a task and let it run without waiting:
163
+
164
+ ```typescript
165
+ async function startBackgroundAnalysis() {
166
+ const task = await ctx.majk.tasks.start({
167
+ title: 'Background Security Scan',
168
+ message: 'Scan the entire codebase for security vulnerabilities',
169
+ taskType: 'analysis',
170
+ triggerImmediately: true
171
+ });
172
+
173
+ console.log(`Started task ${task.id}, running in background`);
174
+ return task.id;
175
+ }
176
+ ```
177
+
178
+ ### Progress Monitoring
179
+
180
+ Track task progress with detailed feedback:
181
+
182
+ ```typescript
183
+ async function monitoredTask() {
184
+ const task = await ctx.majk.tasks.start({
185
+ title: 'Code Refactoring',
186
+ message: 'Refactor the user authentication module',
187
+ taskType: 'code-project'
188
+ });
189
+
190
+ // Set up progress monitoring
191
+ await task.onProgress(progress => {
192
+ console.log(`Stage: ${progress.stage}`);
193
+ console.log(`Message: ${progress.message}`);
194
+
195
+ if (progress.percentage) {
196
+ console.log(`Progress: ${progress.percentage}%`);
197
+ }
198
+
199
+ if (progress.toolCall) {
200
+ console.log(`Tool: ${progress.toolCall.name} (${progress.toolCall.status})`);
201
+ }
202
+ });
203
+
204
+ // Set up message monitoring
205
+ await task.onMessage(message => {
206
+ console.log(`[${message.role}]: ${message.content}`);
207
+ });
208
+
209
+ const result = await task.waitForCompletion();
210
+ return result;
211
+ }
212
+ ```
213
+
214
+ ### Error Handling
215
+
216
+ Handle task failures gracefully:
217
+
218
+ ```typescript
219
+ async function robustTaskExecution() {
220
+ const task = await ctx.majk.tasks.start({
221
+ title: 'Data Processing',
222
+ message: 'Process the uploaded data files',
223
+ taskType: 'automation'
224
+ });
225
+
226
+ // Set up error handling
227
+ await task.onError(error => {
228
+ console.error(`Task failed: ${error.message}`);
229
+ console.error(`Error code: ${error.code}`);
230
+ if (error.details) {
231
+ console.error('Details:', error.details);
232
+ }
233
+ });
234
+
235
+ try {
236
+ const result = await task.waitForCompletion(600000); // 10 minutes
237
+
238
+ if (result.success) {
239
+ console.log('Task completed successfully');
240
+ return result.output;
241
+ } else {
242
+ console.error('Task failed:', result.error);
243
+ throw new Error(result.error);
244
+ }
245
+ } catch (error) {
246
+ console.error('Task timeout or error:', error.message);
247
+ await task.stop(); // Clean shutdown
248
+ throw error;
249
+ }
250
+ }
251
+ ```
252
+
253
+ ### Batch Task Management
254
+
255
+ Manage multiple tasks concurrently:
256
+
257
+ ```typescript
258
+ async function processBatchTasks() {
259
+ const files = ['file1.js', 'file2.js', 'file3.js'];
260
+ const tasks = [];
261
+
262
+ // Start multiple tasks
263
+ for (const file of files) {
264
+ const task = await ctx.majk.tasks.start({
265
+ title: `Process ${file}`,
266
+ message: `Analyze and optimize ${file}`,
267
+ taskType: 'code-project',
268
+ context: { filename: file }
269
+ });
270
+ tasks.push(task);
271
+ }
272
+
273
+ // Wait for all tasks to complete
274
+ const results = await Promise.all(
275
+ tasks.map(task => task.waitForCompletion())
276
+ );
277
+
278
+ // Process results
279
+ const successful = results.filter(r => r.success).length;
280
+ const failed = results.filter(r => !r.success).length;
281
+
282
+ console.log(`Completed: ${successful}, Failed: ${failed}`);
283
+ return results;
284
+ }
285
+ ```
286
+
287
+ ### Interactive Task Communication
288
+
289
+ Send additional instructions during task execution:
290
+
291
+ ```typescript
292
+ async function interactiveTask() {
293
+ const task = await ctx.majk.tasks.start({
294
+ title: 'Code Review',
295
+ message: 'Review the authentication module',
296
+ taskType: 'code-project'
297
+ });
298
+
299
+ // Wait a bit then send additional instructions
300
+ setTimeout(async () => {
301
+ await task.send('Please pay special attention to SQL injection vulnerabilities');
302
+ }, 5000);
303
+
304
+ // Send follow-up after more time
305
+ setTimeout(async () => {
306
+ await task.sendFollowup('Also check for proper error handling');
307
+ }, 10000);
308
+
309
+ return await task.waitForCompletion();
310
+ }
311
+ ```
312
+
313
+ ### Task Discovery and Management
314
+
315
+ List and manage existing tasks:
316
+
317
+ ```typescript
318
+ async function manageActiveTasks() {
319
+ // List all running tasks
320
+ const runningTasks = await ctx.majk.tasks.list({
321
+ status: 'running'
322
+ });
323
+
324
+ console.log(`Found ${runningTasks.length} running tasks`);
325
+
326
+ // List tasks by agent
327
+ const agentTasks = await ctx.majk.tasks.list({
328
+ agentId: 'code-analyzer'
329
+ });
330
+
331
+ // List recent tasks
332
+ const recentTasks = await ctx.majk.tasks.list({
333
+ startedAfter: new Date(Date.now() - 24 * 60 * 60 * 1000) // Last 24 hours
334
+ });
335
+
336
+ // Get specific task
337
+ const task = await ctx.majk.tasks.get('task-id-123');
338
+ if (task) {
339
+ const status = await task.getStatus();
340
+ console.log(`Task ${task.id} status: ${status}`);
341
+ }
342
+ }
343
+ ```
344
+
345
+ ### Global Task Event Monitoring
346
+
347
+ Listen for task lifecycle events across the system:
348
+
349
+ ```typescript
350
+ async function setupGlobalTaskMonitoring() {
351
+ // Monitor task starts
352
+ await ctx.majk.tasks.onTaskStarted(event => {
353
+ console.log(`Task started: ${event.taskId} by ${event.agentId}`);
354
+ });
355
+
356
+ // Monitor task completions
357
+ await ctx.majk.tasks.onTaskCompleted(event => {
358
+ console.log(`Task completed: ${event.taskId}`);
359
+ });
360
+
361
+ // Monitor task failures
362
+ await ctx.majk.tasks.onTaskFailed(event => {
363
+ console.log(`Task failed: ${event.taskId}`);
364
+ });
365
+ }
366
+ ```
367
+
368
+ ## Best Practices
369
+
370
+ ### Resource Management
371
+
372
+ Always clean up event handlers and stop tasks when appropriate:
373
+
374
+ ```typescript
375
+ async function properResourceManagement() {
376
+ const task = await ctx.majk.tasks.start({
377
+ title: 'Long Running Task',
378
+ message: 'This might take a while',
379
+ taskType: 'analysis'
380
+ });
381
+
382
+ // Set up handlers
383
+ const unsubscribeProgress = await task.onProgress(progress => {
384
+ console.log('Progress:', progress.message);
385
+ });
386
+
387
+ const unsubscribeError = await task.onError(error => {
388
+ console.error('Error:', error.message);
389
+ });
390
+
391
+ try {
392
+ const result = await task.waitForCompletion();
393
+ return result;
394
+ } finally {
395
+ // Clean up subscriptions
396
+ unsubscribeProgress();
397
+ unsubscribeError();
398
+ }
399
+ }
400
+ ```
401
+
402
+ ### Timeout Handling
403
+
404
+ Use appropriate timeouts for different task types:
405
+
406
+ ```typescript
407
+ function getTimeoutForTaskType(taskType: string): number {
408
+ switch (taskType) {
409
+ case 'chat':
410
+ return 30000; // 30 seconds
411
+ case 'analysis':
412
+ return 300000; // 5 minutes
413
+ case 'code-project':
414
+ return 600000; // 10 minutes
415
+ case 'research':
416
+ return 900000; // 15 minutes
417
+ default:
418
+ return 120000; // 2 minutes
419
+ }
420
+ }
421
+
422
+ async function taskWithAppropriateTimeout() {
423
+ const taskType = 'analysis';
424
+ const task = await ctx.majk.tasks.start({
425
+ title: 'Security Analysis',
426
+ message: 'Analyze for security issues',
427
+ taskType
428
+ });
429
+
430
+ const timeout = getTimeoutForTaskType(taskType);
431
+ return await task.waitForCompletion(timeout);
432
+ }
433
+ ```
434
+
435
+ ### Context Enrichment
436
+
437
+ Provide rich context for better task execution:
438
+
439
+ ```typescript
440
+ async function taskWithRichContext() {
441
+ const task = await ctx.majk.tasks.start({
442
+ title: 'Code Optimization',
443
+ message: 'Optimize the payment processing module',
444
+ taskType: 'code-project',
445
+ workingDirectory: './src/payments',
446
+ context: {
447
+ priority: 'high',
448
+ deadline: '2024-01-15',
449
+ constraints: {
450
+ maintainCompatibility: true,
451
+ maxPerformanceImpact: '5%'
452
+ },
453
+ relatedFiles: [
454
+ 'payment-processor.js',
455
+ 'transaction-validator.js',
456
+ 'payment-gateway.js'
457
+ ],
458
+ requirements: [
459
+ 'Reduce memory usage',
460
+ 'Improve error handling',
461
+ 'Add comprehensive logging'
462
+ ]
463
+ }
464
+ });
465
+
466
+ return await task.waitForCompletion();
467
+ }
468
+ ```
469
+
470
+ ## Type Definitions
471
+
472
+ ### TaskMessage
473
+
474
+ ```typescript
475
+ interface TaskMessage {
476
+ role: 'user' | 'assistant' | 'tool' | 'system';
477
+ content: string;
478
+ timestamp: Date;
479
+ seq: number;
480
+ }
481
+ ```
482
+
483
+ ### TaskProgress
484
+
485
+ ```typescript
486
+ interface TaskProgress {
487
+ stage?: string; // Current processing stage
488
+ message?: string; // Progress description
489
+ percentage?: number; // Completion percentage (0-100)
490
+ messageCount?: number; // Number of messages exchanged
491
+ toolCall?: { // Currently executing tool
492
+ name: string;
493
+ status: string;
494
+ };
495
+ }
496
+ ```
497
+
498
+ ### TaskResult
499
+
500
+ ```typescript
501
+ interface TaskResult {
502
+ success: boolean; // Whether task completed successfully
503
+ output?: any; // Task output data
504
+ error?: string; // Error message if failed
505
+ conversationId?: string; // Associated conversation ID
506
+ duration?: number; // Execution time in milliseconds
507
+ }
508
+ ```
509
+
510
+ ### TaskError
511
+
512
+ ```typescript
513
+ interface TaskError {
514
+ code: string; // Error code for categorization
515
+ message: string; // Human-readable error message
516
+ details?: any; // Additional error context
517
+ }
518
+ ```
519
+
520
+ ### TaskFilter
521
+
522
+ ```typescript
523
+ interface TaskFilter {
524
+ status?: 'pending' | 'running' | 'completed' | 'failed';
525
+ agentId?: string;
526
+ teamMemberId?: string;
527
+ startedAfter?: Date;
528
+ startedBefore?: Date;
529
+ }
530
+ ```
531
+
532
+ ## Error Handling
533
+
534
+ The Task API can throw various errors during operation:
535
+
536
+ ```typescript
537
+ async function handleTaskErrors() {
538
+ try {
539
+ const task = await ctx.majk.tasks.start({
540
+ title: 'Test Task',
541
+ message: 'Test message'
542
+ });
543
+
544
+ await task.waitForCompletion();
545
+ } catch (error) {
546
+ if (error.code === 'TASK_TIMEOUT') {
547
+ console.error('Task timed out');
548
+ } else if (error.code === 'AGENT_UNAVAILABLE') {
549
+ console.error('Requested agent is not available');
550
+ } else if (error.code === 'INVALID_CONTEXT') {
551
+ console.error('Task context is invalid');
552
+ } else {
553
+ console.error('Unknown error:', error.message);
554
+ }
555
+ }
556
+ }
557
+ ```
558
+
559
+ ## Integration Examples
560
+
561
+ ### With Batch Processing
562
+
563
+ Combine task management with batch operations:
564
+
565
+ ```typescript
566
+ async function batchTaskProcessing() {
567
+ const files = await getFilesToProcess();
568
+ const batchSize = 5;
569
+ const activeTasks = new Set();
570
+
571
+ for (let i = 0; i < files.length; i += batchSize) {
572
+ const batch = files.slice(i, i + batchSize);
573
+
574
+ for (const file of batch) {
575
+ const task = await ctx.majk.tasks.start({
576
+ title: `Process ${file}`,
577
+ message: `Analyze and process ${file}`,
578
+ taskType: 'code-project'
579
+ });
580
+
581
+ activeTasks.add(task);
582
+
583
+ // Remove completed tasks
584
+ task.onComplete(() => {
585
+ activeTasks.delete(task);
586
+ });
587
+ }
588
+
589
+ // Wait for current batch to complete before starting next
590
+ await Promise.all([...activeTasks].map(task => task.waitForCompletion()));
591
+ }
592
+ }
593
+ ```
594
+
595
+ ### With Event Bus Integration
596
+
597
+ Integrate task events with the broader event system:
598
+
599
+ ```typescript
600
+ async function integrateWithEventBus() {
601
+ // Listen to task events and forward to event bus
602
+ await ctx.majk.tasks.onTaskCompleted(async (event) => {
603
+ // Emit custom event
604
+ await ctx.majk.eventBus.emit('custom:task:completed', {
605
+ taskId: event.taskId,
606
+ agentId: event.agentId,
607
+ completedAt: event.timestamp
608
+ });
609
+ });
610
+
611
+ // Start task and let it be monitored by event system
612
+ const task = await ctx.majk.tasks.start({
613
+ title: 'Monitored Task',
614
+ message: 'This task will emit events',
615
+ taskType: 'automation'
616
+ });
617
+
618
+ return task;
619
+ }
620
+ ```
621
+
622
+ The Task API provides a powerful foundation for managing asynchronous work across your MAJK plugin ecosystem. Use it to orchestrate complex workflows, delegate work to specialized agents, and build responsive applications that can handle long-running operations gracefully.