opencode-swarm 7.79.1 → 7.79.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -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.79.1",
72
+ version: "7.79.4",
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",
@@ -90,7 +90,7 @@ var init_package = __esm(() => {
90
90
  license: "MIT",
91
91
  repository: {
92
92
  type: "git",
93
- url: "https://github.com/zaxbysauce/opencode-swarm.git"
93
+ url: "https://github.com/ZaxbyHub/opencode-swarm.git"
94
94
  },
95
95
  publishConfig: {
96
96
  access: "public",
@@ -129,6 +129,7 @@ var init_package = __esm(() => {
129
129
  ".opencode/skills/critic-gate",
130
130
  ".opencode/skills/execute",
131
131
  ".opencode/skills/phase-wrap",
132
+ ".opencode/skills/loop",
132
133
  "tests/fixtures/memory-recall",
133
134
  "README.md",
134
135
  "LICENSE"
@@ -17210,7 +17211,8 @@ var init_bundled_skills = __esm(() => {
17210
17211
  "plan",
17211
17212
  "critic-gate",
17212
17213
  "execute",
17213
- "phase-wrap"
17214
+ "phase-wrap",
17215
+ "loop"
17214
17216
  ];
17215
17217
  syncedProjectSkillTargets = new Set;
17216
17218
  });
@@ -27658,8 +27660,16 @@ var init_tool_policy = __esm(() => {
27658
27660
  }).sort());
27659
27661
  SWARM_COMMAND_TOOL_ALLOWLIST = lazySet(() => VALID_COMMANDS.filter((cmd) => COMMAND_REGISTRY[cmd]?.toolPolicy === "agent"));
27660
27662
  HUMAN_ONLY_SWARM_COMMANDS = lazySet(() => VALID_COMMANDS.filter((cmd) => {
27661
- const policy = COMMAND_REGISTRY[cmd]?.toolPolicy;
27662
- return policy === "human-only" || policy === "restricted";
27663
+ const entry = COMMAND_REGISTRY[cmd];
27664
+ const policy = entry?.toolPolicy;
27665
+ if (policy === "human-only" || policy === "restricted")
27666
+ return true;
27667
+ if (entry?.aliasOf) {
27668
+ const target = COMMAND_REGISTRY[entry.aliasOf];
27669
+ const targetPolicy = target?.toolPolicy;
27670
+ return targetPolicy === "human-only" || targetPolicy === "restricted";
27671
+ }
27672
+ return false;
27663
27673
  }));
27664
27674
  NO_ARGS = lazySet(() => VALID_COMMANDS.filter((cmd) => COMMAND_REGISTRY[cmd]?.toolNoArgs === true));
27665
27675
  SUMMARY_ID_PATTERN = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/;
@@ -78781,6 +78791,116 @@ var init_learning = __esm(() => {
78781
78791
  init_learning_metrics();
78782
78792
  });
78783
78793
 
78794
+ // src/commands/loop.ts
78795
+ function sanitizeObjective(raw) {
78796
+ const collapsed = raw.replace(/\s+/g, " ").trim();
78797
+ const stripped = collapsed.replace(/\[\s*MODE\s*:[^\]]*\]/gi, "");
78798
+ const normalized = stripped.replace(/\s+/g, " ").trim();
78799
+ if (normalized.length <= MAX_OBJECTIVE_LEN)
78800
+ return normalized;
78801
+ return `${normalized.slice(0, MAX_OBJECTIVE_LEN)}…`;
78802
+ }
78803
+ function isPositiveInteger(raw) {
78804
+ return /^\d+$/.test(raw);
78805
+ }
78806
+ function parseArgs7(args2) {
78807
+ const result = {
78808
+ maxCycles: DEFAULT_MAX_CYCLES,
78809
+ autonomy: DEFAULT_AUTONOMY,
78810
+ depth: DEFAULT_DEPTH2,
78811
+ resume: false,
78812
+ rest: []
78813
+ };
78814
+ let i2 = 0;
78815
+ while (i2 < args2.length) {
78816
+ const token = args2[i2];
78817
+ if (token === "--max-cycles") {
78818
+ if (i2 + 1 >= args2.length) {
78819
+ return { ...result, error: `Flag "${token}" requires a value` };
78820
+ }
78821
+ const value = args2[++i2];
78822
+ if (!isPositiveInteger(value) || Number(value) < MIN_MAX_CYCLES || Number(value) > MAX_MAX_CYCLES) {
78823
+ return {
78824
+ ...result,
78825
+ error: `Invalid --max-cycles value "${value}". Must be an integer between ${MIN_MAX_CYCLES} and ${MAX_MAX_CYCLES}.`
78826
+ };
78827
+ }
78828
+ result.maxCycles = Number(value);
78829
+ } else if (token === "--autonomy") {
78830
+ if (i2 + 1 >= args2.length) {
78831
+ return { ...result, error: `Flag "${token}" requires a value` };
78832
+ }
78833
+ const value = args2[++i2];
78834
+ if (!AUTONOMY_LEVELS.has(value)) {
78835
+ return {
78836
+ ...result,
78837
+ error: `Invalid autonomy "${value}". Must be one of: checkpoint, auto.`
78838
+ };
78839
+ }
78840
+ result.autonomy = value;
78841
+ } else if (token === "--depth") {
78842
+ if (i2 + 1 >= args2.length) {
78843
+ return { ...result, error: `Flag "${token}" requires a value` };
78844
+ }
78845
+ const value = args2[++i2];
78846
+ if (!DEPTHS2.has(value)) {
78847
+ return {
78848
+ ...result,
78849
+ error: `Invalid depth "${value}". Must be one of: standard, exhaustive.`
78850
+ };
78851
+ }
78852
+ result.depth = value;
78853
+ } else if (token === "--resume") {
78854
+ result.resume = true;
78855
+ } else if (token.startsWith("--")) {
78856
+ return { ...result, error: `Unknown flag "${token}"` };
78857
+ } else {
78858
+ result.rest.push(token);
78859
+ }
78860
+ i2++;
78861
+ }
78862
+ return result;
78863
+ }
78864
+ async function handleLoopCommand(_directory, args2) {
78865
+ const parsed = parseArgs7(args2);
78866
+ if (parsed.error) {
78867
+ return `Error: ${parsed.error}
78868
+
78869
+ ${USAGE7}`;
78870
+ }
78871
+ const objective = sanitizeObjective(parsed.rest.join(" "));
78872
+ if (!objective && !parsed.resume) {
78873
+ return USAGE7;
78874
+ }
78875
+ const header = `[MODE: LOOP max_cycles=${parsed.maxCycles} autonomy=${parsed.autonomy}` + ` depth=${parsed.depth} resume=${parsed.resume}]`;
78876
+ if (!objective && parsed.resume) {
78877
+ return `${header} Resume the existing compound-engineering loop from durable state in .swarm/loop/. Read the latest run state, report cycle progress, and continue from the current phase.`;
78878
+ }
78879
+ return `${header} ${objective}`;
78880
+ }
78881
+ var MAX_OBJECTIVE_LEN = 2000, DEPTHS2, AUTONOMY_LEVELS, DEFAULT_DEPTH2 = "standard", DEFAULT_AUTONOMY = "checkpoint", DEFAULT_MAX_CYCLES = 3, MIN_MAX_CYCLES = 1, MAX_MAX_CYCLES = 5, USAGE7 = `Usage: /swarm loop <objective> [--max-cycles 1..5] [--autonomy checkpoint|auto] [--depth standard|exhaustive] [--resume]
78882
+
78883
+ Run a compound-engineering loop: brainstorm → plan → build → review → improve,
78884
+ iterating until the objective is met or a budget stop condition fires.
78885
+
78886
+ Examples:
78887
+ /swarm loop "add rate limiting to the public API"
78888
+ /swarm loop "harden auth session handling" --depth exhaustive --max-cycles 2
78889
+ /swarm loop "migrate config loader" --autonomy auto
78890
+ /swarm loop --resume
78891
+
78892
+ Flags:
78893
+ --max-cycles <N> outer improvement cycles, 1..5 (default: 3)
78894
+ --autonomy <level> checkpoint (pause at phase gates, default) or auto
78895
+ (run unattended; hard stop conditions still apply)
78896
+ --depth <name> standard (default) or exhaustive (wider exploration)
78897
+ --resume resume the existing loop run from durable state in
78898
+ .swarm/loop/ instead of starting a new objective`;
78899
+ var init_loop = __esm(() => {
78900
+ DEPTHS2 = new Set(["standard", "exhaustive"]);
78901
+ AUTONOMY_LEVELS = new Set(["checkpoint", "auto"]);
78902
+ });
78903
+
78784
78904
  // src/memory/config.ts
78785
78905
  function resolveMemoryConfig(input) {
78786
78906
  return {
@@ -83478,7 +83598,7 @@ var init_pr_monitor_status = __esm(() => {
83478
83598
  });
83479
83599
 
83480
83600
  // src/commands/pr-review.ts
83481
- function parseArgs7(args2) {
83601
+ function parseArgs8(args2) {
83482
83602
  const out2 = { council: false, rest: [] };
83483
83603
  for (const token of args2) {
83484
83604
  if (token === "--council") {
@@ -83497,29 +83617,29 @@ function parseArgs7(args2) {
83497
83617
  return out2;
83498
83618
  }
83499
83619
  function handlePrReviewCommand(directory, args2) {
83500
- const parsed = parseArgs7(args2);
83620
+ const parsed = parseArgs8(args2);
83501
83621
  if (parsed.unknownFlag) {
83502
83622
  return `Error: Unknown flag "${parsed.unknownFlag}"
83503
83623
 
83504
- ${USAGE7}`;
83624
+ ${USAGE8}`;
83505
83625
  }
83506
83626
  const resolved = resolvePrCommandInput(parsed.rest, directory);
83507
83627
  if (resolved === null) {
83508
- return USAGE7;
83628
+ return USAGE8;
83509
83629
  }
83510
83630
  if ("error" in resolved) {
83511
83631
  return `Error: ${resolved.error}
83512
83632
 
83513
- ${USAGE7}`;
83633
+ ${USAGE8}`;
83514
83634
  }
83515
83635
  const councilFlag = parsed.council ? "council=true" : "council=false";
83516
83636
  const signal = `[MODE: PR_REVIEW pr="${resolved.prUrl}" ${councilFlag}]`;
83517
83637
  return resolved.instructions ? `${signal} ${resolved.instructions}` : signal;
83518
83638
  }
83519
- var USAGE7;
83639
+ var USAGE8;
83520
83640
  var init_pr_review = __esm(() => {
83521
83641
  init_pr_ref();
83522
- USAGE7 = [
83642
+ USAGE8 = [
83523
83643
  "Usage: /swarm pr-review <url|owner/repo#N|N> [--council] [instructions...]",
83524
83644
  "",
83525
83645
  "Run a full swarm PR review on a GitHub pull request.",
@@ -90854,7 +90974,7 @@ var init_rollback = __esm(() => {
90854
90974
  });
90855
90975
 
90856
90976
  // src/commands/sdd.ts
90857
- function parseArgs8(args2) {
90977
+ function parseArgs9(args2) {
90858
90978
  const parsed = { json: false, dryRun: false };
90859
90979
  for (let i2 = 0;i2 < args2.length; i2++) {
90860
90980
  const token = args2[i2];
@@ -90885,11 +91005,11 @@ function formatList(items) {
90885
91005
  `) : "- none";
90886
91006
  }
90887
91007
  async function handleSddStatusCommand(directory, args2) {
90888
- const parsed = parseArgs8(args2);
91008
+ const parsed = parseArgs9(args2);
90889
91009
  if (parsed.error)
90890
91010
  return `Error: ${parsed.error}
90891
91011
 
90892
- ${USAGE8}`;
91012
+ ${USAGE9}`;
90893
91013
  const status = loadSddStatusSync(directory);
90894
91014
  if (parsed.json)
90895
91015
  return JSON.stringify(status, null, 2);
@@ -90923,11 +91043,11 @@ ${formatList([
90923
91043
  `);
90924
91044
  }
90925
91045
  async function handleSddValidateCommand(directory, args2) {
90926
- const parsed = parseArgs8(args2);
91046
+ const parsed = parseArgs9(args2);
90927
91047
  if (parsed.error)
90928
91048
  return `Error: ${parsed.error}
90929
91049
 
90930
- ${USAGE8}`;
91050
+ ${USAGE9}`;
90931
91051
  const status = loadSddStatusSync(directory);
90932
91052
  const projection = buildOpenSpecProjectionSync(directory, {
90933
91053
  changeId: parsed.changeId
@@ -90965,11 +91085,11 @@ ${formatList(result.warnings)}` : ""
90965
91085
  `);
90966
91086
  }
90967
91087
  async function handleSddProjectCommand(directory, args2) {
90968
- const parsed = parseArgs8(args2);
91088
+ const parsed = parseArgs9(args2);
90969
91089
  if (parsed.error)
90970
91090
  return `Error: ${parsed.error}
90971
91091
 
90972
- ${USAGE8}`;
91092
+ ${USAGE9}`;
90973
91093
  const result = writeProjectedSpecSync(directory, {
90974
91094
  changeId: parsed.changeId,
90975
91095
  dryRun: parsed.dryRun
@@ -90989,7 +91109,7 @@ ${USAGE8}`;
90989
91109
  return [
90990
91110
  "SDD projection failed: no valid OpenSpec-compatible projection could be built.",
90991
91111
  "",
90992
- USAGE8
91112
+ USAGE9
90993
91113
  ].join(`
90994
91114
  `);
90995
91115
  }
@@ -91006,9 +91126,9 @@ ${formatList(result.projection.warnings)}` : ""
91006
91126
  `);
91007
91127
  }
91008
91128
  async function handleSddCommand(_directory, _args) {
91009
- return USAGE8;
91129
+ return USAGE9;
91010
91130
  }
91011
- var USAGE8 = `Usage:
91131
+ var USAGE9 = `Usage:
91012
91132
  /swarm sdd status [--json]
91013
91133
  /swarm sdd validate [--json] [--change <id>]
91014
91134
  /swarm sdd project [--dry-run] [--json] [--change <id>]
@@ -92693,6 +92813,7 @@ var init_registry = __esm(() => {
92693
92813
  init_issue();
92694
92814
  init_knowledge();
92695
92815
  init_learning();
92816
+ init_loop();
92696
92817
  init_memory2();
92697
92818
  init_plan();
92698
92819
  init_post_mortem();
@@ -93052,6 +93173,24 @@ Subcommands:
93052
93173
  category: "utility",
93053
93174
  toolPolicy: "human-only"
93054
93175
  },
93176
+ "sdd-status": {
93177
+ handler: (ctx) => handleSddStatusCommand(ctx.directory, ctx.args),
93178
+ description: "Show OpenSpec-compatible SDD status and effective spec source",
93179
+ aliasOf: "sdd status",
93180
+ deprecated: true
93181
+ },
93182
+ "sdd-validate": {
93183
+ handler: (ctx) => handleSddValidateCommand(ctx.directory, ctx.args),
93184
+ description: "Validate OpenSpec-compatible artifacts and effective spec projection",
93185
+ aliasOf: "sdd validate",
93186
+ deprecated: true
93187
+ },
93188
+ "sdd-project": {
93189
+ handler: (ctx) => handleSddProjectCommand(ctx.directory, ctx.args),
93190
+ description: "Materialize the OpenSpec-compatible effective spec into .swarm/spec.md",
93191
+ aliasOf: "sdd project",
93192
+ deprecated: true
93193
+ },
93055
93194
  analyze: {
93056
93195
  handler: (ctx) => handleAnalyzeCommand(ctx.directory, ctx.args),
93057
93196
  description: "Analyze spec.md vs plan.md for requirement coverage gaps",
@@ -93081,6 +93220,14 @@ Subcommands:
93081
93220
  category: "agent",
93082
93221
  toolPolicy: "none"
93083
93222
  },
93223
+ loop: {
93224
+ handler: (ctx) => handleModeCommandWithBundledSkills(ctx, handleLoopCommand),
93225
+ description: "Enter architect MODE: LOOP — compound-engineering loop: brainstorm → plan → build → review → improve, iterating until done [objective]",
93226
+ args: "<objective> [--max-cycles 1..5] [--autonomy checkpoint|auto] [--depth standard|exhaustive] [--resume]",
93227
+ details: "Triggers the architect to run the compound-engineering loop defined in .opencode/skills/loop/SKILL.md: BRAINSTORM (requirements) → PLAN (+ critic gate) → BUILD (execute) → REVIEW (independent reviewer + critic on the diff, report-only) → IMPROVE (phase-wrap retrospective + compounding learning capture), then evaluate stop conditions and loop for another improvement cycle if the objective is unmet and budget remains. Generator and reviewer/critic run in separate contexts; failing assertions must be fixed at the root cause, never weakened, mocked, or skipped. Defense-in-depth stop conditions: objective met, --max-cycles budget (default 3), no-progress/plateau, oscillation, unrecoverable error, or explicit user stop. --autonomy checkpoint (default) pauses at phase gates for user approval; --autonomy auto runs unattended with hard stops still enforced. --depth exhaustive widens exploration. --resume continues an existing loop run from durable .swarm/loop/ state. Distinct from full-auto (autonomous cross-phase oversight) and turbo (parallel lanes within a phase): loop is a user-initiated, gated, compounding workflow.",
93228
+ category: "agent",
93229
+ toolPolicy: "none"
93230
+ },
93084
93231
  council: {
93085
93232
  handler: (ctx) => handleModeCommandWithBundledSkills(ctx, handleCouncilCommand),
93086
93233
  description: "Enter architect MODE: COUNCIL — multi-model deliberation [question] [--preset <name>] [--spec-review]",
@@ -93113,6 +93260,12 @@ Subcommands:
93113
93260
  category: "agent",
93114
93261
  toolPolicy: "human-only"
93115
93262
  },
93263
+ "pr-subscribe": {
93264
+ handler: (ctx) => handlePrSubscribeCommand(ctx.directory, ctx.args, ctx.sessionID),
93265
+ description: "Subscribe the current session to PR state-change notifications",
93266
+ aliasOf: "pr subscribe",
93267
+ deprecated: true
93268
+ },
93116
93269
  "pr unsubscribe": {
93117
93270
  handler: (ctx) => handlePrUnsubscribeCommand(ctx.directory, ctx.args, ctx.sessionID),
93118
93271
  description: "Unsubscribe the current session from PR state-change notifications",
@@ -93121,6 +93274,12 @@ Subcommands:
93121
93274
  category: "agent",
93122
93275
  toolPolicy: "human-only"
93123
93276
  },
93277
+ "pr-unsubscribe": {
93278
+ handler: (ctx) => handlePrUnsubscribeCommand(ctx.directory, ctx.args, ctx.sessionID),
93279
+ description: "Unsubscribe the current session from PR state-change notifications",
93280
+ aliasOf: "pr unsubscribe",
93281
+ deprecated: true
93282
+ },
93124
93283
  "pr status": {
93125
93284
  handler: (ctx) => handlePrMonitorStatusCommand(ctx.directory, ctx.args, ctx.sessionID),
93126
93285
  description: "Show PR monitor subscription status for the current session",
@@ -93130,6 +93289,12 @@ Subcommands:
93130
93289
  toolPolicy: "agent",
93131
93290
  toolNoArgs: true
93132
93291
  },
93292
+ "pr-status": {
93293
+ handler: (ctx) => handlePrMonitorStatusCommand(ctx.directory, ctx.args, ctx.sessionID),
93294
+ description: "Show PR monitor subscription status for the current session",
93295
+ aliasOf: "pr status",
93296
+ deprecated: true
93297
+ },
93133
93298
  "deep-dive": {
93134
93299
  handler: (ctx) => handleModeCommandWithBundledSkills(ctx, handleDeepDiveCommand),
93135
93300
  description: "Launch deep codebase audit with parallel explorer waves, dual reviewers, and critic challenge [scope]",
@@ -93428,6 +93593,30 @@ Subcommands:
93428
93593
  category: "utility",
93429
93594
  toolPolicy: "human-only"
93430
93595
  },
93596
+ "memory-status": {
93597
+ handler: (ctx) => handleMemoryStatusCommand(ctx.directory, ctx.args),
93598
+ description: "Show Swarm memory provider, JSONL, and migration status",
93599
+ aliasOf: "memory status",
93600
+ deprecated: true
93601
+ },
93602
+ "memory-export": {
93603
+ handler: (ctx) => handleMemoryExportCommand(ctx.directory, ctx.args),
93604
+ description: "Export current Swarm memory to JSONL files",
93605
+ aliasOf: "memory export",
93606
+ deprecated: true
93607
+ },
93608
+ "memory-import": {
93609
+ handler: (ctx) => handleMemoryImportCommand(ctx.directory, ctx.args),
93610
+ description: "Import legacy JSONL memory into SQLite",
93611
+ aliasOf: "memory import",
93612
+ deprecated: true
93613
+ },
93614
+ "memory-migrate": {
93615
+ handler: (ctx) => handleMemoryMigrateCommand(ctx.directory, ctx.args),
93616
+ description: "Run the one-time legacy JSONL to SQLite migration",
93617
+ aliasOf: "memory migrate",
93618
+ deprecated: true
93619
+ },
93431
93620
  checkpoint: {
93432
93621
  handler: (ctx) => handleCheckpointCommand(ctx.directory, ctx.args),
93433
93622
  description: "Manage project checkpoints [save|restore|delete|list] <label>",
@@ -93784,7 +93973,7 @@ function buildSlashCommandsList() {
93784
93973
  "acknowledge-spec-drift",
93785
93974
  "council"
93786
93975
  ],
93787
- "Execution Modes": ["turbo", "full-auto"],
93976
+ "Execution Modes": ["turbo", "full-auto", "loop"],
93788
93977
  Observation: [
93789
93978
  "status",
93790
93979
  "history",
@@ -94575,7 +94764,7 @@ HARD CONSTRAINTS:
94575
94764
 
94576
94765
  <!-- BEHAVIORAL_GUIDANCE_START -->
94577
94766
  - Treat brainstorm output as discovery material until the loaded skill transitions to SPECIFY or PLAN.
94578
- - When council.general.enabled is true, the brainstorm skill offers the user a General Council advisory input option before spec writing. This is NOT a QA gate — it's an early workflow option. The convene_general_council tool must be available when council.general.enabled is true.
94767
+ - When council.general.enabled is true, the brainstorm skill offers the user a General Council advisory input option before spec writing, and the plan skill offers it before save_plan. This is NOT a QA gate — it's an early workflow option. The convene_general_council tool must be available when council.general.enabled is true.
94579
94768
  <!-- BEHAVIORAL_GUIDANCE_END -->
94580
94769
 
94581
94770
  ### MODE: SPECIFY
@@ -94592,7 +94781,7 @@ HARD CONSTRAINTS:
94592
94781
 
94593
94782
  <!-- BEHAVIORAL_GUIDANCE_START -->
94594
94783
  - Follow the loaded skill's spec creation, clarification, and transition rules.
94595
- - General Council advisory input is available via the /swarm council command at any time. It is NOT offered as a SPECIFY workflow step — it moved to BRAINSTORM Phase 1b as an early option before spec writing.
94784
+ - General Council advisory input is available via the /swarm council command at any time. It is NOT offered as a SPECIFY workflow step — it is offered in BRAINSTORM Phase 1b before spec writing and in MODE: PLAN before save_plan.
94596
94785
  <!-- BEHAVIORAL_GUIDANCE_END -->
94597
94786
 
94598
94787
  <!-- BEHAVIORAL_GUIDANCE_START -->
@@ -94685,6 +94874,22 @@ HARD CONSTRAINTS (apply regardless of skill load success):
94685
94874
  - Explorers generate candidate findings only — reviewers verify or reject
94686
94875
  - Critics challenge only HIGH/CRITICAL findings — do NOT waste cycles on lower severity
94687
94876
 
94877
+ ### MODE: LOOP
94878
+ Activates when: architect receives \`[MODE: LOOP max_cycles=N autonomy=checkpoint|auto depth=standard|exhaustive resume=true|false] <objective>\` signal from the loop command handler.
94879
+
94880
+ Purpose: Run the compound-engineering loop — BRAINSTORM → PLAN → BUILD → REVIEW → IMPROVE — iterating until the objective is met or a stop condition fires. Each cycle reuses the existing mode skills (brainstorm, plan, critic-gate, execute, phase-wrap) and then captures learnings so the next cycle is cheaper (compounding). This is a real implementation workflow: it DOES delegate to coder, DOES declare scope, and DOES mutate source code through the normal EXECUTE path. It is distinct from full-auto (autonomous cross-phase oversight) and turbo (parallel lanes within a phase): LOOP is a user-initiated, gated, compounding workflow.
94881
+
94882
+ ACTION: Load skill file:.opencode/skills/loop/SKILL.md immediately and follow its protocol. Parse the header to get \`max_cycles\`, \`autonomy\`, \`depth\`, and \`resume\`.
94883
+
94884
+ HARD CONSTRAINTS (apply regardless of skill load success):
94885
+ - Execute the loop phases IN ORDER as defined in the skill; do not skip a phase or collapse phases. A phase's entry gate must pass before it starts and its exit gate must pass (with positive evidence) before the next phase starts.
94886
+ - Keep generation and verification in SEPARATE contexts: the coder implements; an independent reviewer and a separate critic verify the actual diff. The same context must not both write and approve a change. The REVIEW phase is report-only — a distinct fix step applies changes.
94887
+ - NEVER weaken, mock, skip, or delete a failing test or assertion to make a gate pass. Fix the root cause or stop and report.
94888
+ - Honor defense-in-depth stop conditions and NEVER exceed \`max_cycles\`: stop when the objective is met, the cycle budget is exhausted, progress plateaus (a cycle yields no qualifying improvement), the same change oscillates, an unrecoverable error occurs, or the user says stop.
94889
+ - autonomy=checkpoint: pause at each phase gate and wait for explicit user approval before proceeding. autonomy=auto: proceed across gates without prompting, but still enforce every hard stop condition and the mandatory review/critic gates.
94890
+ - Before declaring the loop complete, run the IMPROVE/compound capture step: persist categorized learnings durably and ensure they are discoverable to the next loop. Do not declare completion without it.
94891
+ - Persist loop run state under \`.swarm/loop/\`; derive cycle/phase progress from git and the plan ledger, not from conversation memory, so the loop can resume after interruption.
94892
+
94688
94893
  ### MODE: DEEP_RESEARCH
94689
94894
  Activates when: architect receives \`[MODE: DEEP_RESEARCH depth=X max_researchers=N rounds=N output=report|brief] <question>\` signal from the deep-research command handler.
94690
94895
 
@@ -94791,6 +94996,7 @@ Purpose: Create or ingest the implementation plan, apply QA gate selections afte
94791
94996
  ACTION: Load skill file:.opencode/skills/plan/SKILL.md immediately. Follow the protocol defined there.
94792
94997
 
94793
94998
  HARD CONSTRAINTS (apply regardless of skill load success):
94999
+ - Before drafting or saving a plan, offer the loaded skill's General Council advisory option when \`council.general.enabled\` is true and a search API key is configured. If the user accepts, use the council output as context before calling \`save_plan\` and before any critic pre-plan review.
94794
95000
  - Use the \`save_plan\` tool as the primary plan writer. Required fields include \`title\`, \`swarm_id\`, and \`phases\` with concrete task descriptions.
94795
95001
  - Example call: save_plan({ title: "My Real Project", swarm_id: "mega", phases: [{ id: 1, name: "Setup", tasks: [{ id: "1.1", description: "Install dependencies and configure TypeScript", size: "small" }] }] })
94796
95002
 
@@ -123946,7 +124152,7 @@ var convene_general_council = createSwarmTool({
123946
124152
  description: "Synthesize responses from a multi-model General Council. Accepts parallel member " + "responses (Round 1, optionally Round 2), detects disagreements, and returns " + "consensus points, persisting disagreements, and a structured synthesis. " + "Architect-only. Config-gated on council.general.enabled in the resolved config: global ~/.config/opencode/opencode-swarm.json, then project .opencode/opencode-swarm.json overrides.",
123947
124153
  args: {
123948
124154
  question: exports_external.string().min(1).max(8000).describe("The question put to the council, or the spec text to review."),
123949
- mode: exports_external.enum(["general", "spec_review"]).optional().describe('"general" for /swarm council; "spec_review" for SPECIFY-COUNCIL-REVIEW gate.'),
124155
+ mode: exports_external.enum(["general", "spec_review"]).optional().describe('"general" for /swarm council or pre-save PLAN advisory; "spec_review" for manual /swarm council --spec-review.'),
123950
124156
  members: exports_external.array(exports_external.string()).optional().describe("Optional list of member IDs convened (for evidence/audit)."),
123951
124157
  round1Responses: exports_external.array(exports_external.object({
123952
124158
  memberId: exports_external.string().min(1),
@@ -147398,6 +147604,10 @@ async function initializeOpenCodeSwarm(ctx) {
147398
147604
  template: "/swarm brainstorm $ARGUMENTS",
147399
147605
  description: "Use /swarm brainstorm to enter the architect MODE: BRAINSTORM planning workflow"
147400
147606
  },
147607
+ "swarm-loop": {
147608
+ template: "/swarm loop $ARGUMENTS",
147609
+ description: "Use /swarm loop <objective> to run a compound-engineering loop: brainstorm → plan → build → review → improve, iterating until done [--max-cycles 1..5] [--autonomy checkpoint|auto] [--depth standard|exhaustive] [--resume]"
147610
+ },
147401
147611
  "swarm-council": {
147402
147612
  template: "/swarm council $ARGUMENTS",
147403
147613
  description: "Use /swarm council <question> to convene a multi-model General Council deliberation (generalist / skeptic / domain expert) [--preset <name>] [--spec-review]"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.79.1",
3
+ "version": "7.79.4",
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",
@@ -21,7 +21,7 @@
21
21
  "license": "MIT",
22
22
  "repository": {
23
23
  "type": "git",
24
- "url": "https://github.com/zaxbysauce/opencode-swarm.git"
24
+ "url": "https://github.com/ZaxbyHub/opencode-swarm.git"
25
25
  },
26
26
  "publishConfig": {
27
27
  "access": "public",
@@ -60,6 +60,7 @@
60
60
  ".opencode/skills/critic-gate",
61
61
  ".opencode/skills/execute",
62
62
  ".opencode/skills/phase-wrap",
63
+ ".opencode/skills/loop",
63
64
  "tests/fixtures/memory-recall",
64
65
  "README.md",
65
66
  "LICENSE"