opencode-swarm 6.12.0 → 6.13.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/README.md CHANGED
@@ -84,6 +84,31 @@ By default, Swarm uses whatever model OpenCode is configured with. To route diff
84
84
  "architect": { "model": "anthropic/claude-opus-4-6" },
85
85
  "coder": { "model": "minimax-coding-plan/MiniMax-M2.5" },
86
86
  "reviewer": { "model": "zai-coding-plan/glm-5" }
87
+ },
88
+ "guardrails": {
89
+ "max_tool_calls": 200,
90
+ "max_duration_minutes": 30,
91
+ "profiles": {
92
+ "coder": { "max_tool_calls": 500 }
93
+ }
94
+ },
95
+ "tool_filter": {
96
+ "enabled": true,
97
+ "overrides": {}
98
+ },
99
+ "review_passes": {
100
+ "always_security_review": false,
101
+ "security_globs": ["**/*auth*", "**/*crypto*", "**/*session*"]
102
+ },
103
+ "automation": {
104
+ "mode": "manual",
105
+ "capabilities": {
106
+ "plan_sync": false,
107
+ "phase_preflight": false,
108
+ "config_doctor_on_startup": false,
109
+ "evidence_auto_summaries": false,
110
+ "decision_drift_detection": false
111
+ }
87
112
  }
88
113
  }
89
114
  ```
@@ -341,23 +366,99 @@ Config file location: `~/.config/opencode/opencode-swarm.json` (global) or `.ope
341
366
  "automation": {
342
367
  "mode": "manual",
343
368
  "capabilities": {
344
- "plan_sync": false,
369
+ "plan_sync": true,
345
370
  "phase_preflight": false,
346
371
  "config_doctor_on_startup": false,
347
- "evidence_auto_summaries": false,
348
- "decision_drift_detection": false
372
+ "config_doctor_autofix": false,
373
+ "evidence_auto_summaries": true,
374
+ "decision_drift_detection": true
349
375
  }
350
376
  }
351
377
  }
352
378
  ```
353
379
 
354
- ### Automation Modes
380
+ ### Automation
355
381
 
356
- | Mode | Behavior |
357
- |------|----------|
358
- | `manual` | No background automation (default) |
359
- | `hybrid` | Background automation for safe ops, manual for sensitive ones |
360
- | `auto` | Full background automation |
382
+ ## Plan Cursor (v6.13)
383
+
384
+ The `plan_cursor` config compresses the plan that is injected into the LLM context.
385
+
386
+ ```json
387
+ {
388
+ "plan_cursor": {
389
+ "enabled": true,
390
+ "max_tokens": 1500,
391
+ "lookahead_tasks": 2
392
+ }
393
+ }
394
+ ```
395
+
396
+ - **enabled** – When `true` (default) Swarm injects a compact plan cursor instead of the full `plan.md`.
397
+ - **max_tokens** – Upper bound on the number of tokens emitted for the cursor (default 1500). The cursor contains the current phase summary, the full current task, and up to `lookahead_tasks` upcoming tasks. Earlier phases are reduced to one‑line summaries.
398
+ - **lookahead_tasks** – Number of future tasks to include in full detail (default 2). Set to `0` to show only the current task.
399
+
400
+ Disabling (`"enabled": false`) falls back to the pre‑v6.13 behavior of injecting the entire plan text.
401
+
402
+ ## Tool Output Truncation (v6.13)
403
+
404
+ Control the size of tool outputs that are sent back to the LLM.
405
+
406
+ ```json
407
+ {
408
+ "tool_output": {
409
+ "truncation_enabled": true,
410
+ "max_lines": 150,
411
+ "per_tool": {
412
+ "diff": 200,
413
+ "symbols": 100
414
+ }
415
+ }
416
+ }
417
+ ```
418
+
419
+ - **truncation_enabled** – Global switch (default true).
420
+ - **max_lines** – Default line limit for any tool output.
421
+ - **per_tool** – Overrides `max_lines` for specific tools. The `diff` and `symbols` tools are truncated by default because their outputs can be very large.
422
+
423
+ When truncation is active, a footer is appended:
424
+
425
+ ```
426
+ ---
427
+ [output truncated to {maxLines} lines – use `tool_output.per_tool.<tool>` to adjust]
428
+ ```
429
+
430
+ ## Mode Detection (v6.13)
431
+
432
+ Swarm now explicitly distinguishes five architect modes:
433
+
434
+ | Mode | When Injected |
435
+ |------|----------------|
436
+ | `DISCOVER` | After the explorer finishes scanning the codebase. |
437
+ | `PLAN` | When the architect writes or updates the plan. |
438
+ | `EXECUTE` | During task implementation (the normal pipeline). |
439
+ | `PHASE-WRAP` | After all tasks in a phase are completed, before docs are updated. |
440
+ | `UNKNOWN` | Fallback when the current state does not match any known mode. |
441
+
442
+ Each mode determines which injection blocks are added to the LLM prompt (e.g., plan cursor is injected in `PLAN`, tool output truncation in `EXECUTE`, etc.).
443
+
444
+ Default mode: `manual`. No background automation — all actions require explicit slash commands.
445
+
446
+ Modes:
447
+
448
+ - `manual` — No background automation. All actions via slash commands (default).
449
+ - `hybrid` — Background automation for safe operations, manual for sensitive ones.
450
+ - `auto` — Full background automation.
451
+
452
+ Capability defaults:
453
+
454
+ - `plan_sync`: `true` — Background plan synchronization using `fs.watch` with debounced writes (300ms) and 2-second polling fallback
455
+ - `phase_preflight`: `false` — Phase preflight checks before agent execution (opt-in)
456
+ - `config_doctor_on_startup`: `false` — Validate configuration on startup
457
+ - `config_doctor_autofix`: `false` — Auto-fix for config doctor (opt-in, security-sensitive)
458
+ - `evidence_auto_summaries`: `true` — Automatic summaries for evidence bundles
459
+ - `decision_drift_detection`: `true` — Detect drift between planned and actual decisions
460
+
461
+ ---
361
462
 
362
463
  ### Disabling Agents
363
464
 
@@ -396,8 +497,110 @@ Config file location: `~/.config/opencode/opencode-swarm.json` (global) or `.ope
396
497
 
397
498
  ---
398
499
 
500
+ ## Role-Scoped Tool Filtering
501
+
502
+ Swarm limits which tools each agent can access based on their role. This prevents agents from using tools that aren't appropriate for their responsibilities, reducing errors and keeping agents focused.
503
+
504
+ ### Default Tool Allocations
505
+
506
+ | Agent | Tools | Count | Rationale |
507
+ |-------|-------|:---:|-----------|
508
+ | **architect** | All 17 tools | 17 | Orchestrator needs full visibility |
509
+ | **reviewer** | diff, imports, lint, pkg_audit, pre_check_batch, secretscan, symbols, complexity_hotspots, retrieve_summary, extract_code_blocks, test_runner | 11 | Security-focused QA |
510
+ | **coder** | diff, imports, lint, symbols, extract_code_blocks, retrieve_summary | 6 | Write-focused, minimal read tools |
511
+ | **test_engineer** | test_runner, diff, symbols, extract_code_blocks, retrieve_summary, imports, complexity_hotspots, pkg_audit | 8 | Testing and verification |
512
+ | **explorer** | complexity_hotspots, detect_domains, extract_code_blocks, gitingest, imports, retrieve_summary, schema_drift, symbols, todo_extract | 9 | Discovery and analysis |
513
+ | **sme** | complexity_hotspots, detect_domains, extract_code_blocks, imports, retrieve_summary, schema_drift, symbols | 7 | Domain expertise research |
514
+ | **critic** | complexity_hotspots, detect_domains, imports, retrieve_summary, symbols | 5 | Plan review, minimal toolset |
515
+ | **docs** | detect_domains, extract_code_blocks, gitingest, imports, retrieve_summary, schema_drift, symbols, todo_extract | 8 | Documentation synthesis |
516
+ | **designer** | extract_code_blocks, retrieve_summary, symbols | 3 | UI-focused, minimal toolset |
517
+
518
+ ### Configuration
519
+
520
+ Tool filtering is enabled by default. Customize it in your config:
521
+
522
+ ```json
523
+ {
524
+ "tool_filter": {
525
+ "enabled": true,
526
+ "overrides": {
527
+ "coder": ["diff", "imports", "lint", "symbols", "test_runner"],
528
+ "reviewer": ["diff", "secretscan", "sast_scan", "symbols"]
529
+ }
530
+ }
531
+ }
532
+ ```
533
+
534
+ | Option | Type | Default | Description |
535
+ |--------|------|---------|-------------|
536
+ | `enabled` | boolean | `true` | Enable tool filtering globally |
537
+ | `overrides` | Record<string, string[]> | `{}` | Per-agent tool whitelist. Empty array denies all tools. |
538
+
539
+ ### Troubleshooting: Agent Missing a Tool
540
+
541
+ If an agent reports it doesn't have access to a tool it needs:
542
+
543
+ 1. Check if the tool is in the agent's default allocation (see table above)
544
+ 2. Add a custom override in your config:
545
+
546
+ ```json
547
+ {
548
+ "tool_filter": {
549
+ "overrides": {
550
+ "coder": ["diff", "imports", "lint", "symbols", "extract_code_blocks", "retrieve_summary", "test_runner"]
551
+ }
552
+ }
553
+ }
554
+ ```
555
+
556
+ 3. To completely disable filtering for all agents:
557
+
558
+ ```json
559
+ {
560
+ "tool_filter": {
561
+ "enabled": false
562
+ }
563
+ }
564
+ ```
565
+
566
+ ### Available Tools Reference
567
+
568
+ The following tools can be assigned to agents via overrides:
569
+
570
+ | Tool | Purpose |
571
+ |------|---------|
572
+ | `checkpoint` | Save/restore git checkpoints |
573
+ | `complexity_hotspots` | Identify high-risk code areas |
574
+ | `detect_domains` | Detect SME domains from text |
575
+ | `diff` | Analyze git diffs and changes |
576
+ | `evidence_check` | Verify task evidence |
577
+ | `extract_code_blocks` | Extract code from markdown |
578
+ | `gitingest` | Ingest external repositories |
579
+ | `imports` | Analyze import relationships |
580
+ | `lint` | Run project linters |
581
+ | `pkg_audit` | Security audit of dependencies |
582
+ | `pre_check_batch` | Parallel pre-checks (lint, secrets, SAST, quality) |
583
+ | `retrieve_summary` | Retrieve summarized tool outputs |
584
+ | `schema_drift` | Detect OpenAPI/schema drift |
585
+ | `secretscan` | Scan for secrets in code |
586
+ | `symbols` | Extract exported symbols |
587
+ | `test_runner` | Run project tests |
588
+ | `todo_extract` | Extract TODO/FIXME comments |
589
+
590
+ ---
591
+
399
592
  ## Recent Changes
400
593
 
594
+ ### v6.13.0 — Context Efficiency
595
+
596
+ This release focuses on reducing context usage and improving mode-conditional behavior:
597
+
598
+ - **Role-Scoped Tool Filtering**: Agent tools filtered via AGENT_TOOL_MAP
599
+ - **Plan Cursor**: Compressed plan summary under 1,500 tokens
600
+ - **Mode Detection**: DISCOVER/PLAN/EXECUTE/PHASE-WRAP/UNKNOWN modes
601
+ - **Tool Output Truncation**: diff/symbols outputs truncated with footer
602
+ - **ZodError Fixes**: Optional current_phase, 'completed' status support
603
+
401
604
  ### v6.12.0 — Anti-Process-Violation Hardening
402
605
 
403
606
  This release adds runtime detection hooks to catch and warn about architect workflow violations:
@@ -437,7 +640,7 @@ bun test
437
640
 
438
641
  See [CHANGELOG.md](CHANGELOG.md) for shipped features.
439
642
 
440
- Upcoming: v6.12 targets process violation hardening based on field testing with models that attempt to bypass QA gates.
643
+ Upcoming: v6.14 focuses on further context optimization and agent coordination improvements.
441
644
 
442
645
  ---
443
646
 
@@ -1,3 +1,4 @@
1
+ import type { ToolName } from '../tools/tool-names';
1
2
  export declare const QA_AGENTS: readonly ["reviewer", "critic"];
2
3
  export declare const PIPELINE_AGENTS: readonly ["explorer", "coder", "test_engineer"];
3
4
  export declare const ORCHESTRATOR_NAME: "architect";
@@ -6,6 +7,7 @@ export declare const ALL_AGENT_NAMES: readonly ["architect", "sme", "docs", "des
6
7
  export type QAAgentName = (typeof QA_AGENTS)[number];
7
8
  export type PipelineAgentName = (typeof PIPELINE_AGENTS)[number];
8
9
  export type AgentName = (typeof ALL_AGENT_NAMES)[number];
10
+ export declare const AGENT_TOOL_MAP: Record<AgentName, ToolName[]>;
9
11
  export declare const DEFAULT_MODELS: Record<string, string>;
10
12
  export declare function isQAAgent(name: string): name is QAAgentName;
11
13
  export declare function isSubagent(name: string): boolean;
@@ -3,11 +3,11 @@ export declare const EVIDENCE_MAX_JSON_BYTES: number;
3
3
  export declare const EVIDENCE_MAX_PATCH_BYTES: number;
4
4
  export declare const EVIDENCE_MAX_TASK_BYTES: number;
5
5
  export declare const EvidenceTypeSchema: z.ZodEnum<{
6
- placeholder: "placeholder";
6
+ diff: "diff";
7
7
  quality_budget: "quality_budget";
8
+ placeholder: "placeholder";
8
9
  review: "review";
9
10
  test: "test";
10
- diff: "diff";
11
11
  approval: "approval";
12
12
  note: "note";
13
13
  retrospective: "retrospective";
@@ -28,11 +28,11 @@ export type EvidenceVerdict = z.infer<typeof EvidenceVerdictSchema>;
28
28
  export declare const BaseEvidenceSchema: z.ZodObject<{
29
29
  task_id: z.ZodString;
30
30
  type: z.ZodEnum<{
31
- placeholder: "placeholder";
31
+ diff: "diff";
32
32
  quality_budget: "quality_budget";
33
+ placeholder: "placeholder";
33
34
  review: "review";
34
35
  test: "test";
35
- diff: "diff";
36
36
  approval: "approval";
37
37
  note: "note";
38
38
  retrospective: "retrospective";
@@ -15,10 +15,23 @@ export type TaskSize = z.infer<typeof TaskSizeSchema>;
15
15
  export declare const PhaseStatusSchema: z.ZodEnum<{
16
16
  pending: "pending";
17
17
  in_progress: "in_progress";
18
+ completed: "completed";
18
19
  blocked: "blocked";
19
20
  complete: "complete";
20
21
  }>;
21
22
  export type PhaseStatus = z.infer<typeof PhaseStatusSchema>;
23
+ /**
24
+ * Normalize phase status - 'completed' maps to 'complete'.
25
+ * @param status - The phase status to normalize
26
+ * @returns Normalized status ('completed' becomes 'complete')
27
+ */
28
+ export declare function normalizePhaseStatus(status: PhaseStatus): PhaseStatus;
29
+ /**
30
+ * Check if a phase status represents completion.
31
+ * @param status - The phase status to check
32
+ * @returns true if status is 'complete' or 'completed'
33
+ */
34
+ export declare function isPhaseComplete(status: PhaseStatus): boolean;
22
35
  export declare const MigrationStatusSchema: z.ZodEnum<{
23
36
  native: "native";
24
37
  migrated: "migrated";
@@ -53,6 +66,7 @@ export declare const PhaseSchema: z.ZodObject<{
53
66
  status: z.ZodDefault<z.ZodEnum<{
54
67
  pending: "pending";
55
68
  in_progress: "in_progress";
69
+ completed: "completed";
56
70
  blocked: "blocked";
57
71
  complete: "complete";
58
72
  }>>;
@@ -83,13 +97,14 @@ export declare const PlanSchema: z.ZodObject<{
83
97
  schema_version: z.ZodLiteral<"1.0.0">;
84
98
  title: z.ZodString;
85
99
  swarm: z.ZodString;
86
- current_phase: z.ZodNumber;
100
+ current_phase: z.ZodOptional<z.ZodNumber>;
87
101
  phases: z.ZodArray<z.ZodObject<{
88
102
  id: z.ZodNumber;
89
103
  name: z.ZodString;
90
104
  status: z.ZodDefault<z.ZodEnum<{
91
105
  pending: "pending";
92
106
  in_progress: "in_progress";
107
+ completed: "completed";
93
108
  blocked: "blocked";
94
109
  complete: "complete";
95
110
  }>>;
@@ -122,3 +137,15 @@ export declare const PlanSchema: z.ZodObject<{
122
137
  }>>;
123
138
  }, z.core.$strip>;
124
139
  export type Plan = z.infer<typeof PlanSchema>;
140
+ /**
141
+ * Find the first phase that is in progress.
142
+ * @param phases - Array of phases
143
+ * @returns Phase number of first in-progress phase, or first phase if none
144
+ */
145
+ export declare function findFirstActivePhase(phases: Phase[]): number | undefined;
146
+ /**
147
+ * Get the current phase from a plan, with fallback inference.
148
+ * @param plan - The plan object
149
+ * @returns The current phase number, or inferred value, or 1 as last resort
150
+ */
151
+ export declare function getCurrentPhase(plan: Plan): number;
@@ -1,4 +1,19 @@
1
1
  import { z } from 'zod';
2
+ /**
3
+ * Strips known Swarm prefixes from agent names to get the canonical agent name.
4
+ *
5
+ * Strategy:
6
+ * 1. First try stripping known prefixes from the front (e.g., 'paid_architect' -> 'architect')
7
+ * 2. If that doesn't yield a known agent, check if the name ENDS with a known agent name
8
+ * (e.g., 'not-an-architect' -> 'architect', 'team-alpha-reviewer' -> 'reviewer')
9
+ *
10
+ * Supports underscore, hyphen, and space separators.
11
+ * Case-insensitive matching, but returns the canonical lowercase agent name.
12
+ *
13
+ * @param agentName - The potentially prefixed agent name
14
+ * @returns The canonical agent name, or the original if no known agent found
15
+ */
16
+ export declare function stripKnownSwarmPrefix(agentName: string): string;
2
17
  export declare const AgentOverrideConfigSchema: z.ZodObject<{
3
18
  model: z.ZodOptional<z.ZodString>;
4
19
  temperature: z.ZodOptional<z.ZodNumber>;
@@ -269,32 +284,34 @@ export declare const GuardrailsConfigSchema: z.ZodObject<{
269
284
  }, z.core.$strip>;
270
285
  export type GuardrailsConfig = z.infer<typeof GuardrailsConfigSchema>;
271
286
  /**
272
- * Strip any swarm prefix from an agent name to get the base agent name.
273
- * Works with any swarm name by checking if the name (or suffix after removing
274
- * a prefix) matches a known agent name from ALL_AGENT_NAMES.
287
+ * Resolves guardrails configuration for a specific agent.
275
288
  *
276
- * Normalization handles:
277
- * - Case-insensitive matching (e.g., "PAID_ARCHITECT" "architect")
278
- * - Multiple separators: underscore, hyphen, space (e.g., "paid-architect", "paid architect")
289
+ * Resolution order (later values override earlier):
290
+ * 1. Base config values
291
+ * 2. Built-in agent profile defaults from DEFAULT_AGENT_PROFILES (known agents only)
292
+ * 3. User profile overrides - checks in order:
293
+ * a. config.profiles[originalAgentName] (e.g., 'paid_coder')
294
+ * b. config.profiles[canonicalName] (e.g., 'coder')
279
295
  *
280
- * Examples: 'local_architect' 'architect', 'enterprise_coder' 'coder',
281
- * 'paid-architect' 'architect', 'PAID_ARCHITECT' 'architect',
282
- * 'architect' → 'architect', 'unknown_thing' → 'unknown_thing'
296
+ * For prefixed agent names (e.g., 'local_coder'), strips prefixes using stripKnownSwarmPrefix.
297
+ * Unknown agent names get base config + user profile (NOT architect defaults - prevents bypass).
283
298
  *
284
- * @param name - The agent name (possibly prefixed)
285
- * @returns The base agent name if recognized, or the original name
299
+ * @param config - The base guardrails configuration
300
+ * @param agentName - Optional agent name to resolve profile for
301
+ * @returns Resolved configuration object
286
302
  */
287
- export declare function stripKnownSwarmPrefix(name: string): string;
288
- /**
289
- * Resolve guardrails configuration for a specific agent.
290
- * Merges the base config with built-in agent-type defaults and
291
- * any per-agent profile overrides. Merge order: base < built-in < user profile.
292
- *
293
- * @param base - The base guardrails configuration
294
- * @param agentName - Optional agent name to look up profile overrides
295
- * @returns The effective guardrails configuration for the agent
296
- */
297
- export declare function resolveGuardrailsConfig(base: GuardrailsConfig, agentName?: string): GuardrailsConfig;
303
+ export declare function resolveGuardrailsConfig(config: GuardrailsConfig, agentName?: string): GuardrailsConfig;
304
+ export declare const ToolFilterConfigSchema: z.ZodObject<{
305
+ enabled: z.ZodDefault<z.ZodBoolean>;
306
+ overrides: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
307
+ }, z.core.$strip>;
308
+ export type ToolFilterConfig = z.infer<typeof ToolFilterConfigSchema>;
309
+ export declare const PlanCursorConfigSchema: z.ZodObject<{
310
+ enabled: z.ZodDefault<z.ZodBoolean>;
311
+ max_tokens: z.ZodDefault<z.ZodNumber>;
312
+ lookahead_tasks: z.ZodDefault<z.ZodNumber>;
313
+ }, z.core.$strip>;
314
+ export type PlanCursorConfig = z.infer<typeof PlanCursorConfigSchema>;
298
315
  export declare const CheckpointConfigSchema: z.ZodObject<{
299
316
  enabled: z.ZodDefault<z.ZodBoolean>;
300
317
  auto_checkpoint_threshold: z.ZodDefault<z.ZodNumber>;
@@ -441,6 +458,15 @@ export declare const PluginConfigSchema: z.ZodObject<{
441
458
  idle_timeout_minutes: z.ZodOptional<z.ZodNumber>;
442
459
  }, z.core.$strip>>>;
443
460
  }, z.core.$strip>>;
461
+ tool_filter: z.ZodOptional<z.ZodObject<{
462
+ enabled: z.ZodDefault<z.ZodBoolean>;
463
+ overrides: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
464
+ }, z.core.$strip>>;
465
+ plan_cursor: z.ZodOptional<z.ZodObject<{
466
+ enabled: z.ZodDefault<z.ZodBoolean>;
467
+ max_tokens: z.ZodDefault<z.ZodNumber>;
468
+ lookahead_tasks: z.ZodDefault<z.ZodNumber>;
469
+ }, z.core.$strip>>;
444
470
  evidence: z.ZodOptional<z.ZodObject<{
445
471
  enabled: z.ZodDefault<z.ZodBoolean>;
446
472
  max_age_days: z.ZodDefault<z.ZodNumber>;
@@ -520,6 +546,11 @@ export declare const PluginConfigSchema: z.ZodObject<{
520
546
  decision_drift_detection: boolean;
521
547
  };
522
548
  }, unknown>>>;
549
+ tool_output: z.ZodOptional<z.ZodObject<{
550
+ truncation_enabled: z.ZodDefault<z.ZodBoolean>;
551
+ max_lines: z.ZodDefault<z.ZodNumber>;
552
+ per_tool: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
553
+ }, z.core.$strip>>;
523
554
  }, z.core.$strip>;
524
555
  export type PluginConfig = z.infer<typeof PluginConfigSchema>;
525
556
  export type { AgentName, PipelineAgentName, QAAgentName, } from './constants';
@@ -37,3 +37,17 @@ export declare function extractCurrentTaskFromPlan(plan: Plan): string | null;
37
37
  * Extracts incomplete tasks from the current phase of a Plan object.
38
38
  */
39
39
  export declare function extractIncompleteTasksFromPlan(plan: Plan, maxChars?: number): string | null;
40
+ /**
41
+ * Extracts plan cursor - a concise summary of current phase, current task,
42
+ * and lookahead tasks for context-aware agent communication.
43
+ *
44
+ * @param planContent - The raw plan markdown content
45
+ * @param options - Optional configuration
46
+ * @param options.maxTokens - Target max tokens (default 1500, ~6000 chars)
47
+ * @param options.lookaheadTasks - Number of lookahead tasks (default 2)
48
+ * @returns A [SWARM PLAN CURSOR] block with phase summaries and task details
49
+ */
50
+ export declare function extractPlanCursor(planContent: string, options?: {
51
+ maxTokens?: number;
52
+ lookaheadTasks?: number;
53
+ }): string;
@@ -5,6 +5,7 @@ export { createDelegationGateHook } from './delegation-gate';
5
5
  export { createDelegationTrackerHook } from './delegation-tracker';
6
6
  export { extractCurrentPhase, extractCurrentPhaseFromPlan, extractCurrentTask, extractCurrentTaskFromPlan, extractDecisions, extractIncompleteTasks, extractIncompleteTasksFromPlan, extractPatterns, } from './extractors';
7
7
  export { createGuardrailsHooks } from './guardrails';
8
+ export { consolidateSystemMessages } from './messages-transform';
8
9
  export { createPhaseMonitorHook } from './phase-monitor';
9
10
  export { createPipelineTrackerHook } from './pipeline-tracker';
10
11
  export { createSystemEnhancerHook } from './system-enhancer';
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Consolidates multiple system messages into a single system message at index 0.
3
+ *
4
+ * Note: Merged content order matches original insertion order (OpenCode base prompt
5
+ * first, then swarm agent prompt) - this assumes sequential message construction.
6
+ */
7
+ type Message = {
8
+ role: string;
9
+ content: unknown;
10
+ [key: string]: unknown;
11
+ };
12
+ export declare function consolidateSystemMessages(messages: Message[]): Message[];
13
+ export {};
@@ -10,3 +10,14 @@ import type { PluginConfig } from '../config';
10
10
  * Creates the experimental.chat.system.transform hook for system enhancement.
11
11
  */
12
12
  export declare function createSystemEnhancerHook(config: PluginConfig, directory: string): Record<string, unknown>;
13
+ /**
14
+ * Architect operational mode derived from plan state.
15
+ */
16
+ export type ArchitectMode = 'DISCOVER' | 'PLAN' | 'EXECUTE' | 'PHASE-WRAP' | 'UNKNOWN';
17
+ /**
18
+ * Detect the current architect operational mode based on plan state.
19
+ *
20
+ * @param directory - The project directory to check
21
+ * @returns The current architect mode based on plan state
22
+ */
23
+ export declare function detectArchitectMode(directory: string): Promise<ArchitectMode>;