opencode-swarm 6.22.1 → 6.22.3

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/index.js CHANGED
@@ -46,6 +46,42 @@ var __export = (target, all) => {
46
46
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
47
47
  var __require = import.meta.require;
48
48
 
49
+ // src/tools/tool-names.ts
50
+ var TOOL_NAMES, TOOL_NAME_SET;
51
+ var init_tool_names = __esm(() => {
52
+ TOOL_NAMES = [
53
+ "diff",
54
+ "syntax_check",
55
+ "placeholder_scan",
56
+ "imports",
57
+ "lint",
58
+ "secretscan",
59
+ "sast_scan",
60
+ "build_check",
61
+ "pre_check_batch",
62
+ "quality_budget",
63
+ "symbols",
64
+ "complexity_hotspots",
65
+ "schema_drift",
66
+ "todo_extract",
67
+ "evidence_check",
68
+ "sbom_generate",
69
+ "checkpoint",
70
+ "pkg_audit",
71
+ "test_runner",
72
+ "detect_domains",
73
+ "gitingest",
74
+ "retrieve_summary",
75
+ "extract_code_blocks",
76
+ "phase_complete",
77
+ "save_plan",
78
+ "update_task_status",
79
+ "write_retro",
80
+ "declare_scope"
81
+ ];
82
+ TOOL_NAME_SET = new Set(TOOL_NAMES);
83
+ });
84
+
49
85
  // src/utils/merge.ts
50
86
  function deepMergeInternal(base, override, depth) {
51
87
  if (depth >= MAX_MERGE_DEPTH) {
@@ -72,6 +108,173 @@ function deepMerge(base, override) {
72
108
  }
73
109
  var MAX_MERGE_DEPTH = 10;
74
110
 
111
+ // src/config/constants.ts
112
+ function isQAAgent(name2) {
113
+ return QA_AGENTS.includes(name2);
114
+ }
115
+ function isSubagent(name2) {
116
+ return ALL_SUBAGENT_NAMES.includes(name2);
117
+ }
118
+ function isLowCapabilityModel(modelId) {
119
+ if (!modelId)
120
+ return false;
121
+ const lower = modelId.toLowerCase();
122
+ return LOW_CAPABILITY_MODELS.some((substr) => lower.includes(substr));
123
+ }
124
+ var QA_AGENTS, PIPELINE_AGENTS, ORCHESTRATOR_NAME = "architect", ALL_SUBAGENT_NAMES, ALL_AGENT_NAMES, AGENT_TOOL_MAP, DEFAULT_MODELS, DEFAULT_SCORING_CONFIG, LOW_CAPABILITY_MODELS;
125
+ var init_constants = __esm(() => {
126
+ init_tool_names();
127
+ QA_AGENTS = ["reviewer", "critic"];
128
+ PIPELINE_AGENTS = ["explorer", "coder", "test_engineer"];
129
+ ALL_SUBAGENT_NAMES = [
130
+ "sme",
131
+ "docs",
132
+ "designer",
133
+ ...QA_AGENTS,
134
+ ...PIPELINE_AGENTS
135
+ ];
136
+ ALL_AGENT_NAMES = [
137
+ ORCHESTRATOR_NAME,
138
+ ...ALL_SUBAGENT_NAMES
139
+ ];
140
+ AGENT_TOOL_MAP = {
141
+ architect: [
142
+ "checkpoint",
143
+ "complexity_hotspots",
144
+ "detect_domains",
145
+ "evidence_check",
146
+ "extract_code_blocks",
147
+ "gitingest",
148
+ "imports",
149
+ "lint",
150
+ "diff",
151
+ "pkg_audit",
152
+ "pre_check_batch",
153
+ "retrieve_summary",
154
+ "save_plan",
155
+ "schema_drift",
156
+ "secretscan",
157
+ "symbols",
158
+ "test_runner",
159
+ "todo_extract",
160
+ "update_task_status",
161
+ "write_retro",
162
+ "declare_scope"
163
+ ],
164
+ explorer: [
165
+ "complexity_hotspots",
166
+ "detect_domains",
167
+ "extract_code_blocks",
168
+ "gitingest",
169
+ "imports",
170
+ "retrieve_summary",
171
+ "schema_drift",
172
+ "symbols",
173
+ "todo_extract"
174
+ ],
175
+ coder: [
176
+ "diff",
177
+ "imports",
178
+ "lint",
179
+ "symbols",
180
+ "extract_code_blocks",
181
+ "retrieve_summary"
182
+ ],
183
+ test_engineer: [
184
+ "test_runner",
185
+ "diff",
186
+ "symbols",
187
+ "extract_code_blocks",
188
+ "retrieve_summary",
189
+ "imports",
190
+ "complexity_hotspots",
191
+ "pkg_audit"
192
+ ],
193
+ sme: [
194
+ "complexity_hotspots",
195
+ "detect_domains",
196
+ "extract_code_blocks",
197
+ "imports",
198
+ "retrieve_summary",
199
+ "schema_drift",
200
+ "symbols"
201
+ ],
202
+ reviewer: [
203
+ "diff",
204
+ "imports",
205
+ "lint",
206
+ "pkg_audit",
207
+ "pre_check_batch",
208
+ "secretscan",
209
+ "symbols",
210
+ "complexity_hotspots",
211
+ "retrieve_summary",
212
+ "extract_code_blocks",
213
+ "test_runner"
214
+ ],
215
+ critic: [
216
+ "complexity_hotspots",
217
+ "detect_domains",
218
+ "imports",
219
+ "retrieve_summary",
220
+ "symbols"
221
+ ],
222
+ docs: [
223
+ "detect_domains",
224
+ "extract_code_blocks",
225
+ "gitingest",
226
+ "imports",
227
+ "retrieve_summary",
228
+ "schema_drift",
229
+ "symbols",
230
+ "todo_extract"
231
+ ],
232
+ designer: ["extract_code_blocks", "retrieve_summary", "symbols"]
233
+ };
234
+ for (const [agentName, tools] of Object.entries(AGENT_TOOL_MAP)) {
235
+ const invalidTools = tools.filter((tool) => !TOOL_NAME_SET.has(tool));
236
+ if (invalidTools.length > 0) {
237
+ throw new Error(`Agent '${agentName}' has invalid tool names: [${invalidTools.join(", ")}]. ` + `All tools must be registered in TOOL_NAME_SET.`);
238
+ }
239
+ }
240
+ DEFAULT_MODELS = {
241
+ explorer: "opencode/trinity-large-preview-free",
242
+ coder: "opencode/minimax-m2.5-free",
243
+ reviewer: "opencode/big-pickle",
244
+ test_engineer: "opencode/gpt-5-nano",
245
+ sme: "opencode/trinity-large-preview-free",
246
+ critic: "opencode/trinity-large-preview-free",
247
+ docs: "opencode/trinity-large-preview-free",
248
+ designer: "opencode/trinity-large-preview-free",
249
+ default: "opencode/trinity-large-preview-free"
250
+ };
251
+ DEFAULT_SCORING_CONFIG = {
252
+ enabled: false,
253
+ max_candidates: 100,
254
+ weights: {
255
+ phase: 1,
256
+ current_task: 2,
257
+ blocked_task: 1.5,
258
+ recent_failure: 2.5,
259
+ recent_success: 0.5,
260
+ evidence_presence: 1,
261
+ decision_recency: 1.5,
262
+ dependency_proximity: 1
263
+ },
264
+ decision_decay: {
265
+ mode: "exponential",
266
+ half_life_hours: 24
267
+ },
268
+ token_ratios: {
269
+ prose: 0.25,
270
+ code: 0.4,
271
+ markdown: 0.3,
272
+ json: 0.35
273
+ }
274
+ };
275
+ LOW_CAPABILITY_MODELS = ["mini", "nano", "small", "free"];
276
+ });
277
+
75
278
  // node_modules/zod/v4/core/core.js
76
279
  function $constructor(name2, initializer, params) {
77
280
  function init2(inst, def) {
@@ -14170,6 +14373,649 @@ var init_evidence_schema = __esm(() => {
14170
14373
  });
14171
14374
  });
14172
14375
 
14376
+ // src/config/schema.ts
14377
+ function stripKnownSwarmPrefix(agentName) {
14378
+ if (!agentName)
14379
+ return agentName;
14380
+ const normalized = agentName.toLowerCase();
14381
+ let stripped = normalized;
14382
+ let previous = "";
14383
+ while (stripped !== previous) {
14384
+ previous = stripped;
14385
+ for (const prefix of KNOWN_SWARM_PREFIXES) {
14386
+ for (const sep of SEPARATORS) {
14387
+ const prefixWithSep = prefix + sep;
14388
+ if (stripped.startsWith(prefixWithSep)) {
14389
+ stripped = stripped.slice(prefixWithSep.length);
14390
+ break;
14391
+ }
14392
+ }
14393
+ if (stripped !== previous)
14394
+ break;
14395
+ }
14396
+ }
14397
+ if (ALL_AGENT_NAMES.includes(stripped)) {
14398
+ return stripped;
14399
+ }
14400
+ for (const agent of ALL_AGENT_NAMES) {
14401
+ for (const sep of SEPARATORS) {
14402
+ const suffix = sep + agent;
14403
+ if (normalized.endsWith(suffix)) {
14404
+ return agent;
14405
+ }
14406
+ }
14407
+ if (normalized === agent) {
14408
+ return agent;
14409
+ }
14410
+ }
14411
+ return agentName;
14412
+ }
14413
+ function resolveGuardrailsConfig(config2, agentName) {
14414
+ if (!agentName) {
14415
+ return config2;
14416
+ }
14417
+ const canonicalName = stripKnownSwarmPrefix(agentName);
14418
+ const hasBuiltInProfile = canonicalName in DEFAULT_AGENT_PROFILES;
14419
+ const userProfile = config2.profiles?.[agentName] ?? config2.profiles?.[canonicalName];
14420
+ if (!hasBuiltInProfile) {
14421
+ if (userProfile) {
14422
+ return { ...config2, ...userProfile };
14423
+ }
14424
+ return config2;
14425
+ }
14426
+ const builtInProfile = DEFAULT_AGENT_PROFILES[canonicalName];
14427
+ const resolved = {
14428
+ ...config2,
14429
+ ...builtInProfile,
14430
+ ...userProfile || {}
14431
+ };
14432
+ return resolved;
14433
+ }
14434
+ var KNOWN_SWARM_PREFIXES, SEPARATORS, AgentOverrideConfigSchema, SwarmConfigSchema, HooksConfigSchema, ScoringWeightsSchema, DecisionDecaySchema, TokenRatiosSchema, ScoringConfigSchema, ContextBudgetConfigSchema, EvidenceConfigSchema, GateFeatureSchema, PlaceholderScanConfigSchema, QualityBudgetConfigSchema, GateConfigSchema, PipelineConfigSchema, PhaseCompleteConfigSchema, SummaryConfigSchema, ReviewPassesConfigSchema, AdversarialDetectionConfigSchema, IntegrationAnalysisConfigSchema, DocsConfigSchema, UIReviewConfigSchema, CompactionAdvisoryConfigSchema, LintConfigSchema, SecretscanConfigSchema, GuardrailsProfileSchema, DEFAULT_AGENT_PROFILES, DEFAULT_ARCHITECT_PROFILE, GuardrailsConfigSchema, ToolFilterConfigSchema, PlanCursorConfigSchema, CheckpointConfigSchema, AutomationModeSchema, AutomationCapabilitiesSchema, AutomationConfigSchemaBase, AutomationConfigSchema, KnowledgeConfigSchema, CuratorConfigSchema, PluginConfigSchema;
14435
+ var init_schema = __esm(() => {
14436
+ init_zod();
14437
+ init_constants();
14438
+ KNOWN_SWARM_PREFIXES = [
14439
+ "paid",
14440
+ "local",
14441
+ "cloud",
14442
+ "enterprise",
14443
+ "mega",
14444
+ "default",
14445
+ "custom",
14446
+ "team",
14447
+ "project",
14448
+ "swarm",
14449
+ "synthetic"
14450
+ ];
14451
+ SEPARATORS = ["_", "-", " "];
14452
+ AgentOverrideConfigSchema = exports_external.object({
14453
+ model: exports_external.string().optional(),
14454
+ temperature: exports_external.number().min(0).max(2).optional(),
14455
+ disabled: exports_external.boolean().optional()
14456
+ });
14457
+ SwarmConfigSchema = exports_external.object({
14458
+ name: exports_external.string().optional(),
14459
+ agents: exports_external.record(exports_external.string(), AgentOverrideConfigSchema).optional()
14460
+ });
14461
+ HooksConfigSchema = exports_external.object({
14462
+ system_enhancer: exports_external.boolean().default(true),
14463
+ compaction: exports_external.boolean().default(true),
14464
+ agent_activity: exports_external.boolean().default(true),
14465
+ delegation_tracker: exports_external.boolean().default(false),
14466
+ agent_awareness_max_chars: exports_external.number().min(50).max(2000).default(300),
14467
+ delegation_gate: exports_external.boolean().default(true),
14468
+ delegation_max_chars: exports_external.number().min(500).max(20000).default(4000)
14469
+ });
14470
+ ScoringWeightsSchema = exports_external.object({
14471
+ phase: exports_external.number().min(0).max(5).default(1),
14472
+ current_task: exports_external.number().min(0).max(5).default(2),
14473
+ blocked_task: exports_external.number().min(0).max(5).default(1.5),
14474
+ recent_failure: exports_external.number().min(0).max(5).default(2.5),
14475
+ recent_success: exports_external.number().min(0).max(5).default(0.5),
14476
+ evidence_presence: exports_external.number().min(0).max(5).default(1),
14477
+ decision_recency: exports_external.number().min(0).max(5).default(1.5),
14478
+ dependency_proximity: exports_external.number().min(0).max(5).default(1)
14479
+ });
14480
+ DecisionDecaySchema = exports_external.object({
14481
+ mode: exports_external.enum(["linear", "exponential"]).default("exponential"),
14482
+ half_life_hours: exports_external.number().min(1).max(168).default(24)
14483
+ });
14484
+ TokenRatiosSchema = exports_external.object({
14485
+ prose: exports_external.number().min(0.1).max(1).default(0.25),
14486
+ code: exports_external.number().min(0.1).max(1).default(0.4),
14487
+ markdown: exports_external.number().min(0.1).max(1).default(0.3),
14488
+ json: exports_external.number().min(0.1).max(1).default(0.35)
14489
+ });
14490
+ ScoringConfigSchema = exports_external.object({
14491
+ enabled: exports_external.boolean().default(false),
14492
+ max_candidates: exports_external.number().min(10).max(500).default(100),
14493
+ weights: ScoringWeightsSchema.optional(),
14494
+ decision_decay: DecisionDecaySchema.optional(),
14495
+ token_ratios: TokenRatiosSchema.optional()
14496
+ });
14497
+ ContextBudgetConfigSchema = exports_external.object({
14498
+ enabled: exports_external.boolean().default(true),
14499
+ warn_threshold: exports_external.number().min(0).max(1).default(0.7),
14500
+ critical_threshold: exports_external.number().min(0).max(1).default(0.9),
14501
+ model_limits: exports_external.record(exports_external.string(), exports_external.number().min(1000)).default({ default: 128000 }),
14502
+ max_injection_tokens: exports_external.number().min(100).max(50000).default(4000),
14503
+ tracked_agents: exports_external.array(exports_external.string()).default(["architect"]),
14504
+ scoring: ScoringConfigSchema.optional(),
14505
+ enforce: exports_external.boolean().default(true),
14506
+ prune_target: exports_external.number().min(0).max(1).default(0.7),
14507
+ preserve_last_n_turns: exports_external.number().min(0).max(100).default(4),
14508
+ recent_window: exports_external.number().min(1).max(100).default(10),
14509
+ enforce_on_agent_switch: exports_external.boolean().default(true),
14510
+ tool_output_mask_threshold: exports_external.number().min(100).max(1e5).default(2000)
14511
+ });
14512
+ EvidenceConfigSchema = exports_external.object({
14513
+ enabled: exports_external.boolean().default(true),
14514
+ max_age_days: exports_external.number().min(1).max(365).default(90),
14515
+ max_bundles: exports_external.number().min(10).max(1e4).default(1000),
14516
+ auto_archive: exports_external.boolean().default(false)
14517
+ });
14518
+ GateFeatureSchema = exports_external.object({
14519
+ enabled: exports_external.boolean().default(true)
14520
+ });
14521
+ PlaceholderScanConfigSchema = GateFeatureSchema.extend({
14522
+ deny_patterns: exports_external.array(exports_external.string()).default([
14523
+ "TODO",
14524
+ "FIXME",
14525
+ "TBD",
14526
+ "XXX",
14527
+ "placeholder",
14528
+ "stub",
14529
+ "wip",
14530
+ "not implemented"
14531
+ ]),
14532
+ allow_globs: exports_external.array(exports_external.string()).default([
14533
+ "docs/**",
14534
+ "examples/**",
14535
+ "tests/**",
14536
+ "**/*.test.*",
14537
+ "**/*.spec.*",
14538
+ "**/mocks/**",
14539
+ "**/__tests__/**"
14540
+ ]),
14541
+ max_allowed_findings: exports_external.number().min(0).default(0)
14542
+ });
14543
+ QualityBudgetConfigSchema = GateFeatureSchema.extend({
14544
+ max_complexity_delta: exports_external.number().default(5),
14545
+ max_public_api_delta: exports_external.number().default(10),
14546
+ max_duplication_ratio: exports_external.number().default(0.05),
14547
+ min_test_to_code_ratio: exports_external.number().default(0.3),
14548
+ enforce_on_globs: exports_external.array(exports_external.string()).default(["src/**"]),
14549
+ exclude_globs: exports_external.array(exports_external.string()).default(["docs/**", "tests/**", "**/*.test.*"])
14550
+ });
14551
+ GateConfigSchema = exports_external.object({
14552
+ syntax_check: GateFeatureSchema.default({ enabled: true }),
14553
+ placeholder_scan: PlaceholderScanConfigSchema.default({
14554
+ enabled: true,
14555
+ deny_patterns: [
14556
+ "TODO",
14557
+ "FIXME",
14558
+ "TBD",
14559
+ "XXX",
14560
+ "placeholder",
14561
+ "stub",
14562
+ "wip",
14563
+ "not implemented"
14564
+ ],
14565
+ allow_globs: [
14566
+ "docs/**",
14567
+ "examples/**",
14568
+ "tests/**",
14569
+ "**/*.test.*",
14570
+ "**/*.spec.*",
14571
+ "**/mocks/**",
14572
+ "**/__tests__/**"
14573
+ ],
14574
+ max_allowed_findings: 0
14575
+ }),
14576
+ sast_scan: GateFeatureSchema.default({ enabled: true }),
14577
+ sbom_generate: GateFeatureSchema.default({ enabled: true }),
14578
+ build_check: GateFeatureSchema.default({ enabled: true }),
14579
+ quality_budget: QualityBudgetConfigSchema
14580
+ });
14581
+ PipelineConfigSchema = exports_external.object({
14582
+ parallel_precheck: exports_external.boolean().default(true)
14583
+ });
14584
+ PhaseCompleteConfigSchema = exports_external.object({
14585
+ enabled: exports_external.boolean().default(true),
14586
+ required_agents: exports_external.array(exports_external.enum(["coder", "reviewer", "test_engineer"])).default(["coder", "reviewer", "test_engineer"]),
14587
+ require_docs: exports_external.boolean().default(true),
14588
+ policy: exports_external.enum(["enforce", "warn"]).default("enforce")
14589
+ });
14590
+ SummaryConfigSchema = exports_external.object({
14591
+ enabled: exports_external.boolean().default(true),
14592
+ threshold_bytes: exports_external.number().min(1024).max(1048576).default(102400),
14593
+ max_summary_chars: exports_external.number().min(100).max(5000).default(1000),
14594
+ max_stored_bytes: exports_external.number().min(10240).max(104857600).default(10485760),
14595
+ retention_days: exports_external.number().min(1).max(365).default(7),
14596
+ exempt_tools: exports_external.array(exports_external.string()).default(["retrieve_summary", "task", "read"])
14597
+ });
14598
+ ReviewPassesConfigSchema = exports_external.object({
14599
+ always_security_review: exports_external.boolean().default(false),
14600
+ security_globs: exports_external.array(exports_external.string()).default([
14601
+ "**/auth/**",
14602
+ "**/api/**",
14603
+ "**/crypto/**",
14604
+ "**/security/**",
14605
+ "**/middleware/**",
14606
+ "**/session/**",
14607
+ "**/token/**"
14608
+ ])
14609
+ });
14610
+ AdversarialDetectionConfigSchema = exports_external.object({
14611
+ enabled: exports_external.boolean().default(true),
14612
+ policy: exports_external.enum(["warn", "gate", "ignore"]).default("warn"),
14613
+ pairs: exports_external.array(exports_external.tuple([exports_external.string(), exports_external.string()])).default([["coder", "reviewer"]])
14614
+ });
14615
+ IntegrationAnalysisConfigSchema = exports_external.object({
14616
+ enabled: exports_external.boolean().default(true)
14617
+ });
14618
+ DocsConfigSchema = exports_external.object({
14619
+ enabled: exports_external.boolean().default(true),
14620
+ doc_patterns: exports_external.array(exports_external.string()).default([
14621
+ "README.md",
14622
+ "CONTRIBUTING.md",
14623
+ "docs/**/*.md",
14624
+ "docs/**/*.rst",
14625
+ "**/CHANGELOG.md"
14626
+ ])
14627
+ });
14628
+ UIReviewConfigSchema = exports_external.object({
14629
+ enabled: exports_external.boolean().default(false),
14630
+ trigger_paths: exports_external.array(exports_external.string()).default([
14631
+ "**/pages/**",
14632
+ "**/components/**",
14633
+ "**/views/**",
14634
+ "**/screens/**",
14635
+ "**/ui/**",
14636
+ "**/layouts/**"
14637
+ ]),
14638
+ trigger_keywords: exports_external.array(exports_external.string()).default([
14639
+ "new page",
14640
+ "new screen",
14641
+ "new component",
14642
+ "redesign",
14643
+ "layout change",
14644
+ "form",
14645
+ "modal",
14646
+ "dialog",
14647
+ "dropdown",
14648
+ "sidebar",
14649
+ "navbar",
14650
+ "dashboard",
14651
+ "landing page",
14652
+ "signup",
14653
+ "login form",
14654
+ "settings page",
14655
+ "profile page"
14656
+ ])
14657
+ });
14658
+ CompactionAdvisoryConfigSchema = exports_external.object({
14659
+ enabled: exports_external.boolean().default(true),
14660
+ thresholds: exports_external.array(exports_external.number().int().min(10).max(500)).default([50, 75, 100, 125, 150]),
14661
+ message: exports_external.string().default("[SWARM HINT] Session has " + "$" + "{totalToolCalls} tool calls. Consider compacting at next phase boundary to maintain context quality.")
14662
+ });
14663
+ LintConfigSchema = exports_external.object({
14664
+ enabled: exports_external.boolean().default(true),
14665
+ mode: exports_external.enum(["check", "fix"]).default("check"),
14666
+ linter: exports_external.enum(["biome", "eslint", "auto"]).default("auto"),
14667
+ patterns: exports_external.array(exports_external.string()).default([
14668
+ "**/*.{ts,tsx,js,jsx,mjs,cjs}",
14669
+ "**/biome.json",
14670
+ "**/biome.jsonc"
14671
+ ]),
14672
+ exclude: exports_external.array(exports_external.string()).default([
14673
+ "**/node_modules/**",
14674
+ "**/dist/**",
14675
+ "**/.git/**",
14676
+ "**/coverage/**",
14677
+ "**/*.min.js"
14678
+ ])
14679
+ });
14680
+ SecretscanConfigSchema = exports_external.object({
14681
+ enabled: exports_external.boolean().default(true),
14682
+ patterns: exports_external.array(exports_external.string()).default([
14683
+ "**/*.{env,properties,yml,yaml,json,js,ts}",
14684
+ "**/.env*",
14685
+ "**/secrets/**",
14686
+ "**/credentials/**",
14687
+ "**/config/**/*.ts",
14688
+ "**/config/**/*.js"
14689
+ ]),
14690
+ exclude: exports_external.array(exports_external.string()).default([
14691
+ "**/node_modules/**",
14692
+ "**/dist/**",
14693
+ "**/.git/**",
14694
+ "**/coverage/**",
14695
+ "**/test/**",
14696
+ "**/tests/**",
14697
+ "**/__tests__/**",
14698
+ "**/*.test.ts",
14699
+ "**/*.test.js",
14700
+ "**/*.spec.ts",
14701
+ "**/*.spec.js"
14702
+ ]),
14703
+ extensions: exports_external.array(exports_external.string()).default([
14704
+ ".env",
14705
+ ".properties",
14706
+ ".yml",
14707
+ ".yaml",
14708
+ ".json",
14709
+ ".js",
14710
+ ".ts",
14711
+ ".py",
14712
+ ".rb",
14713
+ ".go",
14714
+ ".java",
14715
+ ".cs",
14716
+ ".php"
14717
+ ])
14718
+ });
14719
+ GuardrailsProfileSchema = exports_external.object({
14720
+ max_tool_calls: exports_external.number().min(0).max(1000).optional(),
14721
+ max_duration_minutes: exports_external.number().min(0).max(480).optional(),
14722
+ max_repetitions: exports_external.number().min(3).max(50).optional(),
14723
+ max_consecutive_errors: exports_external.number().min(2).max(20).optional(),
14724
+ warning_threshold: exports_external.number().min(0.1).max(0.9).optional(),
14725
+ idle_timeout_minutes: exports_external.number().min(5).max(240).optional()
14726
+ });
14727
+ DEFAULT_AGENT_PROFILES = {
14728
+ architect: {
14729
+ max_tool_calls: 0,
14730
+ max_duration_minutes: 0,
14731
+ max_consecutive_errors: 8,
14732
+ warning_threshold: 0.75
14733
+ },
14734
+ coder: {
14735
+ max_tool_calls: 400,
14736
+ max_duration_minutes: 45,
14737
+ warning_threshold: 0.85
14738
+ },
14739
+ test_engineer: {
14740
+ max_tool_calls: 400,
14741
+ max_duration_minutes: 45,
14742
+ warning_threshold: 0.85
14743
+ },
14744
+ explorer: {
14745
+ max_tool_calls: 150,
14746
+ max_duration_minutes: 20,
14747
+ warning_threshold: 0.75
14748
+ },
14749
+ reviewer: {
14750
+ max_tool_calls: 200,
14751
+ max_duration_minutes: 30,
14752
+ warning_threshold: 0.65
14753
+ },
14754
+ critic: {
14755
+ max_tool_calls: 200,
14756
+ max_duration_minutes: 30,
14757
+ warning_threshold: 0.65
14758
+ },
14759
+ sme: {
14760
+ max_tool_calls: 200,
14761
+ max_duration_minutes: 30,
14762
+ warning_threshold: 0.65
14763
+ },
14764
+ docs: {
14765
+ max_tool_calls: 200,
14766
+ max_duration_minutes: 30,
14767
+ warning_threshold: 0.75
14768
+ },
14769
+ designer: {
14770
+ max_tool_calls: 150,
14771
+ max_duration_minutes: 20,
14772
+ warning_threshold: 0.75
14773
+ }
14774
+ };
14775
+ DEFAULT_ARCHITECT_PROFILE = DEFAULT_AGENT_PROFILES.architect;
14776
+ GuardrailsConfigSchema = exports_external.object({
14777
+ enabled: exports_external.boolean().default(true),
14778
+ max_tool_calls: exports_external.number().min(0).max(1000).default(200),
14779
+ max_duration_minutes: exports_external.number().min(0).max(480).default(30),
14780
+ max_repetitions: exports_external.number().min(3).max(50).default(10),
14781
+ max_consecutive_errors: exports_external.number().min(2).max(20).default(5),
14782
+ warning_threshold: exports_external.number().min(0.1).max(0.9).default(0.75),
14783
+ idle_timeout_minutes: exports_external.number().min(5).max(240).default(60),
14784
+ profiles: exports_external.record(exports_external.string(), GuardrailsProfileSchema).optional()
14785
+ });
14786
+ ToolFilterConfigSchema = exports_external.object({
14787
+ enabled: exports_external.boolean().default(true),
14788
+ overrides: exports_external.record(exports_external.string(), exports_external.array(exports_external.string())).default({})
14789
+ });
14790
+ PlanCursorConfigSchema = exports_external.object({
14791
+ enabled: exports_external.boolean().default(true),
14792
+ max_tokens: exports_external.number().min(500).max(4000).default(1500),
14793
+ lookahead_tasks: exports_external.number().min(0).max(5).default(2)
14794
+ });
14795
+ CheckpointConfigSchema = exports_external.object({
14796
+ enabled: exports_external.boolean().default(true),
14797
+ auto_checkpoint_threshold: exports_external.number().min(1).max(20).default(3)
14798
+ });
14799
+ AutomationModeSchema = exports_external.enum(["manual", "hybrid", "auto"]);
14800
+ AutomationCapabilitiesSchema = exports_external.object({
14801
+ plan_sync: exports_external.boolean().default(true),
14802
+ phase_preflight: exports_external.boolean().default(false),
14803
+ config_doctor_on_startup: exports_external.boolean().default(false),
14804
+ config_doctor_autofix: exports_external.boolean().default(false),
14805
+ evidence_auto_summaries: exports_external.boolean().default(true),
14806
+ decision_drift_detection: exports_external.boolean().default(true)
14807
+ });
14808
+ AutomationConfigSchemaBase = exports_external.object({
14809
+ mode: AutomationModeSchema.default("manual"),
14810
+ capabilities: AutomationCapabilitiesSchema.default({
14811
+ plan_sync: true,
14812
+ phase_preflight: false,
14813
+ config_doctor_on_startup: false,
14814
+ config_doctor_autofix: false,
14815
+ evidence_auto_summaries: true,
14816
+ decision_drift_detection: true
14817
+ })
14818
+ });
14819
+ AutomationConfigSchema = AutomationConfigSchemaBase;
14820
+ KnowledgeConfigSchema = exports_external.object({
14821
+ enabled: exports_external.boolean().default(true),
14822
+ swarm_max_entries: exports_external.number().min(1).max(1e4).default(100),
14823
+ hive_max_entries: exports_external.number().min(1).max(1e5).default(200),
14824
+ auto_promote_days: exports_external.number().min(1).max(3650).default(90),
14825
+ max_inject_count: exports_external.number().min(0).max(50).default(5),
14826
+ dedup_threshold: exports_external.number().min(0).max(1).default(0.6),
14827
+ scope_filter: exports_external.array(exports_external.string()).default(["global"]),
14828
+ hive_enabled: exports_external.boolean().default(true),
14829
+ rejected_max_entries: exports_external.number().min(1).max(1000).default(20),
14830
+ validation_enabled: exports_external.boolean().default(true),
14831
+ evergreen_confidence: exports_external.number().min(0).max(1).default(0.9),
14832
+ evergreen_utility: exports_external.number().min(0).max(1).default(0.8),
14833
+ low_utility_threshold: exports_external.number().min(0).max(1).default(0.3),
14834
+ min_retrievals_for_utility: exports_external.number().min(1).max(100).default(3),
14835
+ schema_version: exports_external.number().int().min(1).default(1)
14836
+ });
14837
+ CuratorConfigSchema = exports_external.object({
14838
+ enabled: exports_external.boolean().default(false),
14839
+ init_enabled: exports_external.boolean().default(true),
14840
+ phase_enabled: exports_external.boolean().default(true),
14841
+ max_summary_tokens: exports_external.number().min(500).max(8000).default(2000),
14842
+ min_knowledge_confidence: exports_external.number().min(0).max(1).default(0.7),
14843
+ compliance_report: exports_external.boolean().default(true),
14844
+ suppress_warnings: exports_external.boolean().default(true),
14845
+ drift_inject_max_chars: exports_external.number().min(100).max(2000).default(500)
14846
+ });
14847
+ PluginConfigSchema = exports_external.object({
14848
+ agents: exports_external.record(exports_external.string(), AgentOverrideConfigSchema).optional(),
14849
+ swarms: exports_external.record(exports_external.string(), SwarmConfigSchema).optional(),
14850
+ max_iterations: exports_external.number().min(1).max(10).default(5),
14851
+ pipeline: PipelineConfigSchema.optional(),
14852
+ phase_complete: PhaseCompleteConfigSchema.optional(),
14853
+ qa_retry_limit: exports_external.number().min(1).max(10).default(3),
14854
+ inject_phase_reminders: exports_external.boolean().default(true),
14855
+ hooks: HooksConfigSchema.optional(),
14856
+ gates: GateConfigSchema.optional(),
14857
+ context_budget: ContextBudgetConfigSchema.optional(),
14858
+ guardrails: GuardrailsConfigSchema.optional(),
14859
+ tool_filter: ToolFilterConfigSchema.optional(),
14860
+ plan_cursor: PlanCursorConfigSchema.optional(),
14861
+ evidence: EvidenceConfigSchema.optional(),
14862
+ summaries: SummaryConfigSchema.optional(),
14863
+ review_passes: ReviewPassesConfigSchema.optional(),
14864
+ adversarial_detection: AdversarialDetectionConfigSchema.optional(),
14865
+ integration_analysis: IntegrationAnalysisConfigSchema.optional(),
14866
+ docs: DocsConfigSchema.optional(),
14867
+ ui_review: UIReviewConfigSchema.optional(),
14868
+ compaction_advisory: CompactionAdvisoryConfigSchema.optional(),
14869
+ lint: LintConfigSchema.optional(),
14870
+ secretscan: SecretscanConfigSchema.optional(),
14871
+ checkpoint: CheckpointConfigSchema.optional(),
14872
+ automation: AutomationConfigSchema.optional(),
14873
+ knowledge: KnowledgeConfigSchema.optional(),
14874
+ curator: CuratorConfigSchema.optional(),
14875
+ tool_output: exports_external.object({
14876
+ truncation_enabled: exports_external.boolean().default(true),
14877
+ max_lines: exports_external.number().min(10).max(500).default(150),
14878
+ per_tool: exports_external.record(exports_external.string(), exports_external.number()).optional()
14879
+ }).optional()
14880
+ });
14881
+ });
14882
+
14883
+ // src/config/loader.ts
14884
+ import * as fs2 from "fs";
14885
+ import * as os from "os";
14886
+ import * as path from "path";
14887
+ function getUserConfigDir() {
14888
+ return process.env.XDG_CONFIG_HOME || path.join(os.homedir(), ".config");
14889
+ }
14890
+ function loadRawConfigFromPath(configPath) {
14891
+ try {
14892
+ const stats = fs2.statSync(configPath);
14893
+ if (stats.size > MAX_CONFIG_FILE_BYTES) {
14894
+ console.warn(`[opencode-swarm] Config file too large (max 100 KB): ${configPath}`);
14895
+ console.warn("[opencode-swarm] \u26A0\uFE0F SECURITY: Config file exceeds size limit. Falling back to safe defaults with guardrails ENABLED.");
14896
+ return { config: null, fileExisted: true, hadError: true };
14897
+ }
14898
+ const content = fs2.readFileSync(configPath, "utf-8");
14899
+ if (content.length > MAX_CONFIG_FILE_BYTES) {
14900
+ console.warn(`[opencode-swarm] Config file too large after read (max 100 KB): ${configPath}`);
14901
+ console.warn("[opencode-swarm] \u26A0\uFE0F SECURITY: Config file exceeds size limit. Falling back to safe defaults with guardrails ENABLED.");
14902
+ return { config: null, fileExisted: true, hadError: true };
14903
+ }
14904
+ let sanitizedContent = content;
14905
+ if (content.charCodeAt(0) === 65279) {
14906
+ sanitizedContent = content.slice(1);
14907
+ }
14908
+ const rawConfig = JSON.parse(sanitizedContent);
14909
+ if (typeof rawConfig !== "object" || rawConfig === null || Array.isArray(rawConfig)) {
14910
+ console.warn(`[opencode-swarm] Invalid config at ${configPath}: expected an object`);
14911
+ console.warn("[opencode-swarm] \u26A0\uFE0F SECURITY: Config format invalid. Falling back to safe defaults with guardrails ENABLED.");
14912
+ return { config: null, fileExisted: true, hadError: true };
14913
+ }
14914
+ return {
14915
+ config: rawConfig,
14916
+ fileExisted: true,
14917
+ hadError: false
14918
+ };
14919
+ } catch (error48) {
14920
+ const isFileNotFoundError = error48 instanceof Error && "code" in error48 && error48.code === "ENOENT";
14921
+ if (!isFileNotFoundError) {
14922
+ const errorMessage = error48 instanceof Error ? error48.message : String(error48);
14923
+ console.warn(`[opencode-swarm] \u26A0\uFE0F CONFIG LOAD FAILURE \u2014 config exists at ${configPath} but could not be loaded: ${errorMessage}`);
14924
+ console.warn("[opencode-swarm] \u26A0\uFE0F SECURITY: Config load failed. Falling back to safe defaults with guardrails ENABLED.");
14925
+ return { config: null, fileExisted: true, hadError: true };
14926
+ }
14927
+ return { config: null, fileExisted: false, hadError: false };
14928
+ }
14929
+ }
14930
+ function migratePresetsConfig(raw) {
14931
+ if (raw.presets && typeof raw.presets === "object" && !raw.agents) {
14932
+ const presetName = raw.preset || "remote";
14933
+ const presets = raw.presets;
14934
+ const activePreset = presets[presetName] || Object.values(presets)[0];
14935
+ if (activePreset && typeof activePreset === "object") {
14936
+ const migrated = { ...raw, agents: activePreset };
14937
+ delete migrated.preset;
14938
+ delete migrated.presets;
14939
+ delete migrated.swarm_mode;
14940
+ console.warn("[opencode-swarm] Migrated v6.12 presets config to agents format. Consider updating your opencode-swarm.json.");
14941
+ return migrated;
14942
+ }
14943
+ }
14944
+ return raw;
14945
+ }
14946
+ function loadPluginConfig(directory) {
14947
+ const userConfigPath = path.join(getUserConfigDir(), "opencode", CONFIG_FILENAME);
14948
+ const projectConfigPath = path.join(directory, ".opencode", CONFIG_FILENAME);
14949
+ const userResult = loadRawConfigFromPath(userConfigPath);
14950
+ const projectResult = loadRawConfigFromPath(projectConfigPath);
14951
+ const rawUserConfig = userResult.config;
14952
+ const rawProjectConfig = projectResult.config;
14953
+ const loadedFromFile = userResult.fileExisted || projectResult.fileExisted;
14954
+ const configHadErrors = userResult.hadError || projectResult.hadError;
14955
+ let mergedRaw = rawUserConfig ?? {};
14956
+ if (rawProjectConfig) {
14957
+ mergedRaw = deepMerge(mergedRaw, rawProjectConfig);
14958
+ }
14959
+ mergedRaw = migratePresetsConfig(mergedRaw);
14960
+ const result = PluginConfigSchema.safeParse(mergedRaw);
14961
+ if (!result.success) {
14962
+ if (rawUserConfig) {
14963
+ const userParseResult = PluginConfigSchema.safeParse(rawUserConfig);
14964
+ if (userParseResult.success) {
14965
+ console.warn("[opencode-swarm] Project config ignored due to validation errors. Using user config.");
14966
+ return userParseResult.data;
14967
+ }
14968
+ }
14969
+ console.warn("[opencode-swarm] Merged config validation failed:");
14970
+ console.warn(result.error.format());
14971
+ console.warn("[opencode-swarm] \u26A0\uFE0F SECURITY: Falling back to conservative defaults with guardrails ENABLED. Fix the config file to restore custom configuration.");
14972
+ return PluginConfigSchema.parse({
14973
+ guardrails: { enabled: true }
14974
+ });
14975
+ }
14976
+ if (loadedFromFile && configHadErrors) {
14977
+ return PluginConfigSchema.parse({
14978
+ ...mergedRaw,
14979
+ guardrails: { enabled: true }
14980
+ });
14981
+ }
14982
+ return result.data;
14983
+ }
14984
+ function loadPluginConfigWithMeta(directory) {
14985
+ const userConfigPath = path.join(getUserConfigDir(), "opencode", CONFIG_FILENAME);
14986
+ const projectConfigPath = path.join(directory, ".opencode", CONFIG_FILENAME);
14987
+ const userResult = loadRawConfigFromPath(userConfigPath);
14988
+ const projectResult = loadRawConfigFromPath(projectConfigPath);
14989
+ const loadedFromFile = userResult.fileExisted || projectResult.fileExisted;
14990
+ const config2 = loadPluginConfig(directory);
14991
+ return { config: config2, loadedFromFile };
14992
+ }
14993
+ function loadAgentPrompt(agentName) {
14994
+ const promptsDir = path.join(getUserConfigDir(), "opencode", PROMPTS_DIR_NAME);
14995
+ const result = {};
14996
+ const promptPath = path.join(promptsDir, `${agentName}.md`);
14997
+ if (fs2.existsSync(promptPath)) {
14998
+ try {
14999
+ result.prompt = fs2.readFileSync(promptPath, "utf-8");
15000
+ } catch (error48) {
15001
+ console.warn(`[opencode-swarm] Error reading prompt file ${promptPath}:`, error48 instanceof Error ? error48.message : String(error48));
15002
+ }
15003
+ }
15004
+ const appendPromptPath = path.join(promptsDir, `${agentName}_append.md`);
15005
+ if (fs2.existsSync(appendPromptPath)) {
15006
+ try {
15007
+ result.appendPrompt = fs2.readFileSync(appendPromptPath, "utf-8");
15008
+ } catch (error48) {
15009
+ console.warn(`[opencode-swarm] Error reading append prompt ${appendPromptPath}:`, error48 instanceof Error ? error48.message : String(error48));
15010
+ }
15011
+ }
15012
+ return result;
15013
+ }
15014
+ var CONFIG_FILENAME = "opencode-swarm.json", PROMPTS_DIR_NAME = "opencode-swarm", MAX_CONFIG_FILE_BYTES = 102400;
15015
+ var init_loader = __esm(() => {
15016
+ init_schema();
15017
+ });
15018
+
14173
15019
  // src/config/plan-schema.ts
14174
15020
  var TaskStatusSchema, TaskSizeSchema, PhaseStatusSchema, MigrationStatusSchema, TaskSchema, PhaseSchema, PlanSchema;
14175
15021
  var init_plan_schema = __esm(() => {
@@ -14221,6 +15067,57 @@ var init_plan_schema = __esm(() => {
14221
15067
  });
14222
15068
  });
14223
15069
 
15070
+ // src/config/index.ts
15071
+ var exports_config = {};
15072
+ __export(exports_config, {
15073
+ loadPluginConfigWithMeta: () => loadPluginConfigWithMeta,
15074
+ loadPluginConfig: () => loadPluginConfig,
15075
+ loadAgentPrompt: () => loadAgentPrompt,
15076
+ isSubagent: () => isSubagent,
15077
+ isQAAgent: () => isQAAgent,
15078
+ TestEvidenceSchema: () => TestEvidenceSchema,
15079
+ TaskStatusSchema: () => TaskStatusSchema,
15080
+ TaskSizeSchema: () => TaskSizeSchema,
15081
+ TaskSchema: () => TaskSchema,
15082
+ SwarmConfigSchema: () => SwarmConfigSchema,
15083
+ ReviewEvidenceSchema: () => ReviewEvidenceSchema,
15084
+ QA_AGENTS: () => QA_AGENTS,
15085
+ PluginConfigSchema: () => PluginConfigSchema,
15086
+ PlanSchema: () => PlanSchema,
15087
+ PipelineConfigSchema: () => PipelineConfigSchema,
15088
+ PhaseStatusSchema: () => PhaseStatusSchema,
15089
+ PhaseSchema: () => PhaseSchema,
15090
+ PhaseCompleteConfigSchema: () => PhaseCompleteConfigSchema,
15091
+ PIPELINE_AGENTS: () => PIPELINE_AGENTS,
15092
+ ORCHESTRATOR_NAME: () => ORCHESTRATOR_NAME,
15093
+ NoteEvidenceSchema: () => NoteEvidenceSchema,
15094
+ MigrationStatusSchema: () => MigrationStatusSchema,
15095
+ EvidenceVerdictSchema: () => EvidenceVerdictSchema,
15096
+ EvidenceTypeSchema: () => EvidenceTypeSchema,
15097
+ EvidenceSchema: () => EvidenceSchema,
15098
+ EvidenceBundleSchema: () => EvidenceBundleSchema,
15099
+ EVIDENCE_MAX_TASK_BYTES: () => EVIDENCE_MAX_TASK_BYTES,
15100
+ EVIDENCE_MAX_PATCH_BYTES: () => EVIDENCE_MAX_PATCH_BYTES,
15101
+ EVIDENCE_MAX_JSON_BYTES: () => EVIDENCE_MAX_JSON_BYTES,
15102
+ DiffEvidenceSchema: () => DiffEvidenceSchema,
15103
+ DEFAULT_MODELS: () => DEFAULT_MODELS,
15104
+ BaseEvidenceSchema: () => BaseEvidenceSchema,
15105
+ AutomationModeSchema: () => AutomationModeSchema,
15106
+ AutomationConfigSchema: () => AutomationConfigSchema,
15107
+ AutomationCapabilitiesSchema: () => AutomationCapabilitiesSchema,
15108
+ ApprovalEvidenceSchema: () => ApprovalEvidenceSchema,
15109
+ AgentOverrideConfigSchema: () => AgentOverrideConfigSchema,
15110
+ ALL_SUBAGENT_NAMES: () => ALL_SUBAGENT_NAMES,
15111
+ ALL_AGENT_NAMES: () => ALL_AGENT_NAMES
15112
+ });
15113
+ var init_config = __esm(() => {
15114
+ init_constants();
15115
+ init_evidence_schema();
15116
+ init_loader();
15117
+ init_plan_schema();
15118
+ init_schema();
15119
+ });
15120
+
14224
15121
  // src/utils/errors.ts
14225
15122
  var SwarmError;
14226
15123
  var init_errors3 = __esm(() => {
@@ -38106,842 +39003,10 @@ var init_runtime = __esm(() => {
38106
39003
  // src/index.ts
38107
39004
  import * as path48 from "path";
38108
39005
 
38109
- // src/tools/tool-names.ts
38110
- var TOOL_NAMES = [
38111
- "diff",
38112
- "syntax_check",
38113
- "placeholder_scan",
38114
- "imports",
38115
- "lint",
38116
- "secretscan",
38117
- "sast_scan",
38118
- "build_check",
38119
- "pre_check_batch",
38120
- "quality_budget",
38121
- "symbols",
38122
- "complexity_hotspots",
38123
- "schema_drift",
38124
- "todo_extract",
38125
- "evidence_check",
38126
- "sbom_generate",
38127
- "checkpoint",
38128
- "pkg_audit",
38129
- "test_runner",
38130
- "detect_domains",
38131
- "gitingest",
38132
- "retrieve_summary",
38133
- "extract_code_blocks",
38134
- "phase_complete",
38135
- "save_plan",
38136
- "update_task_status",
38137
- "write_retro",
38138
- "declare_scope"
38139
- ];
38140
- var TOOL_NAME_SET = new Set(TOOL_NAMES);
38141
-
38142
- // src/config/constants.ts
38143
- var QA_AGENTS = ["reviewer", "critic"];
38144
- var PIPELINE_AGENTS = ["explorer", "coder", "test_engineer"];
38145
- var ORCHESTRATOR_NAME = "architect";
38146
- var ALL_SUBAGENT_NAMES = [
38147
- "sme",
38148
- "docs",
38149
- "designer",
38150
- ...QA_AGENTS,
38151
- ...PIPELINE_AGENTS
38152
- ];
38153
- var ALL_AGENT_NAMES = [
38154
- ORCHESTRATOR_NAME,
38155
- ...ALL_SUBAGENT_NAMES
38156
- ];
38157
- var AGENT_TOOL_MAP = {
38158
- architect: [
38159
- "checkpoint",
38160
- "complexity_hotspots",
38161
- "detect_domains",
38162
- "evidence_check",
38163
- "extract_code_blocks",
38164
- "gitingest",
38165
- "imports",
38166
- "lint",
38167
- "diff",
38168
- "pkg_audit",
38169
- "pre_check_batch",
38170
- "retrieve_summary",
38171
- "save_plan",
38172
- "schema_drift",
38173
- "secretscan",
38174
- "symbols",
38175
- "test_runner",
38176
- "todo_extract",
38177
- "update_task_status",
38178
- "write_retro",
38179
- "declare_scope"
38180
- ],
38181
- explorer: [
38182
- "complexity_hotspots",
38183
- "detect_domains",
38184
- "extract_code_blocks",
38185
- "gitingest",
38186
- "imports",
38187
- "retrieve_summary",
38188
- "schema_drift",
38189
- "symbols",
38190
- "todo_extract"
38191
- ],
38192
- coder: [
38193
- "diff",
38194
- "imports",
38195
- "lint",
38196
- "symbols",
38197
- "extract_code_blocks",
38198
- "retrieve_summary"
38199
- ],
38200
- test_engineer: [
38201
- "test_runner",
38202
- "diff",
38203
- "symbols",
38204
- "extract_code_blocks",
38205
- "retrieve_summary",
38206
- "imports",
38207
- "complexity_hotspots",
38208
- "pkg_audit"
38209
- ],
38210
- sme: [
38211
- "complexity_hotspots",
38212
- "detect_domains",
38213
- "extract_code_blocks",
38214
- "imports",
38215
- "retrieve_summary",
38216
- "schema_drift",
38217
- "symbols"
38218
- ],
38219
- reviewer: [
38220
- "diff",
38221
- "imports",
38222
- "lint",
38223
- "pkg_audit",
38224
- "pre_check_batch",
38225
- "secretscan",
38226
- "symbols",
38227
- "complexity_hotspots",
38228
- "retrieve_summary",
38229
- "extract_code_blocks",
38230
- "test_runner"
38231
- ],
38232
- critic: [
38233
- "complexity_hotspots",
38234
- "detect_domains",
38235
- "imports",
38236
- "retrieve_summary",
38237
- "symbols"
38238
- ],
38239
- docs: [
38240
- "detect_domains",
38241
- "extract_code_blocks",
38242
- "gitingest",
38243
- "imports",
38244
- "retrieve_summary",
38245
- "schema_drift",
38246
- "symbols",
38247
- "todo_extract"
38248
- ],
38249
- designer: ["extract_code_blocks", "retrieve_summary", "symbols"]
38250
- };
38251
- for (const [agentName, tools] of Object.entries(AGENT_TOOL_MAP)) {
38252
- const invalidTools = tools.filter((tool) => !TOOL_NAME_SET.has(tool));
38253
- if (invalidTools.length > 0) {
38254
- throw new Error(`Agent '${agentName}' has invalid tool names: [${invalidTools.join(", ")}]. ` + `All tools must be registered in TOOL_NAME_SET.`);
38255
- }
38256
- }
38257
- var DEFAULT_MODELS = {
38258
- explorer: "opencode/trinity-large-preview-free",
38259
- coder: "opencode/minimax-m2.5-free",
38260
- reviewer: "opencode/big-pickle",
38261
- test_engineer: "opencode/gpt-5-nano",
38262
- sme: "opencode/trinity-large-preview-free",
38263
- critic: "opencode/trinity-large-preview-free",
38264
- docs: "opencode/trinity-large-preview-free",
38265
- designer: "opencode/trinity-large-preview-free",
38266
- default: "opencode/trinity-large-preview-free"
38267
- };
38268
- var DEFAULT_SCORING_CONFIG = {
38269
- enabled: false,
38270
- max_candidates: 100,
38271
- weights: {
38272
- phase: 1,
38273
- current_task: 2,
38274
- blocked_task: 1.5,
38275
- recent_failure: 2.5,
38276
- recent_success: 0.5,
38277
- evidence_presence: 1,
38278
- decision_recency: 1.5,
38279
- dependency_proximity: 1
38280
- },
38281
- decision_decay: {
38282
- mode: "exponential",
38283
- half_life_hours: 24
38284
- },
38285
- token_ratios: {
38286
- prose: 0.25,
38287
- code: 0.4,
38288
- markdown: 0.3,
38289
- json: 0.35
38290
- }
38291
- };
38292
- var LOW_CAPABILITY_MODELS = ["mini", "nano", "small", "free"];
38293
- function isLowCapabilityModel(modelId) {
38294
- if (!modelId)
38295
- return false;
38296
- const lower = modelId.toLowerCase();
38297
- return LOW_CAPABILITY_MODELS.some((substr) => lower.includes(substr));
38298
- }
38299
-
38300
- // src/config/index.ts
38301
- init_evidence_schema();
38302
-
38303
- // src/config/loader.ts
38304
- import * as fs2 from "fs";
38305
- import * as os from "os";
38306
- import * as path from "path";
38307
-
38308
- // src/config/schema.ts
38309
- init_zod();
38310
- var KNOWN_SWARM_PREFIXES = [
38311
- "paid",
38312
- "local",
38313
- "cloud",
38314
- "enterprise",
38315
- "mega",
38316
- "default",
38317
- "custom",
38318
- "team",
38319
- "project",
38320
- "swarm",
38321
- "synthetic"
38322
- ];
38323
- var SEPARATORS = ["_", "-", " "];
38324
- function stripKnownSwarmPrefix(agentName) {
38325
- if (!agentName)
38326
- return agentName;
38327
- const normalized = agentName.toLowerCase();
38328
- let stripped = normalized;
38329
- let previous = "";
38330
- while (stripped !== previous) {
38331
- previous = stripped;
38332
- for (const prefix of KNOWN_SWARM_PREFIXES) {
38333
- for (const sep of SEPARATORS) {
38334
- const prefixWithSep = prefix + sep;
38335
- if (stripped.startsWith(prefixWithSep)) {
38336
- stripped = stripped.slice(prefixWithSep.length);
38337
- break;
38338
- }
38339
- }
38340
- if (stripped !== previous)
38341
- break;
38342
- }
38343
- }
38344
- if (ALL_AGENT_NAMES.includes(stripped)) {
38345
- return stripped;
38346
- }
38347
- for (const agent of ALL_AGENT_NAMES) {
38348
- for (const sep of SEPARATORS) {
38349
- const suffix = sep + agent;
38350
- if (normalized.endsWith(suffix)) {
38351
- return agent;
38352
- }
38353
- }
38354
- if (normalized === agent) {
38355
- return agent;
38356
- }
38357
- }
38358
- return agentName;
38359
- }
38360
- var AgentOverrideConfigSchema = exports_external.object({
38361
- model: exports_external.string().optional(),
38362
- temperature: exports_external.number().min(0).max(2).optional(),
38363
- disabled: exports_external.boolean().optional()
38364
- });
38365
- var SwarmConfigSchema = exports_external.object({
38366
- name: exports_external.string().optional(),
38367
- agents: exports_external.record(exports_external.string(), AgentOverrideConfigSchema).optional()
38368
- });
38369
- var HooksConfigSchema = exports_external.object({
38370
- system_enhancer: exports_external.boolean().default(true),
38371
- compaction: exports_external.boolean().default(true),
38372
- agent_activity: exports_external.boolean().default(true),
38373
- delegation_tracker: exports_external.boolean().default(false),
38374
- agent_awareness_max_chars: exports_external.number().min(50).max(2000).default(300),
38375
- delegation_gate: exports_external.boolean().default(true),
38376
- delegation_max_chars: exports_external.number().min(500).max(20000).default(4000)
38377
- });
38378
- var ScoringWeightsSchema = exports_external.object({
38379
- phase: exports_external.number().min(0).max(5).default(1),
38380
- current_task: exports_external.number().min(0).max(5).default(2),
38381
- blocked_task: exports_external.number().min(0).max(5).default(1.5),
38382
- recent_failure: exports_external.number().min(0).max(5).default(2.5),
38383
- recent_success: exports_external.number().min(0).max(5).default(0.5),
38384
- evidence_presence: exports_external.number().min(0).max(5).default(1),
38385
- decision_recency: exports_external.number().min(0).max(5).default(1.5),
38386
- dependency_proximity: exports_external.number().min(0).max(5).default(1)
38387
- });
38388
- var DecisionDecaySchema = exports_external.object({
38389
- mode: exports_external.enum(["linear", "exponential"]).default("exponential"),
38390
- half_life_hours: exports_external.number().min(1).max(168).default(24)
38391
- });
38392
- var TokenRatiosSchema = exports_external.object({
38393
- prose: exports_external.number().min(0.1).max(1).default(0.25),
38394
- code: exports_external.number().min(0.1).max(1).default(0.4),
38395
- markdown: exports_external.number().min(0.1).max(1).default(0.3),
38396
- json: exports_external.number().min(0.1).max(1).default(0.35)
38397
- });
38398
- var ScoringConfigSchema = exports_external.object({
38399
- enabled: exports_external.boolean().default(false),
38400
- max_candidates: exports_external.number().min(10).max(500).default(100),
38401
- weights: ScoringWeightsSchema.optional(),
38402
- decision_decay: DecisionDecaySchema.optional(),
38403
- token_ratios: TokenRatiosSchema.optional()
38404
- });
38405
- var ContextBudgetConfigSchema = exports_external.object({
38406
- enabled: exports_external.boolean().default(true),
38407
- warn_threshold: exports_external.number().min(0).max(1).default(0.7),
38408
- critical_threshold: exports_external.number().min(0).max(1).default(0.9),
38409
- model_limits: exports_external.record(exports_external.string(), exports_external.number().min(1000)).default({ default: 128000 }),
38410
- max_injection_tokens: exports_external.number().min(100).max(50000).default(4000),
38411
- tracked_agents: exports_external.array(exports_external.string()).default(["architect"]),
38412
- scoring: ScoringConfigSchema.optional(),
38413
- enforce: exports_external.boolean().default(true),
38414
- prune_target: exports_external.number().min(0).max(1).default(0.7),
38415
- preserve_last_n_turns: exports_external.number().min(0).max(100).default(4),
38416
- recent_window: exports_external.number().min(1).max(100).default(10),
38417
- enforce_on_agent_switch: exports_external.boolean().default(true),
38418
- tool_output_mask_threshold: exports_external.number().min(100).max(1e5).default(2000)
38419
- });
38420
- var EvidenceConfigSchema = exports_external.object({
38421
- enabled: exports_external.boolean().default(true),
38422
- max_age_days: exports_external.number().min(1).max(365).default(90),
38423
- max_bundles: exports_external.number().min(10).max(1e4).default(1000),
38424
- auto_archive: exports_external.boolean().default(false)
38425
- });
38426
- var GateFeatureSchema = exports_external.object({
38427
- enabled: exports_external.boolean().default(true)
38428
- });
38429
- var PlaceholderScanConfigSchema = GateFeatureSchema.extend({
38430
- deny_patterns: exports_external.array(exports_external.string()).default([
38431
- "TODO",
38432
- "FIXME",
38433
- "TBD",
38434
- "XXX",
38435
- "placeholder",
38436
- "stub",
38437
- "wip",
38438
- "not implemented"
38439
- ]),
38440
- allow_globs: exports_external.array(exports_external.string()).default([
38441
- "docs/**",
38442
- "examples/**",
38443
- "tests/**",
38444
- "**/*.test.*",
38445
- "**/*.spec.*",
38446
- "**/mocks/**",
38447
- "**/__tests__/**"
38448
- ]),
38449
- max_allowed_findings: exports_external.number().min(0).default(0)
38450
- });
38451
- var QualityBudgetConfigSchema = GateFeatureSchema.extend({
38452
- max_complexity_delta: exports_external.number().default(5),
38453
- max_public_api_delta: exports_external.number().default(10),
38454
- max_duplication_ratio: exports_external.number().default(0.05),
38455
- min_test_to_code_ratio: exports_external.number().default(0.3),
38456
- enforce_on_globs: exports_external.array(exports_external.string()).default(["src/**"]),
38457
- exclude_globs: exports_external.array(exports_external.string()).default(["docs/**", "tests/**", "**/*.test.*"])
38458
- });
38459
- var GateConfigSchema = exports_external.object({
38460
- syntax_check: GateFeatureSchema.default({ enabled: true }),
38461
- placeholder_scan: PlaceholderScanConfigSchema.default({
38462
- enabled: true,
38463
- deny_patterns: [
38464
- "TODO",
38465
- "FIXME",
38466
- "TBD",
38467
- "XXX",
38468
- "placeholder",
38469
- "stub",
38470
- "wip",
38471
- "not implemented"
38472
- ],
38473
- allow_globs: [
38474
- "docs/**",
38475
- "examples/**",
38476
- "tests/**",
38477
- "**/*.test.*",
38478
- "**/*.spec.*",
38479
- "**/mocks/**",
38480
- "**/__tests__/**"
38481
- ],
38482
- max_allowed_findings: 0
38483
- }),
38484
- sast_scan: GateFeatureSchema.default({ enabled: true }),
38485
- sbom_generate: GateFeatureSchema.default({ enabled: true }),
38486
- build_check: GateFeatureSchema.default({ enabled: true }),
38487
- quality_budget: QualityBudgetConfigSchema
38488
- });
38489
- var PipelineConfigSchema = exports_external.object({
38490
- parallel_precheck: exports_external.boolean().default(true)
38491
- });
38492
- var PhaseCompleteConfigSchema = exports_external.object({
38493
- enabled: exports_external.boolean().default(true),
38494
- required_agents: exports_external.array(exports_external.enum(["coder", "reviewer", "test_engineer"])).default(["coder", "reviewer", "test_engineer"]),
38495
- require_docs: exports_external.boolean().default(true),
38496
- policy: exports_external.enum(["enforce", "warn"]).default("enforce")
38497
- });
38498
- var SummaryConfigSchema = exports_external.object({
38499
- enabled: exports_external.boolean().default(true),
38500
- threshold_bytes: exports_external.number().min(1024).max(1048576).default(102400),
38501
- max_summary_chars: exports_external.number().min(100).max(5000).default(1000),
38502
- max_stored_bytes: exports_external.number().min(10240).max(104857600).default(10485760),
38503
- retention_days: exports_external.number().min(1).max(365).default(7),
38504
- exempt_tools: exports_external.array(exports_external.string()).default(["retrieve_summary", "task", "read"])
38505
- });
38506
- var ReviewPassesConfigSchema = exports_external.object({
38507
- always_security_review: exports_external.boolean().default(false),
38508
- security_globs: exports_external.array(exports_external.string()).default([
38509
- "**/auth/**",
38510
- "**/api/**",
38511
- "**/crypto/**",
38512
- "**/security/**",
38513
- "**/middleware/**",
38514
- "**/session/**",
38515
- "**/token/**"
38516
- ])
38517
- });
38518
- var AdversarialDetectionConfigSchema = exports_external.object({
38519
- enabled: exports_external.boolean().default(true),
38520
- policy: exports_external.enum(["warn", "gate", "ignore"]).default("warn"),
38521
- pairs: exports_external.array(exports_external.tuple([exports_external.string(), exports_external.string()])).default([["coder", "reviewer"]])
38522
- });
38523
- var IntegrationAnalysisConfigSchema = exports_external.object({
38524
- enabled: exports_external.boolean().default(true)
38525
- });
38526
- var DocsConfigSchema = exports_external.object({
38527
- enabled: exports_external.boolean().default(true),
38528
- doc_patterns: exports_external.array(exports_external.string()).default([
38529
- "README.md",
38530
- "CONTRIBUTING.md",
38531
- "docs/**/*.md",
38532
- "docs/**/*.rst",
38533
- "**/CHANGELOG.md"
38534
- ])
38535
- });
38536
- var UIReviewConfigSchema = exports_external.object({
38537
- enabled: exports_external.boolean().default(false),
38538
- trigger_paths: exports_external.array(exports_external.string()).default([
38539
- "**/pages/**",
38540
- "**/components/**",
38541
- "**/views/**",
38542
- "**/screens/**",
38543
- "**/ui/**",
38544
- "**/layouts/**"
38545
- ]),
38546
- trigger_keywords: exports_external.array(exports_external.string()).default([
38547
- "new page",
38548
- "new screen",
38549
- "new component",
38550
- "redesign",
38551
- "layout change",
38552
- "form",
38553
- "modal",
38554
- "dialog",
38555
- "dropdown",
38556
- "sidebar",
38557
- "navbar",
38558
- "dashboard",
38559
- "landing page",
38560
- "signup",
38561
- "login form",
38562
- "settings page",
38563
- "profile page"
38564
- ])
38565
- });
38566
- var CompactionAdvisoryConfigSchema = exports_external.object({
38567
- enabled: exports_external.boolean().default(true),
38568
- thresholds: exports_external.array(exports_external.number().int().min(10).max(500)).default([50, 75, 100, 125, 150]),
38569
- message: exports_external.string().default("[SWARM HINT] Session has " + "$" + "{totalToolCalls} tool calls. Consider compacting at next phase boundary to maintain context quality.")
38570
- });
38571
- var LintConfigSchema = exports_external.object({
38572
- enabled: exports_external.boolean().default(true),
38573
- mode: exports_external.enum(["check", "fix"]).default("check"),
38574
- linter: exports_external.enum(["biome", "eslint", "auto"]).default("auto"),
38575
- patterns: exports_external.array(exports_external.string()).default([
38576
- "**/*.{ts,tsx,js,jsx,mjs,cjs}",
38577
- "**/biome.json",
38578
- "**/biome.jsonc"
38579
- ]),
38580
- exclude: exports_external.array(exports_external.string()).default([
38581
- "**/node_modules/**",
38582
- "**/dist/**",
38583
- "**/.git/**",
38584
- "**/coverage/**",
38585
- "**/*.min.js"
38586
- ])
38587
- });
38588
- var SecretscanConfigSchema = exports_external.object({
38589
- enabled: exports_external.boolean().default(true),
38590
- patterns: exports_external.array(exports_external.string()).default([
38591
- "**/*.{env,properties,yml,yaml,json,js,ts}",
38592
- "**/.env*",
38593
- "**/secrets/**",
38594
- "**/credentials/**",
38595
- "**/config/**/*.ts",
38596
- "**/config/**/*.js"
38597
- ]),
38598
- exclude: exports_external.array(exports_external.string()).default([
38599
- "**/node_modules/**",
38600
- "**/dist/**",
38601
- "**/.git/**",
38602
- "**/coverage/**",
38603
- "**/test/**",
38604
- "**/tests/**",
38605
- "**/__tests__/**",
38606
- "**/*.test.ts",
38607
- "**/*.test.js",
38608
- "**/*.spec.ts",
38609
- "**/*.spec.js"
38610
- ]),
38611
- extensions: exports_external.array(exports_external.string()).default([
38612
- ".env",
38613
- ".properties",
38614
- ".yml",
38615
- ".yaml",
38616
- ".json",
38617
- ".js",
38618
- ".ts",
38619
- ".py",
38620
- ".rb",
38621
- ".go",
38622
- ".java",
38623
- ".cs",
38624
- ".php"
38625
- ])
38626
- });
38627
- var GuardrailsProfileSchema = exports_external.object({
38628
- max_tool_calls: exports_external.number().min(0).max(1000).optional(),
38629
- max_duration_minutes: exports_external.number().min(0).max(480).optional(),
38630
- max_repetitions: exports_external.number().min(3).max(50).optional(),
38631
- max_consecutive_errors: exports_external.number().min(2).max(20).optional(),
38632
- warning_threshold: exports_external.number().min(0.1).max(0.9).optional(),
38633
- idle_timeout_minutes: exports_external.number().min(5).max(240).optional()
38634
- });
38635
- var DEFAULT_AGENT_PROFILES = {
38636
- architect: {
38637
- max_tool_calls: 0,
38638
- max_duration_minutes: 0,
38639
- max_consecutive_errors: 8,
38640
- warning_threshold: 0.75
38641
- },
38642
- coder: {
38643
- max_tool_calls: 400,
38644
- max_duration_minutes: 45,
38645
- warning_threshold: 0.85
38646
- },
38647
- test_engineer: {
38648
- max_tool_calls: 400,
38649
- max_duration_minutes: 45,
38650
- warning_threshold: 0.85
38651
- },
38652
- explorer: {
38653
- max_tool_calls: 150,
38654
- max_duration_minutes: 20,
38655
- warning_threshold: 0.75
38656
- },
38657
- reviewer: {
38658
- max_tool_calls: 200,
38659
- max_duration_minutes: 30,
38660
- warning_threshold: 0.65
38661
- },
38662
- critic: {
38663
- max_tool_calls: 200,
38664
- max_duration_minutes: 30,
38665
- warning_threshold: 0.65
38666
- },
38667
- sme: {
38668
- max_tool_calls: 200,
38669
- max_duration_minutes: 30,
38670
- warning_threshold: 0.65
38671
- },
38672
- docs: {
38673
- max_tool_calls: 200,
38674
- max_duration_minutes: 30,
38675
- warning_threshold: 0.75
38676
- },
38677
- designer: {
38678
- max_tool_calls: 150,
38679
- max_duration_minutes: 20,
38680
- warning_threshold: 0.75
38681
- }
38682
- };
38683
- var DEFAULT_ARCHITECT_PROFILE = DEFAULT_AGENT_PROFILES.architect;
38684
- var GuardrailsConfigSchema = exports_external.object({
38685
- enabled: exports_external.boolean().default(true),
38686
- max_tool_calls: exports_external.number().min(0).max(1000).default(200),
38687
- max_duration_minutes: exports_external.number().min(0).max(480).default(30),
38688
- max_repetitions: exports_external.number().min(3).max(50).default(10),
38689
- max_consecutive_errors: exports_external.number().min(2).max(20).default(5),
38690
- warning_threshold: exports_external.number().min(0.1).max(0.9).default(0.75),
38691
- idle_timeout_minutes: exports_external.number().min(5).max(240).default(60),
38692
- profiles: exports_external.record(exports_external.string(), GuardrailsProfileSchema).optional()
38693
- });
38694
- function resolveGuardrailsConfig(config2, agentName) {
38695
- if (!agentName) {
38696
- return config2;
38697
- }
38698
- const canonicalName = stripKnownSwarmPrefix(agentName);
38699
- const hasBuiltInProfile = canonicalName in DEFAULT_AGENT_PROFILES;
38700
- const userProfile = config2.profiles?.[agentName] ?? config2.profiles?.[canonicalName];
38701
- if (!hasBuiltInProfile) {
38702
- if (userProfile) {
38703
- return { ...config2, ...userProfile };
38704
- }
38705
- return config2;
38706
- }
38707
- const builtInProfile = DEFAULT_AGENT_PROFILES[canonicalName];
38708
- const resolved = {
38709
- ...config2,
38710
- ...builtInProfile,
38711
- ...userProfile || {}
38712
- };
38713
- return resolved;
38714
- }
38715
- var ToolFilterConfigSchema = exports_external.object({
38716
- enabled: exports_external.boolean().default(true),
38717
- overrides: exports_external.record(exports_external.string(), exports_external.array(exports_external.string())).default({})
38718
- });
38719
- var PlanCursorConfigSchema = exports_external.object({
38720
- enabled: exports_external.boolean().default(true),
38721
- max_tokens: exports_external.number().min(500).max(4000).default(1500),
38722
- lookahead_tasks: exports_external.number().min(0).max(5).default(2)
38723
- });
38724
- var CheckpointConfigSchema = exports_external.object({
38725
- enabled: exports_external.boolean().default(true),
38726
- auto_checkpoint_threshold: exports_external.number().min(1).max(20).default(3)
38727
- });
38728
- var AutomationModeSchema = exports_external.enum(["manual", "hybrid", "auto"]);
38729
- var AutomationCapabilitiesSchema = exports_external.object({
38730
- plan_sync: exports_external.boolean().default(true),
38731
- phase_preflight: exports_external.boolean().default(false),
38732
- config_doctor_on_startup: exports_external.boolean().default(false),
38733
- config_doctor_autofix: exports_external.boolean().default(false),
38734
- evidence_auto_summaries: exports_external.boolean().default(true),
38735
- decision_drift_detection: exports_external.boolean().default(true)
38736
- });
38737
- var AutomationConfigSchemaBase = exports_external.object({
38738
- mode: AutomationModeSchema.default("manual"),
38739
- capabilities: AutomationCapabilitiesSchema.default({
38740
- plan_sync: true,
38741
- phase_preflight: false,
38742
- config_doctor_on_startup: false,
38743
- config_doctor_autofix: false,
38744
- evidence_auto_summaries: true,
38745
- decision_drift_detection: true
38746
- })
38747
- });
38748
- var AutomationConfigSchema = AutomationConfigSchemaBase;
38749
- var KnowledgeConfigSchema = exports_external.object({
38750
- enabled: exports_external.boolean().default(true),
38751
- swarm_max_entries: exports_external.number().min(1).max(1e4).default(100),
38752
- hive_max_entries: exports_external.number().min(1).max(1e5).default(200),
38753
- auto_promote_days: exports_external.number().min(1).max(3650).default(90),
38754
- max_inject_count: exports_external.number().min(0).max(50).default(5),
38755
- dedup_threshold: exports_external.number().min(0).max(1).default(0.6),
38756
- scope_filter: exports_external.array(exports_external.string()).default(["global"]),
38757
- hive_enabled: exports_external.boolean().default(true),
38758
- rejected_max_entries: exports_external.number().min(1).max(1000).default(20),
38759
- validation_enabled: exports_external.boolean().default(true),
38760
- evergreen_confidence: exports_external.number().min(0).max(1).default(0.9),
38761
- evergreen_utility: exports_external.number().min(0).max(1).default(0.8),
38762
- low_utility_threshold: exports_external.number().min(0).max(1).default(0.3),
38763
- min_retrievals_for_utility: exports_external.number().min(1).max(100).default(3),
38764
- schema_version: exports_external.number().int().min(1).default(1)
38765
- });
38766
- var CuratorConfigSchema = exports_external.object({
38767
- enabled: exports_external.boolean().default(false),
38768
- init_enabled: exports_external.boolean().default(true),
38769
- phase_enabled: exports_external.boolean().default(true),
38770
- max_summary_tokens: exports_external.number().min(500).max(8000).default(2000),
38771
- min_knowledge_confidence: exports_external.number().min(0).max(1).default(0.7),
38772
- compliance_report: exports_external.boolean().default(true),
38773
- suppress_warnings: exports_external.boolean().default(true),
38774
- drift_inject_max_chars: exports_external.number().min(100).max(2000).default(500)
38775
- });
38776
- var PluginConfigSchema = exports_external.object({
38777
- agents: exports_external.record(exports_external.string(), AgentOverrideConfigSchema).optional(),
38778
- swarms: exports_external.record(exports_external.string(), SwarmConfigSchema).optional(),
38779
- max_iterations: exports_external.number().min(1).max(10).default(5),
38780
- pipeline: PipelineConfigSchema.optional(),
38781
- phase_complete: PhaseCompleteConfigSchema.optional(),
38782
- qa_retry_limit: exports_external.number().min(1).max(10).default(3),
38783
- inject_phase_reminders: exports_external.boolean().default(true),
38784
- hooks: HooksConfigSchema.optional(),
38785
- gates: GateConfigSchema.optional(),
38786
- context_budget: ContextBudgetConfigSchema.optional(),
38787
- guardrails: GuardrailsConfigSchema.optional(),
38788
- tool_filter: ToolFilterConfigSchema.optional(),
38789
- plan_cursor: PlanCursorConfigSchema.optional(),
38790
- evidence: EvidenceConfigSchema.optional(),
38791
- summaries: SummaryConfigSchema.optional(),
38792
- review_passes: ReviewPassesConfigSchema.optional(),
38793
- adversarial_detection: AdversarialDetectionConfigSchema.optional(),
38794
- integration_analysis: IntegrationAnalysisConfigSchema.optional(),
38795
- docs: DocsConfigSchema.optional(),
38796
- ui_review: UIReviewConfigSchema.optional(),
38797
- compaction_advisory: CompactionAdvisoryConfigSchema.optional(),
38798
- lint: LintConfigSchema.optional(),
38799
- secretscan: SecretscanConfigSchema.optional(),
38800
- checkpoint: CheckpointConfigSchema.optional(),
38801
- automation: AutomationConfigSchema.optional(),
38802
- knowledge: KnowledgeConfigSchema.optional(),
38803
- curator: CuratorConfigSchema.optional(),
38804
- tool_output: exports_external.object({
38805
- truncation_enabled: exports_external.boolean().default(true),
38806
- max_lines: exports_external.number().min(10).max(500).default(150),
38807
- per_tool: exports_external.record(exports_external.string(), exports_external.number()).optional()
38808
- }).optional()
38809
- });
38810
-
38811
- // src/config/loader.ts
38812
- var CONFIG_FILENAME = "opencode-swarm.json";
38813
- var PROMPTS_DIR_NAME = "opencode-swarm";
38814
- var MAX_CONFIG_FILE_BYTES = 102400;
38815
- function getUserConfigDir() {
38816
- return process.env.XDG_CONFIG_HOME || path.join(os.homedir(), ".config");
38817
- }
38818
- function loadRawConfigFromPath(configPath) {
38819
- try {
38820
- const stats = fs2.statSync(configPath);
38821
- if (stats.size > MAX_CONFIG_FILE_BYTES) {
38822
- console.warn(`[opencode-swarm] Config file too large (max 100 KB): ${configPath}`);
38823
- console.warn("[opencode-swarm] \u26A0\uFE0F SECURITY: Config file exceeds size limit. Falling back to safe defaults with guardrails ENABLED.");
38824
- return { config: null, fileExisted: true, hadError: true };
38825
- }
38826
- const content = fs2.readFileSync(configPath, "utf-8");
38827
- if (content.length > MAX_CONFIG_FILE_BYTES) {
38828
- console.warn(`[opencode-swarm] Config file too large after read (max 100 KB): ${configPath}`);
38829
- console.warn("[opencode-swarm] \u26A0\uFE0F SECURITY: Config file exceeds size limit. Falling back to safe defaults with guardrails ENABLED.");
38830
- return { config: null, fileExisted: true, hadError: true };
38831
- }
38832
- let sanitizedContent = content;
38833
- if (content.charCodeAt(0) === 65279) {
38834
- sanitizedContent = content.slice(1);
38835
- }
38836
- const rawConfig = JSON.parse(sanitizedContent);
38837
- if (typeof rawConfig !== "object" || rawConfig === null || Array.isArray(rawConfig)) {
38838
- console.warn(`[opencode-swarm] Invalid config at ${configPath}: expected an object`);
38839
- console.warn("[opencode-swarm] \u26A0\uFE0F SECURITY: Config format invalid. Falling back to safe defaults with guardrails ENABLED.");
38840
- return { config: null, fileExisted: true, hadError: true };
38841
- }
38842
- return {
38843
- config: rawConfig,
38844
- fileExisted: true,
38845
- hadError: false
38846
- };
38847
- } catch (error48) {
38848
- const isFileNotFoundError = error48 instanceof Error && "code" in error48 && error48.code === "ENOENT";
38849
- if (!isFileNotFoundError) {
38850
- const errorMessage = error48 instanceof Error ? error48.message : String(error48);
38851
- console.warn(`[opencode-swarm] \u26A0\uFE0F CONFIG LOAD FAILURE \u2014 config exists at ${configPath} but could not be loaded: ${errorMessage}`);
38852
- console.warn("[opencode-swarm] \u26A0\uFE0F SECURITY: Config load failed. Falling back to safe defaults with guardrails ENABLED.");
38853
- return { config: null, fileExisted: true, hadError: true };
38854
- }
38855
- return { config: null, fileExisted: false, hadError: false };
38856
- }
38857
- }
38858
- function migratePresetsConfig(raw) {
38859
- if (raw.presets && typeof raw.presets === "object" && !raw.agents) {
38860
- const presetName = raw.preset || "remote";
38861
- const presets = raw.presets;
38862
- const activePreset = presets[presetName] || Object.values(presets)[0];
38863
- if (activePreset && typeof activePreset === "object") {
38864
- const migrated = { ...raw, agents: activePreset };
38865
- delete migrated.preset;
38866
- delete migrated.presets;
38867
- delete migrated.swarm_mode;
38868
- console.warn("[opencode-swarm] Migrated v6.12 presets config to agents format. Consider updating your opencode-swarm.json.");
38869
- return migrated;
38870
- }
38871
- }
38872
- return raw;
38873
- }
38874
- function loadPluginConfig(directory) {
38875
- const userConfigPath = path.join(getUserConfigDir(), "opencode", CONFIG_FILENAME);
38876
- const projectConfigPath = path.join(directory, ".opencode", CONFIG_FILENAME);
38877
- const userResult = loadRawConfigFromPath(userConfigPath);
38878
- const projectResult = loadRawConfigFromPath(projectConfigPath);
38879
- const rawUserConfig = userResult.config;
38880
- const rawProjectConfig = projectResult.config;
38881
- const loadedFromFile = userResult.fileExisted || projectResult.fileExisted;
38882
- const configHadErrors = userResult.hadError || projectResult.hadError;
38883
- let mergedRaw = rawUserConfig ?? {};
38884
- if (rawProjectConfig) {
38885
- mergedRaw = deepMerge(mergedRaw, rawProjectConfig);
38886
- }
38887
- mergedRaw = migratePresetsConfig(mergedRaw);
38888
- const result = PluginConfigSchema.safeParse(mergedRaw);
38889
- if (!result.success) {
38890
- if (rawUserConfig) {
38891
- const userParseResult = PluginConfigSchema.safeParse(rawUserConfig);
38892
- if (userParseResult.success) {
38893
- console.warn("[opencode-swarm] Project config ignored due to validation errors. Using user config.");
38894
- return userParseResult.data;
38895
- }
38896
- }
38897
- console.warn("[opencode-swarm] Merged config validation failed:");
38898
- console.warn(result.error.format());
38899
- console.warn("[opencode-swarm] \u26A0\uFE0F SECURITY: Falling back to conservative defaults with guardrails ENABLED. Fix the config file to restore custom configuration.");
38900
- return PluginConfigSchema.parse({
38901
- guardrails: { enabled: true }
38902
- });
38903
- }
38904
- if (loadedFromFile && configHadErrors) {
38905
- return PluginConfigSchema.parse({
38906
- ...mergedRaw,
38907
- guardrails: { enabled: true }
38908
- });
38909
- }
38910
- return result.data;
38911
- }
38912
- function loadPluginConfigWithMeta(directory) {
38913
- const userConfigPath = path.join(getUserConfigDir(), "opencode", CONFIG_FILENAME);
38914
- const projectConfigPath = path.join(directory, ".opencode", CONFIG_FILENAME);
38915
- const userResult = loadRawConfigFromPath(userConfigPath);
38916
- const projectResult = loadRawConfigFromPath(projectConfigPath);
38917
- const loadedFromFile = userResult.fileExisted || projectResult.fileExisted;
38918
- const config2 = loadPluginConfig(directory);
38919
- return { config: config2, loadedFromFile };
38920
- }
38921
- function loadAgentPrompt(agentName) {
38922
- const promptsDir = path.join(getUserConfigDir(), "opencode", PROMPTS_DIR_NAME);
38923
- const result = {};
38924
- const promptPath = path.join(promptsDir, `${agentName}.md`);
38925
- if (fs2.existsSync(promptPath)) {
38926
- try {
38927
- result.prompt = fs2.readFileSync(promptPath, "utf-8");
38928
- } catch (error48) {
38929
- console.warn(`[opencode-swarm] Error reading prompt file ${promptPath}:`, error48 instanceof Error ? error48.message : String(error48));
38930
- }
38931
- }
38932
- const appendPromptPath = path.join(promptsDir, `${agentName}_append.md`);
38933
- if (fs2.existsSync(appendPromptPath)) {
38934
- try {
38935
- result.appendPrompt = fs2.readFileSync(appendPromptPath, "utf-8");
38936
- } catch (error48) {
38937
- console.warn(`[opencode-swarm] Error reading append prompt ${appendPromptPath}:`, error48 instanceof Error ? error48.message : String(error48));
38938
- }
38939
- }
38940
- return result;
38941
- }
38942
-
38943
- // src/config/index.ts
38944
- init_plan_schema();
39006
+ // src/agents/index.ts
39007
+ init_config();
39008
+ init_constants();
39009
+ init_schema();
38945
39010
 
38946
39011
  // src/agents/architect.ts
38947
39012
  var ARCHITECT_PROMPT = `You are Architect - orchestrator of a multi-agent swarm.
@@ -41825,6 +41890,7 @@ async function handleAnalyzeCommand(_directory, args2) {
41825
41890
  }
41826
41891
 
41827
41892
  // src/commands/archive.ts
41893
+ init_loader();
41828
41894
  init_manager();
41829
41895
  async function handleArchiveCommand(directory, args2) {
41830
41896
  const config2 = loadPluginConfig(directory);
@@ -41899,6 +41965,8 @@ async function handleArchiveCommand(directory, args2) {
41899
41965
  init_manager();
41900
41966
 
41901
41967
  // src/state.ts
41968
+ init_constants();
41969
+ init_schema();
41902
41970
  var swarmState = {
41903
41971
  activeToolCalls: new Map,
41904
41972
  toolAggregates: new Map,
@@ -41939,6 +42007,7 @@ function startAgentSession(sessionId, agentName, staleDurationMs = 7200000) {
41939
42007
  lastPhaseCompleteTimestamp: 0,
41940
42008
  lastPhaseCompletePhase: 0,
41941
42009
  phaseAgentsDispatched: new Set,
42010
+ lastCompletedPhaseAgentsDispatched: new Set,
41942
42011
  qaSkipCount: 0,
41943
42012
  qaSkipTaskIds: [],
41944
42013
  taskWorkflowStates: new Map,
@@ -42009,6 +42078,9 @@ function ensureAgentSession(sessionId, agentName) {
42009
42078
  if (!session.phaseAgentsDispatched) {
42010
42079
  session.phaseAgentsDispatched = new Set;
42011
42080
  }
42081
+ if (!session.lastCompletedPhaseAgentsDispatched) {
42082
+ session.lastCompletedPhaseAgentsDispatched = new Set;
42083
+ }
42012
42084
  if (session.qaSkipCount === undefined) {
42013
42085
  session.qaSkipCount = 0;
42014
42086
  }
@@ -42471,6 +42543,7 @@ async function handleClarifyCommand(_directory, args2) {
42471
42543
  }
42472
42544
 
42473
42545
  // src/commands/config.ts
42546
+ init_loader();
42474
42547
  import * as os2 from "os";
42475
42548
  import * as path8 from "path";
42476
42549
  function getUserConfigDir2() {
@@ -43029,12 +43102,13 @@ async function handleDarkMatterCommand(directory, args2) {
43029
43102
  }
43030
43103
 
43031
43104
  // src/services/diagnose-service.ts
43032
- import { execSync } from "child_process";
43033
- import { existsSync as existsSync6, readdirSync as readdirSync2, readFileSync as readFileSync4, statSync as statSync4 } from "fs";
43034
- import path12 from "path";
43105
+ init_loader();
43035
43106
  init_manager();
43036
43107
  init_utils2();
43037
43108
  init_manager2();
43109
+ import { execSync } from "child_process";
43110
+ import { existsSync as existsSync6, readdirSync as readdirSync2, readFileSync as readFileSync4, statSync as statSync4 } from "fs";
43111
+ import path12 from "path";
43038
43112
  function validateTaskDag(plan) {
43039
43113
  const allTaskIds = new Set;
43040
43114
  for (const phase of plan.phases) {
@@ -43663,6 +43737,7 @@ async function handleDiagnoseCommand(directory, _args) {
43663
43737
  return formatDiagnoseMarkdown(diagnoseData);
43664
43738
  }
43665
43739
  // src/commands/doctor.ts
43740
+ init_loader();
43666
43741
  init_config_doctor();
43667
43742
  function formatDoctorMarkdown(result) {
43668
43743
  const lines = [
@@ -44246,6 +44321,7 @@ function serializeAgentSession(s) {
44246
44321
  const partialGateWarningsIssuedForTask = Array.from(s.partialGateWarningsIssuedForTask ?? new Set);
44247
44322
  const catastrophicPhaseWarnings = Array.from(s.catastrophicPhaseWarnings ?? new Set);
44248
44323
  const phaseAgentsDispatched = Array.from(s.phaseAgentsDispatched ?? new Set);
44324
+ const lastCompletedPhaseAgentsDispatched = Array.from(s.lastCompletedPhaseAgentsDispatched ?? new Set);
44249
44325
  const windows = {};
44250
44326
  const rawWindows = s.windows ?? {};
44251
44327
  for (const [key, win] of Object.entries(rawWindows)) {
@@ -44283,6 +44359,7 @@ function serializeAgentSession(s) {
44283
44359
  lastPhaseCompleteTimestamp: s.lastPhaseCompleteTimestamp ?? 0,
44284
44360
  lastPhaseCompletePhase: s.lastPhaseCompletePhase ?? 0,
44285
44361
  phaseAgentsDispatched,
44362
+ lastCompletedPhaseAgentsDispatched,
44286
44363
  qaSkipCount: s.qaSkipCount ?? 0,
44287
44364
  qaSkipTaskIds: s.qaSkipTaskIds ?? [],
44288
44365
  taskWorkflowStates: Object.fromEntries(s.taskWorkflowStates ?? new Map)
@@ -44463,6 +44540,9 @@ async function handleHistoryCommand(directory, _args) {
44463
44540
  const historyData = await getHistoryData(directory);
44464
44541
  return formatHistoryMarkdown(historyData);
44465
44542
  }
44543
+ // src/commands/knowledge.ts
44544
+ init_schema();
44545
+
44466
44546
  // src/hooks/knowledge-migrator.ts
44467
44547
  import { randomUUID as randomUUID2 } from "crypto";
44468
44548
  import { existsSync as existsSync8, readFileSync as readFileSync6 } from "fs";
@@ -46591,6 +46671,11 @@ function createSwarmCommandHandler(directory, agents) {
46591
46671
  };
46592
46672
  }
46593
46673
 
46674
+ // src/index.ts
46675
+ init_config();
46676
+ init_constants();
46677
+ init_schema();
46678
+
46594
46679
  // src/hooks/agent-activity.ts
46595
46680
  import { renameSync as renameSync6, unlinkSync as unlinkSync3 } from "fs";
46596
46681
  init_utils();
@@ -46763,6 +46848,7 @@ function createCompactionCustomizerHook(config3, directory) {
46763
46848
  };
46764
46849
  }
46765
46850
  // src/hooks/context-budget.ts
46851
+ init_schema();
46766
46852
  init_utils();
46767
46853
 
46768
46854
  // src/hooks/message-priority.ts
@@ -47234,6 +47320,7 @@ function maskToolOutput(msg, _threshold) {
47234
47320
  return freedTokens;
47235
47321
  }
47236
47322
  // src/hooks/delegation-gate.ts
47323
+ init_schema();
47237
47324
  function extractTaskLine(text) {
47238
47325
  const match = text.match(/TASK:\s*(.+?)(?:\n|$)/i);
47239
47326
  return match ? match[1].trim() : null;
@@ -47581,6 +47668,8 @@ function createDelegationSanitizerHook(directory) {
47581
47668
  return safeHook(hook);
47582
47669
  }
47583
47670
  // src/hooks/delegation-tracker.ts
47671
+ init_constants();
47672
+ init_schema();
47584
47673
  function createDelegationTrackerHook(config3, guardrailsEnabled = true) {
47585
47674
  return async (input, _output) => {
47586
47675
  const now = Date.now();
@@ -47627,8 +47716,10 @@ function createDelegationTrackerHook(config3, guardrailsEnabled = true) {
47627
47716
  };
47628
47717
  }
47629
47718
  // src/hooks/guardrails.ts
47630
- import * as path25 from "path";
47719
+ init_constants();
47720
+ init_schema();
47631
47721
  init_manager2();
47722
+ import * as path25 from "path";
47632
47723
  init_utils();
47633
47724
  function extractPhaseNumber(phaseString) {
47634
47725
  if (!phaseString)
@@ -48333,6 +48424,7 @@ function consolidateSystemMessages(messages) {
48333
48424
  });
48334
48425
  }
48335
48426
  // src/hooks/phase-monitor.ts
48427
+ init_schema();
48336
48428
  init_manager2();
48337
48429
 
48338
48430
  // src/hooks/curator.ts
@@ -48755,7 +48847,9 @@ function createPhaseMonitorHook(directory, preflightManager) {
48755
48847
  if (lastKnownPhase === null) {
48756
48848
  lastKnownPhase = currentPhase;
48757
48849
  try {
48758
- const curatorConfig = CuratorConfigSchema.parse({});
48850
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await Promise.resolve().then(() => (init_config(), exports_config));
48851
+ const { config: config3 } = loadPluginConfigWithMeta2(directory);
48852
+ const curatorConfig = CuratorConfigSchema.parse(config3.curator ?? {});
48759
48853
  if (curatorConfig.enabled && curatorConfig.init_enabled) {
48760
48854
  await runCuratorInit(directory, curatorConfig);
48761
48855
  }
@@ -48860,10 +48954,12 @@ ${originalText}`;
48860
48954
  };
48861
48955
  }
48862
48956
  // src/hooks/system-enhancer.ts
48863
- import * as fs16 from "fs";
48957
+ init_constants();
48958
+ init_schema();
48864
48959
  init_manager();
48865
48960
  init_detector();
48866
48961
  init_manager2();
48962
+ import * as fs16 from "fs";
48867
48963
 
48868
48964
  // src/services/decision-drift-analyzer.ts
48869
48965
  init_utils2();
@@ -49302,6 +49398,8 @@ init_preflight_service();
49302
49398
  init_utils();
49303
49399
 
49304
49400
  // src/hooks/adversarial-detector.ts
49401
+ init_constants();
49402
+ init_schema();
49305
49403
  function safeGet(obj, key) {
49306
49404
  if (!obj || !Object.hasOwn(obj, key))
49307
49405
  return;
@@ -51146,6 +51244,7 @@ function createKnowledgeCuratorHook(directory, config3) {
51146
51244
  }
51147
51245
 
51148
51246
  // src/hooks/knowledge-injector.ts
51247
+ init_schema();
51149
51248
  init_manager2();
51150
51249
 
51151
51250
  // src/services/run-memory.ts
@@ -51634,6 +51733,7 @@ function deserializeAgentSession(s) {
51634
51733
  const partialGateWarningsIssuedForTask = new Set(s.partialGateWarningsIssuedForTask ?? []);
51635
51734
  const catastrophicPhaseWarnings = new Set(s.catastrophicPhaseWarnings ?? []);
51636
51735
  const phaseAgentsDispatched = new Set(s.phaseAgentsDispatched ?? []);
51736
+ const lastCompletedPhaseAgentsDispatched = new Set(s.lastCompletedPhaseAgentsDispatched ?? []);
51637
51737
  return {
51638
51738
  agentName: s.agentName,
51639
51739
  lastToolCallTime: s.lastToolCallTime,
@@ -51655,6 +51755,7 @@ function deserializeAgentSession(s) {
51655
51755
  lastPhaseCompleteTimestamp: s.lastPhaseCompleteTimestamp ?? 0,
51656
51756
  lastPhaseCompletePhase: s.lastPhaseCompletePhase ?? 0,
51657
51757
  phaseAgentsDispatched,
51758
+ lastCompletedPhaseAgentsDispatched,
51658
51759
  qaSkipCount: s.qaSkipCount ?? 0,
51659
51760
  qaSkipTaskIds: s.qaSkipTaskIds ?? [],
51660
51761
  taskWorkflowStates: deserializeTaskWorkflowStates(s.taskWorkflowStates),
@@ -53823,9 +53924,11 @@ init_lint();
53823
53924
 
53824
53925
  // src/tools/phase-complete.ts
53825
53926
  init_dist();
53927
+ init_config();
53928
+ init_schema();
53929
+ init_manager();
53826
53930
  import * as fs25 from "fs";
53827
53931
  import * as path37 from "path";
53828
- init_manager();
53829
53932
  init_utils2();
53830
53933
  init_create_tool();
53831
53934
  function collectCrossSessionDispatchedAgents(phaseReferenceTimestamp, callerSessionId) {
@@ -53839,6 +53942,11 @@ function collectCrossSessionDispatchedAgents(phaseReferenceTimestamp, callerSess
53839
53942
  agents.add(agent);
53840
53943
  }
53841
53944
  }
53945
+ if (callerSession.lastCompletedPhaseAgentsDispatched) {
53946
+ for (const agent of callerSession.lastCompletedPhaseAgentsDispatched) {
53947
+ agents.add(agent);
53948
+ }
53949
+ }
53842
53950
  const callerDelegations = swarmState.delegationChains.get(callerSessionId);
53843
53951
  if (callerDelegations) {
53844
53952
  for (const delegation of callerDelegations) {
@@ -53854,7 +53962,8 @@ function collectCrossSessionDispatchedAgents(phaseReferenceTimestamp, callerSess
53854
53962
  const hasRecentToolCalls = session.lastToolCallTime >= phaseReferenceTimestamp;
53855
53963
  const delegations = swarmState.delegationChains.get(sessionId);
53856
53964
  const hasRecentDelegations = delegations?.some((d) => d.timestamp >= phaseReferenceTimestamp) ?? false;
53857
- const hasActivity = hasRecentToolCalls || hasRecentDelegations;
53965
+ const hasRestoredAgents = (session.phaseAgentsDispatched?.size ?? 0) > 0 && session.lastPhaseCompleteTimestamp === phaseReferenceTimestamp;
53966
+ const hasActivity = hasRecentToolCalls || hasRecentDelegations || hasRestoredAgents;
53858
53967
  if (hasActivity) {
53859
53968
  contributorSessionIds.push(sessionId);
53860
53969
  if (session.phaseAgentsDispatched) {
@@ -53862,6 +53971,11 @@ function collectCrossSessionDispatchedAgents(phaseReferenceTimestamp, callerSess
53862
53971
  agents.add(agent);
53863
53972
  }
53864
53973
  }
53974
+ if (session.lastCompletedPhaseAgentsDispatched) {
53975
+ for (const agent of session.lastCompletedPhaseAgentsDispatched) {
53976
+ agents.add(agent);
53977
+ }
53978
+ }
53865
53979
  const delegations2 = swarmState.delegationChains.get(sessionId);
53866
53980
  if (delegations2) {
53867
53981
  for (const delegation of delegations2) {
@@ -54094,6 +54208,9 @@ async function executePhaseComplete(args2, workingDirectory) {
54094
54208
  for (const contributorSessionId of crossSessionResult.contributorSessionIds) {
54095
54209
  const contributorSession = swarmState.agentSessions.get(contributorSessionId);
54096
54210
  if (contributorSession) {
54211
+ if (contributorSession.phaseAgentsDispatched.size > 0) {
54212
+ contributorSession.lastCompletedPhaseAgentsDispatched = new Set(contributorSession.phaseAgentsDispatched);
54213
+ }
54097
54214
  contributorSession.phaseAgentsDispatched = new Set;
54098
54215
  contributorSession.lastPhaseCompleteTimestamp = now;
54099
54216
  contributorSession.lastPhaseCompletePhase = phase;
@@ -60152,6 +60269,18 @@ function checkReviewerGate(taskId) {
60152
60269
  if (allIdle) {
60153
60270
  console.warn(`[update-task-status] Issue #81 regression detected for task ${taskId}: all ${stateEntries.length} session(s) show idle state. taskWorkflowStates may not be persisting across sessions.`);
60154
60271
  }
60272
+ try {
60273
+ const planPath = path47.join(process.cwd(), ".swarm", "plan.json");
60274
+ const planRaw = fs35.readFileSync(planPath, "utf-8");
60275
+ const plan = JSON.parse(planRaw);
60276
+ for (const planPhase of plan.phases ?? []) {
60277
+ for (const task of planPhase.tasks ?? []) {
60278
+ if (task.id === taskId && task.status === "completed") {
60279
+ return { blocked: false, reason: "" };
60280
+ }
60281
+ }
60282
+ }
60283
+ } catch {}
60155
60284
  const currentStateStr = stateEntries.length > 0 ? stateEntries.join(", ") : "no active sessions";
60156
60285
  return {
60157
60286
  blocked: true,