code-graph-context 2.4.4 → 2.5.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/dist/cli/cli.js CHANGED
File without changes
@@ -34,6 +34,11 @@ export const TOOL_NAMES = {
34
34
  swarmPheromone: 'swarm_pheromone',
35
35
  swarmSense: 'swarm_sense',
36
36
  swarmCleanup: 'swarm_cleanup',
37
+ swarmPostTask: 'swarm_post_task',
38
+ swarmClaimTask: 'swarm_claim_task',
39
+ swarmCompleteTask: 'swarm_complete_task',
40
+ swarmGetTasks: 'swarm_get_tasks',
41
+ swarmOrchestrate: 'swarm_orchestrate',
37
42
  };
38
43
  // Tool Metadata
39
44
  export const TOOL_METADATA = {
@@ -474,6 +479,275 @@ swarm_cleanup({ projectId: "backend", all: true })
474
479
 
475
480
  **Note:** \`warning\` pheromones are preserved by default. Pass \`keepTypes: []\` to delete everything.`,
476
481
  },
482
+ [TOOL_NAMES.swarmPostTask]: {
483
+ title: 'Swarm Post Task',
484
+ description: `Post a task to the swarm blackboard for agents to claim and work on.
485
+
486
+ **What is the Blackboard?**
487
+ The blackboard is a shared task queue where agents post work, claim tasks, and coordinate. Unlike pheromones (indirect coordination), tasks are explicit work items with dependencies.
488
+
489
+ **Parameters:**
490
+ - projectId: Project to post the task in
491
+ - swarmId: Group related tasks together
492
+ - title: Short task title (max 200 chars)
493
+ - description: Detailed description of what needs to be done
494
+ - type: Task category (implement, refactor, fix, test, review, document, investigate, plan)
495
+ - priority: Urgency level (critical, high, normal, low, backlog)
496
+ - targetNodeIds: Code nodes this task affects (from search_codebase)
497
+ - targetFilePaths: File paths this task affects
498
+ - dependencies: Task IDs that must complete before this task can start
499
+ - createdBy: Your agent ID
500
+ - metadata: Additional context (acceptance criteria, notes, etc.)
501
+
502
+ **Task Lifecycle:**
503
+ available → claimed → in_progress → needs_review → completed
504
+ ↘ blocked (if dependencies incomplete)
505
+ ↘ failed (if something goes wrong)
506
+
507
+ **Dependency Management:**
508
+ Tasks with incomplete dependencies are automatically marked as "blocked" and become "available" when all dependencies complete.
509
+
510
+ **Example:**
511
+ \`\`\`
512
+ swarm_post_task({
513
+ projectId: "backend",
514
+ swarmId: "feature_auth",
515
+ title: "Implement JWT validation",
516
+ description: "Add JWT token validation to the auth middleware...",
517
+ type: "implement",
518
+ priority: "high",
519
+ targetNodeIds: ["proj_xxx:Class:AuthMiddleware"],
520
+ dependencies: ["task_abc123"], // Must complete first
521
+ createdBy: "planner_agent"
522
+ })
523
+ \`\`\``,
524
+ },
525
+ [TOOL_NAMES.swarmClaimTask]: {
526
+ title: 'Swarm Claim Task',
527
+ description: `Claim a task from the blackboard to work on it.
528
+
529
+ **Actions:**
530
+ - claim: Reserve a task (prevents others from taking it)
531
+ - start: Begin working on a claimed task (transitions to in_progress)
532
+ - release: Give up a task you've claimed (makes it available again)
533
+
534
+ **Auto-Selection:**
535
+ If you don't specify a taskId, the tool claims the highest-priority available task matching your criteria:
536
+ - types: Only consider certain task types (e.g., ["fix", "implement"])
537
+ - minPriority: Only consider tasks at or above this priority
538
+
539
+ **Claim Flow:**
540
+ 1. swarm_claim_task({ action: "claim" }) - Reserve the task
541
+ 2. swarm_claim_task({ action: "start", taskId: "..." }) - Begin work
542
+ 3. [Do the work]
543
+ 4. swarm_complete_task({ action: "complete" }) - Finish
544
+
545
+ **Example - Claim specific task:**
546
+ \`\`\`
547
+ swarm_claim_task({
548
+ projectId: "backend",
549
+ swarmId: "feature_auth",
550
+ agentId: "worker_1",
551
+ taskId: "task_abc123",
552
+ action: "claim"
553
+ })
554
+ \`\`\`
555
+
556
+ **Example - Auto-select highest priority:**
557
+ \`\`\`
558
+ swarm_claim_task({
559
+ projectId: "backend",
560
+ swarmId: "feature_auth",
561
+ agentId: "worker_1",
562
+ types: ["implement", "fix"],
563
+ minPriority: "normal"
564
+ })
565
+ \`\`\`
566
+
567
+ **Releasing Tasks:**
568
+ If you can't complete a task, release it so others can pick it up:
569
+ \`\`\`
570
+ swarm_claim_task({
571
+ projectId: "backend",
572
+ taskId: "task_abc123",
573
+ agentId: "worker_1",
574
+ action: "release",
575
+ releaseReason: "Blocked by external API issue"
576
+ })
577
+ \`\`\``,
578
+ },
579
+ [TOOL_NAMES.swarmCompleteTask]: {
580
+ title: 'Swarm Complete Task',
581
+ description: `Mark a task as completed, failed, or request review.
582
+
583
+ **Actions:**
584
+ - complete: Task finished successfully (triggers dependent tasks to become available)
585
+ - fail: Task failed (can be retried if retryable=true)
586
+ - request_review: Submit work for review before completion
587
+ - approve: Reviewer approves the work (completes the task)
588
+ - reject: Reviewer rejects (returns to in_progress or marks failed)
589
+ - retry: Make a failed task available again
590
+
591
+ **Completing with Artifacts:**
592
+ \`\`\`
593
+ swarm_complete_task({
594
+ projectId: "backend",
595
+ taskId: "task_abc123",
596
+ agentId: "worker_1",
597
+ action: "complete",
598
+ summary: "Implemented JWT validation with RS256 signing",
599
+ artifacts: {
600
+ files: ["src/auth/jwt.service.ts"],
601
+ commits: ["abc123"],
602
+ pullRequests: ["#42"]
603
+ },
604
+ filesChanged: ["src/auth/jwt.service.ts", "src/auth/auth.module.ts"],
605
+ linesAdded: 150,
606
+ linesRemoved: 20
607
+ })
608
+ \`\`\`
609
+
610
+ **Request Review (for important changes):**
611
+ \`\`\`
612
+ swarm_complete_task({
613
+ projectId: "backend",
614
+ taskId: "task_abc123",
615
+ agentId: "worker_1",
616
+ action: "request_review",
617
+ summary: "Implemented auth - needs security review",
618
+ reviewNotes: "Please verify token expiration logic"
619
+ })
620
+ \`\`\`
621
+
622
+ **Approve/Reject (for reviewers):**
623
+ \`\`\`
624
+ swarm_complete_task({
625
+ projectId: "backend",
626
+ taskId: "task_abc123",
627
+ agentId: "reviewer_1",
628
+ action: "approve",
629
+ reviewerId: "reviewer_1",
630
+ notes: "LGTM"
631
+ })
632
+ \`\`\`
633
+
634
+ **Failing a Task:**
635
+ \`\`\`
636
+ swarm_complete_task({
637
+ projectId: "backend",
638
+ taskId: "task_abc123",
639
+ agentId: "worker_1",
640
+ action: "fail",
641
+ reason: "External API is down",
642
+ errorDetails: "ConnectionTimeout after 30s",
643
+ retryable: true
644
+ })
645
+ \`\`\``,
646
+ },
647
+ [TOOL_NAMES.swarmGetTasks]: {
648
+ title: 'Swarm Get Tasks',
649
+ description: `Query tasks from the blackboard with filters.
650
+
651
+ **Basic Usage:**
652
+ \`\`\`
653
+ // Get all available tasks in a swarm
654
+ swarm_get_tasks({
655
+ projectId: "backend",
656
+ swarmId: "feature_auth",
657
+ statuses: ["available"]
658
+ })
659
+
660
+ // Get a specific task with full details
661
+ swarm_get_tasks({
662
+ projectId: "backend",
663
+ taskId: "task_abc123"
664
+ })
665
+
666
+ // Get your claimed/in-progress tasks
667
+ swarm_get_tasks({
668
+ projectId: "backend",
669
+ claimedBy: "worker_1",
670
+ statuses: ["claimed", "in_progress"]
671
+ })
672
+ \`\`\`
673
+
674
+ **Filters:**
675
+ - swarmId: Filter by swarm
676
+ - statuses: Task statuses (available, claimed, in_progress, blocked, needs_review, completed, failed, cancelled)
677
+ - types: Task types (implement, refactor, fix, test, review, document, investigate, plan)
678
+ - claimedBy: Agent who has the task
679
+ - createdBy: Agent who created the task
680
+ - minPriority: Minimum priority level
681
+
682
+ **Sorting:**
683
+ - priority: Highest priority first (default)
684
+ - created: Newest first
685
+ - updated: Most recently updated first
686
+
687
+ **Additional Data:**
688
+ - includeStats: true - Get aggregate statistics (counts by status, type, agent)
689
+ - includeDependencyGraph: true - Get task dependency graph for visualization
690
+
691
+ **Example with stats:**
692
+ \`\`\`
693
+ swarm_get_tasks({
694
+ projectId: "backend",
695
+ swarmId: "feature_auth",
696
+ includeStats: true
697
+ })
698
+ // Returns: { tasks: [...], stats: { byStatus: {available: 5, in_progress: 2}, ... } }
699
+ \`\`\``,
700
+ },
701
+ [TOOL_NAMES.swarmOrchestrate]: {
702
+ title: 'Swarm Orchestrate',
703
+ description: `Orchestrate multiple agents to tackle complex, multi-file code tasks in parallel.
704
+
705
+ **What This Does:**
706
+ Spawns and coordinates multiple LLM worker agents to execute complex codebase changes. Uses the code graph to understand dependencies and the swarm system for coordination.
707
+
708
+ **Example Tasks:**
709
+ - "Rename getUserById to fetchUser across the codebase"
710
+ - "Add JSDoc comments to all exported functions in src/core/"
711
+ - "Convert all class components to functional React components"
712
+ - "Add deprecation warnings to all v1 API endpoints"
713
+
714
+ **How It Works:**
715
+ 1. **Analyze** - Uses search_codebase to find affected nodes and impact_analysis for dependencies
716
+ 2. **Plan** - Decomposes task into atomic, dependency-ordered SwarmTasks
717
+ 3. **Spawn** - Starts N worker agents that claim tasks and leave pheromones
718
+ 4. **Monitor** - Tracks progress, detects blocked agents, enables self-healing
719
+ 5. **Complete** - Aggregates results and cleans up pheromones
720
+
721
+ **Parameters:**
722
+ - projectId: Project to operate on
723
+ - task: Natural language description of the task
724
+ - maxAgents: Maximum concurrent worker agents (default: 3)
725
+ - dryRun: If true, only plan without executing (default: false)
726
+ - autoApprove: Skip approval step for each task (default: false)
727
+ - priority: Overall priority level (critical, high, normal, low, backlog)
728
+
729
+ **Self-Healing:**
730
+ - Pheromone decay automatically frees stuck work
731
+ - Failed tasks become available for retry
732
+ - Blocked agents release tasks for others
733
+
734
+ **Example:**
735
+ \`\`\`
736
+ swarm_orchestrate({
737
+ projectId: "backend",
738
+ task: "Add JSDoc comments to all exported functions in src/services/",
739
+ maxAgents: 3,
740
+ dryRun: false
741
+ })
742
+ \`\`\`
743
+
744
+ **Returns:**
745
+ - swarmId: Unique identifier for this swarm run
746
+ - status: planning | executing | completed | failed
747
+ - plan: Task breakdown with dependency graph
748
+ - progress: Real-time completion stats
749
+ - results: Summary of changes made`,
750
+ },
477
751
  };
478
752
  // Default Values
479
753
  export const DEFAULTS = {
@@ -0,0 +1,251 @@
1
+ /**
2
+ * Swarm Worker Handler
3
+ * Defines the protocol for worker agents spawned by the orchestrator
4
+ *
5
+ * This handler provides:
6
+ * 1. Worker agent initialization and lifecycle management
7
+ * 2. Task claiming and execution protocol
8
+ * 3. Pheromone coordination for conflict avoidance
9
+ * 4. Progress reporting and error handling
10
+ */
11
+ import { ORCHESTRATOR_CONFIG, generateAgentId } from '../tools/swarm-constants.js';
12
+ /**
13
+ * SwarmWorkerHandler - Manages worker agent behavior
14
+ *
15
+ * Note: This handler generates prompts and protocols for worker agents.
16
+ * The actual agent execution is done by Claude Code's Task tool.
17
+ */
18
+ export class SwarmWorkerHandler {
19
+ workerProgress = new Map();
20
+ /**
21
+ * Generate the prompt/instructions for a worker agent
22
+ * This is used when spawning agents via Claude Code's Task tool
23
+ */
24
+ generateWorkerPrompt(config) {
25
+ const agentId = generateAgentId(config.swarmId, config.agentIndex);
26
+ return `You are a swarm worker agent (${agentId}) participating in swarm ${config.swarmId}.
27
+
28
+ ## Your Role
29
+ You are part of a coordinated team of AI agents working together on a complex codebase task. Your job is to claim available tasks, execute them, and coordinate with other workers through pheromone markers.
30
+
31
+ ## Project Context
32
+ - Project ID: ${config.projectId}
33
+ - Swarm ID: ${config.swarmId}
34
+ - Agent ID: ${agentId}
35
+
36
+ ## Your Workflow
37
+
38
+ ### 1. Check for Available Work
39
+ First, sense what other agents are doing:
40
+ \`\`\`
41
+ swarm_sense({
42
+ projectId: "${config.projectId}",
43
+ swarmId: "${config.swarmId}",
44
+ types: ["modifying", "claiming"],
45
+ excludeAgentId: "${agentId}"
46
+ })
47
+ \`\`\`
48
+
49
+ ### 2. Claim a Task
50
+ Claim the highest-priority available task:
51
+ \`\`\`
52
+ swarm_claim_task({
53
+ projectId: "${config.projectId}",
54
+ swarmId: "${config.swarmId}",
55
+ agentId: "${agentId}",
56
+ action: "claim"
57
+ })
58
+ \`\`\`
59
+
60
+ If no task is returned, check if the swarm is complete:
61
+ \`\`\`
62
+ swarm_get_tasks({
63
+ projectId: "${config.projectId}",
64
+ swarmId: "${config.swarmId}",
65
+ includeStats: true
66
+ })
67
+ \`\`\`
68
+
69
+ If stats show available=0 and inProgress=0, the swarm is complete. Exit gracefully.
70
+
71
+ ### 3. Leave Pheromone Marker
72
+ Before starting work, mark the target node:
73
+ \`\`\`
74
+ swarm_pheromone({
75
+ projectId: "${config.projectId}",
76
+ nodeId: "<first target node from task>",
77
+ type: "modifying",
78
+ agentId: "${agentId}",
79
+ swarmId: "${config.swarmId}"
80
+ })
81
+ \`\`\`
82
+
83
+ ### 4. Start the Task
84
+ \`\`\`
85
+ swarm_claim_task({
86
+ projectId: "${config.projectId}",
87
+ taskId: "<claimed task id>",
88
+ agentId: "${agentId}",
89
+ action: "start"
90
+ })
91
+ \`\`\`
92
+
93
+ ### 5. Execute the Task
94
+ Read the task description carefully and execute it:
95
+ - Use Read tool to understand the current code
96
+ - Use Edit tool to make changes
97
+ - Follow the task's acceptance criteria
98
+ - Keep changes focused and atomic
99
+
100
+ ### 6. Mark Completion
101
+ On success:
102
+ \`\`\`
103
+ swarm_complete_task({
104
+ projectId: "${config.projectId}",
105
+ taskId: "<task id>",
106
+ agentId: "${agentId}",
107
+ action: "complete",
108
+ summary: "<brief summary of what you did>",
109
+ filesChanged: ["<list of files changed>"]
110
+ })
111
+ \`\`\`
112
+
113
+ Update pheromone to completed:
114
+ \`\`\`
115
+ swarm_pheromone({
116
+ projectId: "${config.projectId}",
117
+ nodeId: "<target node>",
118
+ type: "completed",
119
+ agentId: "${agentId}",
120
+ swarmId: "${config.swarmId}",
121
+ data: { summary: "<what you did>" }
122
+ })
123
+ \`\`\`
124
+
125
+ On failure:
126
+ \`\`\`
127
+ swarm_complete_task({
128
+ projectId: "${config.projectId}",
129
+ taskId: "<task id>",
130
+ agentId: "${agentId}",
131
+ action: "fail",
132
+ reason: "<what went wrong>",
133
+ retryable: true
134
+ })
135
+ \`\`\`
136
+
137
+ Leave a blocked pheromone (will decay, allowing retry):
138
+ \`\`\`
139
+ swarm_pheromone({
140
+ projectId: "${config.projectId}",
141
+ nodeId: "<target node>",
142
+ type: "blocked",
143
+ agentId: "${agentId}",
144
+ swarmId: "${config.swarmId}",
145
+ data: { error: "<error message>" }
146
+ })
147
+ \`\`\`
148
+
149
+ ### 7. Loop
150
+ Return to step 1 and claim the next available task.
151
+ Continue until no tasks remain.
152
+
153
+ ## Important Rules
154
+
155
+ 1. **Always leave pheromones** - This prevents conflicts with other agents
156
+ 2. **Check before claiming** - Use swarm_sense to avoid conflicts
157
+ 3. **Keep changes atomic** - One logical change per task
158
+ 4. **Report honestly** - If you can't complete a task, mark it as failed so others can try
159
+ 5. **Don't modify code outside your task** - Stay focused on assigned work
160
+ 6. **Exit when done** - When no tasks remain, complete gracefully
161
+
162
+ ## Conflict Avoidance
163
+
164
+ If you see a "modifying" or "claiming" pheromone on a node:
165
+ - Skip that task and find another
166
+ - The pheromone will decay if the other agent fails
167
+
168
+ ## Error Recovery
169
+
170
+ If you encounter an error:
171
+ 1. Mark the task as failed with retryable=true
172
+ 2. Leave a "blocked" pheromone (5 min decay)
173
+ 3. Move on to the next task
174
+ 4. Another agent (or you, later) can retry
175
+
176
+ Begin working now. Start by sensing the environment and claiming your first task.`;
177
+ }
178
+ /**
179
+ * Initialize a worker's progress tracking
180
+ */
181
+ initializeWorker(config) {
182
+ const agentId = generateAgentId(config.swarmId, config.agentIndex);
183
+ const progress = {
184
+ agentId,
185
+ state: 'idle',
186
+ tasksCompleted: 0,
187
+ tasksFailed: 0,
188
+ lastActivityTime: Date.now(),
189
+ };
190
+ this.workerProgress.set(agentId, progress);
191
+ return progress;
192
+ }
193
+ /**
194
+ * Update worker progress
195
+ */
196
+ updateWorkerProgress(agentId, update) {
197
+ const progress = this.workerProgress.get(agentId);
198
+ if (!progress)
199
+ return null;
200
+ Object.assign(progress, update, { lastActivityTime: Date.now() });
201
+ return progress;
202
+ }
203
+ /**
204
+ * Get all worker progress for a swarm
205
+ */
206
+ getSwarmProgress(swarmId) {
207
+ const results = [];
208
+ for (const [agentId, progress] of this.workerProgress) {
209
+ if (agentId.startsWith(swarmId)) {
210
+ results.push(progress);
211
+ }
212
+ }
213
+ return results;
214
+ }
215
+ /**
216
+ * Check if a worker has timed out
217
+ */
218
+ isWorkerTimedOut(agentId, timeoutMs = ORCHESTRATOR_CONFIG.workerTimeoutMs) {
219
+ const progress = this.workerProgress.get(agentId);
220
+ if (!progress)
221
+ return true;
222
+ const elapsed = Date.now() - progress.lastActivityTime;
223
+ return elapsed > timeoutMs;
224
+ }
225
+ /**
226
+ * Clean up worker tracking for a swarm
227
+ */
228
+ cleanupSwarm(swarmId) {
229
+ for (const agentId of this.workerProgress.keys()) {
230
+ if (agentId.startsWith(swarmId)) {
231
+ this.workerProgress.delete(agentId);
232
+ }
233
+ }
234
+ }
235
+ /**
236
+ * Get aggregate stats for all workers in a swarm
237
+ */
238
+ getSwarmStats(swarmId) {
239
+ const workers = this.getSwarmProgress(swarmId);
240
+ return {
241
+ activeWorkers: workers.filter((w) => w.state === 'working' || w.state === 'claiming').length,
242
+ idleWorkers: workers.filter((w) => w.state === 'idle').length,
243
+ totalTasksCompleted: workers.reduce((sum, w) => sum + w.tasksCompleted, 0),
244
+ totalTasksFailed: workers.reduce((sum, w) => sum + w.tasksFailed, 0),
245
+ };
246
+ }
247
+ }
248
+ /**
249
+ * Export singleton instance
250
+ */
251
+ export const swarmWorkerHandler = new SwarmWorkerHandler();