opencode-swarm 7.32.1 → 7.32.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -34,7 +34,7 @@ var package_default;
34
34
  var init_package = __esm(() => {
35
35
  package_default = {
36
36
  name: "opencode-swarm",
37
- version: "7.32.1",
37
+ version: "7.32.2",
38
38
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
39
39
  main: "dist/index.js",
40
40
  types: "dist/index.d.ts",
@@ -0,0 +1,30 @@
1
+ export interface ParsedCriticResponse {
2
+ verdict: string;
3
+ reasoning: string;
4
+ evidenceChecked: string[];
5
+ antiPatternsDetected: string[];
6
+ escalationNeeded: boolean;
7
+ rawResponse: string;
8
+ }
9
+ interface ParseCriticResponseOptions {
10
+ validVerdicts?: readonly string[];
11
+ onUnknownVerdict?: (value: string) => void;
12
+ }
13
+ /**
14
+ * Parses a structured critic response into a `ParsedCriticResponse`.
15
+ *
16
+ * Expected format (one field per line, value may span multiple lines until the next field):
17
+ * VERDICT: <value>
18
+ * REASONING: <text>
19
+ * EVIDENCE_CHECKED: <comma-separated list or "none">
20
+ * ANTI_PATTERNS_DETECTED: <comma-separated list or "none">
21
+ * ESCALATION_NEEDED: YES | NO
22
+ *
23
+ * @param rawResponse - The raw text response from the critic agent.
24
+ * @param options.validVerdicts - Override the default verdict allowlist. Unknown verdicts
25
+ * (those not in this list) default to `NEEDS_REVISION` and trigger `onUnknownVerdict`.
26
+ * @param options.onUnknownVerdict - Called with the raw verdict string when it is not
27
+ * in `validVerdicts`. Use for logging or metrics. Does not affect parsing outcome.
28
+ */
29
+ export declare function parseCriticResponseFields(rawResponse: string, options?: ParseCriticResponseOptions): ParsedCriticResponse;
30
+ export {};
@@ -1,10 +1,5 @@
1
- export interface FullAutoCriticResult {
2
- verdict: string;
3
- reasoning: string;
4
- evidenceChecked: string[];
5
- antiPatternsDetected: string[];
6
- escalationNeeded: boolean;
7
- rawResponse: string;
1
+ import { type ParsedCriticResponse } from './critic-response-parser';
2
+ export interface FullAutoCriticResult extends ParsedCriticResponse {
8
3
  }
9
4
  export type FullAutoTriggerSource = 'text_pattern' | 'tool_action' | 'cadence' | 'subagent_return' | 'phase_boundary' | 'task_completion' | 'risk';
10
5
  export interface FullAutoOversightEvent {
@@ -8,6 +8,7 @@
8
8
  * and injects the critic's autonomous oversight response when escalation is detected.
9
9
  */
10
10
  import type { PluginConfig } from '../config';
11
+ import { type ParsedCriticResponse } from '../full-auto/critic-response-parser';
11
12
  interface MessageWithParts {
12
13
  info: {
13
14
  role: string;
@@ -24,13 +25,7 @@ interface MessageWithParts {
24
25
  /**
25
26
  * Result from critic dispatch — used to inject verdict into message stream.
26
27
  */
27
- interface CriticDispatchResult {
28
- verdict: string;
29
- reasoning: string;
30
- evidenceChecked: string[];
31
- antiPatternsDetected: string[];
32
- escalationNeeded: boolean;
33
- rawResponse: string;
28
+ interface CriticDispatchResult extends ParsedCriticResponse {
34
29
  }
35
30
  /**
36
31
  * Parses the critic's structured text response into a CriticDispatchResult.
package/dist/index.js CHANGED
@@ -48,7 +48,7 @@ var package_default;
48
48
  var init_package = __esm(() => {
49
49
  package_default = {
50
50
  name: "opencode-swarm",
51
- version: "7.32.1",
51
+ version: "7.32.2",
52
52
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
53
53
  main: "dist/index.js",
54
54
  types: "dist/index.d.ts",
@@ -85071,11 +85071,18 @@ init_utils2();
85071
85071
  init_file_locks();
85072
85072
  init_state();
85073
85073
  init_logger();
85074
- init_state2();
85075
85074
  import * as fs40 from "node:fs";
85076
85075
  import * as path62 from "node:path";
85077
- var oversightSequenceCounter = 0;
85078
- var VALID_VERDICTS = [
85076
+
85077
+ // src/full-auto/critic-response-parser.ts
85078
+ var KNOWN_FIELDS = new Set([
85079
+ "VERDICT",
85080
+ "REASONING",
85081
+ "EVIDENCE_CHECKED",
85082
+ "ANTI_PATTERNS_DETECTED",
85083
+ "ESCALATION_NEEDED"
85084
+ ]);
85085
+ var DEFAULT_VALID_VERDICTS = [
85079
85086
  "APPROVED",
85080
85087
  "NEEDS_REVISION",
85081
85088
  "REJECTED",
@@ -85085,7 +85092,8 @@ var VALID_VERDICTS = [
85085
85092
  "REPHRASE",
85086
85093
  "PENDING"
85087
85094
  ];
85088
- function parseFullAutoCriticResponse(rawResponse) {
85095
+ function parseCriticResponseFields(rawResponse, options = {}) {
85096
+ const validVerdicts = options.validVerdicts ?? DEFAULT_VALID_VERDICTS;
85089
85097
  const result = {
85090
85098
  verdict: "NEEDS_REVISION",
85091
85099
  reasoning: "",
@@ -85102,10 +85110,10 @@ function parseFullAutoCriticResponse(rawResponse) {
85102
85110
  switch (key) {
85103
85111
  case "VERDICT": {
85104
85112
  const normalized = value.trim().toUpperCase().replace(/[`*]/g, "");
85105
- if (VALID_VERDICTS.includes(normalized)) {
85113
+ if (validVerdicts.includes(normalized)) {
85106
85114
  res.verdict = normalized;
85107
85115
  } else {
85108
- warn(`[full-auto/oversight] Unknown verdict '${value}' — defaulting to NEEDS_REVISION`);
85116
+ options.onUnknownVerdict?.(value);
85109
85117
  res.verdict = "NEEDS_REVISION";
85110
85118
  }
85111
85119
  break;
@@ -85132,13 +85140,7 @@ function parseFullAutoCriticResponse(rawResponse) {
85132
85140
  const colonIndex = line.indexOf(":");
85133
85141
  if (colonIndex !== -1) {
85134
85142
  const key = line.slice(0, colonIndex).trim().toUpperCase();
85135
- if ([
85136
- "VERDICT",
85137
- "REASONING",
85138
- "EVIDENCE_CHECKED",
85139
- "ANTI_PATTERNS_DETECTED",
85140
- "ESCALATION_NEEDED"
85141
- ].includes(key)) {
85143
+ if (KNOWN_FIELDS.has(key)) {
85142
85144
  if (currentKey)
85143
85145
  commitField(result, currentKey, currentValue);
85144
85146
  currentKey = key;
@@ -85156,6 +85158,17 @@ ${line}`;
85156
85158
  commitField(result, currentKey, currentValue);
85157
85159
  return result;
85158
85160
  }
85161
+
85162
+ // src/full-auto/oversight.ts
85163
+ init_state2();
85164
+ var oversightSequenceCounter = 0;
85165
+ function parseFullAutoCriticResponse(rawResponse) {
85166
+ return parseCriticResponseFields(rawResponse, {
85167
+ onUnknownVerdict: (value) => {
85168
+ warn(`[full-auto/oversight] Unknown verdict '${value}' — defaulting to NEEDS_REVISION`);
85169
+ }
85170
+ });
85171
+ }
85159
85172
  function buildOversightPrompt(input) {
85160
85173
  const {
85161
85174
  trigger,
@@ -86674,88 +86687,11 @@ function extractMessageText3(message) {
86674
86687
  `);
86675
86688
  }
86676
86689
  function parseCriticResponse(rawResponse) {
86677
- const result = {
86678
- verdict: "NEEDS_REVISION",
86679
- reasoning: "",
86680
- evidenceChecked: [],
86681
- antiPatternsDetected: [],
86682
- escalationNeeded: false,
86683
- rawResponse
86684
- };
86685
- const lines = rawResponse.split(`
86686
- `);
86687
- let currentKey = "";
86688
- let currentValue = "";
86689
- const commitField = (res, key, value) => {
86690
- switch (key) {
86691
- case "VERDICT": {
86692
- const validVerdicts = [
86693
- "APPROVED",
86694
- "NEEDS_REVISION",
86695
- "REJECTED",
86696
- "BLOCKED",
86697
- "ANSWER",
86698
- "ESCALATE_TO_HUMAN",
86699
- "REPHRASE"
86700
- ];
86701
- const normalized = value.trim().toUpperCase().replace(/[`*]/g, "");
86702
- if (validVerdicts.includes(normalized)) {
86703
- res.verdict = normalized;
86704
- } else {
86705
- warn(`[full-auto-intercept] Unknown verdict '${value}' — defaulting to NEEDS_REVISION`);
86706
- res.verdict = "NEEDS_REVISION";
86707
- }
86708
- break;
86709
- }
86710
- case "REASONING":
86711
- res.reasoning = value.trim();
86712
- break;
86713
- case "EVIDENCE_CHECKED":
86714
- if (value && value !== "none" && value !== '"none"') {
86715
- res.evidenceChecked = value.split(",").map((s) => s.trim()).filter(Boolean);
86716
- }
86717
- break;
86718
- case "ANTI_PATTERNS_DETECTED":
86719
- if (value && value !== "none" && value !== '"none"') {
86720
- res.antiPatternsDetected = value.split(",").map((s) => s.trim()).filter(Boolean);
86721
- }
86722
- break;
86723
- case "ESCALATION_NEEDED":
86724
- res.escalationNeeded = value.trim().toUpperCase() === "YES";
86725
- break;
86690
+ return parseCriticResponseFields(rawResponse, {
86691
+ onUnknownVerdict: (value) => {
86692
+ warn(`[full-auto-intercept] Unknown verdict '${value}' — defaulting to NEEDS_REVISION`);
86726
86693
  }
86727
- };
86728
- for (const line of lines) {
86729
- const colonIndex = line.indexOf(":");
86730
- if (colonIndex !== -1) {
86731
- const key = line.slice(0, colonIndex).trim().toUpperCase();
86732
- if ([
86733
- "VERDICT",
86734
- "REASONING",
86735
- "EVIDENCE_CHECKED",
86736
- "ANTI_PATTERNS_DETECTED",
86737
- "ESCALATION_NEEDED"
86738
- ].includes(key)) {
86739
- if (currentKey) {
86740
- commitField(result, currentKey, currentValue);
86741
- }
86742
- currentKey = key;
86743
- currentValue = line.slice(colonIndex + 1).trim();
86744
- } else {
86745
- currentValue += `
86746
- ${line}`;
86747
- }
86748
- } else {
86749
- if (line.trim()) {
86750
- currentValue += `
86751
- ${line}`;
86752
- }
86753
- }
86754
- }
86755
- if (currentKey) {
86756
- commitField(result, currentKey, currentValue);
86757
- }
86758
- return result;
86694
+ });
86759
86695
  }
86760
86696
  function escalationTypeToInteractionMode(escalationType) {
86761
86697
  return escalationType === "phase_completion" ? "phase_completion" : "question_resolution";
@@ -86789,7 +86725,8 @@ async function writeAutoOversightEvent(directory, architectOutput, criticVerdict
86789
86725
  fs43.appendFileSync(eventsPath, `${JSON.stringify(event)}
86790
86726
  `, "utf-8");
86791
86727
  } catch (writeError) {
86792
- error48(`[full-auto-intercept] Warning: failed to write auto_oversight event: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
86728
+ error48(`[full-auto-intercept] Failed to write auto_oversight event: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
86729
+ throw writeError;
86793
86730
  } finally {
86794
86731
  if (lockResult?.acquired && lockResult.lock._release) {
86795
86732
  try {
@@ -86974,11 +86911,7 @@ ESCALATION_NEEDED: NO`;
86974
86911
  rawResponse: criticResponse
86975
86912
  };
86976
86913
  }
86977
- try {
86978
- await writeAutoOversightEvent(directory, architectOutput, parsed.verdict, parsed.reasoning, parsed.evidenceChecked, interactionCount, deadlockCount, escalationType);
86979
- } catch (writeError) {
86980
- error48(`[full-auto-intercept] Failed to write auto_oversight event: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
86981
- }
86914
+ await writeAutoOversightEvent(directory, architectOutput, parsed.verdict, parsed.reasoning, parsed.evidenceChecked, interactionCount, deadlockCount, escalationType);
86982
86915
  try {
86983
86916
  await mirrorReactiveVerdictToV2({
86984
86917
  directory,
@@ -93958,6 +93891,7 @@ async function writeDelegationEvent(directory, event) {
93958
93891
  `, "utf-8");
93959
93892
  } catch (error93) {
93960
93893
  error48(`[full-auto/delegation] failed to write event: ${error93 instanceof Error ? error93.message : String(error93)}`);
93894
+ throw error93;
93961
93895
  } finally {
93962
93896
  if (lockResult?.acquired && lockResult.lock._release) {
93963
93897
  try {
@@ -105260,7 +105194,7 @@ function verifyFullAutoPhaseApproval(directory, sessionID, phase, config3) {
105260
105194
  };
105261
105195
  }
105262
105196
  const events = files.map((f) => parseEvidence(f)).filter((e) => Boolean(e));
105263
- const phaseBoundary = events.filter((e) => (e.phase === phase || e.phase === undefined) && e.trigger_source === "phase_boundary" && (e.verdict ?? "").toUpperCase() === "APPROVED");
105197
+ const phaseBoundary = events.filter((e) => e.phase === phase && e.trigger_source === "phase_boundary" && (e.verdict ?? "").toUpperCase() === "APPROVED");
105264
105198
  if (phaseBoundary.length === 0) {
105265
105199
  return failClosed ? {
105266
105200
  ok: false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.32.1",
3
+ "version": "7.32.2",
4
4
  "description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",