opencode-swarm 7.97.0 → 7.98.1

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.
Files changed (31) hide show
  1. package/README.md +7 -1
  2. package/dist/agents/architect.d.ts +1 -1
  3. package/dist/cli/{config-doctor-h1xrvq83.js → config-doctor-7yrxfa6b.js} +2 -2
  4. package/dist/cli/{guardrail-explain-t6svvtmn.js → guardrail-explain-cm08h4mt.js} +5 -5
  5. package/dist/cli/{guardrail-log-9yyeccv5.js → guardrail-log-53z1cf46.js} +3 -3
  6. package/dist/cli/{index-a9ghr5cx.js → index-0rgde8qc.js} +2 -2
  7. package/dist/cli/{index-tqbb2jx6.js → index-471qxz9g.js} +33 -9
  8. package/dist/cli/{index-b223mczb.js → index-5z2e78tv.js} +1 -1
  9. package/dist/cli/{index-byb9tgay.js → index-attgb1ma.js} +6 -6
  10. package/dist/cli/{index-rdc6nvmw.js → index-gnd1280x.js} +1 -1
  11. package/dist/cli/{index-sgdr2e4n.js → index-zgba613y.js} +63 -64
  12. package/dist/cli/{index-xx3sv77e.js → index-zy22fg5h.js} +1 -1
  13. package/dist/cli/index.js +4 -4
  14. package/dist/cli/{schema-a8fneygm.js → schema-mygkbbe9.js} +5 -1
  15. package/dist/config/constants.d.ts +4 -0
  16. package/dist/config/schema.d.ts +11 -0
  17. package/dist/evidence/normalize-verdict.d.ts +67 -0
  18. package/dist/hooks/knowledge-curator.d.ts +1 -0
  19. package/dist/hooks/knowledge-injector.d.ts +1 -1
  20. package/dist/index.js +758 -355
  21. package/dist/services/external-skill-validator.d.ts +10 -2
  22. package/dist/services/injection-budget.d.ts +98 -0
  23. package/dist/summaries/summarizer.d.ts +36 -0
  24. package/dist/tools/context-status.d.ts +102 -0
  25. package/dist/tools/index.d.ts +1 -0
  26. package/dist/tools/manifest.d.ts +1 -0
  27. package/dist/tools/tool-metadata.d.ts +11 -7
  28. package/dist/tools/write-drift-evidence.d.ts +11 -0
  29. package/dist/tools/write-hallucination-evidence.d.ts +11 -0
  30. package/dist/tools/write-mutation-evidence.d.ts +11 -0
  31. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -69,7 +69,7 @@ var package_default;
69
69
  var init_package = __esm(() => {
70
70
  package_default = {
71
71
  name: "opencode-swarm",
72
- version: "7.97.0",
72
+ version: "7.98.1",
73
73
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
74
74
  main: "dist/index.js",
75
75
  types: "dist/index.d.ts",
@@ -542,6 +542,10 @@ var init_tool_metadata = __esm(() => {
542
542
  description: "detect hidden couplings by analyzing git history",
543
543
  agents: ["architect"]
544
544
  },
545
+ context_status: {
546
+ description: "report current context-window headroom for the active session — returns tokens-used, model-limit, usage-percent, threshold-state (none/warn/critical), model name, and provider. Pure read-only: no state mutation, no warning injection. Works whether context_budget.enabled is true or false.",
547
+ agents: ["architect"]
548
+ },
545
549
  search: {
546
550
  description: "Workspace-scoped ripgrep-style text search with structured JSON output. Supports literal and regex modes, glob filtering, and result limits. NOTE: This is text search, not structural AST search — use symbols and imports tools for structural queries.",
547
551
  agents: [
@@ -658,19 +662,19 @@ var init_tool_metadata = __esm(() => {
658
662
  },
659
663
  skill_generate: {
660
664
  description: "compile knowledge entries into a structured SKILL.md draft",
661
- agents: ["architect", "skill_improver"]
665
+ agents: ["skill_improver"]
662
666
  },
663
667
  skill_list: {
664
668
  description: "list generated skill files and their status",
665
- agents: ["architect", "skill_improver"]
669
+ agents: ["skill_improver"]
666
670
  },
667
671
  skill_apply: {
668
672
  description: "activate a draft skill proposal",
669
- agents: ["architect"]
673
+ agents: []
670
674
  },
671
675
  skill_inspect: {
672
676
  description: "inspect the content and source entries of a skill file",
673
- agents: ["architect", "skill_improver"]
677
+ agents: ["skill_improver"]
674
678
  },
675
679
  run_stale_reconciliation: {
676
680
  description: "reconcile skills against the knowledge store: mark skills stale when source knowledge is archived or deleted, or clear stale markers",
@@ -678,15 +682,15 @@ var init_tool_metadata = __esm(() => {
678
682
  },
679
683
  skill_regenerate: {
680
684
  description: "regenerate an active skill by re-clustering its source knowledge entries and updating the SKILL.md in place",
681
- agents: ["architect"]
685
+ agents: []
682
686
  },
683
687
  skill_retire: {
684
688
  description: "retire a generated skill by adding a retired.marker file; retired skills are excluded from scoring and injection",
685
- agents: ["architect"]
689
+ agents: []
686
690
  },
687
691
  skill_improve: {
688
692
  description: "run the skill_improver agent to review and refine skills",
689
- agents: ["architect", "skill_improver"]
693
+ agents: ["skill_improver"]
690
694
  },
691
695
  spec_write: {
692
696
  description: "author or update .swarm/spec.md for the current project",
@@ -910,7 +914,7 @@ function isLowCapabilityModel(modelId) {
910
914
  const lower = (modelId || "").toLowerCase();
911
915
  return LOW_CAPABILITY_MODELS.some((substr) => lower.includes(substr));
912
916
  }
913
- var OPENCODE_NATIVE_AGENTS, CLAUDE_CODE_NATIVE_COMMANDS, MEMORY_AGENT_TOOL_MAP, EXTERNAL_SKILL_TOOL_NAMES, EXTERNAL_SKILL_AGENT_TOOL_MAP, COUNCIL_TOOL_NAMES, COUNCIL_AGENT_TOOL_MAP, GENERAL_COUNCIL_TOOL_NAMES, GENERAL_COUNCIL_AGENT_TOOL_MAP, TURBO_TOOL_NAMES, TURBO_AGENT_TOOL_MAP, WRITE_TOOL_NAMES, DEFAULT_MODELS, DEFAULT_SCORING_CONFIG, LOW_CAPABILITY_MODELS, TURBO_MODE_BANNER = `## \uD83D\uDE80 TURBO MODE ACTIVE
917
+ var OPENCODE_NATIVE_AGENTS, CLAUDE_CODE_NATIVE_COMMANDS, MEMORY_AGENT_TOOL_MAP, EXTERNAL_SKILL_TOOL_NAMES, EXTERNAL_SKILL_AGENT_TOOL_MAP, COUNCIL_TOOL_NAMES, COUNCIL_AGENT_TOOL_MAP, GENERAL_COUNCIL_TOOL_NAMES, GENERAL_COUNCIL_AGENT_TOOL_MAP, TURBO_TOOL_NAMES, TURBO_AGENT_TOOL_MAP, SKILL_TOOL_NAMES, SKILL_AGENT_TOOL_MAP, WRITE_TOOL_NAMES, DEFAULT_MODELS, DEFAULT_SCORING_CONFIG, LOW_CAPABILITY_MODELS, TURBO_MODE_BANNER = `## \uD83D\uDE80 TURBO MODE ACTIVE
914
918
 
915
919
  **Speed optimization enabled for this session.**
916
920
 
@@ -1211,6 +1215,18 @@ var init_constants = __esm(() => {
1211
1215
  TURBO_AGENT_TOOL_MAP = {
1212
1216
  architect: [...TURBO_TOOL_NAMES]
1213
1217
  };
1218
+ SKILL_TOOL_NAMES = [
1219
+ "skill_generate",
1220
+ "skill_list",
1221
+ "skill_apply",
1222
+ "skill_inspect",
1223
+ "skill_regenerate",
1224
+ "skill_retire",
1225
+ "skill_improve"
1226
+ ];
1227
+ SKILL_AGENT_TOOL_MAP = {
1228
+ architect: [...SKILL_TOOL_NAMES]
1229
+ };
1214
1230
  WRITE_TOOL_NAMES = [
1215
1231
  "write",
1216
1232
  "edit",
@@ -15466,6 +15482,7 @@ __export(exports_schema, {
15466
15482
  StandardTurboConfigSchema: () => StandardTurboConfigSchema,
15467
15483
  SpecWriterConfigSchema: () => SpecWriterConfigSchema,
15468
15484
  SlopDetectorConfigSchema: () => SlopDetectorConfigSchema,
15485
+ SkillsConfigSchema: () => SkillsConfigSchema,
15469
15486
  SkillPropagationConfigSchema: () => SkillPropagationConfigSchema,
15470
15487
  SkillImproverConfigSchema: () => SkillImproverConfigSchema,
15471
15488
  SelfReviewConfigSchema: () => SelfReviewConfigSchema,
@@ -15507,6 +15524,7 @@ __export(exports_schema, {
15507
15524
  DiscoverySourceSchema: () => DiscoverySourceSchema,
15508
15525
  DesignDocsConfigSchema: () => DesignDocsConfigSchema,
15509
15526
  DecisionDecaySchema: () => DecisionDecaySchema,
15527
+ DEFAULT_SKILLS_CONFIG: () => DEFAULT_SKILLS_CONFIG,
15510
15528
  DEFAULT_EXTERNAL_SKILLS_CONFIG: () => DEFAULT_EXTERNAL_SKILLS_CONFIG,
15511
15529
  DEFAULT_ARCHITECT_PROFILE: () => DEFAULT_ARCHITECT_PROFILE,
15512
15530
  DEFAULT_AGENT_PROFILES: () => DEFAULT_AGENT_PROFILES,
@@ -15606,7 +15624,7 @@ function resolveExternalSkillsConfig(input) {
15606
15624
  };
15607
15625
  return merged;
15608
15626
  }
15609
- var _internals, SEPARATORS, CANONICAL_ROLES_LONGEST_FIRST, CANONICAL_ROLES_SET, AgentReasoningConfigSchema, AgentThinkingConfigSchema, AgentOverrideConfigSchema, SwarmConfigSchema, HooksConfigSchema, ScoringWeightsSchema, DecisionDecaySchema, TokenRatiosSchema, ScoringConfigSchema, ContextBudgetConfigSchema, EvidenceConfigSchema, GateFeatureSchema, PlaceholderScanConfigSchema, QualityBudgetConfigSchema, GateConfigSchema, PipelineConfigSchema, PhaseCompleteConfigSchema, SummaryConfigSchema, ReviewPassesConfigSchema, AutoReviewConfigSchema, AdversarialDetectionConfigSchema, AdversarialTestingConfigSchemaBase, AdversarialTestingConfigSchema, IntegrationAnalysisConfigSchema, DocsConfigSchema, DesignDocsConfigSchema, UIReviewConfigSchema, CompactionAdvisoryConfigSchema, LintConfigSchema, SecretscanConfigSchema, GuardrailsProfileSchema, DEFAULT_AGENT_PROFILES, DEFAULT_ARCHITECT_PROFILE, GuardrailsConfigSchema, WatchdogConfigSchema, SelfReviewConfigSchema, ToolFilterConfigSchema, PlanCursorConfigSchema, ContextMapConfigSchema, RepoGraphConfigSchema, CheckpointConfigSchema, AutomationModeSchema, AutomationCapabilitiesSchema, AutomationConfigSchemaBase, AutomationConfigSchema, KnowledgeConfigSchema, MemoryConfigSchema, CuratorConfigSchema, ArchitecturalSupervisionConfigSchema, KnowledgeApplicationConfigSchema, SkillPropagationConfigSchema, SkillImproverConfigSchema, SpecWriterConfigSchema, SlopDetectorConfigSchema, IncrementalVerifyConfigSchema, CompactionConfigSchema, PrmConfigSchema, AgentAuthorityRuleSchema, AuthorityConfigSchema, GeneralCouncilMemberConfigSchema, GeneralCouncilConfigSchema, CouncilConfigSchema, PrMonitorConfigSchema, ParallelizationConfigSchema, WorktreeIsolationConfigSchema, LeanTurboConfigSchema, EpicConfigSchema, StandardTurboConfigSchema, LeanTurboStrategyConfigSchema, TurboConfigSchema, ExternalSkillCandidateSourceTypeSchema, ExternalSkillCandidateEvaluationVerdictSchema, DiscoverySourceSchema, ExternalSkillCandidateSchema, ExternalSkillsConfigSchema, DEFAULT_EXTERNAL_SKILLS_CONFIG, PluginConfigSchema;
15627
+ var _internals, SEPARATORS, CANONICAL_ROLES_LONGEST_FIRST, CANONICAL_ROLES_SET, AgentReasoningConfigSchema, AgentThinkingConfigSchema, AgentOverrideConfigSchema, SwarmConfigSchema, HooksConfigSchema, ScoringWeightsSchema, DecisionDecaySchema, TokenRatiosSchema, ScoringConfigSchema, ContextBudgetConfigSchema, EvidenceConfigSchema, GateFeatureSchema, PlaceholderScanConfigSchema, QualityBudgetConfigSchema, GateConfigSchema, PipelineConfigSchema, PhaseCompleteConfigSchema, SummaryConfigSchema, ReviewPassesConfigSchema, AutoReviewConfigSchema, AdversarialDetectionConfigSchema, AdversarialTestingConfigSchemaBase, AdversarialTestingConfigSchema, IntegrationAnalysisConfigSchema, DocsConfigSchema, DesignDocsConfigSchema, UIReviewConfigSchema, CompactionAdvisoryConfigSchema, LintConfigSchema, SecretscanConfigSchema, GuardrailsProfileSchema, DEFAULT_AGENT_PROFILES, DEFAULT_ARCHITECT_PROFILE, GuardrailsConfigSchema, WatchdogConfigSchema, SelfReviewConfigSchema, ToolFilterConfigSchema, PlanCursorConfigSchema, ContextMapConfigSchema, RepoGraphConfigSchema, CheckpointConfigSchema, AutomationModeSchema, AutomationCapabilitiesSchema, AutomationConfigSchemaBase, AutomationConfigSchema, KnowledgeConfigSchema, MemoryConfigSchema, CuratorConfigSchema, ArchitecturalSupervisionConfigSchema, KnowledgeApplicationConfigSchema, SkillPropagationConfigSchema, SkillImproverConfigSchema, SkillsConfigSchema, SpecWriterConfigSchema, SlopDetectorConfigSchema, IncrementalVerifyConfigSchema, CompactionConfigSchema, PrmConfigSchema, AgentAuthorityRuleSchema, AuthorityConfigSchema, GeneralCouncilMemberConfigSchema, GeneralCouncilConfigSchema, CouncilConfigSchema, PrMonitorConfigSchema, ParallelizationConfigSchema, WorktreeIsolationConfigSchema, LeanTurboConfigSchema, EpicConfigSchema, StandardTurboConfigSchema, LeanTurboStrategyConfigSchema, TurboConfigSchema, ExternalSkillCandidateSourceTypeSchema, ExternalSkillCandidateEvaluationVerdictSchema, DiscoverySourceSchema, ExternalSkillCandidateSchema, ExternalSkillsConfigSchema, DEFAULT_EXTERNAL_SKILLS_CONFIG, DEFAULT_SKILLS_CONFIG, PluginConfigSchema;
15610
15628
  var init_schema = __esm(() => {
15611
15629
  init_zod();
15612
15630
  init_constants();
@@ -15684,6 +15702,7 @@ var init_schema = __esm(() => {
15684
15702
  critical_threshold: exports_external.number().min(0).max(1).default(0.9),
15685
15703
  model_limits: exports_external.record(exports_external.string(), exports_external.number().min(1000)).default({ default: 128000 }),
15686
15704
  max_injection_tokens: exports_external.number().min(100).max(50000).default(4000),
15705
+ unified_injection_tokens: exports_external.number().min(100).max(50000).optional(),
15687
15706
  tracked_agents: exports_external.array(exports_external.string()).default(["architect"]),
15688
15707
  scoring: ScoringConfigSchema.optional(),
15689
15708
  enforce: exports_external.boolean().default(true),
@@ -16302,6 +16321,9 @@ var init_schema = __esm(() => {
16302
16321
  quota_window: exports_external.enum(["utc", "local"]).default("utc"),
16303
16322
  allow_deterministic_fallback: exports_external.boolean().default(true)
16304
16323
  });
16324
+ SkillsConfigSchema = exports_external.object({
16325
+ enabled: exports_external.boolean().default(false)
16326
+ });
16305
16327
  SpecWriterConfigSchema = exports_external.object({
16306
16328
  enabled: exports_external.boolean().default(true),
16307
16329
  model: exports_external.string().nullable().default(null),
@@ -16562,6 +16584,9 @@ var init_schema = __esm(() => {
16562
16584
  max_concurrent_fetches: 5,
16563
16585
  fetch_timeout_ms: 30000
16564
16586
  };
16587
+ DEFAULT_SKILLS_CONFIG = {
16588
+ enabled: false
16589
+ };
16565
16590
  PluginConfigSchema = exports_external.object({
16566
16591
  agents: exports_external.record(exports_external.string(), AgentOverrideConfigSchema).optional(),
16567
16592
  default_agent: exports_external.string().optional().transform((v) => {
@@ -16789,7 +16814,8 @@ var init_schema = __esm(() => {
16789
16814
  }
16790
16815
  })),
16791
16816
  pr_monitor: PrMonitorConfigSchema.optional(),
16792
- external_skills: ExternalSkillsConfigSchema.optional()
16817
+ external_skills: ExternalSkillsConfigSchema.optional(),
16818
+ skills: SkillsConfigSchema.optional()
16793
16819
  });
16794
16820
  });
16795
16821
 
@@ -70404,48 +70430,43 @@ function recordSeenRetroSection(key, value, timestamp) {
70404
70430
  function hashContent2(content) {
70405
70431
  return createHash9("sha1").update(content).digest("hex");
70406
70432
  }
70407
- function isWriteToSwarmPlan(input) {
70408
- if (typeof input !== "object" || input === null)
70409
- return false;
70410
- const record3 = input;
70411
- const toolName = record3.toolName;
70412
- if (typeof toolName !== "string")
70413
- return false;
70414
- if (!["write", "edit", "apply_patch", "swarm_apply_patch"].includes(toolName))
70415
- return false;
70416
- const rawPath = record3.path;
70417
- const rawFile = record3.file;
70418
- const pathField = typeof rawPath === "string" ? rawPath.replace(/\\/g, "/") : undefined;
70419
- const fileField = typeof rawFile === "string" ? rawFile.replace(/\\/g, "/") : undefined;
70420
- if (typeof pathField === "string" && pathField.includes(".swarm/plan.md")) {
70421
- return true;
70422
- }
70423
- if (typeof fileField === "string" && fileField.includes(".swarm/plan.md")) {
70424
- return true;
70425
- }
70426
- return false;
70427
- }
70428
70433
  function isWriteToEvidenceFile(input) {
70429
- if (typeof input !== "object" || input === null)
70430
- return false;
70431
- const record3 = input;
70432
- const toolName = record3.toolName;
70433
- if (typeof toolName !== "string")
70434
- return false;
70435
- if (!["write", "edit", "apply_patch", "swarm_apply_patch"].includes(toolName))
70434
+ const trigger = normalizeWriteTrigger(input);
70435
+ return isEvidencePath(trigger?.filePath);
70436
+ }
70437
+ function isRecord(value) {
70438
+ return typeof value === "object" && value !== null;
70439
+ }
70440
+ function normalizePathField(value) {
70441
+ return typeof value === "string" ? value.replace(/\\/g, "/") : null;
70442
+ }
70443
+ function firstPathFromRecord(record3) {
70444
+ return normalizePathField(record3.path) ?? normalizePathField(record3.filePath) ?? normalizePathField(record3.file);
70445
+ }
70446
+ function normalizeWriteTrigger(input, output) {
70447
+ if (!isRecord(input))
70448
+ return null;
70449
+ const toolName = typeof input.toolName === "string" ? input.toolName : typeof input.tool === "string" ? input.tool : null;
70450
+ if (!toolName || !WRITE_TOOLS.has(toolName))
70451
+ return null;
70452
+ const inputArgs = isRecord(input.args) ? input.args : null;
70453
+ const outputArgs = isRecord(output) && isRecord(output.args) ? output.args : null;
70454
+ const filePath = firstPathFromRecord(input) ?? (inputArgs ? firstPathFromRecord(inputArgs) : null) ?? (outputArgs ? firstPathFromRecord(outputArgs) : null);
70455
+ if (!filePath)
70456
+ return null;
70457
+ return {
70458
+ toolName,
70459
+ filePath,
70460
+ sessionID: typeof input.sessionID === "string" ? input.sessionID : "default"
70461
+ };
70462
+ }
70463
+ function isEvidencePath(filePath) {
70464
+ if (!filePath)
70436
70465
  return false;
70437
- const rawPath = record3.path;
70438
- const rawFile = record3.file;
70439
- const pathField = typeof rawPath === "string" ? rawPath.replace(/\\/g, "/") : undefined;
70440
- const fileField = typeof rawFile === "string" ? rawFile.replace(/\\/g, "/") : undefined;
70441
- const evidenceRegex = /\.swarm\/+evidence\/+/i;
70442
- if (typeof pathField === "string" && evidenceRegex.test(pathField)) {
70443
- return true;
70444
- }
70445
- if (typeof fileField === "string" && evidenceRegex.test(fileField)) {
70446
- return true;
70447
- }
70448
- return false;
70466
+ return /(?:^|\/)\.swarm\/+evidence\//i.test(filePath);
70467
+ }
70468
+ function isPlanPath(filePath) {
70469
+ return filePath?.includes(".swarm/plan.md") ?? false;
70449
70470
  }
70450
70471
  function extractRetrospectiveSection(planContent) {
70451
70472
  const headingRegex = /^###\s+Lessons\s+Learned$/m;
@@ -71127,24 +71148,22 @@ async function runAutoPromotion(directory, config3) {
71127
71148
  }
71128
71149
  }
71129
71150
  function createKnowledgeCuratorHook(directory, config3, options = {}) {
71130
- const handler = async (input, _output) => {
71151
+ const handler = async (input, output) => {
71131
71152
  pruneSeenRetroSections();
71132
71153
  if (!config3.enabled)
71133
71154
  return;
71134
- if (!isWriteToSwarmPlan(input) && !isWriteToEvidenceFile(input))
71155
+ const trigger = normalizeWriteTrigger(input, output);
71156
+ if (!trigger)
71157
+ return;
71158
+ const isPlanTrigger = isPlanPath(trigger.filePath);
71159
+ const isEvidenceTrigger = isEvidencePath(trigger.filePath) && !isPlanTrigger;
71160
+ if (!isPlanTrigger && !isEvidenceTrigger)
71135
71161
  return;
71136
- const sessionID = input?.sessionID ?? "default";
71137
- const isEvidenceTrigger = isWriteToEvidenceFile(input) && !isWriteToSwarmPlan(input);
71138
71162
  if (isEvidenceTrigger) {
71139
- const record3 = input;
71140
- const rawPath = record3.path;
71141
- const rawFile = record3.file;
71142
- const filePath = typeof rawPath === "string" ? rawPath.replace(/\\/g, "/") : typeof rawFile === "string" ? rawFile.replace(/\\/g, "/") : null;
71143
- if (!filePath)
71144
- return;
71145
- const evidenceKey = `evidence:${sessionID}:${filePath}`;
71163
+ const relativeEvidencePath = trigger.filePath.replace(/^.*\.swarm\//, "");
71164
+ const evidenceKey = `evidence:${trigger.sessionID}:${relativeEvidencePath}`;
71146
71165
  const lastSeenEvidence = seenRetroSections.get(evidenceKey);
71147
- const evidenceContent = await readSwarmFileAsync(directory, filePath.replace(/^.*\.swarm\//, ""));
71166
+ const evidenceContent = await readSwarmFileAsync(directory, relativeEvidencePath);
71148
71167
  if (!evidenceContent)
71149
71168
  return;
71150
71169
  let evidenceData;
@@ -71172,7 +71191,7 @@ function createKnowledgeCuratorHook(directory, config3, options = {}) {
71172
71191
  const projectName2 = evidenceData.project_name ?? "unknown";
71173
71192
  const phaseNumber2 = typeof evidenceData.phase_number === "number" ? evidenceData.phase_number : 1;
71174
71193
  await _internals35.curateAndStoreSwarm(lessons, projectName2, { phase_number: phaseNumber2 }, directory, config3, {
71175
- llmDelegate: options.llmDelegateFactory?.(sessionID),
71194
+ llmDelegate: options.llmDelegateFactory?.(trigger.sessionID),
71176
71195
  enrichmentQuota: options.enrichmentQuota
71177
71196
  });
71178
71197
  return;
@@ -71183,7 +71202,7 @@ function createKnowledgeCuratorHook(directory, config3, options = {}) {
71183
71202
  const section = extractRetrospectiveSection(planContent);
71184
71203
  if (!section)
71185
71204
  return;
71186
- if (!checkRetroChanged(sessionID, section))
71205
+ if (!checkRetroChanged(trigger.sessionID, section))
71187
71206
  return;
71188
71207
  const allLessons = extractLessonsFromRetro(section);
71189
71208
  if (allLessons.length === 0)
@@ -71197,13 +71216,13 @@ function createKnowledgeCuratorHook(directory, config3, options = {}) {
71197
71216
  const phaseMatch = /^Phase:\s*(\d+)/m.exec(planContent);
71198
71217
  const phaseNumber = phaseMatch ? parseInt(phaseMatch[1], 10) : 1;
71199
71218
  await _internals35.curateAndStoreSwarm(normalLessons, projectName, { phase_number: phaseNumber }, directory, config3, {
71200
- llmDelegate: options.llmDelegateFactory?.(sessionID),
71219
+ llmDelegate: options.llmDelegateFactory?.(trigger.sessionID),
71201
71220
  enrichmentQuota: options.enrichmentQuota
71202
71221
  });
71203
71222
  };
71204
71223
  return safeHook(handler);
71205
71224
  }
71206
- var seenRetroSections, MAX_TRACKED_RETRO_SECTIONS = 500, ENRICHMENT_ALLOWED_FIELDS, ENRICHMENT_LLM_TIMEOUT_MS = 60000, ENRICHMENT_BATCH_SIZE = 6, MESO_INSIGHT_BATCH_LIMIT = 20, KNOWLEDGE_CATEGORIES, OUTCOME_PROMOTION_BLOCK = -0.3, _internals35;
71225
+ var seenRetroSections, MAX_TRACKED_RETRO_SECTIONS = 500, WRITE_TOOLS, ENRICHMENT_ALLOWED_FIELDS, ENRICHMENT_LLM_TIMEOUT_MS = 60000, ENRICHMENT_BATCH_SIZE = 6, MESO_INSIGHT_BATCH_LIMIT = 20, KNOWLEDGE_CATEGORIES, OUTCOME_PROMOTION_BLOCK = -0.3, _internals35;
71207
71226
  var init_knowledge_curator = __esm(() => {
71208
71227
  init_skill_improver_quota();
71209
71228
  init_synonym_map();
@@ -71215,6 +71234,12 @@ var init_knowledge_curator = __esm(() => {
71215
71234
  init_micro_reflector();
71216
71235
  init_utils2();
71217
71236
  seenRetroSections = new Map;
71237
+ WRITE_TOOLS = new Set([
71238
+ "write",
71239
+ "edit",
71240
+ "apply_patch",
71241
+ "swarm_apply_patch"
71242
+ ]);
71218
71243
  ENRICHMENT_ALLOWED_FIELDS = [
71219
71244
  "triggers",
71220
71245
  "required_actions",
@@ -101547,7 +101572,7 @@ Members verify prior findings are resolved without re-reviewing unchanged code.
101547
101572
  The architect resolves any \`unresolvedConflicts\` in \`unifiedFeedbackMd\` BEFORE
101548
101573
  sending it to the coder — the coder never sees contradictory instructions.`;
101549
101574
  }
101550
- function buildYourToolsList(council, memoryEnabled = false, externalSkillsEnabled = false, turboEnabled = false) {
101575
+ function buildYourToolsList(council, memoryEnabled = false, externalSkillsEnabled = false, turboEnabled = false, skillsEnabled = false) {
101551
101576
  const qaCouncilEnabled = council?.enabled === true;
101552
101577
  const generalCouncilEnabled = council?.general?.enabled === true;
101553
101578
  const tools = [
@@ -101556,7 +101581,8 @@ function buildYourToolsList(council, memoryEnabled = false, externalSkillsEnable
101556
101581
  ...externalSkillsEnabled ? EXTERNAL_SKILL_AGENT_TOOL_MAP.architect ?? [] : [],
101557
101582
  ...qaCouncilEnabled ? COUNCIL_AGENT_TOOL_MAP.architect ?? [] : [],
101558
101583
  ...generalCouncilEnabled ? GENERAL_COUNCIL_AGENT_TOOL_MAP.architect ?? [] : [],
101559
- ...turboEnabled ? TURBO_AGENT_TOOL_MAP.architect ?? [] : []
101584
+ ...turboEnabled ? TURBO_AGENT_TOOL_MAP.architect ?? [] : [],
101585
+ ...skillsEnabled ? SKILL_AGENT_TOOL_MAP.architect ?? [] : []
101560
101586
  ];
101561
101587
  const sorted = [...tools].sort();
101562
101588
  return `Task (delegation), ${sorted.join(", ")}.`;
@@ -101608,7 +101634,7 @@ If the user accepts the default (1), skip writing this section entirely — seri
101608
101634
  \`\`\`
101609
101635
  If the user keeps the default phase-level behavior, do not write this section.`;
101610
101636
  }
101611
- function buildAvailableToolsList(council, memoryEnabled = false, externalSkillsEnabled = false, turboEnabled = false) {
101637
+ function buildAvailableToolsList(council, memoryEnabled = false, externalSkillsEnabled = false, turboEnabled = false, skillsEnabled = false) {
101612
101638
  const qaCouncilEnabled = council?.enabled === true;
101613
101639
  const generalCouncilEnabled = council?.general?.enabled === true;
101614
101640
  const tools = [
@@ -101617,7 +101643,8 @@ function buildAvailableToolsList(council, memoryEnabled = false, externalSkillsE
101617
101643
  ...externalSkillsEnabled ? EXTERNAL_SKILL_AGENT_TOOL_MAP.architect ?? [] : [],
101618
101644
  ...qaCouncilEnabled ? COUNCIL_AGENT_TOOL_MAP.architect ?? [] : [],
101619
101645
  ...generalCouncilEnabled ? GENERAL_COUNCIL_AGENT_TOOL_MAP.architect ?? [] : [],
101620
- ...turboEnabled ? TURBO_AGENT_TOOL_MAP.architect ?? [] : []
101646
+ ...turboEnabled ? TURBO_AGENT_TOOL_MAP.architect ?? [] : [],
101647
+ ...skillsEnabled ? SKILL_AGENT_TOOL_MAP.architect ?? [] : []
101621
101648
  ];
101622
101649
  const sorted = [...tools].sort();
101623
101650
  return sorted.map((t) => {
@@ -101753,7 +101780,7 @@ function buildSlashCommandsList() {
101753
101780
  return lines.join(`
101754
101781
  `);
101755
101782
  }
101756
- function createArchitectAgent(model, customPrompt, customAppendPrompt, adversarialTesting, council, uiReview, memoryEnabled = false, architecturalSupervision, designDocsEnabled = false, externalSkillsEnabled = false, turboEnabled = false) {
101783
+ function createArchitectAgent(model, customPrompt, customAppendPrompt, adversarialTesting, council, uiReview, memoryEnabled = false, architecturalSupervision, designDocsEnabled = false, externalSkillsEnabled = false, turboEnabled = false, skillsEnabled = false) {
101757
101784
  let prompt = ARCHITECT_PROMPT;
101758
101785
  if (customPrompt) {
101759
101786
  prompt = customPrompt;
@@ -101762,7 +101789,7 @@ function createArchitectAgent(model, customPrompt, customAppendPrompt, adversari
101762
101789
 
101763
101790
  ${customAppendPrompt}`;
101764
101791
  }
101765
- prompt = prompt?.replace("{{YOUR_TOOLS}}", buildYourToolsList(council, memoryEnabled, externalSkillsEnabled, turboEnabled))?.replace("{{AVAILABLE_TOOLS}}", buildAvailableToolsList(council, memoryEnabled, externalSkillsEnabled, turboEnabled))?.replace("{{SLASH_COMMANDS}}", buildSlashCommandsList());
101792
+ prompt = prompt?.replace("{{YOUR_TOOLS}}", buildYourToolsList(council, memoryEnabled, externalSkillsEnabled, turboEnabled, skillsEnabled))?.replace("{{AVAILABLE_TOOLS}}", buildAvailableToolsList(council, memoryEnabled, externalSkillsEnabled, turboEnabled, skillsEnabled))?.replace("{{SLASH_COMMANDS}}", buildSlashCommandsList());
101766
101793
  prompt = prompt?.replace(/\{\{QA_GATE_DIALOGUE_SPECIFY\}\}/g, buildQaGateSelectionDialogue("SPECIFY"))?.replace(/\{\{QA_GATE_DIALOGUE_BRAINSTORM\}\}/g, buildQaGateSelectionDialogue("BRAINSTORM"))?.replace(/\{\{QA_GATE_DIALOGUE_PLAN\}\}/g, buildQaGateSelectionDialogue("PLAN"));
101767
101794
  const councilBlock = buildCouncilWorkflow(council);
101768
101795
  const hasPlaceholder = prompt?.includes("{{COUNCIL_WORKFLOW}}") === true;
@@ -105437,7 +105464,7 @@ function createSwarmAgents(swarmId, swarmConfig, isDefault, pluginConfig, projec
105437
105464
  const prefixName = (name) => `${prefix}${name}`;
105438
105465
  if (!isAgentDisabled("architect", swarmAgents, swarmPrefix)) {
105439
105466
  const architectPrompts = getPrompts("architect");
105440
- const architect = createArchitectAgent(getModel("architect"), architectPrompts.prompt, architectPrompts.appendPrompt, pluginConfig?.adversarial_testing, pluginConfig?.council, pluginConfig?.ui_review, pluginConfig?.memory?.enabled === true, pluginConfig?.architectural_supervision, pluginConfig?.design_docs?.enabled === true, pluginConfig?.external_skills?.curation_enabled === true, pluginConfig?.turbo !== undefined);
105467
+ const architect = createArchitectAgent(getModel("architect"), architectPrompts.prompt, architectPrompts.appendPrompt, pluginConfig?.adversarial_testing, pluginConfig?.council, pluginConfig?.ui_review, pluginConfig?.memory?.enabled === true, pluginConfig?.architectural_supervision, pluginConfig?.design_docs?.enabled === true, pluginConfig?.external_skills?.curation_enabled === true, pluginConfig?.turbo !== undefined, pluginConfig?.skills?.enabled === true);
105441
105468
  architect.name = prefixName("architect");
105442
105469
  const swarmName = swarmConfig.name || swarmId;
105443
105470
  const swarmIdentity = isDefault ? "default" : swarmId;
@@ -105778,6 +105805,17 @@ function getAgentConfigs(config3, directory, sessionId, projectContext) {
105778
105805
  allowedTools = Array.from(new Set([...allowedTools ?? [], ...turboTools]));
105779
105806
  }
105780
105807
  }
105808
+ {
105809
+ const skillTools = SKILL_AGENT_TOOL_MAP[baseAgentName] ?? [];
105810
+ if (skillTools.length > 0 && allowedTools) {
105811
+ if (config3?.skills?.enabled === true) {
105812
+ allowedTools = Array.from(new Set([...allowedTools, ...skillTools]));
105813
+ } else {
105814
+ const skillToolsSet = new Set(skillTools);
105815
+ allowedTools = allowedTools.filter((t) => !skillToolsSet.has(t));
105816
+ }
105817
+ }
105818
+ }
105781
105819
  if (baseAgentName === "architect" && config3?.council?.enabled !== true && override !== undefined) {
105782
105820
  const councilTools = [
105783
105821
  "declare_council_criteria",
@@ -108330,7 +108368,7 @@ var init_knowledge_recall = __esm(() => {
108330
108368
  init_knowledge_diagnostics();
108331
108369
  init_create_tool();
108332
108370
  knowledge_recall = createSwarmTool({
108333
- description: "Search the knowledge base for relevant past decisions, patterns, and lessons learned. Returns ranked results via the unified hybrid retrieval service and a trace_id for knowledge_receipt.",
108371
+ description: "Performs semantic natural-language search across the knowledge base for relevant past decisions, patterns, and lessons learned. Returns ranked results via the unified hybrid retrieval service and a trace_id for knowledge_receipt. This is the tool to use when the user has a QUESTION about what the knowledge base contains. For structured filter-based retrieval (by category, status, or score), use `knowledge_query` instead.",
108334
108372
  args: {
108335
108373
  query: exports_external.string().min(3).describe("Natural language search query"),
108336
108374
  top_n: exports_external.number().int().min(1).max(20).optional().describe("Maximum results to return (default: 5)"),
@@ -108650,7 +108688,7 @@ var init_curator_drift = __esm(() => {
108650
108688
  var exports_design_doc_drift = {};
108651
108689
  __export(exports_design_doc_drift, {
108652
108690
  runDesignDocDriftCheck: () => runDesignDocDriftCheck,
108653
- _internals: () => _internals116
108691
+ _internals: () => _internals117
108654
108692
  });
108655
108693
  import * as fs122 from "node:fs";
108656
108694
  import * as path194 from "node:path";
@@ -108783,7 +108821,7 @@ async function runDesignDocDriftCheck(directory, phase, outDir) {
108783
108821
  return null;
108784
108822
  }
108785
108823
  }
108786
- var DOC_DRIFT_REPORT_PREFIX = "doc-drift-phase-", MAX_TRACEABILITY_BYTES, DESIGN_DOC_FILES, TRACEABILITY_REL, _internals116;
108824
+ var DOC_DRIFT_REPORT_PREFIX = "doc-drift-phase-", MAX_TRACEABILITY_BYTES, DESIGN_DOC_FILES, TRACEABILITY_REL, _internals117;
108787
108825
  var init_design_doc_drift = __esm(() => {
108788
108826
  init_event_bus();
108789
108827
  init_effective_spec();
@@ -108798,7 +108836,7 @@ var init_design_doc_drift = __esm(() => {
108798
108836
  "idiom-notes": path194.join("reference", "idiom-notes.md")
108799
108837
  };
108800
108838
  TRACEABILITY_REL = path194.join("reference", "traceability.json");
108801
- _internals116 = {
108839
+ _internals117 = {
108802
108840
  mtimeMsOrNull,
108803
108841
  resolveAnchorWithin,
108804
108842
  DESIGN_DOC_FILES
@@ -108809,7 +108847,7 @@ var init_design_doc_drift = __esm(() => {
108809
108847
  var exports_project_context = {};
108810
108848
  __export(exports_project_context, {
108811
108849
  buildProjectContext: () => buildProjectContext,
108812
- _internals: () => _internals131,
108850
+ _internals: () => _internals135,
108813
108851
  LANG_BACKEND_DETECTION_TIMEOUT_MS: () => LANG_BACKEND_DETECTION_TIMEOUT_MS
108814
108852
  });
108815
108853
  import * as fs146 from "node:fs";
@@ -108893,7 +108931,7 @@ function selectLintCommand(backend, directory) {
108893
108931
  return null;
108894
108932
  }
108895
108933
  async function buildProjectContext(directory) {
108896
- const backend = await _internals131.pickBackend(directory);
108934
+ const backend = await _internals135.pickBackend(directory);
108897
108935
  if (!backend)
108898
108936
  return null;
108899
108937
  const ctx = emptyProjectContext();
@@ -108932,17 +108970,17 @@ async function buildProjectContext(directory) {
108932
108970
  if (backend.prompts.reviewerChecklist.length > 0) {
108933
108971
  ctx.REVIEWER_CHECKLIST = bulletList(backend.prompts.reviewerChecklist);
108934
108972
  }
108935
- const profiles = _internals131.pickedProfiles(directory);
108973
+ const profiles = _internals135.pickedProfiles(directory);
108936
108974
  if (profiles.length > 1) {
108937
108975
  ctx.PROJECT_CONTEXT_SECONDARY_LANGUAGES = profiles.slice(1).map((p) => p.id).join(", ");
108938
108976
  }
108939
108977
  return ctx;
108940
108978
  }
108941
- var LANG_BACKEND_DETECTION_TIMEOUT_MS = 300, _internals131;
108979
+ var LANG_BACKEND_DETECTION_TIMEOUT_MS = 300, _internals135;
108942
108980
  var init_project_context = __esm(() => {
108943
108981
  init_dispatch();
108944
108982
  init_framework_detector();
108945
- _internals131 = {
108983
+ _internals135 = {
108946
108984
  pickBackend,
108947
108985
  pickedProfiles
108948
108986
  };
@@ -117975,6 +118013,73 @@ init_preflight_integration();
117975
118013
  init_preflight_service();
117976
118014
  init_status_service();
117977
118015
 
118016
+ // src/services/injection-budget.ts
118017
+ function charsToTokens(chars) {
118018
+ if (chars <= 0)
118019
+ return 0;
118020
+ return Math.ceil(chars * 0.33);
118021
+ }
118022
+ function allocateInjectionBudget(systemEnhancerDemandTokens, knowledgeInjectorDemandChars, config3) {
118023
+ const budget = config3.totalBudgetTokens;
118024
+ const seDemand = Math.max(0, systemEnhancerDemandTokens);
118025
+ const kiChars = Math.max(0, knowledgeInjectorDemandChars);
118026
+ const ceiling = Math.max(0, budget);
118027
+ const kiDemand = charsToTokens(kiChars);
118028
+ if (seDemand + kiDemand <= ceiling) {
118029
+ return {
118030
+ systemEnhancerTokens: seDemand,
118031
+ knowledgeInjectorTokens: kiDemand,
118032
+ totalTokens: seDemand + kiDemand
118033
+ };
118034
+ }
118035
+ if (seDemand >= ceiling) {
118036
+ return {
118037
+ systemEnhancerTokens: ceiling,
118038
+ knowledgeInjectorTokens: 0,
118039
+ totalTokens: ceiling
118040
+ };
118041
+ }
118042
+ if (kiDemand >= ceiling) {
118043
+ return {
118044
+ systemEnhancerTokens: 0,
118045
+ knowledgeInjectorTokens: ceiling,
118046
+ totalTokens: ceiling
118047
+ };
118048
+ }
118049
+ const totalDemand = seDemand + kiDemand;
118050
+ const seShare = Math.floor(seDemand / totalDemand * ceiling);
118051
+ const kiShare = ceiling - seShare;
118052
+ return {
118053
+ systemEnhancerTokens: seShare,
118054
+ knowledgeInjectorTokens: kiShare,
118055
+ totalTokens: ceiling
118056
+ };
118057
+ }
118058
+ var sessionBudgets = new Map;
118059
+ var MAX_TRACKED_SESSIONS = 256;
118060
+ function evictSessionBudgets() {
118061
+ while (sessionBudgets.size > MAX_TRACKED_SESSIONS) {
118062
+ const firstKey = sessionBudgets.keys().next().value;
118063
+ if (firstKey === undefined)
118064
+ break;
118065
+ sessionBudgets.delete(firstKey);
118066
+ }
118067
+ }
118068
+ function resetUnifiedBudget(sessionID, totalBudget) {
118069
+ sessionBudgets.set(sessionID, { total: totalBudget, used: 0, seDemand: 0 });
118070
+ evictSessionBudgets();
118071
+ }
118072
+ function setSystemEnhancerDemand(sessionID, demand) {
118073
+ const budget = sessionBudgets.get(sessionID);
118074
+ if (!budget)
118075
+ return;
118076
+ budget.seDemand = demand;
118077
+ }
118078
+ function getSystemEnhancerDemand(sessionID) {
118079
+ const budget = sessionBudgets.get(sessionID);
118080
+ return budget?.seDemand ?? 0;
118081
+ }
118082
+
117978
118083
  // src/hooks/system-enhancer.ts
117979
118084
  init_telemetry();
117980
118085
  init_co_change_analyzer();
@@ -118246,7 +118351,7 @@ var MAX_RECENT_CALLS = 20;
118246
118351
  var SPIRAL_THRESHOLD = 5;
118247
118352
  var SPIRAL_WINDOW_MS = 300000;
118248
118353
  var SPIRAL_COOLDOWN_MS = 60000;
118249
- var MAX_TRACKED_SESSIONS = 500;
118354
+ var MAX_TRACKED_SESSIONS2 = 500;
118250
118355
  function recordToolCall(tool3, args2, sessionId) {
118251
118356
  const argsHash = typeof args2 === "string" ? args2.slice(0, 100) : JSON.stringify(args2 ?? "").slice(0, 100);
118252
118357
  let calls = recentToolCallsBySession.get(sessionId);
@@ -118276,7 +118381,7 @@ async function detectDebuggingSpiral(_directory, sessionId) {
118276
118381
  if (allSameTool && allSimilarArgs) {
118277
118382
  lastSpiralTimestampBySession.set(sessionId, now);
118278
118383
  recentToolCallsBySession.delete(sessionId);
118279
- if (lastSpiralTimestampBySession.size > MAX_TRACKED_SESSIONS) {
118384
+ if (lastSpiralTimestampBySession.size > MAX_TRACKED_SESSIONS2) {
118280
118385
  for (const oldest of lastSpiralTimestampBySession.keys()) {
118281
118386
  if (oldest !== sessionId) {
118282
118387
  lastSpiralTimestampBySession.delete(oldest);
@@ -119605,8 +119710,10 @@ function createSystemEnhancerHook(config3, directory) {
119605
119710
  try {
119606
119711
  let tryInject = function(text) {
119607
119712
  const tokens = estimateTokens(text);
119608
- if (injectedTokens + tokens > maxInjectionTokens) {
119609
- warn(`system-enhancer: injection budget exceeded (${injectedTokens + tokens} > ${maxInjectionTokens} tokens) — truncating system prompt content`);
119713
+ actualDemand += tokens;
119714
+ const effectiveMax = seAllocation;
119715
+ if (injectedTokens + tokens > effectiveMax) {
119716
+ warn(`system-enhancer: injection budget exceeded (${injectedTokens + tokens} > ${effectiveMax} tokens) — truncating system prompt content`);
119610
119717
  return;
119611
119718
  }
119612
119719
  output.system.push(text);
@@ -119620,6 +119727,18 @@ function createSystemEnhancerHook(config3, directory) {
119620
119727
  }
119621
119728
  const maxInjectionTokens = config3.context_budget?.max_injection_tokens ?? 4000;
119622
119729
  let injectedTokens = 0;
119730
+ let actualDemand = 0;
119731
+ let seAllocation;
119732
+ let unifiedBudget;
119733
+ if (config3.context_budget?.unified_injection_tokens !== undefined && _input.sessionID) {
119734
+ unifiedBudget = config3.context_budget.unified_injection_tokens;
119735
+ const allocation = allocateInjectionBudget(maxInjectionTokens, 0, {
119736
+ totalBudgetTokens: unifiedBudget
119737
+ });
119738
+ seAllocation = allocation.systemEnhancerTokens;
119739
+ } else {
119740
+ seAllocation = maxInjectionTokens;
119741
+ }
119623
119742
  const contextContent = await readSwarmFileAsync(directory, "context.md");
119624
119743
  try {
119625
119744
  const { scanDocIndex: scanDocIndex2 } = await Promise.resolve().then(() => (init_doc_scan(), exports_doc_scan));
@@ -120057,6 +120176,15 @@ ${budgetWarning}`);
120057
120176
  tryInject(envPrompt);
120058
120177
  }
120059
120178
  } catch {}
120179
+ if (unifiedBudget !== undefined && _input.sessionID) {
120180
+ const totalDemand = actualDemand;
120181
+ const allocation = allocateInjectionBudget(totalDemand, 0, {
120182
+ totalBudgetTokens: unifiedBudget
120183
+ });
120184
+ seAllocation = allocation.systemEnhancerTokens;
120185
+ resetUnifiedBudget(_input.sessionID, unifiedBudget);
120186
+ setSystemEnhancerDemand(_input.sessionID, totalDemand);
120187
+ } else {}
120060
120188
  return;
120061
120189
  }
120062
120190
  const mode_b = await detectArchitectMode(directory);
@@ -120538,7 +120666,8 @@ ${handoffBlock}`;
120538
120666
  } catch {}
120539
120667
  const ranked = rankCandidates(candidates, effectiveConfig);
120540
120668
  for (const candidate of ranked) {
120541
- if (injectedTokens + candidate.tokens > maxInjectionTokens) {
120669
+ actualDemand += candidate.tokens;
120670
+ if (injectedTokens + candidate.tokens > seAllocation) {
120542
120671
  continue;
120543
120672
  }
120544
120673
  output.system.push(candidate.text);
@@ -120577,6 +120706,15 @@ ${budgetWarning_b}`);
120577
120706
  }
120578
120707
  }
120579
120708
  }
120709
+ if (unifiedBudget !== undefined && _input.sessionID) {
120710
+ const totalDemand = actualDemand;
120711
+ const allocation = allocateInjectionBudget(totalDemand, 0, {
120712
+ totalBudgetTokens: unifiedBudget
120713
+ });
120714
+ seAllocation = allocation.systemEnhancerTokens;
120715
+ resetUnifiedBudget(_input.sessionID, unifiedBudget);
120716
+ setSystemEnhancerDemand(_input.sessionID, totalDemand);
120717
+ }
120580
120718
  } catch (error93) {
120581
120719
  warn("System enhancer failed:", error93);
120582
120720
  }
@@ -120696,6 +120834,71 @@ function formatBytes(bytes) {
120696
120834
  const formatted = unitIndex === 0 ? size.toString() : size.toFixed(1);
120697
120835
  return `${formatted} ${units[unitIndex]}`;
120698
120836
  }
120837
+ function jsonTypeSignature(value) {
120838
+ if (value === null)
120839
+ return "null";
120840
+ if (Array.isArray(value)) {
120841
+ const len = value.length;
120842
+ if (len === 0)
120843
+ return "array<>";
120844
+ const first = value[0];
120845
+ return `array<${len}, ${jsonTypeSignature(first)}>`;
120846
+ }
120847
+ switch (typeof value) {
120848
+ case "string":
120849
+ return "string";
120850
+ case "number":
120851
+ return Number.isInteger(value) ? "number" : "number(float)";
120852
+ case "boolean":
120853
+ return "boolean";
120854
+ case "object":
120855
+ return "object";
120856
+ default:
120857
+ return typeof value;
120858
+ }
120859
+ }
120860
+ function summarizeJsonObject(parsed) {
120861
+ const keys = Object.keys(parsed);
120862
+ const parts = keys.map((key) => `${key}: ${jsonTypeSignature(parsed[key])}`);
120863
+ return `{ ${parts.join(", ")} }`;
120864
+ }
120865
+ function summarizeJsonArray(parsed) {
120866
+ const len = parsed.length;
120867
+ if (len === 0)
120868
+ return "[ 0 items ]";
120869
+ const firstSig = jsonTypeSignature(parsed[0]);
120870
+ return `[ ${len} items, first: ${firstSig} ]`;
120871
+ }
120872
+ var DECLARATION_PATTERN = /(?:export\s+)?(?:async\s+)?(?:function|class|interface|type|const|let|var)\s+(\w+)/g;
120873
+ function extractCodeSignatures(code) {
120874
+ const signatures = [];
120875
+ for (const match of code.matchAll(DECLARATION_PATTERN)) {
120876
+ const name = match[1];
120877
+ if (name && !signatures.includes(name)) {
120878
+ signatures.push(name);
120879
+ }
120880
+ }
120881
+ return signatures;
120882
+ }
120883
+ function summarizeCode(output) {
120884
+ const signatures = extractCodeSignatures(output);
120885
+ const lines = output.split(`
120886
+ `).filter((line) => line.trim().length > 0).slice(0, 5);
120887
+ if (signatures.length === 0) {
120888
+ return lines.join(`
120889
+ `);
120890
+ }
120891
+ const sigLine = `// declarations: ${signatures.join(", ")}`;
120892
+ const previewLines = [sigLine, ...lines];
120893
+ return previewLines.join(`
120894
+ `);
120895
+ }
120896
+ function summarizeText(output, maxLines) {
120897
+ const lines = output.split(`
120898
+ `).filter((line) => line.trim().length > 0).slice(0, maxLines);
120899
+ return lines.join(`
120900
+ `);
120901
+ }
120699
120902
  function createSummary(output, toolName, summaryId, maxSummaryChars) {
120700
120903
  const contentType = detectContentType(output, toolName);
120701
120904
  const lineCount = output.split(`
@@ -120712,36 +120915,23 @@ function createSummary(output, toolName, summaryId, maxSummaryChars) {
120712
120915
  try {
120713
120916
  const parsed = JSON.parse(output.trim());
120714
120917
  if (Array.isArray(parsed)) {
120715
- preview = `[ ${parsed.length} items ]`;
120918
+ preview = summarizeJsonArray(parsed);
120716
120919
  } else if (typeof parsed === "object" && parsed !== null) {
120717
- const keys = Object.keys(parsed).slice(0, 3);
120718
- preview = `{ ${keys.join(", ")}${Object.keys(parsed).length > 3 ? ", ..." : ""} }`;
120920
+ preview = summarizeJsonObject(parsed);
120719
120921
  } else {
120720
- const lines = output.split(`
120721
- `).filter((line) => line.trim().length > 0).slice(0, 3);
120722
- preview = lines.join(`
120723
- `);
120922
+ preview = summarizeText(output, 3);
120724
120923
  }
120725
120924
  } catch {
120726
- const lines = output.split(`
120727
- `).filter((line) => line.trim().length > 0).slice(0, 3);
120728
- preview = lines.join(`
120729
- `);
120925
+ preview = summarizeText(output, 3);
120730
120926
  }
120731
120927
  break;
120732
120928
  }
120733
120929
  case "code": {
120734
- const lines = output.split(`
120735
- `).filter((line) => line.trim().length > 0).slice(0, 5);
120736
- preview = lines.join(`
120737
- `);
120930
+ preview = summarizeCode(output);
120738
120931
  break;
120739
120932
  }
120740
120933
  case "text": {
120741
- const lines = output.split(`
120742
- `).filter((line) => line.trim().length > 0).slice(0, 5);
120743
- preview = lines.join(`
120744
- `);
120934
+ preview = summarizeText(output, 5);
120745
120935
  break;
120746
120936
  }
120747
120937
  case "binary": {
@@ -120749,10 +120939,7 @@ function createSummary(output, toolName, summaryId, maxSummaryChars) {
120749
120939
  break;
120750
120940
  }
120751
120941
  default: {
120752
- const lines = output.split(`
120753
- `).filter((line) => line.trim().length > 0).slice(0, 5);
120754
- preview = lines.join(`
120755
- `);
120942
+ preview = summarizeText(output, 5);
120756
120943
  }
120757
120944
  }
120758
120945
  if (preview.length > maxPreviewChars) {
@@ -121205,12 +121392,12 @@ init_logger();
121205
121392
  init_normalize_tool_name();
121206
121393
  init_review_receipt();
121207
121394
  init_utils2();
121208
- var MAX_TRACKED_SESSIONS2 = 256;
121395
+ var MAX_TRACKED_SESSIONS3 = 256;
121209
121396
  var COOLDOWN_MS = 60000;
121210
121397
  var inFlightSessions = new Set;
121211
121398
  var lastDispatchBySession = new Map;
121212
121399
  function evictCooldownMap() {
121213
- while (lastDispatchBySession.size > MAX_TRACKED_SESSIONS2) {
121400
+ while (lastDispatchBySession.size > MAX_TRACKED_SESSIONS3) {
121214
121401
  const firstKey = lastDispatchBySession.keys().next().value;
121215
121402
  if (firstKey === undefined)
121216
121403
  break;
@@ -122333,7 +122520,7 @@ function injectKnowledgeMessage(output, text) {
122333
122520
  };
122334
122521
  output.messages.splice(insertIdx, 0, knowledgeMessage);
122335
122522
  }
122336
- function createKnowledgeInjectorHook(directory, config3, modelLimitOverrides = {}) {
122523
+ function createKnowledgeInjectorHook(directory, config3, modelLimitOverrides = {}, unifiedInjectionTokens = undefined) {
122337
122524
  function buildContextCacheKey(phase, ctx) {
122338
122525
  const parts = [
122339
122526
  String(phase),
@@ -122367,11 +122554,19 @@ function createKnowledgeInjectorHook(directory, config3, modelLimitOverrides = {
122367
122554
  return;
122368
122555
  }
122369
122556
  const maxInjectChars = config3.inject_char_budget ?? 2000;
122370
- const effectiveBudget = headroomChars >= MODEL_LIMIT_CHARS * 0.6 ? maxInjectChars : headroomChars >= MODEL_LIMIT_CHARS * 0.2 ? Math.floor(maxInjectChars * 0.5) : Math.floor(maxInjectChars * 0.25);
122557
+ let effectiveBudget = headroomChars >= MODEL_LIMIT_CHARS * 0.6 ? maxInjectChars : headroomChars >= MODEL_LIMIT_CHARS * 0.2 ? Math.floor(maxInjectChars * 0.5) : Math.floor(maxInjectChars * 0.25);
122371
122558
  const systemMsg = output.messages.find((m) => m.info?.role === "system");
122372
122559
  const agentName = systemMsg?.info?.agent;
122373
122560
  if (!agentName)
122374
122561
  return;
122562
+ if (unifiedInjectionTokens !== undefined) {
122563
+ const sessionID2 = systemMsg?.info?.sessionID;
122564
+ const seDemand = sessionID2 ? getSystemEnhancerDemand(sessionID2) : 0;
122565
+ const allocation = allocateInjectionBudget(seDemand, effectiveBudget, {
122566
+ totalBudgetTokens: unifiedInjectionTokens
122567
+ });
122568
+ effectiveBudget = Math.floor(allocation.knowledgeInjectorTokens / 0.33);
122569
+ }
122375
122570
  if (isDelegatedAgent(agentName)) {
122376
122571
  await injectForDelegateIntoMessages(directory, config3, output, agentName, systemMsg?.info?.sessionID);
122377
122572
  return;
@@ -124005,7 +124200,7 @@ function extractText2(out) {
124005
124200
  }
124006
124201
  return "";
124007
124202
  }
124008
- var MAX_TRACKED_SESSIONS3 = 256;
124203
+ var MAX_TRACKED_SESSIONS4 = 256;
124009
124204
  var WARNING_TTL_MS = 5 * 60 * 1000;
124010
124205
  var fullAutoInputWarningStash = new Map;
124011
124206
  function isExpired2(w, nowMs = Date.now()) {
@@ -124020,7 +124215,7 @@ function evictExpired() {
124020
124215
  if (isExpired2(w, now))
124021
124216
  fullAutoInputWarningStash.delete(sid);
124022
124217
  }
124023
- while (fullAutoInputWarningStash.size > MAX_TRACKED_SESSIONS3) {
124218
+ while (fullAutoInputWarningStash.size > MAX_TRACKED_SESSIONS4) {
124024
124219
  const firstKey = fullAutoInputWarningStash.keys().next().value;
124025
124220
  if (firstKey === undefined)
124026
124221
  break;
@@ -125036,7 +125231,7 @@ init_state2();
125036
125231
  init_delegation_gate();
125037
125232
  init_normalize_tool_name();
125038
125233
  import * as path154 from "node:path";
125039
- var WRITE_TOOLS = new Set(WRITE_TOOL_NAMES);
125234
+ var WRITE_TOOLS2 = new Set(WRITE_TOOL_NAMES);
125040
125235
  function createScopeGuardHook(config3, directory, injectAdvisory) {
125041
125236
  const enabled = config3.enabled ?? true;
125042
125237
  const _skipInTurbo = config3.skip_in_turbo ?? false;
@@ -125045,7 +125240,7 @@ function createScopeGuardHook(config3, directory, injectAdvisory) {
125045
125240
  if (!enabled)
125046
125241
  return;
125047
125242
  const toolName = normalizeToolName(input.tool);
125048
- if (!WRITE_TOOLS.has(toolName))
125243
+ if (!WRITE_TOOLS2.has(toolName))
125049
125244
  return;
125050
125245
  const sessionId = input.sessionID;
125051
125246
  const activeAgent = swarmState.activeAgent.get(sessionId);
@@ -128939,6 +129134,77 @@ var complexity_hotspots = createSwarmTool({
128939
129134
  }
128940
129135
  });
128941
129136
 
129137
+ // src/tools/context-status.ts
129138
+ init_config();
129139
+ init_model_limits();
129140
+ init_utils2();
129141
+ init_state2();
129142
+ init_create_tool();
129143
+ var _internals93 = {
129144
+ loadPluginConfig,
129145
+ fetchSessionMessages: async (sessionID, directory, limit = 100) => {
129146
+ if (!swarmState.opencodeClient?.session)
129147
+ return null;
129148
+ try {
129149
+ const result = await swarmState.opencodeClient.session.messages({
129150
+ path: { id: sessionID },
129151
+ query: { directory, limit }
129152
+ });
129153
+ return result.data ?? null;
129154
+ } catch {
129155
+ return null;
129156
+ }
129157
+ }
129158
+ };
129159
+ function computeContextHeadroom(messages, warnThreshold = 0.7, criticalThreshold = 0.9, modelLimitsConfig = {}) {
129160
+ const { modelID, providerID } = extractModelInfo(messages);
129161
+ const modelLimit = resolveModelLimit(modelID, providerID, modelLimitsConfig);
129162
+ let totalTokens = 0;
129163
+ for (const message of messages) {
129164
+ if (!message?.parts)
129165
+ continue;
129166
+ for (const part of message.parts) {
129167
+ if (part?.type === "text" && part.text) {
129168
+ totalTokens += estimateTokens(part.text);
129169
+ }
129170
+ }
129171
+ }
129172
+ const usagePercent = totalTokens / modelLimit;
129173
+ let thresholdCrossed = "none";
129174
+ if (usagePercent > criticalThreshold) {
129175
+ thresholdCrossed = "critical";
129176
+ } else if (usagePercent > warnThreshold) {
129177
+ thresholdCrossed = "warn";
129178
+ }
129179
+ return {
129180
+ tokensUsed: totalTokens,
129181
+ modelLimit,
129182
+ usagePercent,
129183
+ thresholdCrossed,
129184
+ modelId: modelID ?? null,
129185
+ provider: providerID ?? null
129186
+ };
129187
+ }
129188
+ var context_status = createSwarmTool({
129189
+ description: "Report current context-window headroom for the active session. Returns tokens-used, model-limit, usage-percent, threshold-state (none/warn/critical), model name, and provider. Pure read-only — no state mutation, no warning injection. Works whether context_budget.enabled is true or false.",
129190
+ args: {},
129191
+ async execute(_args, directory, ctx) {
129192
+ const config3 = _internals93.loadPluginConfig(directory);
129193
+ const warnThreshold = config3.context_budget?.warn_threshold ?? 0.7;
129194
+ const criticalThreshold = config3.context_budget?.critical_threshold ?? 0.9;
129195
+ const modelLimitsConfig = config3.context_budget?.model_limits ?? {};
129196
+ let messages = [];
129197
+ if (ctx?.sessionID) {
129198
+ const sessionMessages = await _internals93.fetchSessionMessages(ctx.sessionID, directory);
129199
+ if (sessionMessages) {
129200
+ messages = sessionMessages;
129201
+ }
129202
+ }
129203
+ const headroom = computeContextHeadroom(messages, warnThreshold, criticalThreshold, modelLimitsConfig);
129204
+ return JSON.stringify(headroom, null, 2);
129205
+ }
129206
+ });
129207
+
128942
129208
  // src/tools/convene-council.ts
128943
129209
  init_zod();
128944
129210
  init_loader();
@@ -128970,7 +129236,7 @@ var VALID_TASK_ID = /^\d+\.\d+(\.\d+)*$/;
128970
129236
  var COUNCIL_GATE_NAME = "council";
128971
129237
  var COUNCIL_AGENT_ID = "architect";
128972
129238
  var EvidenceFileSchema = exports_external.record(exports_external.string(), exports_external.unknown());
128973
- var _internals93 = {
129239
+ var _internals94 = {
128974
129240
  withTaskEvidenceLock
128975
129241
  };
128976
129242
  var FORBIDDEN_KEYS = new Set(["__proto__", "constructor", "prototype"]);
@@ -129005,7 +129271,7 @@ async function writeCouncilEvidence(workingDir, synthesis) {
129005
129271
  const dir = join130(workingDir, EVIDENCE_DIR2);
129006
129272
  mkdirSync42(dir, { recursive: true });
129007
129273
  const filePath = taskEvidencePath(workingDir, synthesis.taskId);
129008
- await _internals93.withTaskEvidenceLock(workingDir, synthesis.taskId, COUNCIL_AGENT_ID, async () => {
129274
+ await _internals94.withTaskEvidenceLock(workingDir, synthesis.taskId, COUNCIL_AGENT_ID, async () => {
129009
129275
  const existingRoot = Object.create(null);
129010
129276
  if (existsSync93(filePath)) {
129011
129277
  try {
@@ -131525,7 +131791,7 @@ var CollectLaneResultsArgsSchema = exports_external.object({
131525
131791
  include_pending: exports_external.boolean().optional().describe("Include pending/running lanes in lane_results. Defaults to true for non-blocking polls and false for wait=true joins."),
131526
131792
  cancel_pending: exports_external.boolean().optional().describe("Abort and mark pending/running lanes cancelled")
131527
131793
  });
131528
- var _internals94 = {
131794
+ var _internals95 = {
131529
131795
  getSessionOps: () => swarmState.opencodeClient?.session ?? null,
131530
131796
  getGeneratedAgentNames: () => swarmState.generatedAgentNames,
131531
131797
  createParallelDispatcher,
@@ -131549,7 +131815,7 @@ async function executeDispatchLanes(args2, directory, context = {}) {
131549
131815
  errors: duplicateLaneIds.map((id) => `Duplicate lane id: ${id}`)
131550
131816
  });
131551
131817
  }
131552
- const session = _internals94.getSessionOps();
131818
+ const session = _internals95.getSessionOps();
131553
131819
  if (!session) {
131554
131820
  return failureResult({
131555
131821
  failure_class: "no_client",
@@ -131567,7 +131833,7 @@ async function executeDispatchLanes(args2, directory, context = {}) {
131567
131833
  const lanes = applyExplorerFormatSuffix(common.lanes);
131568
131834
  const maxConcurrent = Math.min(parsed.data.max_concurrent ?? lanes.length, lanes.length, MAX_LANES);
131569
131835
  const timeoutMs = parsed.data.timeout_ms ?? DEFAULT_TIMEOUT_MS3;
131570
- const dispatcher = _internals94.createParallelDispatcher({
131836
+ const dispatcher = _internals95.createParallelDispatcher({
131571
131837
  enabled: true,
131572
131838
  maxConcurrentTasks: maxConcurrent,
131573
131839
  evidenceLockTimeoutMs: 0
@@ -131597,7 +131863,7 @@ async function executeDispatchLanesAsync(args2, directory, context = {}) {
131597
131863
  errors: duplicateLaneIds.map((id) => `Duplicate lane id: ${id}`)
131598
131864
  });
131599
131865
  }
131600
- const session = _internals94.getSessionOps();
131866
+ const session = _internals95.getSessionOps();
131601
131867
  if (!session || typeof session.promptAsync !== "function") {
131602
131868
  return asyncFailureResult({
131603
131869
  failure_class: "no_client",
@@ -131623,7 +131889,7 @@ async function executeDispatchLanesAsync(args2, directory, context = {}) {
131623
131889
  }
131624
131890
  const maxConcurrent = Math.min(parsed.data.max_concurrent ?? lanes.length, lanes.length, MAX_LANES);
131625
131891
  const launchTimeoutMs = parsed.data.launch_timeout_ms ?? parsed.data.timeout_ms ?? DEFAULT_ASYNC_LAUNCH_TIMEOUT_MS;
131626
- const dispatcher = _internals94.createParallelDispatcher({
131892
+ const dispatcher = _internals95.createParallelDispatcher({
131627
131893
  enabled: true,
131628
131894
  maxConcurrentTasks: maxConcurrent,
131629
131895
  evidenceLockTimeoutMs: 0
@@ -131671,7 +131937,7 @@ async function executeCollectLaneResults(args2, directory, context = {}) {
131671
131937
  errors: parsed.error.issues.map((issue3) => `${issue3.path.join(".")}: ${issue3.message}`)
131672
131938
  });
131673
131939
  }
131674
- const session = _internals94.getSessionOps();
131940
+ const session = _internals95.getSessionOps();
131675
131941
  if (!session || typeof session.messages !== "function") {
131676
131942
  return collectFailureResult({
131677
131943
  failure_class: "no_client",
@@ -131680,7 +131946,7 @@ async function executeCollectLaneResults(args2, directory, context = {}) {
131680
131946
  });
131681
131947
  }
131682
131948
  const timeoutMs = parsed.data.timeout_ms ?? DEFAULT_COLLECT_TIMEOUT_MS;
131683
- const deadline = _internals94.now() + timeoutMs;
131949
+ const deadline = _internals95.now() + timeoutMs;
131684
131950
  const batchFilter = context.sessionID !== undefined ? { parentSessionId: context.sessionID } : undefined;
131685
131951
  let records = findByBatchId(directory, parsed.data.batch_id, batchFilter);
131686
131952
  if (records.length === 0) {
@@ -131700,11 +131966,11 @@ async function executeCollectLaneResults(args2, directory, context = {}) {
131700
131966
  keepPolling = false;
131701
131967
  continue;
131702
131968
  }
131703
- if (_internals94.now() >= deadline) {
131969
+ if (_internals95.now() >= deadline) {
131704
131970
  keepPolling = false;
131705
131971
  continue;
131706
131972
  }
131707
- await _internals94.sleep(Math.min(pollIntervalMs, Math.max(0, deadline - _internals94.now())));
131973
+ await _internals95.sleep(Math.min(pollIntervalMs, Math.max(0, deadline - _internals95.now())));
131708
131974
  pollIntervalMs = nextCollectPollInterval(pollIntervalMs);
131709
131975
  }
131710
131976
  return buildCollectResult(parsed.data.batch_id, records, parsed.data.include_pending ?? parsed.data.wait !== true);
@@ -131935,7 +132201,7 @@ async function isLaneReadyForCollection(session, directory, sessionId) {
131935
132201
  async function sweepStaleAsyncLaneRecords(session, directory, records, staleTimeoutMs) {
131936
132202
  if (staleTimeoutMs <= 0)
131937
132203
  return;
131938
- const now = _internals94.now();
132204
+ const now = _internals95.now();
131939
132205
  for (const record3 of records) {
131940
132206
  if (record3.status !== "pending" && record3.status !== "running" && record3.status !== "ingestion_error")
131941
132207
  continue;
@@ -132146,7 +132412,7 @@ function failedLane(lane, role, startedAt, error93, slotId, runId, sessionId) {
132146
132412
  };
132147
132413
  }
132148
132414
  function validateLaneAgent(agent, context) {
132149
- const generatedAgentNames = _internals94.getGeneratedAgentNames();
132415
+ const generatedAgentNames = _internals95.getGeneratedAgentNames();
132150
132416
  const role = resolveGeneratedAgentRole(agent, generatedAgentNames);
132151
132417
  if (!isKnownCanonicalRole(role)) {
132152
132418
  return {
@@ -132297,7 +132563,7 @@ function applyCommonPrompt(lanes, commonPrompt) {
132297
132563
  return { ok: true, lanes: merged };
132298
132564
  }
132299
132565
  function applyExplorerFormatSuffix(lanes) {
132300
- const generatedAgentNames = _internals94.getGeneratedAgentNames();
132566
+ const generatedAgentNames = _internals95.getGeneratedAgentNames();
132301
132567
  return lanes.map((lane) => {
132302
132568
  const role = resolveGeneratedAgentRole(lane.agent, generatedAgentNames);
132303
132569
  if (role !== "explorer")
@@ -132370,10 +132636,10 @@ function boundErrorString(text) {
132370
132636
  return `${text.slice(0, MAX_ERROR_CHARS)}${ERROR_TRUNCATION_SUFFIX}`;
132371
132637
  }
132372
132638
  function isoNow() {
132373
- return new Date(_internals94.now()).toISOString();
132639
+ return new Date(_internals95.now()).toISOString();
132374
132640
  }
132375
132641
  function makeBatchId() {
132376
- return `lanes-${_internals94.now().toString(36)}`;
132642
+ return `lanes-${_internals95.now().toString(36)}`;
132377
132643
  }
132378
132644
  function promptHash(lane, directory, batchId) {
132379
132645
  return digestText2(JSON.stringify({
@@ -132665,7 +132931,7 @@ function buildIsUpstreamCommittedWithStatus(directory, options) {
132665
132931
  const max = options?.maxCommits ?? MAX_LOG_COMMITS;
132666
132932
  let subjects;
132667
132933
  try {
132668
- subjects = _internals95.readGitLogSubjects(directory, max);
132934
+ subjects = _internals96.readGitLogSubjects(directory, max);
132669
132935
  } catch (err) {
132670
132936
  const msg = err instanceof Error ? err.message : String(err);
132671
132937
  criticalWarn(`[epic:upstream-commits] git log scan failed (degrading to permissive predicate, the activation gate may flip fail-closed): ${msg}`);
@@ -132687,7 +132953,7 @@ function buildIsUpstreamCommittedWithStatus(directory, options) {
132687
132953
  gitFailed: false
132688
132954
  };
132689
132955
  }
132690
- var _internals95 = {
132956
+ var _internals96 = {
132691
132957
  readGitLogSubjects: (cwd, max) => {
132692
132958
  return _internals4.gitExec(["log", "--no-merges", `--max-count=${max}`, "--pretty=%s"], cwd);
132693
132959
  }
@@ -133092,7 +133358,7 @@ function readPlanJson(directory) {
133092
133358
  }
133093
133359
  async function executeEpicPlanWaves(args2) {
133094
133360
  const { directory, phase, scopes } = args2;
133095
- const plan = _internals96.readPlanJson(directory);
133361
+ const plan = _internals97.readPlanJson(directory);
133096
133362
  if (!plan) {
133097
133363
  return {
133098
133364
  success: false,
@@ -133145,7 +133411,7 @@ async function executeEpicPlanWaves(args2) {
133145
133411
  try {
133146
133412
  const tasksMissingScope = [];
133147
133413
  for (const task of pendingTasks) {
133148
- const declaredScope = _internals96.readTaskScopes(directory, task.id);
133414
+ const declaredScope = _internals97.readTaskScopes(directory, task.id);
133149
133415
  const filesTouched = task.files_touched ?? [];
133150
133416
  const providedScope = scopes && task.id in scopes ? scopes[task.id] : null;
133151
133417
  if ((declaredScope === null || declaredScope.length === 0) && filesTouched.length === 0 && (providedScope === null || providedScope.length === 0)) {
@@ -133168,8 +133434,8 @@ async function executeEpicPlanWaves(args2) {
133168
133434
  };
133169
133435
  }
133170
133436
  let isUpstreamCommitted;
133171
- if (_internals96.isGitRepo(directory)) {
133172
- const evidence = _internals96.buildIsUpstreamCommittedWithStatus(directory);
133437
+ if (_internals97.isGitRepo(directory)) {
133438
+ const evidence = _internals97.buildIsUpstreamCommittedWithStatus(directory);
133173
133439
  if (evidence.gitFailed) {
133174
133440
  criticalWarn(`[epic_plan_waves] wave-planning blocked for directory=${directory} phase=${phase}: git log scan failed. Any prior promote verdict in .swarm/evidence/epic-promotions.jsonl for this phase is not backed by actual parallel execution.`);
133175
133441
  return {
@@ -133184,7 +133450,7 @@ async function executeEpicPlanWaves(args2) {
133184
133450
  }
133185
133451
  let leanConfig = { ...DEFAULT_LEAN_TURBO_CONFIG };
133186
133452
  try {
133187
- const loaded = await _internals96.loadPluginConfigWithMeta(directory);
133453
+ const loaded = await _internals97.loadPluginConfigWithMeta(directory);
133188
133454
  const userLean = loaded?.config?.turbo?.lean;
133189
133455
  if (userLean) {
133190
133456
  leanConfig = { ...leanConfig, ...userLean };
@@ -133208,7 +133474,7 @@ async function executeEpicPlanWaves(args2) {
133208
133474
  };
133209
133475
  }
133210
133476
  }
133211
- var _internals96 = {
133477
+ var _internals97 = {
133212
133478
  readPlanJson,
133213
133479
  readTaskScopes,
133214
133480
  isGitRepo: (cwd) => isGitRepo(cwd),
@@ -133240,7 +133506,7 @@ init_state2();
133240
133506
  init_divergence_recorder();
133241
133507
  init_logger();
133242
133508
  init_create_tool();
133243
- var _internals97 = {
133509
+ var _internals98 = {
133244
133510
  hasActiveEpicMode,
133245
133511
  getAgentSession,
133246
133512
  readScopeFromDisk,
@@ -133249,7 +133515,7 @@ var _internals97 = {
133249
133515
  };
133250
133516
  async function findPhaseForTask(directory, taskId) {
133251
133517
  try {
133252
- const plan = await _internals97.loadPlanJsonOnly(directory);
133518
+ const plan = await _internals98.loadPlanJsonOnly(directory);
133253
133519
  if (!plan)
133254
133520
  return;
133255
133521
  for (const phase of plan.phases) {
@@ -133262,20 +133528,20 @@ async function findPhaseForTask(directory, taskId) {
133262
133528
  }
133263
133529
  async function executeEpicRecordDivergence(args2) {
133264
133530
  const { directory, taskId, sessionID } = args2;
133265
- if (!_internals97.hasActiveEpicMode(sessionID)) {
133531
+ if (!_internals98.hasActiveEpicMode(sessionID)) {
133266
133532
  return { success: true, reason: "epic-mode-not-active" };
133267
133533
  }
133268
- const session = _internals97.getAgentSession(sessionID);
133534
+ const session = _internals98.getAgentSession(sessionID);
133269
133535
  if (!session) {
133270
133536
  return { success: true, reason: "no-session" };
133271
133537
  }
133272
- const declaredScope = _internals97.readScopeFromDisk(directory, taskId);
133538
+ const declaredScope = _internals98.readScopeFromDisk(directory, taskId);
133273
133539
  if (declaredScope === null) {
133274
133540
  return { success: true, reason: "no-scope" };
133275
133541
  }
133276
133542
  const actualFiles = session.modifiedFilesThisCoderTask ?? [];
133277
133543
  const phaseNumber = await findPhaseForTask(directory, taskId);
133278
- const result = _internals97.recordTaskDivergence({
133544
+ const result = _internals98.recordTaskDivergence({
133279
133545
  directory,
133280
133546
  sessionID,
133281
133547
  taskId,
@@ -133657,7 +133923,7 @@ init_state4();
133657
133923
 
133658
133924
  // src/turbo/lean/state-lock.ts
133659
133925
  init_file_locks();
133660
- var _internals98 = { tryAcquireLock };
133926
+ var _internals99 = { tryAcquireLock };
133661
133927
 
133662
133928
  class TurboStateLockTimeoutError extends Error {
133663
133929
  directory;
@@ -133685,7 +133951,7 @@ async function withTurboStateLock(directory, sessionID, fn2, timeoutMs = 30000)
133685
133951
  while (true) {
133686
133952
  let result;
133687
133953
  try {
133688
- result = await _internals98.tryAcquireLock(directory, lockPath, agent, sessionID);
133954
+ result = await _internals99.tryAcquireLock(directory, lockPath, agent, sessionID);
133689
133955
  } catch (acquireErr) {
133690
133956
  console.warn(`[lean-turbo] state lock acquisition error for ${sessionID} (${lockPath}), will retry: ${acquireErr instanceof Error ? acquireErr.message : String(acquireErr)}`);
133691
133957
  }
@@ -134432,7 +134698,7 @@ ${fileList}
134432
134698
  // src/tools/epic-run-phase.ts
134433
134699
  init_logger();
134434
134700
  init_create_tool();
134435
- var _internals99 = {
134701
+ var _internals100 = {
134436
134702
  loadPluginConfigWithMeta,
134437
134703
  loadPlanJsonOnly,
134438
134704
  getCoChangeData,
@@ -134454,13 +134720,13 @@ var _internals99 = {
134454
134720
  };
134455
134721
  async function executeEpicDecidePhase(args2) {
134456
134722
  const { directory, phase, sessionID } = args2;
134457
- if (!_internals99.isEpicModeActive(directory, sessionID)) {
134723
+ if (!_internals100.isEpicModeActive(directory, sessionID)) {
134458
134724
  return {
134459
134725
  success: false,
134460
134726
  reason: "epic-mode-not-active"
134461
134727
  };
134462
134728
  }
134463
- const plan = await _internals99.loadPlanJsonOnly(directory);
134729
+ const plan = await _internals100.loadPlanJsonOnly(directory);
134464
134730
  if (plan === null) {
134465
134731
  return { success: false, reason: "no-plan" };
134466
134732
  }
@@ -134490,7 +134756,7 @@ async function executeEpicDecidePhase(args2) {
134490
134756
  }
134491
134757
  const tasksMissingScope = [];
134492
134758
  for (const task of pendingTasks) {
134493
- const declaredScope = _internals99.readTaskScopes(directory, task.id);
134759
+ const declaredScope = _internals100.readTaskScopes(directory, task.id);
134494
134760
  const filesTouched = task.files_touched ?? [];
134495
134761
  if ((declaredScope === null || declaredScope.length === 0) && filesTouched.length === 0) {
134496
134762
  tasksMissingScope.push(task.id);
@@ -134510,7 +134776,7 @@ async function executeEpicDecidePhase(args2) {
134510
134776
  };
134511
134777
  }
134512
134778
  }
134513
- const { config: config3 } = _internals99.loadPluginConfigWithMeta(directory);
134779
+ const { config: config3 } = _internals100.loadPluginConfigWithMeta(directory);
134514
134780
  const modeCfg = config3.turbo?.epic?.mode;
134515
134781
  const cochangeCfg = config3.turbo?.epic?.cochange;
134516
134782
  const calibrationCfg = config3.turbo?.epic?.calibration;
@@ -134523,14 +134789,14 @@ async function executeEpicDecidePhase(args2) {
134523
134789
  let extraHotModules = [];
134524
134790
  if (calibrationEnabled) {
134525
134791
  try {
134526
- const currentCalibration = _internals99.loadCalibrationState(directory);
134792
+ const currentCalibration = _internals100.loadCalibrationState(directory);
134527
134793
  if (currentCalibration !== null) {
134528
- const history = _internals99.readDivergenceHistory(directory, {
134794
+ const history = _internals100.readDivergenceHistory(directory, {
134529
134795
  maxBytes: Number.POSITIVE_INFINITY
134530
134796
  });
134531
134797
  const newRecords = history.slice(currentCalibration.processedRecords);
134532
134798
  if (newRecords.length > 0) {
134533
- const updated = _internals99.applyCalibration(currentCalibration, newRecords, {
134799
+ const updated = _internals100.applyCalibration(currentCalibration, newRecords, {
134534
134800
  staticThreshold: staticActivationThreshold,
134535
134801
  floorThreshold: calibrationCfg?.floor_threshold,
134536
134802
  tightenStep: calibrationCfg?.tighten_step,
@@ -134539,17 +134805,17 @@ async function executeEpicDecidePhase(args2) {
134539
134805
  });
134540
134806
  let savedSuccessfully = false;
134541
134807
  try {
134542
- _internals99.saveCalibrationState(directory, updated);
134808
+ _internals100.saveCalibrationState(directory, updated);
134543
134809
  savedSuccessfully = true;
134544
134810
  } catch (err) {
134545
134811
  criticalWarn(`[epic_run_phase] calibration persist failed; ignoring this run's calibration delta to avoid drift on next run: ${err instanceof Error ? err.message : String(err)}`);
134546
134812
  }
134547
134813
  const sourceForThisRun = savedSuccessfully ? updated : currentCalibration;
134548
- effectiveThreshold = _internals99.effectiveActivationThreshold(staticActivationThreshold, sourceForThisRun);
134549
- extraHotModules = _internals99.effectiveHotModules([], sourceForThisRun);
134814
+ effectiveThreshold = _internals100.effectiveActivationThreshold(staticActivationThreshold, sourceForThisRun);
134815
+ extraHotModules = _internals100.effectiveHotModules([], sourceForThisRun);
134550
134816
  } else {
134551
- effectiveThreshold = _internals99.effectiveActivationThreshold(staticActivationThreshold, currentCalibration);
134552
- extraHotModules = _internals99.effectiveHotModules([], currentCalibration);
134817
+ effectiveThreshold = _internals100.effectiveActivationThreshold(staticActivationThreshold, currentCalibration);
134818
+ extraHotModules = _internals100.effectiveHotModules([], currentCalibration);
134553
134819
  }
134554
134820
  }
134555
134821
  } catch (err) {
@@ -134565,14 +134831,14 @@ async function executeEpicDecidePhase(args2) {
134565
134831
  }
134566
134832
  }
134567
134833
  const tasks = rawTasks.map((task) => {
134568
- const scopeFiles = _internals99.readTaskScopes(directory, task.id);
134834
+ const scopeFiles = _internals100.readTaskScopes(directory, task.id);
134569
134835
  const scope = scopeFiles ?? task.files_touched ?? [];
134570
134836
  return { id: task.id, scope };
134571
134837
  });
134572
- const { pairs, commitsObserved } = await _internals99.getCoChangeData(directory);
134838
+ const { pairs, commitsObserved } = await _internals100.getCoChangeData(directory);
134573
134839
  const isGitProject = (() => {
134574
134840
  try {
134575
- return _internals99.isGitRepo(directory);
134841
+ return _internals100.isGitRepo(directory);
134576
134842
  } catch {
134577
134843
  return false;
134578
134844
  }
@@ -134605,10 +134871,10 @@ async function executeEpicDecidePhase(args2) {
134605
134871
  const phantomDeps = [...phantomDepsSet];
134606
134872
  let isUpstreamCommitted;
134607
134873
  if (isGitProject) {
134608
- const evidence = _internals99.buildIsUpstreamCommittedWithStatus(directory);
134874
+ const evidence = _internals100.buildIsUpstreamCommittedWithStatus(directory);
134609
134875
  isUpstreamCommitted = evidence.gitFailed ? () => false : evidence.predicate;
134610
134876
  }
134611
- const verdict = _internals99.decideEpicActivation(tasks, pairs, commitsObserved, {
134877
+ const verdict = _internals100.decideEpicActivation(tasks, pairs, commitsObserved, {
134612
134878
  activationThreshold: effectiveThreshold,
134613
134879
  minCommitsForSignal,
134614
134880
  cochangeNpmiThreshold,
@@ -134620,7 +134886,7 @@ async function executeEpicDecidePhase(args2) {
134620
134886
  isUpstreamCommitted
134621
134887
  });
134622
134888
  try {
134623
- _internals99.appendPromotionEvidence(directory, {
134889
+ _internals100.appendPromotionEvidence(directory, {
134624
134890
  timestamp: new Date().toISOString(),
134625
134891
  sessionID,
134626
134892
  phase,
@@ -134630,7 +134896,7 @@ async function executeEpicDecidePhase(args2) {
134630
134896
  warn(`[epic_run_phase] promotion-evidence append failed: ${err instanceof Error ? err.message : String(err)}`);
134631
134897
  }
134632
134898
  try {
134633
- _internals99.recordEpicDecision(directory, sessionID, {
134899
+ _internals100.recordEpicDecision(directory, sessionID, {
134634
134900
  decidedAt: new Date().toISOString(),
134635
134901
  phase,
134636
134902
  decision: verdict.decision,
@@ -134927,7 +135193,7 @@ function candidateFilePath(storePath3, id) {
134927
135193
  }
134928
135194
  return path172.join(storePath3, `${id}.json`);
134929
135195
  }
134930
- var _internals100 = {
135196
+ var _internals101 = {
134931
135197
  randomUUID: crypto12.randomUUID.bind(crypto12),
134932
135198
  fs: {
134933
135199
  mkdir: fs106.mkdir,
@@ -134940,11 +135206,11 @@ var _internals100 = {
134940
135206
  function createExternalSkillStore(directory, config3) {
134941
135207
  const storePath3 = path172.join(directory, ".swarm", "skills", "candidates");
134942
135208
  async function add2(candidate) {
134943
- const id = _internals100.randomUUID();
135209
+ const id = _internals101.randomUUID();
134944
135210
  const full = { ...candidate, id };
134945
135211
  const filePath = path172.join(storePath3, `${id}.json`);
134946
- await _internals100.fs.mkdir(storePath3, { recursive: true });
134947
- await _internals100.atomicWriteFile(filePath, JSON.stringify(full, null, "\t"));
135212
+ await _internals101.fs.mkdir(storePath3, { recursive: true });
135213
+ await _internals101.atomicWriteFile(filePath, JSON.stringify(full, null, "\t"));
134948
135214
  return full;
134949
135215
  }
134950
135216
  async function get2(id) {
@@ -134954,7 +135220,7 @@ function createExternalSkillStore(directory, config3) {
134954
135220
  }
134955
135221
  let raw;
134956
135222
  try {
134957
- raw = await _internals100.fs.readFile(filePath, "utf-8");
135223
+ raw = await _internals101.fs.readFile(filePath, "utf-8");
134958
135224
  } catch (err) {
134959
135225
  if (err.code === "ENOENT") {
134960
135226
  return null;
@@ -134970,7 +135236,7 @@ function createExternalSkillStore(directory, config3) {
134970
135236
  async function list(filter) {
134971
135237
  let entries;
134972
135238
  try {
134973
- entries = await _internals100.fs.readdir(storePath3);
135239
+ entries = await _internals101.fs.readdir(storePath3);
134974
135240
  } catch (err) {
134975
135241
  if (err.code === "ENOENT") {
134976
135242
  return [];
@@ -134985,7 +135251,7 @@ function createExternalSkillStore(directory, config3) {
134985
135251
  const filePath = path172.join(storePath3, entry);
134986
135252
  let raw;
134987
135253
  try {
134988
- raw = await _internals100.fs.readFile(filePath, "utf-8");
135254
+ raw = await _internals101.fs.readFile(filePath, "utf-8");
134989
135255
  } catch {
134990
135256
  continue;
134991
135257
  }
@@ -135052,7 +135318,7 @@ function createExternalSkillStore(directory, config3) {
135052
135318
  ...patch.evaluation_history
135053
135319
  ];
135054
135320
  }
135055
- await _internals100.atomicWriteFile(filePath, JSON.stringify(updated, null, "\t"));
135321
+ await _internals101.atomicWriteFile(filePath, JSON.stringify(updated, null, "\t"));
135056
135322
  return updated;
135057
135323
  }
135058
135324
  async function deleteCandidate(id) {
@@ -135061,7 +135327,7 @@ function createExternalSkillStore(directory, config3) {
135061
135327
  return false;
135062
135328
  }
135063
135329
  try {
135064
- await _internals100.fs.unlink(filePath);
135330
+ await _internals101.fs.unlink(filePath);
135065
135331
  return true;
135066
135332
  } catch (err) {
135067
135333
  if (err.code === "ENOENT") {
@@ -135099,7 +135365,7 @@ function createExternalSkillStore(directory, config3) {
135099
135365
 
135100
135366
  // src/tools/external-skill-delete.ts
135101
135367
  init_create_tool();
135102
- var _internals101 = {
135368
+ var _internals102 = {
135103
135369
  loadConfig: (directory) => {
135104
135370
  const pluginConfig = loadPluginConfig(directory);
135105
135371
  return pluginConfig.external_skills;
@@ -135121,7 +135387,7 @@ var external_skill_delete = createSwarmTool({
135121
135387
  } catch {}
135122
135388
  let config3;
135123
135389
  try {
135124
- config3 = _internals101.loadConfig(directory);
135390
+ config3 = _internals102.loadConfig(directory);
135125
135391
  } catch {
135126
135392
  return JSON.stringify({
135127
135393
  success: false,
@@ -135463,8 +135729,99 @@ function scanInvisibleFormatChars(text, fieldName) {
135463
135729
  }
135464
135730
  return findings;
135465
135731
  }
135466
- function stripMarkdownCodeForUnsafeScan(text) {
135467
- return text.replace(/```[\s\S]*?```/g, " ").replace(/~~~[\s\S]*?~~~/g, " ").replace(/`[^`\n]*`/g, " ");
135732
+ var CODE_SPAN_OR_FENCE_REGEX = /```[\s\S]*?```|~~~[\s\S]*?~~~|`[^`\n]*`/g;
135733
+ var CODE_WARNING_ONLY_PATTERNS = new Set([
135734
+ "backtick_execution",
135735
+ "shell_substitution",
135736
+ "disk_format",
135737
+ "force_kill",
135738
+ "process_group_kill",
135739
+ "kill_all_processes"
135740
+ ]);
135741
+ function splitMarkdownCodeSegments(text) {
135742
+ const segments = [];
135743
+ let cursor = 0;
135744
+ for (const match of text.matchAll(CODE_SPAN_OR_FENCE_REGEX)) {
135745
+ const index = match.index ?? 0;
135746
+ if (index > cursor) {
135747
+ segments.push({ value: text.slice(cursor, index), isCode: false });
135748
+ }
135749
+ segments.push({ value: match[0], isCode: true });
135750
+ cursor = index + match[0].length;
135751
+ }
135752
+ if (cursor < text.length) {
135753
+ segments.push({ value: text.slice(cursor), isCode: false });
135754
+ }
135755
+ return segments.length === 0 ? [{ value: text, isCode: false }] : segments;
135756
+ }
135757
+ function getUnsafeInstructionMetadata(name) {
135758
+ const entry = UNSAFE_INSTRUCTION_PATTERNS.find((item) => item.name === name);
135759
+ return {
135760
+ description: entry?.description ?? "Destructive file removal command",
135761
+ severity: entry?.severity ?? "error"
135762
+ };
135763
+ }
135764
+ function tokenizeShellArgs(input) {
135765
+ const tokens = [];
135766
+ const tokenRegex = /"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|[^\s]+/g;
135767
+ for (const match of input.matchAll(tokenRegex)) {
135768
+ const token = match[1] ?? match[2] ?? match[0];
135769
+ if (token.length > 0)
135770
+ tokens.push(token);
135771
+ }
135772
+ return tokens;
135773
+ }
135774
+ function rmFlagHasShortOption(token, option) {
135775
+ return /^-[A-Za-z]+$/.test(token) && token.slice(1).includes(option);
135776
+ }
135777
+ function isRmOption(token) {
135778
+ return token.startsWith("-") && token !== "-";
135779
+ }
135780
+ function isDangerousRemovalTarget(rawTarget) {
135781
+ const target = rawTarget.replace(/\\/g, "/");
135782
+ if (/^[A-Za-z]:[/\\]?$/.test(target))
135783
+ return true;
135784
+ return target === "/" || target === "/*" || target === "." || target === ".." || target.startsWith(".swarm") || target.startsWith("/.swarm") || target.startsWith("~") || target.startsWith("$") || target.startsWith("${") || target.startsWith("%") || target.startsWith("/home") || target.startsWith("/Users") || target.startsWith("/etc") || target.startsWith("/bin") || target.startsWith("/sbin") || target.startsWith("/usr") || target.startsWith("/var") || /^[A-Za-z]:\/(?:Users|Windows)(?:\/|$)/.test(target);
135785
+ }
135786
+ function findDangerousRemovalCommands(text) {
135787
+ const commands = [];
135788
+ const rmCommandRegex = /\b(?<sudo>sudo\s+)?rm\b(?<args>[^\r\n`;&|]*)/gi;
135789
+ for (const match of text.matchAll(rmCommandRegex)) {
135790
+ const args2 = tokenizeShellArgs(match.groups?.args ?? "");
135791
+ const hasRecursive = args2.some((token) => token === "--recursive" || token === "-R" || rmFlagHasShortOption(token, "r") || rmFlagHasShortOption(token, "R"));
135792
+ const hasForce = args2.some((token) => token === "--force" || token === "-f" || rmFlagHasShortOption(token, "f"));
135793
+ if (!hasRecursive || !hasForce)
135794
+ continue;
135795
+ if (!args2.some((token) => !isRmOption(token) && isDangerousRemovalTarget(token))) {
135796
+ continue;
135797
+ }
135798
+ const pattern = match.groups?.sudo === undefined ? "destructive_file_removal" : "privileged_file_removal";
135799
+ commands.push({
135800
+ pattern,
135801
+ description: getUnsafeInstructionMetadata(pattern).description,
135802
+ match: match[0].trim().slice(0, 100)
135803
+ });
135804
+ }
135805
+ return commands;
135806
+ }
135807
+ function hasDangerousRemovalTarget(text) {
135808
+ return findDangerousRemovalCommands(text).length > 0;
135809
+ }
135810
+ function shouldScanUnsafePatternInSegment(entry, segment) {
135811
+ if (!segment.isCode)
135812
+ return true;
135813
+ if (CODE_WARNING_ONLY_PATTERNS.has(entry.name))
135814
+ return false;
135815
+ if (entry.name === "destructive_file_removal" || entry.name === "privileged_file_removal") {
135816
+ return false;
135817
+ }
135818
+ return true;
135819
+ }
135820
+ function getUnsafeScanSegments(field, value) {
135821
+ if (field !== "skill_body") {
135822
+ return [{ value, isCode: false }];
135823
+ }
135824
+ return splitMarkdownCodeSegments(value);
135468
135825
  }
135469
135826
  function scanPromptInjection(candidate, trustLevel = "low") {
135470
135827
  const fields = extractCandidateFields(candidate);
@@ -135532,17 +135889,37 @@ function scanUnsafeInstructions(candidate, trustLevel = "low") {
135532
135889
  const fieldsScanned = [];
135533
135890
  for (const { field, value } of fields) {
135534
135891
  fieldsScanned.push(field);
135535
- const scanValue = field === "skill_body" ? stripMarkdownCodeForUnsafeScan(value) : value;
135892
+ const scanSegments = getUnsafeScanSegments(field, value);
135893
+ if (field === "skill_body") {
135894
+ for (const segment of scanSegments) {
135895
+ if (!segment.isCode)
135896
+ continue;
135897
+ for (const command of findDangerousRemovalCommands(segment.value)) {
135898
+ findings.push({
135899
+ pattern: command.pattern,
135900
+ field,
135901
+ description: command.description,
135902
+ severity: "error",
135903
+ match: command.match
135904
+ });
135905
+ }
135906
+ }
135907
+ }
135536
135908
  for (const entry of UNSAFE_INSTRUCTION_PATTERNS) {
135537
- const match = entry.pattern.exec(scanValue);
135538
- if (match !== null) {
135539
- findings.push({
135540
- pattern: entry.name,
135541
- field,
135542
- description: entry.description,
135543
- severity: entry.severity,
135544
- match: match[0].slice(0, 100)
135545
- });
135909
+ for (const segment of scanSegments) {
135910
+ if (!shouldScanUnsafePatternInSegment(entry, segment))
135911
+ continue;
135912
+ const match = entry.pattern.exec(segment.value);
135913
+ if (match !== null) {
135914
+ findings.push({
135915
+ pattern: entry.name,
135916
+ field,
135917
+ description: entry.description,
135918
+ severity: entry.severity,
135919
+ match: match[0].slice(0, 100)
135920
+ });
135921
+ break;
135922
+ }
135546
135923
  }
135547
135924
  }
135548
135925
  }
@@ -135589,7 +135966,7 @@ function scanProvenanceIntegrity(candidate, trustLevel = "low", ttlDays) {
135589
135966
  });
135590
135967
  }
135591
135968
  fieldsScanned.push("fetched_at");
135592
- const now = new Date(_internals102.getTimestamp()).getTime();
135969
+ const now = new Date(_internals103.getTimestamp()).getTime();
135593
135970
  const fetchedAtMs = new Date(candidate.fetched_at).getTime();
135594
135971
  if (Number.isNaN(fetchedAtMs)) {
135595
135972
  findings.push({
@@ -135653,7 +136030,7 @@ function scanProvenanceIntegrity(candidate, trustLevel = "low", ttlDays) {
135653
136030
  });
135654
136031
  }
135655
136032
  fieldsScanned.push("skill_body");
135656
- const computedHash = _internals102.computeSha256(candidate.skill_body);
136033
+ const computedHash = _internals103.computeSha256(candidate.skill_body);
135657
136034
  if (computedHash !== candidate.sha256) {
135658
136035
  findings.push({
135659
136036
  pattern: "content_hash_mismatch",
@@ -135703,15 +136080,17 @@ function evaluateCandidate(candidate, options) {
135703
136080
  risk_flags: riskFlags
135704
136081
  };
135705
136082
  }
135706
- var _internals102 = {
136083
+ var _internals103 = {
135707
136084
  getTimestamp: () => new Date().toISOString(),
135708
136085
  computeSha256: (content) => createHash21("sha256").update(content).digest("hex"),
135709
- stripMarkdownCodeForUnsafeScan
136086
+ splitMarkdownCodeSegments,
136087
+ hasDangerousRemovalTarget,
136088
+ isDangerousRemovalTarget
135710
136089
  };
135711
136090
 
135712
136091
  // src/tools/external-skill-discover.ts
135713
136092
  init_create_tool();
135714
- var _internals103 = {
136093
+ var _internals104 = {
135715
136094
  fetchContent: async (_url3, _timeoutMs) => {
135716
136095
  const parsed = new URL(_url3);
135717
136096
  if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
@@ -135872,7 +136251,7 @@ var external_skill_discover = createSwarmTool({
135872
136251
  resolvedContent = content;
135873
136252
  } else {
135874
136253
  try {
135875
- const fetched = await _internals103.fetchContent(resolvedUrl, config3.fetch_timeout_ms);
136254
+ const fetched = await _internals104.fetchContent(resolvedUrl, config3.fetch_timeout_ms);
135876
136255
  if (fetched.finalUrl !== resolvedUrl && matchedSource && !isSubpathUrl(fetched.finalUrl, matchedSource.location)) {
135877
136256
  return JSON.stringify({
135878
136257
  success: false,
@@ -135894,14 +136273,14 @@ var external_skill_discover = createSwarmTool({
135894
136273
  error: `Content too large: ${resolvedContent.length} bytes exceeds max_bytes_per_candidate (${config3.max_bytes_per_candidate})`
135895
136274
  });
135896
136275
  }
135897
- const sha256 = _internals103.computeSha256(resolvedContent);
136276
+ const sha256 = _internals104.computeSha256(resolvedContent);
135898
136277
  const candidate = {
135899
- id: _internals103.uuid(),
136278
+ id: _internals104.uuid(),
135900
136279
  source_url: resolvedUrl,
135901
136280
  source_type: sourceType,
135902
136281
  publisher,
135903
136282
  sha256,
135904
- fetched_at: _internals103.getTimestamp(),
136283
+ fetched_at: _internals104.getTimestamp(),
135905
136284
  skill_name: typeof skillName === "string" ? skillName : undefined,
135906
136285
  skill_description: typeof skillDescription === "string" ? skillDescription : undefined,
135907
136286
  skill_body: resolvedContent,
@@ -135919,7 +136298,7 @@ var external_skill_discover = createSwarmTool({
135919
136298
  candidate.evaluation_history = [
135920
136299
  {
135921
136300
  verdict: result.overall_verdict,
135922
- timestamp: _internals103.getTimestamp(),
136301
+ timestamp: _internals104.getTimestamp(),
135923
136302
  actor: "system",
135924
136303
  reason: `Validation: ${result.gate_results.length} gates, ${result.all_findings.length} findings`,
135925
136304
  gate_results: result.gate_results.map((gr) => ({
@@ -135964,7 +136343,7 @@ var external_skill_discover = createSwarmTool({
135964
136343
  init_zod();
135965
136344
  init_loader();
135966
136345
  init_create_tool();
135967
- var _internals104 = {
136346
+ var _internals105 = {
135968
136347
  loadConfig: (directory) => {
135969
136348
  const pluginConfig = loadPluginConfig(directory);
135970
136349
  return pluginConfig.external_skills;
@@ -135986,7 +136365,7 @@ var external_skill_inspect = createSwarmTool({
135986
136365
  } catch {}
135987
136366
  let config3;
135988
136367
  try {
135989
- config3 = _internals104.loadConfig(directory);
136368
+ config3 = _internals105.loadConfig(directory);
135990
136369
  } catch {
135991
136370
  return JSON.stringify({
135992
136371
  success: false,
@@ -136028,7 +136407,7 @@ var external_skill_inspect = createSwarmTool({
136028
136407
  init_zod();
136029
136408
  init_loader();
136030
136409
  init_create_tool();
136031
- var _internals105 = {
136410
+ var _internals106 = {
136032
136411
  loadConfig: (directory) => {
136033
136412
  const pluginConfig = loadPluginConfig(directory);
136034
136413
  return pluginConfig.external_skills;
@@ -136064,7 +136443,7 @@ var external_skill_list = createSwarmTool({
136064
136443
  } catch {}
136065
136444
  let config3;
136066
136445
  try {
136067
- config3 = _internals105.loadConfig(directory);
136446
+ config3 = _internals106.loadConfig(directory);
136068
136447
  } catch {
136069
136448
  return JSON.stringify({
136070
136449
  success: false,
@@ -136117,7 +136496,7 @@ import { createHash as createHash23 } from "node:crypto";
136117
136496
  import * as fs107 from "node:fs/promises";
136118
136497
  import * as path173 from "node:path";
136119
136498
  init_create_tool();
136120
- var _internals106 = {
136499
+ var _internals107 = {
136121
136500
  loadConfig: (directory) => {
136122
136501
  const pluginConfig = loadPluginConfig(directory);
136123
136502
  return pluginConfig.external_skills;
@@ -136187,7 +136566,7 @@ var external_skill_promote = createSwarmTool({
136187
136566
  } catch {}
136188
136567
  let config3;
136189
136568
  try {
136190
- config3 = _internals106.loadConfig(directory);
136569
+ config3 = _internals107.loadConfig(directory);
136191
136570
  } catch {
136192
136571
  return JSON.stringify({
136193
136572
  success: false,
@@ -136257,8 +136636,8 @@ var external_skill_promote = createSwarmTool({
136257
136636
  }
136258
136637
  const targetDir = path173.join(directory, ".opencode", "skills", "generated", sanitizedSlug);
136259
136638
  const targetPath = path173.join(targetDir, "SKILL.md");
136260
- const timestamp = _internals106.getTimestamp();
136261
- const alreadyExists = await _internals106.fileExists(targetPath);
136639
+ const timestamp = _internals107.getTimestamp();
136640
+ const alreadyExists = await _internals107.fileExists(targetPath);
136262
136641
  if (alreadyExists) {
136263
136642
  return JSON.stringify({
136264
136643
  success: false,
@@ -136267,7 +136646,7 @@ var external_skill_promote = createSwarmTool({
136267
136646
  }
136268
136647
  const skillMarkdown = buildSkillMarkdown(candidate, sanitizedSlug, timestamp);
136269
136648
  try {
136270
- await _internals106.writeSkillFile(targetPath, skillMarkdown);
136649
+ await _internals107.writeSkillFile(targetPath, skillMarkdown);
136271
136650
  } catch (writeErr) {
136272
136651
  const writeError = writeErr;
136273
136652
  if (writeError?.code === "EEXIST") {
@@ -136344,7 +136723,7 @@ var external_skill_promote = createSwarmTool({
136344
136723
  init_zod();
136345
136724
  init_loader();
136346
136725
  init_create_tool();
136347
- var _internals107 = {
136726
+ var _internals108 = {
136348
136727
  loadConfig: (directory) => {
136349
136728
  const pluginConfig = loadPluginConfig(directory);
136350
136729
  return pluginConfig.external_skills;
@@ -136369,7 +136748,7 @@ var external_skill_reject = createSwarmTool({
136369
136748
  } catch {}
136370
136749
  let config3;
136371
136750
  try {
136372
- config3 = _internals107.loadConfig(directory);
136751
+ config3 = _internals108.loadConfig(directory);
136373
136752
  } catch {
136374
136753
  return JSON.stringify({
136375
136754
  success: false,
@@ -136432,7 +136811,7 @@ init_zod();
136432
136811
  init_loader();
136433
136812
  import * as path174 from "node:path";
136434
136813
  init_create_tool();
136435
- var _internals108 = {
136814
+ var _internals109 = {
136436
136815
  loadConfig: (directory) => {
136437
136816
  const pluginConfig = loadPluginConfig(directory);
136438
136817
  return pluginConfig.external_skills;
@@ -136483,7 +136862,7 @@ var external_skill_revoke = createSwarmTool({
136483
136862
  } catch {}
136484
136863
  let config3;
136485
136864
  try {
136486
- config3 = _internals108.loadConfig(directory);
136865
+ config3 = _internals109.loadConfig(directory);
136487
136866
  } catch {
136488
136867
  return JSON.stringify({
136489
136868
  success: false,
@@ -136530,8 +136909,8 @@ var external_skill_revoke = createSwarmTool({
136530
136909
  });
136531
136910
  }
136532
136911
  const skillPath = path174.join(directory, ".opencode", "skills", "generated", slug, "SKILL.md");
136533
- const skillFileRemoved = await _internals108.retireSkillFile(skillPath);
136534
- const timestamp = _internals108.getTimestamp();
136912
+ const skillFileRemoved = await _internals109.retireSkillFile(skillPath);
136913
+ const timestamp = _internals109.getTimestamp();
136535
136914
  const historyEntry = {
136536
136915
  verdict: "revoked",
136537
136916
  timestamp,
@@ -137050,7 +137429,7 @@ var ISSUE_FIELD_ALLOWLIST = new Set([
137050
137429
  "updatedAt"
137051
137430
  ]);
137052
137431
  function resolveGhBinary() {
137053
- return _internals109.resolveExecutableFromPath(["gh"]);
137432
+ return _internals110.resolveExecutableFromPath(["gh"]);
137054
137433
  }
137055
137434
  function normalizeRepo(value) {
137056
137435
  if (value === undefined || value === null || value === "")
@@ -137138,7 +137517,7 @@ var gh_evidence = createSwarmTool({
137138
137517
  if (!Array.isArray(fields)) {
137139
137518
  return JSON.stringify(fields, null, 2);
137140
137519
  }
137141
- const executable = _internals109.resolveGhBinary();
137520
+ const executable = _internals110.resolveGhBinary();
137142
137521
  if (!executable) {
137143
137522
  return JSON.stringify({
137144
137523
  error: true,
@@ -137150,7 +137529,7 @@ var gh_evidence = createSwarmTool({
137150
137529
  if (repo) {
137151
137530
  ghArgs.push("--repo", repo);
137152
137531
  }
137153
- const run = await _internals109.runExternalTool({
137532
+ const run = await _internals110.runExternalTool({
137154
137533
  executable,
137155
137534
  args: ghArgs,
137156
137535
  cwd: directory,
@@ -137201,7 +137580,7 @@ var gh_evidence = createSwarmTool({
137201
137580
  }, null, 2);
137202
137581
  }
137203
137582
  });
137204
- var _internals109 = {
137583
+ var _internals110 = {
137205
137584
  resolveExecutableFromPath,
137206
137585
  resolveGhBinary,
137207
137586
  runExternalTool
@@ -138704,7 +139083,7 @@ function formatHiveEntry(entry) {
138704
139083
  `);
138705
139084
  }
138706
139085
  var knowledge_query = createSwarmTool({
138707
- description: 'Query swarm knowledge (project-level) or hive knowledge (cross-project) with optional filters. Returns human-readable formatted text output. Use tier "all" to query both swarm and hive knowledge.',
139086
+ description: "Performs structured filter-based retrieval of swarm knowledge (project-level) or hive knowledge (cross-project). Returns formatted text for human inspection. This is the tool to use when the user knows the CATEGORY, STATUS, or SCORE they want to filter by. For semantic natural-language search, use `knowledge_recall` instead.",
138708
139087
  args: {
138709
139088
  tier: exports_external.string().optional().describe("Knowledge tier to query: 'swarm', 'hive', or 'all' (default: 'all')"),
138710
139089
  status: exports_external.string().optional().describe("Filter by status: 'candidate', 'established', 'promoted', or 'archived'"),
@@ -139211,7 +139590,7 @@ init_zod();
139211
139590
  init_config();
139212
139591
  init_state2();
139213
139592
  init_create_tool();
139214
- var _internals110 = {
139593
+ var _internals111 = {
139215
139594
  LeanTurboRunner,
139216
139595
  loadPluginConfigWithMeta
139217
139596
  };
@@ -139221,9 +139600,9 @@ async function executeLeanTurboRunPhase(args2) {
139221
139600
  let runError = null;
139222
139601
  let runner = null;
139223
139602
  try {
139224
- const { config: config3 } = _internals110.loadPluginConfigWithMeta(directory);
139603
+ const { config: config3 } = _internals111.loadPluginConfigWithMeta(directory);
139225
139604
  const leanConfig = config3.turbo?.strategy === "lean" ? config3.turbo.lean : undefined;
139226
- runner = new _internals110.LeanTurboRunner({
139605
+ runner = new _internals111.LeanTurboRunner({
139227
139606
  directory,
139228
139607
  sessionID,
139229
139608
  opencodeClient: swarmState.opencodeClient ?? null,
@@ -139559,7 +139938,7 @@ function isStaticallyEquivalent(originalCode, mutatedCode) {
139559
139938
  const strippedMutated = stripCode(mutatedCode);
139560
139939
  return strippedOriginal === strippedMutated;
139561
139940
  }
139562
- var _internals111 = {
139941
+ var _internals112 = {
139563
139942
  isStaticallyEquivalent,
139564
139943
  checkEquivalence,
139565
139944
  batchCheckEquivalence
@@ -139599,7 +139978,7 @@ async function batchCheckEquivalence(patches, llmJudge) {
139599
139978
  const results = [];
139600
139979
  for (const { patch, originalCode, mutatedCode } of patches) {
139601
139980
  try {
139602
- const result = await _internals111.checkEquivalence(patch, originalCode, mutatedCode, llmJudge);
139981
+ const result = await _internals112.checkEquivalence(patch, originalCode, mutatedCode, llmJudge);
139603
139982
  results.push(result);
139604
139983
  } catch (err) {
139605
139984
  results.push({
@@ -139659,7 +140038,7 @@ function validateTestCommand(testCommand) {
139659
140038
  var MUTATION_TIMEOUT_MS = 30000;
139660
140039
  var TOTAL_BUDGET_MS = 300000;
139661
140040
  var GIT_APPLY_TIMEOUT_MS = 5000;
139662
- var _internals112 = {
140041
+ var _internals113 = {
139663
140042
  executeMutation,
139664
140043
  computeReport,
139665
140044
  executeMutationSuite,
@@ -139691,7 +140070,7 @@ async function executeMutation(patch, testCommand, testFiles, workingDir) {
139691
140070
  };
139692
140071
  }
139693
140072
  try {
139694
- const applyResult = _internals112.spawnSync("git", ["apply", "--", patchFile], {
140073
+ const applyResult = _internals113.spawnSync("git", ["apply", "--", patchFile], {
139695
140074
  cwd: workingDir,
139696
140075
  timeout: GIT_APPLY_TIMEOUT_MS,
139697
140076
  stdio: "pipe"
@@ -139722,7 +140101,7 @@ async function executeMutation(patch, testCommand, testFiles, workingDir) {
139722
140101
  try {
139723
140102
  const safeTestFiles = testFiles.filter((f) => !f.startsWith("-"));
139724
140103
  const testArgs = safeTestFiles.length > 0 ? [...testCommand.slice(1), ...safeTestFiles] : testCommand.slice(1);
139725
- const spawnResult = _internals112.spawnSync(testCommand[0], testArgs, {
140104
+ const spawnResult = _internals113.spawnSync(testCommand[0], testArgs, {
139726
140105
  cwd: workingDir,
139727
140106
  timeout: MUTATION_TIMEOUT_MS,
139728
140107
  stdio: "pipe"
@@ -139755,7 +140134,7 @@ async function executeMutation(patch, testCommand, testFiles, workingDir) {
139755
140134
  } finally {
139756
140135
  if (patchFile) {
139757
140136
  try {
139758
- const revertResult = _internals112.spawnSync("git", ["apply", "-R", "--", patchFile], {
140137
+ const revertResult = _internals113.spawnSync("git", ["apply", "-R", "--", patchFile], {
139759
140138
  cwd: workingDir,
139760
140139
  timeout: GIT_APPLY_TIMEOUT_MS,
139761
140140
  stdio: "pipe"
@@ -139952,7 +140331,7 @@ async function executeMutationSuite(patches, testCommand, testFiles, workingDir,
139952
140331
  }
139953
140332
 
139954
140333
  // src/mutation/gate.ts
139955
- var _internals113 = {
140334
+ var _internals114 = {
139956
140335
  evaluateMutationGate,
139957
140336
  buildTestImprovementPrompt,
139958
140337
  buildMessage
@@ -139973,8 +140352,8 @@ function evaluateMutationGate(report, passThreshold = PASS_THRESHOLD, warnThresh
139973
140352
  } else {
139974
140353
  verdict = "fail";
139975
140354
  }
139976
- const testImprovementPrompt = _internals113.buildTestImprovementPrompt(report, passThreshold, verdict);
139977
- const message = _internals113.buildMessage(verdict, adjustedKillRate, report.killed, report.totalMutants, report.equivalent, warnThreshold);
140355
+ const testImprovementPrompt = _internals114.buildTestImprovementPrompt(report, passThreshold, verdict);
140356
+ const message = _internals114.buildMessage(verdict, adjustedKillRate, report.killed, report.totalMutants, report.equivalent, warnThreshold);
139978
140357
  return {
139979
140358
  verdict,
139980
140359
  killRate: report.killRate,
@@ -140119,7 +140498,7 @@ var OSV_MAX_STDERR_BYTES = 256 * 1024;
140119
140498
  var DEFAULT_MAX_RESULTS3 = 200;
140120
140499
  var HARD_CAP_RESULTS3 = 2000;
140121
140500
  function resolveOsvScannerBinary() {
140122
- return _internals114.resolveExecutableFromPath(["osv-scanner"]);
140501
+ return _internals115.resolveExecutableFromPath(["osv-scanner"]);
140123
140502
  }
140124
140503
  function normalizeScanPath(value, workspace) {
140125
140504
  const raw = typeof value === "string" && value.trim() ? value.trim() : ".";
@@ -140207,7 +140586,7 @@ var osv_scan = createSwarmTool({
140207
140586
  }, null, 2);
140208
140587
  }
140209
140588
  const maxResults = sanitizeMaxResults2(obj.max_results);
140210
- const executable = _internals114.resolveOsvScannerBinary();
140589
+ const executable = _internals115.resolveOsvScannerBinary();
140211
140590
  if (!executable) {
140212
140591
  return JSON.stringify({
140213
140592
  error: true,
@@ -140217,7 +140596,7 @@ var osv_scan = createSwarmTool({
140217
140596
  }
140218
140597
  const target = scanPath === "." ? "." : `./${scanPath}`;
140219
140598
  const osvArgs = ["scan", "--format", "json", target];
140220
- const run = await _internals114.runExternalTool({
140599
+ const run = await _internals115.runExternalTool({
140221
140600
  executable,
140222
140601
  args: osvArgs,
140223
140602
  cwd: directory,
@@ -140267,7 +140646,7 @@ var osv_scan = createSwarmTool({
140267
140646
  }, null, 2);
140268
140647
  }
140269
140648
  });
140270
- var _internals114 = {
140649
+ var _internals115 = {
140271
140650
  resolveExecutableFromPath,
140272
140651
  resolveOsvScannerBinary,
140273
140652
  runExternalTool,
@@ -141964,7 +142343,7 @@ function listLaneEvidenceSync(directory, phase) {
141964
142343
  }
141965
142344
  return laneIds;
141966
142345
  }
141967
- var _internals115 = {
142346
+ var _internals116 = {
141968
142347
  listActiveLocks,
141969
142348
  readPersisted: readPersisted3,
141970
142349
  readPlanJson: defaultReadPlanJson,
@@ -142025,7 +142404,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
142025
142404
  reason: "Lean Turbo state unreadable or missing"
142026
142405
  };
142027
142406
  }
142028
- const persisted = _internals115.readPersisted(directory);
142407
+ const persisted = _internals116.readPersisted(directory);
142029
142408
  if (!persisted) {
142030
142409
  return {
142031
142410
  ok: false,
@@ -142089,7 +142468,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
142089
142468
  }
142090
142469
  }
142091
142470
  if (runState.lanes.length > 0) {
142092
- const evidenceLaneIds = new Set(_internals115.listLaneEvidenceSync(directory, phase));
142471
+ const evidenceLaneIds = new Set(_internals116.listLaneEvidenceSync(directory, phase));
142093
142472
  for (const lane of runState.lanes) {
142094
142473
  if ((lane.status === "completed" || lane.status === "failed") && !evidenceLaneIds.has(lane.laneId)) {
142095
142474
  return {
@@ -142099,7 +142478,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
142099
142478
  }
142100
142479
  }
142101
142480
  }
142102
- const activeLocks = _internals115.listActiveLocks(directory);
142481
+ const activeLocks = _internals116.listActiveLocks(directory);
142103
142482
  const phaseLaneIds = new Set(laneIds);
142104
142483
  for (const lock of activeLocks) {
142105
142484
  if (lock.laneId && phaseLaneIds.has(lock.laneId)) {
@@ -142119,7 +142498,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
142119
142498
  }
142120
142499
  const serialDegradedTasks = runState.degradedTasks.filter((dt) => !laneTaskIds.has(dt.taskId));
142121
142500
  if (serialDegradedTasks.length > 0) {
142122
- const plan = _internals115.readPlanJson(directory);
142501
+ const plan = _internals116.readPlanJson(directory);
142123
142502
  if (!plan) {
142124
142503
  return {
142125
142504
  ok: false,
@@ -142163,7 +142542,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
142163
142542
  }
142164
142543
  const serializedTasks = runState.serializedTasks;
142165
142544
  if (Array.isArray(serializedTasks) && serializedTasks.length > 0) {
142166
- const plan = _internals115.readPlanJson(directory);
142545
+ const plan = _internals116.readPlanJson(directory);
142167
142546
  if (!plan) {
142168
142547
  return {
142169
142548
  ok: false,
@@ -142222,7 +142601,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
142222
142601
  }
142223
142602
  let reviewerVerdict = runState.lastReviewerVerdict;
142224
142603
  if (!reviewerVerdict) {
142225
- const evidence = _internals115.readReviewerEvidence(directory, phase);
142604
+ const evidence = _internals116.readReviewerEvidence(directory, phase);
142226
142605
  reviewerVerdict = evidence?.verdict ?? undefined;
142227
142606
  }
142228
142607
  if (mergedConfig.phase_reviewer) {
@@ -142235,7 +142614,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
142235
142614
  }
142236
142615
  let criticVerdict = runState.lastCriticVerdict;
142237
142616
  if (!criticVerdict) {
142238
- const evidence = _internals115.readCriticEvidence(directory, phase);
142617
+ const evidence = _internals116.readCriticEvidence(directory, phase);
142239
142618
  criticVerdict = evidence?.verdict ?? undefined;
142240
142619
  }
142241
142620
  if (mergedConfig.phase_critic) {
@@ -143419,7 +143798,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
143419
143798
  phase_critic: leanConfig.phase_critic,
143420
143799
  integrated_diff_required: leanConfig.integrated_diff_required
143421
143800
  } : undefined;
143422
- const leanCheck = _internals115.verifyLeanTurboPhaseReady(dir, phase, sessionID, leanPhaseReadyConfig);
143801
+ const leanCheck = _internals116.verifyLeanTurboPhaseReady(dir, phase, sessionID, leanPhaseReadyConfig);
143423
143802
  if (!leanCheck.ok) {
143424
143803
  return JSON.stringify({
143425
143804
  success: false,
@@ -145816,11 +146195,11 @@ var quality_budget = createSwarmTool({
145816
146195
  }).optional().describe("Quality budget thresholds")
145817
146196
  },
145818
146197
  async execute(args2, directory) {
145819
- const result = await _internals117.qualityBudget(args2, directory);
146198
+ const result = await _internals118.qualityBudget(args2, directory);
145820
146199
  return JSON.stringify(result);
145821
146200
  }
145822
146201
  });
145823
- var _internals117 = {
146202
+ var _internals118 = {
145824
146203
  qualityBudget
145825
146204
  };
145826
146205
 
@@ -146545,7 +146924,7 @@ var DEFAULT_RULES_DIR = ".swarm/semgrep-rules";
146545
146924
  var DEFAULT_TIMEOUT_MS4 = 30000;
146546
146925
  var MAX_OUTPUT_BYTES8 = 10 * 1024 * 1024;
146547
146926
  var KILL_GRACE_MS = 2000;
146548
- var _internals118 = {
146927
+ var _internals119 = {
146549
146928
  isSemgrepAvailable,
146550
146929
  checkSemgrepAvailable,
146551
146930
  resetSemgrepCache,
@@ -146571,7 +146950,7 @@ function isSemgrepAvailable() {
146571
146950
  }
146572
146951
  }
146573
146952
  async function checkSemgrepAvailable() {
146574
- return _internals118.isSemgrepAvailable();
146953
+ return _internals119.isSemgrepAvailable();
146575
146954
  }
146576
146955
  function resetSemgrepCache() {
146577
146956
  semgrepAvailableCache = null;
@@ -146757,12 +147136,12 @@ async function runSemgrep(options) {
146757
147136
  const timeoutMs = options.timeoutMs || DEFAULT_TIMEOUT_MS4;
146758
147137
  if (files.length === 0) {
146759
147138
  return {
146760
- available: _internals118.isSemgrepAvailable(),
147139
+ available: _internals119.isSemgrepAvailable(),
146761
147140
  findings: [],
146762
147141
  engine: "tier_a"
146763
147142
  };
146764
147143
  }
146765
- if (!_internals118.isSemgrepAvailable()) {
147144
+ if (!_internals119.isSemgrepAvailable()) {
146766
147145
  return {
146767
147146
  available: false,
146768
147147
  findings: [],
@@ -146929,7 +147308,7 @@ function assignOccurrenceIndices(findings, directory) {
146929
147308
  }
146930
147309
  const occIdx = countMap.get(baseKey) ?? 0;
146931
147310
  countMap.set(baseKey, occIdx + 1);
146932
- const fp = _internals119.fingerprintFinding(finding, directory, occIdx);
147311
+ const fp = _internals120.fingerprintFinding(finding, directory, occIdx);
146933
147312
  return {
146934
147313
  finding,
146935
147314
  index: occIdx,
@@ -146998,7 +147377,7 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
146998
147377
  }
146999
147378
  } catch {}
147000
147379
  const scannedRelFiles = new Set(scannedFiles.map((f) => normalizeFindingPath(directory, f)));
147001
- const indexed = _internals119.assignOccurrenceIndices(findings, directory);
147380
+ const indexed = _internals120.assignOccurrenceIndices(findings, directory);
147002
147381
  if (existing && !opts?.force) {
147003
147382
  const prunedFingerprints = existing.fingerprints.filter((fp) => {
147004
147383
  const relFile = fp.slice(0, fp.indexOf("|"));
@@ -147138,7 +147517,7 @@ function loadBaseline(directory, phase) {
147138
147517
  };
147139
147518
  }
147140
147519
  }
147141
- var _internals119 = {
147520
+ var _internals120 = {
147142
147521
  fingerprintFinding,
147143
147522
  assignOccurrenceIndices,
147144
147523
  captureOrMergeBaseline,
@@ -147548,11 +147927,11 @@ var sast_scan = createSwarmTool({
147548
147927
  capture_baseline: safeArgs.capture_baseline,
147549
147928
  phase: safeArgs.phase
147550
147929
  };
147551
- const result = await _internals120.sastScan(input, directory);
147930
+ const result = await _internals121.sastScan(input, directory);
147552
147931
  return JSON.stringify(result, null, 2);
147553
147932
  }
147554
147933
  });
147555
- var _internals120 = {
147934
+ var _internals121 = {
147556
147935
  sastScan,
147557
147936
  sast_scan
147558
147937
  };
@@ -151125,10 +151504,10 @@ function resolvePackagedRipgrep() {
151125
151504
  }
151126
151505
  }
151127
151506
  function resolveRipgrepBinary() {
151128
- return _internals121.resolvePackagedRipgrep() ?? _internals121.resolveExecutableFromPath(["rg"]);
151507
+ return _internals122.resolvePackagedRipgrep() ?? _internals122.resolveExecutableFromPath(["rg"]);
151129
151508
  }
151130
151509
  async function ripgrepSearch(opts) {
151131
- const rgPath = _internals121.resolveRipgrepBinary();
151510
+ const rgPath = _internals122.resolveRipgrepBinary();
151132
151511
  if (!rgPath) {
151133
151512
  return {
151134
151513
  error: true,
@@ -151151,7 +151530,7 @@ async function ripgrepSearch(opts) {
151151
151530
  args2.push("--fixed-strings");
151152
151531
  }
151153
151532
  args2.push("--", opts.query, ".");
151154
- const run = await _internals121.runExternalTool({
151533
+ const run = await _internals122.runExternalTool({
151155
151534
  executable: rgPath,
151156
151535
  args: args2,
151157
151536
  cwd: opts.workspace,
@@ -151455,7 +151834,7 @@ var search = createSwarmTool({
151455
151834
  }, null, 2);
151456
151835
  }
151457
151836
  let result;
151458
- if (_internals121.resolveRipgrepBinary()) {
151837
+ if (_internals122.resolveRipgrepBinary()) {
151459
151838
  result = await ripgrepSearch({
151460
151839
  query,
151461
151840
  mode,
@@ -151482,7 +151861,7 @@ var search = createSwarmTool({
151482
151861
  return JSON.stringify(result, null, 2);
151483
151862
  }
151484
151863
  });
151485
- var _internals121 = {
151864
+ var _internals122 = {
151486
151865
  resolvePackagedRipgrep,
151487
151866
  resolveExecutableFromPath,
151488
151867
  resolveRipgrepBinary,
@@ -151842,18 +152221,18 @@ var run_stale_reconciliation = createSwarmTool({
151842
152221
  if (typeof directory !== "string" || !directory) {
151843
152222
  return JSON.stringify({ found: 0, skills: [] }, null, 2);
151844
152223
  }
151845
- const archivedIds = await _internals122.getArchivedKnowledgeIds(directory);
152224
+ const archivedIds = await _internals123.getArchivedKnowledgeIds(directory);
151846
152225
  const archivedSet = new Set(archivedIds);
151847
152226
  const allKnownIds = new Set;
151848
- const swarmPath = _internals122.resolveSwarmKnowledgePath(directory);
151849
- const hivePath = _internals122.resolveHiveKnowledgePath();
152227
+ const swarmPath = _internals123.resolveSwarmKnowledgePath(directory);
152228
+ const hivePath = _internals123.resolveHiveKnowledgePath();
151850
152229
  try {
151851
- const swarmEntries = await _internals122.readKnowledge(swarmPath);
152230
+ const swarmEntries = await _internals123.readKnowledge(swarmPath);
151852
152231
  for (const e of swarmEntries)
151853
152232
  allKnownIds.add(e.id);
151854
152233
  } catch {}
151855
152234
  try {
151856
- const hiveEntries = await _internals122.readKnowledge(hivePath);
152235
+ const hiveEntries = await _internals123.readKnowledge(hivePath);
151857
152236
  for (const e of hiveEntries)
151858
152237
  allKnownIds.add(e.id);
151859
152238
  } catch {}
@@ -151862,9 +152241,9 @@ var run_stale_reconciliation = createSwarmTool({
151862
152241
  join165(directory, ".opencode", "skills", "generated"),
151863
152242
  join165(directory, ".swarm", "skills", "proposals")
151864
152243
  ]) {
151865
- if (!_internals122.existsSync(dir))
152244
+ if (!_internals123.existsSync(dir))
151866
152245
  continue;
151867
- const entries = await _internals122.readdir(dir, { withFileTypes: true });
152246
+ const entries = await _internals123.readdir(dir, { withFileTypes: true });
151868
152247
  for (const entry of entries) {
151869
152248
  if (entry.isDirectory()) {
151870
152249
  skillEntries.push({
@@ -151885,10 +152264,10 @@ var run_stale_reconciliation = createSwarmTool({
151885
152264
  const results = [];
151886
152265
  for (const { slug, path: path209, isProposal } of skillEntries) {
151887
152266
  const skillMdPath = isProposal ? path209 : join165(path209, "SKILL.md");
151888
- if (!_internals122.existsSync(skillMdPath))
152267
+ if (!_internals123.existsSync(skillMdPath))
151889
152268
  continue;
151890
- const content = await _internals122.readFile(skillMdPath, "utf-8");
151891
- const fm = _internals122.parseDraftFrontmatter(content);
152269
+ const content = await _internals123.readFile(skillMdPath, "utf-8");
152270
+ const fm = _internals123.parseDraftFrontmatter(content);
151892
152271
  const sourceIds = fm?.sourceKnowledgeIds ?? [];
151893
152272
  if (sourceIds.length === 0)
151894
152273
  continue;
@@ -151898,9 +152277,9 @@ var run_stale_reconciliation = createSwarmTool({
151898
152277
  if (args2.clear) {
151899
152278
  if (!isProposal) {
151900
152279
  const markerPath = join165(path209, "stale.marker");
151901
- if (_internals122.existsSync(markerPath)) {
152280
+ if (_internals123.existsSync(markerPath)) {
151902
152281
  try {
151903
- await _internals122.clearSkillStale(path209);
152282
+ await _internals123.clearSkillStale(path209);
151904
152283
  results.push({
151905
152284
  slug,
151906
152285
  reason: affected.join(", "),
@@ -151912,7 +152291,7 @@ var run_stale_reconciliation = createSwarmTool({
151912
152291
  } else {
151913
152292
  if (!isProposal) {
151914
152293
  try {
151915
- await _internals122.retireOrMarkStale(directory, path209, archivedSet);
152294
+ await _internals123.retireOrMarkStale(directory, path209, archivedSet);
151916
152295
  results.push({
151917
152296
  slug,
151918
152297
  reason: affected.join(", "),
@@ -151925,7 +152304,7 @@ var run_stale_reconciliation = createSwarmTool({
151925
152304
  return JSON.stringify({ found: results.length, skills: results }, null, 2);
151926
152305
  }
151927
152306
  });
151928
- var _internals122 = {
152307
+ var _internals123 = {
151929
152308
  run_stale_reconciliation,
151930
152309
  clearSkillStale,
151931
152310
  retireOrMarkStale,
@@ -152903,7 +153282,7 @@ var swarm_memory_propose = createSwarmTool({
152903
153282
  evidenceRefs: exports_external.array(exports_external.string().min(1).max(500)).max(20).optional().describe("Evidence refs such as files, commits, test outputs, or URLs")
152904
153283
  },
152905
153284
  execute: async (args2, directory, ctx) => {
152906
- const { config: config3 } = _internals123.loadPluginConfigWithMeta(directory);
153285
+ const { config: config3 } = _internals124.loadPluginConfigWithMeta(directory);
152907
153286
  if (config3.memory?.enabled !== true) {
152908
153287
  return JSON.stringify({
152909
153288
  success: false,
@@ -152919,7 +153298,7 @@ var swarm_memory_propose = createSwarmTool({
152919
153298
  });
152920
153299
  }
152921
153300
  const agent = getContextAgent3(ctx);
152922
- const gateway = _internals123.createMemoryGateway({
153301
+ const gateway = _internals124.createMemoryGateway({
152923
153302
  directory,
152924
153303
  sessionID: ctx?.sessionID,
152925
153304
  agentRole: agent,
@@ -152944,7 +153323,7 @@ var swarm_memory_propose = createSwarmTool({
152944
153323
  }
152945
153324
  }
152946
153325
  });
152947
- var _internals123 = {
153326
+ var _internals124 = {
152948
153327
  loadPluginConfigWithMeta,
152949
153328
  createMemoryGateway
152950
153329
  };
@@ -152982,7 +153361,7 @@ var swarm_memory_recall = createSwarmTool({
152982
153361
  maxItems: exports_external.number().int().min(1).max(20).optional().describe("Maximum memories to return")
152983
153362
  },
152984
153363
  execute: async (args2, directory, ctx) => {
152985
- const { config: config3 } = _internals124.loadPluginConfigWithMeta(directory);
153364
+ const { config: config3 } = _internals125.loadPluginConfigWithMeta(directory);
152986
153365
  if (config3.memory?.enabled !== true) {
152987
153366
  return JSON.stringify({
152988
153367
  success: false,
@@ -152998,7 +153377,7 @@ var swarm_memory_recall = createSwarmTool({
152998
153377
  });
152999
153378
  }
153000
153379
  const agent = getContextAgent4(ctx);
153001
- const gateway = _internals124.createMemoryGateway({
153380
+ const gateway = _internals125.createMemoryGateway({
153002
153381
  directory,
153003
153382
  sessionID: ctx?.sessionID,
153004
153383
  agentRole: agent,
@@ -153031,7 +153410,7 @@ var RecallArgsSchema = exports_external.object({
153031
153410
  kinds: exports_external.array(exports_external.enum(MEMORY_KINDS2)).optional(),
153032
153411
  maxItems: exports_external.number().int().min(1).max(20).optional()
153033
153412
  });
153034
- var _internals124 = {
153413
+ var _internals125 = {
153035
153414
  loadPluginConfigWithMeta,
153036
153415
  createMemoryGateway
153037
153416
  };
@@ -153557,7 +153936,7 @@ import * as path214 from "node:path";
153557
153936
  init_bun_compat();
153558
153937
  import * as fs138 from "node:fs";
153559
153938
  import * as path213 from "node:path";
153560
- var _internals125 = { bunSpawn };
153939
+ var _internals126 = { bunSpawn };
153561
153940
  var _swarmGitExcludedChecked = false;
153562
153941
  function fileCoversSwarm(content) {
153563
153942
  for (const rawLine of content.split(`
@@ -153590,7 +153969,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
153590
153969
  checkIgnoreExitCode
153591
153970
  ] = await Promise.all([
153592
153971
  (async () => {
153593
- const proc = _internals125.bunSpawn(["git", "-C", directory, "rev-parse", "--show-toplevel"], GIT_SPAWN_OPTIONS);
153972
+ const proc = _internals126.bunSpawn(["git", "-C", directory, "rev-parse", "--show-toplevel"], GIT_SPAWN_OPTIONS);
153594
153973
  try {
153595
153974
  return await Promise.all([proc.exited, proc.stdout.text()]);
153596
153975
  } finally {
@@ -153600,7 +153979,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
153600
153979
  }
153601
153980
  })(),
153602
153981
  (async () => {
153603
- const proc = _internals125.bunSpawn(["git", "-C", directory, "rev-parse", "--git-path", "info/exclude"], GIT_SPAWN_OPTIONS);
153982
+ const proc = _internals126.bunSpawn(["git", "-C", directory, "rev-parse", "--git-path", "info/exclude"], GIT_SPAWN_OPTIONS);
153604
153983
  try {
153605
153984
  return await Promise.all([proc.exited, proc.stdout.text()]);
153606
153985
  } finally {
@@ -153610,7 +153989,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
153610
153989
  }
153611
153990
  })(),
153612
153991
  (async () => {
153613
- const proc = _internals125.bunSpawn(["git", "-C", directory, "check-ignore", "-q", ".swarm/.gitkeep"], GIT_SPAWN_OPTIONS);
153992
+ const proc = _internals126.bunSpawn(["git", "-C", directory, "check-ignore", "-q", ".swarm/.gitkeep"], GIT_SPAWN_OPTIONS);
153614
153993
  try {
153615
153994
  return await proc.exited;
153616
153995
  } finally {
@@ -153649,7 +154028,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
153649
154028
  }
153650
154029
  } catch {}
153651
154030
  }
153652
- const trackedProc = _internals125.bunSpawn(["git", "-C", directory, "ls-files", "--", ".swarm"], GIT_SPAWN_OPTIONS);
154031
+ const trackedProc = _internals126.bunSpawn(["git", "-C", directory, "ls-files", "--", ".swarm"], GIT_SPAWN_OPTIONS);
153653
154032
  let trackedExitCode;
153654
154033
  let trackedOutput;
153655
154034
  try {
@@ -153674,7 +154053,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
153674
154053
  }
153675
154054
 
153676
154055
  // src/hooks/diff-scope.ts
153677
- var _internals126 = { bunSpawn };
154056
+ var _internals127 = { bunSpawn };
153678
154057
  function getDeclaredScope(taskId, directory) {
153679
154058
  try {
153680
154059
  const planPath = path214.join(directory, ".swarm", "plan.json");
@@ -153709,7 +154088,7 @@ var GIT_DIFF_SPAWN_OPTIONS = {
153709
154088
  };
153710
154089
  async function getChangedFiles2(directory) {
153711
154090
  try {
153712
- const proc = _internals126.bunSpawn(["git", "diff", "--name-only", "HEAD~1"], {
154091
+ const proc = _internals127.bunSpawn(["git", "diff", "--name-only", "HEAD~1"], {
153713
154092
  cwd: directory,
153714
154093
  ...GIT_DIFF_SPAWN_OPTIONS
153715
154094
  });
@@ -153726,7 +154105,7 @@ async function getChangedFiles2(directory) {
153726
154105
  return stdout.trim().split(`
153727
154106
  `).map((f) => f.trim()).filter((f) => f.length > 0);
153728
154107
  }
153729
- const proc2 = _internals126.bunSpawn(["git", "diff", "--name-only", "HEAD"], {
154108
+ const proc2 = _internals127.bunSpawn(["git", "diff", "--name-only", "HEAD"], {
153730
154109
  cwd: directory,
153731
154110
  ...GIT_DIFF_SPAWN_OPTIONS
153732
154111
  });
@@ -153784,7 +154163,7 @@ init_telemetry();
153784
154163
  init_file_locks();
153785
154164
  import * as fs140 from "node:fs";
153786
154165
  import * as path215 from "node:path";
153787
- var _internals127 = {
154166
+ var _internals128 = {
153788
154167
  listActiveLocks,
153789
154168
  verifyLeanTurboTaskCompletion
153790
154169
  };
@@ -153926,7 +154305,7 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
153926
154305
  }
153927
154306
  };
153928
154307
  }
153929
- const activeLocks = _internals127.listActiveLocks(directory);
154308
+ const activeLocks = _internals128.listActiveLocks(directory);
153930
154309
  const laneLocks = activeLocks.filter((lock) => lock.laneId === lane.laneId);
153931
154310
  if (laneLocks.length > 0) {
153932
154311
  return {
@@ -153993,7 +154372,7 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
153993
154372
  init_task_id();
153994
154373
  init_create_tool();
153995
154374
  init_resolve_working_directory();
153996
- var _internals128 = {
154375
+ var _internals129 = {
153997
154376
  tryAcquireLock,
153998
154377
  updateTaskStatus,
153999
154378
  resolveWorkingDirectory
@@ -154090,7 +154469,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
154090
154469
  }
154091
154470
  let resolvedDir;
154092
154471
  if (fallbackDir) {
154093
- const resolveResult = _internals128.resolveWorkingDirectory(workingDirectory, fallbackDir);
154472
+ const resolveResult = _internals129.resolveWorkingDirectory(workingDirectory, fallbackDir);
154094
154473
  if (resolveResult.success) {
154095
154474
  resolvedDir = resolveResult.directory;
154096
154475
  } else {
@@ -154437,7 +154816,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
154437
154816
  }
154438
154817
  }
154439
154818
  let directory;
154440
- const resolveResult = _internals128.resolveWorkingDirectory(args2.working_directory, fallbackDir);
154819
+ const resolveResult = _internals129.resolveWorkingDirectory(args2.working_directory, fallbackDir);
154441
154820
  if (!resolveResult.success) {
154442
154821
  return {
154443
154822
  success: false,
@@ -154530,7 +154909,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
154530
154909
  }
154531
154910
  let lockResult;
154532
154911
  try {
154533
- lockResult = await _internals128.tryAcquireLock(directory, planFilePath, agentName, lockTaskId);
154912
+ lockResult = await _internals129.tryAcquireLock(directory, planFilePath, agentName, lockTaskId);
154534
154913
  } catch (error93) {
154535
154914
  return {
154536
154915
  success: false,
@@ -154549,7 +154928,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
154549
154928
  };
154550
154929
  }
154551
154930
  try {
154552
- const updatedPlan = await _internals128.updateTaskStatus(directory, args2.task_id, args2.status);
154931
+ const updatedPlan = await _internals129.updateTaskStatus(directory, args2.task_id, args2.status);
154553
154932
  if (args2.status === "completed") {
154554
154933
  for (const [_sessionId, session] of swarmState.agentSessions) {
154555
154934
  if (!(session.taskWorkflowStates instanceof Map)) {
@@ -155204,7 +155583,7 @@ var web_fetch = createSwarmTool({
155204
155583
  };
155205
155584
  return JSON.stringify(fail, null, 2);
155206
155585
  }
155207
- const config3 = _internals129.loadPluginConfig(dirResult.directory);
155586
+ const config3 = _internals130.loadPluginConfig(dirResult.directory);
155208
155587
  const generalConfig = config3.council?.general;
155209
155588
  if (!generalConfig || generalConfig.enabled !== true) {
155210
155589
  const fail = {
@@ -155214,7 +155593,7 @@ var web_fetch = createSwarmTool({
155214
155593
  };
155215
155594
  return JSON.stringify(fail, null, 2);
155216
155595
  }
155217
- const validated = await validateFetchUrl(parsed.data.url, _internals129.dnsLookup);
155596
+ const validated = await validateFetchUrl(parsed.data.url, _internals130.dnsLookup);
155218
155597
  if (!validated.ok) {
155219
155598
  const fail = {
155220
155599
  success: false,
@@ -155225,7 +155604,7 @@ var web_fetch = createSwarmTool({
155225
155604
  }
155226
155605
  const maxBytes = parsed.data.max_bytes ?? DEFAULT_MAX_BYTES;
155227
155606
  const timeoutMs = parsed.data.timeout_ms ?? DEFAULT_TIMEOUT_MS5;
155228
- const result = await boundedFetch({ url: validated.url, address: validated.address }, maxBytes, timeoutMs, _internals129);
155607
+ const result = await boundedFetch({ url: validated.url, address: validated.address }, maxBytes, timeoutMs, _internals130);
155229
155608
  if (!result.ok) {
155230
155609
  const fail = {
155231
155610
  success: false,
@@ -155260,7 +155639,7 @@ var web_fetch = createSwarmTool({
155260
155639
  });
155261
155640
  async function captureFetchEvidence(directory, url3, title, text) {
155262
155641
  try {
155263
- const written = await _internals129.writeEvidenceDocuments(directory, [
155642
+ const written = await _internals130.writeEvidenceDocuments(directory, [
155264
155643
  {
155265
155644
  sourceType: "crawl",
155266
155645
  url: url3,
@@ -155281,7 +155660,7 @@ async function captureFetchEvidence(directory, url3, title, text) {
155281
155660
  };
155282
155661
  }
155283
155662
  }
155284
- var _internals129 = {
155663
+ var _internals130 = {
155285
155664
  httpRequest: performHttpRequest,
155286
155665
  dnsLookup: lookup,
155287
155666
  loadPluginConfig,
@@ -155595,7 +155974,7 @@ var web_search = createSwarmTool({
155595
155974
  });
155596
155975
  async function captureSearchEvidence(directory, query, results) {
155597
155976
  try {
155598
- const written = await _internals130.writeEvidenceDocuments(directory, results.map((result) => ({
155977
+ const written = await _internals131.writeEvidenceDocuments(directory, results.map((result) => ({
155599
155978
  sourceType: "web_search",
155600
155979
  query,
155601
155980
  title: result.title,
@@ -155623,7 +156002,7 @@ async function captureSearchEvidence(directory, query, results) {
155623
156002
  };
155624
156003
  }
155625
156004
  }
155626
- var _internals130 = {
156005
+ var _internals131 = {
155627
156006
  writeEvidenceDocuments
155628
156007
  };
155629
156008
 
@@ -155756,22 +156135,56 @@ var write_architecture_supervisor_evidence = createSwarmTool({
155756
156135
  // src/tools/write-drift-evidence.ts
155757
156136
  init_zod();
155758
156137
  init_qa_gate_profile();
155759
- init_utils2();
155760
- init_ledger();
155761
- init_manager();
155762
- init_create_tool();
155763
156138
  import fs142 from "node:fs";
155764
156139
  import path219 from "node:path";
155765
- function normalizeVerdict(verdict) {
156140
+
156141
+ // src/evidence/normalize-verdict.ts
156142
+ function normalizeVerdict2(verdict) {
156143
+ if (!LIVE_VERDICT_SET_2.includes(verdict)) {
156144
+ throw new Error(`Invalid verdict: must be 'APPROVED' or 'NEEDS_REVISION', got '${verdict}'`);
156145
+ }
155766
156146
  switch (verdict) {
155767
156147
  case "APPROVED":
155768
156148
  return "approved";
155769
156149
  case "NEEDS_REVISION":
155770
156150
  return "rejected";
155771
156151
  default:
155772
- throw new Error(`Invalid verdict: must be 'APPROVED' or 'NEEDS_REVISION', got '${verdict}'`);
156152
+ return verdict.toLowerCase();
155773
156153
  }
155774
156154
  }
156155
+ function normalizeVerdict4(verdict) {
156156
+ if (!LIVE_VERDICT_SET_4.includes(verdict)) {
156157
+ throw new Error(`Invalid verdict: must be 'PASS', 'WARN', 'FAIL', or 'SKIP', got '${verdict}'`);
156158
+ }
156159
+ switch (verdict) {
156160
+ case "PASS":
156161
+ return "pass";
156162
+ case "WARN":
156163
+ return "warn";
156164
+ case "FAIL":
156165
+ return "fail";
156166
+ case "SKIP":
156167
+ return "skip";
156168
+ default:
156169
+ return verdict.toLowerCase();
156170
+ }
156171
+ }
156172
+ var LIVE_VERDICT_SET_2 = ["APPROVED", "NEEDS_REVISION"];
156173
+ var LIVE_VERDICT_SET_4 = ["PASS", "WARN", "FAIL", "SKIP"];
156174
+ var VERDICT_SET_2 = LIVE_VERDICT_SET_2;
156175
+ var VERDICT_SET_4 = LIVE_VERDICT_SET_4;
156176
+ function isAcceptedVerdict2(v) {
156177
+ return LIVE_VERDICT_SET_2.includes(v);
156178
+ }
156179
+ function isAcceptedVerdict4(v) {
156180
+ return LIVE_VERDICT_SET_4.includes(v);
156181
+ }
156182
+
156183
+ // src/tools/write-drift-evidence.ts
156184
+ init_utils2();
156185
+ init_ledger();
156186
+ init_manager();
156187
+ init_create_tool();
155775
156188
  async function executeWriteDriftEvidence(args2, directory) {
155776
156189
  const phase = args2.phase;
155777
156190
  if (!Number.isInteger(phase) || phase < 1) {
@@ -155781,8 +156194,7 @@ async function executeWriteDriftEvidence(args2, directory) {
155781
156194
  message: "Invalid phase: must be a positive integer"
155782
156195
  }, null, 2);
155783
156196
  }
155784
- const validVerdicts = ["APPROVED", "NEEDS_REVISION"];
155785
- if (!validVerdicts.includes(args2.verdict)) {
156197
+ if (!isAcceptedVerdict2(args2.verdict)) {
155786
156198
  return JSON.stringify({
155787
156199
  success: false,
155788
156200
  phase,
@@ -155797,7 +156209,7 @@ async function executeWriteDriftEvidence(args2, directory) {
155797
156209
  message: "Invalid summary: must be a non-empty string"
155798
156210
  }, null, 2);
155799
156211
  }
155800
- const normalizedVerdict = normalizeVerdict(args2.verdict);
156212
+ const normalizedVerdict = _internals132.normalizeVerdict2(args2.verdict);
155801
156213
  const provenance = args2.provenanceAgentName || args2.provenanceSessionId ? {
155802
156214
  agent_name: args2.provenanceAgentName,
155803
156215
  session_id: args2.provenanceSessionId,
@@ -155894,11 +156306,16 @@ async function executeWriteDriftEvidence(args2, directory) {
155894
156306
  }, null, 2);
155895
156307
  }
155896
156308
  }
156309
+ var _internals132 = {
156310
+ normalizeVerdict2,
156311
+ VERDICT_SET_2,
156312
+ isAcceptedVerdict2
156313
+ };
155897
156314
  var write_drift_evidence = createSwarmTool({
155898
156315
  description: "Write drift verification evidence for a completed phase. " + "Normalizes verdict (APPROVED->approved, NEEDS_REVISION->rejected) and writes " + "a gate-contract formatted EvidenceBundle to .swarm/evidence/{phase}/drift-verifier.json. " + "Use this after critic_drift_verifier delegation to persist the verification result.",
155899
156316
  args: {
155900
156317
  phase: exports_external.number().int().min(1).describe("The phase number for the drift verification (e.g., 1, 2, 3)"),
155901
- verdict: exports_external.enum(["APPROVED", "NEEDS_REVISION"]).describe("Verdict of the drift verification: 'APPROVED' or 'NEEDS_REVISION'"),
156318
+ verdict: exports_external.enum(VERDICT_SET_2).describe("Verdict of the drift verification: 'APPROVED' or 'NEEDS_REVISION'"),
155902
156319
  summary: exports_external.string().describe("Human-readable summary of the drift verification"),
155903
156320
  requirementCoverage: exports_external.string().optional().describe("Requirement coverage report from req_coverage tool (JSON string)"),
155904
156321
  provenanceAgentName: exports_external.string().min(1).optional().describe("Agent name that produced this evidence (optional provenance)"),
@@ -156118,20 +156535,10 @@ var write_final_council_evidence = createSwarmTool({
156118
156535
 
156119
156536
  // src/tools/write-hallucination-evidence.ts
156120
156537
  init_zod();
156121
- init_utils2();
156122
- init_create_tool();
156123
156538
  import fs144 from "node:fs";
156124
156539
  import path221 from "node:path";
156125
- function normalizeVerdict2(verdict) {
156126
- switch (verdict) {
156127
- case "APPROVED":
156128
- return "approved";
156129
- case "NEEDS_REVISION":
156130
- return "rejected";
156131
- default:
156132
- throw new Error(`Invalid verdict: must be 'APPROVED' or 'NEEDS_REVISION', got '${verdict}'`);
156133
- }
156134
- }
156540
+ init_utils2();
156541
+ init_create_tool();
156135
156542
  async function executeWriteHallucinationEvidence(args2, directory) {
156136
156543
  const phase = args2.phase;
156137
156544
  if (!Number.isInteger(phase) || phase < 1) {
@@ -156141,8 +156548,7 @@ async function executeWriteHallucinationEvidence(args2, directory) {
156141
156548
  message: "Invalid phase: must be a positive integer"
156142
156549
  }, null, 2);
156143
156550
  }
156144
- const validVerdicts = ["APPROVED", "NEEDS_REVISION"];
156145
- if (!validVerdicts.includes(args2.verdict)) {
156551
+ if (!isAcceptedVerdict2(args2.verdict)) {
156146
156552
  return JSON.stringify({
156147
156553
  success: false,
156148
156554
  phase,
@@ -156157,7 +156563,7 @@ async function executeWriteHallucinationEvidence(args2, directory) {
156157
156563
  message: "Invalid summary: must be a non-empty string"
156158
156564
  }, null, 2);
156159
156565
  }
156160
- const normalizedVerdict = normalizeVerdict2(args2.verdict);
156566
+ const normalizedVerdict = _internals133.normalizeVerdict2(args2.verdict);
156161
156567
  const evidenceEntry = {
156162
156568
  type: "hallucination-verification",
156163
156569
  verdict: normalizedVerdict,
@@ -156200,11 +156606,16 @@ async function executeWriteHallucinationEvidence(args2, directory) {
156200
156606
  }, null, 2);
156201
156607
  }
156202
156608
  }
156609
+ var _internals133 = {
156610
+ normalizeVerdict2,
156611
+ VERDICT_SET_2,
156612
+ isAcceptedVerdict2
156613
+ };
156203
156614
  var write_hallucination_evidence = createSwarmTool({
156204
156615
  description: "Write hallucination verification evidence for a completed phase. " + "Normalizes verdict (APPROVED->approved, NEEDS_REVISION->rejected) and writes " + "a gate-contract formatted EvidenceBundle to .swarm/evidence/{phase}/hallucination-guard.json. " + "Use this after critic_hallucination_verifier delegation to persist the verification result. " + "Unlike write_drift_evidence, this tool does NOT lock the QA gate profile.",
156205
156616
  args: {
156206
156617
  phase: exports_external.number().int().min(1).describe("The phase number for the hallucination verification (e.g., 1, 2, 3)"),
156207
- verdict: exports_external.enum(["APPROVED", "NEEDS_REVISION"]).describe("Verdict of the hallucination verification: 'APPROVED' or 'NEEDS_REVISION'"),
156618
+ verdict: exports_external.enum(VERDICT_SET_2).describe("Verdict of the hallucination verification: 'APPROVED' or 'NEEDS_REVISION'"),
156208
156619
  summary: exports_external.string().describe("Human-readable summary of the hallucination verification"),
156209
156620
  findings: exports_external.string().optional().describe("Optional bullet list of FABRICATED/DRIFTED/UNSUPPORTED/BROKEN findings (for NEEDS_REVISION)")
156210
156621
  },
@@ -156230,24 +156641,10 @@ var write_hallucination_evidence = createSwarmTool({
156230
156641
 
156231
156642
  // src/tools/write-mutation-evidence.ts
156232
156643
  init_zod();
156233
- init_utils2();
156234
- init_create_tool();
156235
156644
  import fs145 from "node:fs";
156236
156645
  import path222 from "node:path";
156237
- function normalizeVerdict3(verdict) {
156238
- switch (verdict) {
156239
- case "PASS":
156240
- return "pass";
156241
- case "WARN":
156242
- return "warn";
156243
- case "FAIL":
156244
- return "fail";
156245
- case "SKIP":
156246
- return "skip";
156247
- default:
156248
- throw new Error(`Invalid verdict: must be 'PASS', 'WARN', 'FAIL', or 'SKIP', got '${verdict}'`);
156249
- }
156250
- }
156646
+ init_utils2();
156647
+ init_create_tool();
156251
156648
  async function executeWriteMutationEvidence(args2, directory) {
156252
156649
  const phase = args2.phase;
156253
156650
  if (!Number.isInteger(phase) || phase < 1) {
@@ -156257,8 +156654,7 @@ async function executeWriteMutationEvidence(args2, directory) {
156257
156654
  message: "Invalid phase: must be a positive integer"
156258
156655
  }, null, 2);
156259
156656
  }
156260
- const validVerdicts = ["PASS", "WARN", "FAIL", "SKIP"];
156261
- if (!validVerdicts.includes(args2.verdict)) {
156657
+ if (!isAcceptedVerdict4(args2.verdict)) {
156262
156658
  return JSON.stringify({
156263
156659
  success: false,
156264
156660
  phase,
@@ -156291,7 +156687,7 @@ async function executeWriteMutationEvidence(args2, directory) {
156291
156687
  message: "Invalid summary: must be a non-empty string"
156292
156688
  }, null, 2);
156293
156689
  }
156294
- const normalizedVerdict = normalizeVerdict3(args2.verdict);
156690
+ const normalizedVerdict = _internals134.normalizeVerdict4(args2.verdict);
156295
156691
  const evidenceEntry = {
156296
156692
  type: "mutation-gate",
156297
156693
  verdict: normalizedVerdict,
@@ -156338,11 +156734,16 @@ async function executeWriteMutationEvidence(args2, directory) {
156338
156734
  }, null, 2);
156339
156735
  }
156340
156736
  }
156737
+ var _internals134 = {
156738
+ normalizeVerdict4,
156739
+ VERDICT_SET_4,
156740
+ isAcceptedVerdict4
156741
+ };
156341
156742
  var write_mutation_evidence = createSwarmTool({
156342
156743
  description: 'Write mutation gate evidence for a completed phase. Accepts phase, verdict (PASS/WARN/FAIL/SKIP), killRate, adjustedKillRate, summary, and optional survivedMutants. Normalizes uppercase verdicts to lowercase (PASS→pass, WARN→warn, FAIL→fail, SKIP→skip) and writes entries[0].type="mutation-gate" to .swarm/evidence/{phase}/mutation-gate.json using atomic temp+rename write. Use this after mutation_test tool returns to persist the gate verdict.',
156343
156744
  args: {
156344
156745
  phase: exports_external.number().int().min(1).describe("The phase number for the mutation gate (e.g., 1, 2, 3)"),
156345
- verdict: exports_external.enum(["PASS", "WARN", "FAIL", "SKIP"]).describe("Verdict of the mutation gate: 'PASS', 'WARN', 'FAIL', or 'SKIP'"),
156746
+ verdict: exports_external.enum(VERDICT_SET_4).describe("Verdict of the mutation gate: 'PASS', 'WARN', 'FAIL', or 'SKIP'"),
156346
156747
  killRate: exports_external.number().optional().describe("The raw kill rate (e.g., 0.85)"),
156347
156748
  adjustedKillRate: exports_external.number().optional().describe("The adjusted kill rate accounting for timeout survived mutants (e.g., 0.87)"),
156348
156749
  summary: exports_external.string().describe("Human-readable summary of the mutation gate result"),
@@ -156428,6 +156829,7 @@ var TOOL_MANIFEST = defineHandlers({
156428
156829
  knowledge_recall: () => knowledge_recall,
156429
156830
  knowledge_remove: () => knowledge_remove,
156430
156831
  co_change_analyzer: () => co_change_analyzer,
156832
+ context_status: () => context_status,
156431
156833
  search: () => search,
156432
156834
  ast_grep: () => ast_grep,
156433
156835
  actionlint_scan: () => actionlint_scan,
@@ -156772,7 +157174,8 @@ async function initializeOpenCodeSwarm(ctx) {
156772
157174
  });
156773
157175
  const summaryConfig = SummaryConfigSchema.parse(config3.summaries ?? {});
156774
157176
  const toolSummarizerHook = createToolSummarizerHook(summaryConfig, ctx.directory);
156775
- const knowledgeConfig = KnowledgeConfigSchema.parse(config3.knowledge ?? {});
157177
+ const knowledgeConfigBase = config3.knowledge ?? {};
157178
+ const knowledgeConfig = KnowledgeConfigSchema.parse(knowledgeConfigBase);
156776
157179
  const skillImproverConfig = SkillImproverConfigSchema.parse(config3.skill_improver ?? {});
156777
157180
  const skillPropagationConfig = SkillPropagationConfigSchema.parse(config3.skillPropagation ?? {});
156778
157181
  if (skillImproverConfig.enabled && skillImproverConfig.trigger === "scheduled") {
@@ -156809,7 +157212,7 @@ async function initializeOpenCodeSwarm(ctx) {
156809
157212
  }
156810
157213
  }) : undefined;
156811
157214
  const hivePromoterHook = knowledgeConfig.enabled && knowledgeConfig.hive_enabled ? createHivePromoterHook(ctx.directory, knowledgeConfig) : undefined;
156812
- const knowledgeInjectorHook = knowledgeConfig.enabled ? createKnowledgeInjectorHook(ctx.directory, knowledgeConfig, config3.context_budget?.model_limits ?? {}) : undefined;
157215
+ const knowledgeInjectorHook = knowledgeConfig.enabled ? createKnowledgeInjectorHook(ctx.directory, knowledgeConfig, config3.context_budget?.model_limits ?? {}, config3.context_budget?.unified_injection_tokens) : undefined;
156813
157216
  const steeringConsumedHook = createSteeringConsumedHook(ctx.directory);
156814
157217
  const coChangeSuggesterHook = createCoChangeSuggesterHook(ctx.directory);
156815
157218
  const darkMatterDetectorHook = createDarkMatterDetectorHook(ctx.directory);