opencode-swarm 7.13.2 → 7.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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.13.2",
37
+ version: "7.14.0",
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",
@@ -37531,6 +37531,118 @@ var init_dark_matter = __esm(() => {
37531
37531
  init_co_change_analyzer();
37532
37532
  });
37533
37533
 
37534
+ // src/commands/deep-dive.ts
37535
+ function sanitizeScope(raw) {
37536
+ const collapsed = raw.replace(/\s+/g, " ").trim();
37537
+ const stripped = collapsed.replace(/\[\s*MODE\s*:[^\]]*\]/gi, "");
37538
+ const normalized = stripped.replace(/\s+/g, " ").trim();
37539
+ if (normalized.length <= MAX_SCOPE_LEN)
37540
+ return normalized;
37541
+ return `${normalized.slice(0, MAX_SCOPE_LEN)}\u2026`;
37542
+ }
37543
+ function isValidPositiveInteger(raw) {
37544
+ if (!raw || !/^\d+$/.test(raw))
37545
+ return false;
37546
+ const n = Number(raw);
37547
+ if (!Number.isFinite(n) || !Number.isInteger(n) || n < 0)
37548
+ return false;
37549
+ return true;
37550
+ }
37551
+ function parseArgs2(args) {
37552
+ const result = {
37553
+ profile: DEFAULT_PROFILE,
37554
+ maxExplorers: DEFAULT_MAX_EXPLORERS,
37555
+ output: "markdown",
37556
+ updateMain: true,
37557
+ allowDirty: false,
37558
+ rest: []
37559
+ };
37560
+ let i = 0;
37561
+ while (i < args.length) {
37562
+ const token = args[i];
37563
+ if (token === "--profile") {
37564
+ if (i + 1 >= args.length) {
37565
+ return { ...result, error: `Flag "${token}" requires a value` };
37566
+ }
37567
+ const value = args[++i];
37568
+ if (!PROFILES.has(value)) {
37569
+ return {
37570
+ ...result,
37571
+ error: `Invalid profile "${value}". Must be one of: standard, security, ux, architecture, full.`
37572
+ };
37573
+ }
37574
+ result.profile = value;
37575
+ } else if (token === "--max-explorers") {
37576
+ if (i + 1 >= args.length) {
37577
+ return { ...result, error: `Flag "${token}" requires a value` };
37578
+ }
37579
+ const value = args[++i];
37580
+ if (!isValidPositiveInteger(value) || value.includes(".") || value.startsWith("0x") || value.startsWith("0X") || Number(value) < 1 || Number(value) > 8) {
37581
+ return {
37582
+ ...result,
37583
+ error: `Invalid --max-explorers value "${value}". Must be an integer between 1 and 8.`
37584
+ };
37585
+ }
37586
+ result.maxExplorers = Number(value);
37587
+ result.maxExplorersExplicit = true;
37588
+ } else if (token === "--json") {
37589
+ result.output = "json";
37590
+ } else if (token === "--skip-update") {
37591
+ result.updateMain = false;
37592
+ } else if (token === "--allow-dirty") {
37593
+ result.allowDirty = true;
37594
+ } else if (token.startsWith("--")) {
37595
+ return { ...result, error: `Unknown flag "${token}"` };
37596
+ } else {
37597
+ result.rest.push(token);
37598
+ }
37599
+ i++;
37600
+ }
37601
+ return result;
37602
+ }
37603
+ async function handleDeepDiveCommand(_directory, args) {
37604
+ const parsed = parseArgs2(args);
37605
+ if (parsed.error) {
37606
+ return `Error: ${parsed.error}
37607
+
37608
+ ${USAGE2}`;
37609
+ }
37610
+ const scope = sanitizeScope(parsed.rest.join(" "));
37611
+ if (!scope) {
37612
+ return USAGE2;
37613
+ }
37614
+ if (parsed.profile === "full" && !parsed.maxExplorersExplicit) {
37615
+ parsed.maxExplorers = FULL_PROFILE_DEFAULT_MAX_EXPLORERS;
37616
+ }
37617
+ const header = `[MODE: DEEP_DIVE profile=${parsed.profile} max_explorers=${parsed.maxExplorers} output=${parsed.output} update_main=${parsed.updateMain} allow_dirty=${parsed.allowDirty}] ${scope}`;
37618
+ return header;
37619
+ }
37620
+ var MAX_SCOPE_LEN = 2000, PROFILES, DEFAULT_PROFILE = "standard", DEFAULT_MAX_EXPLORERS = 6, FULL_PROFILE_DEFAULT_MAX_EXPLORERS = 8, USAGE2 = `Usage: /swarm deep-dive <scope> [--profile standard|security|ux|architecture|full] [--max-explorers N] [--json] [--skip-update] [--allow-dirty]
37621
+
37622
+ Run a bounded, evidence-backed deep dive on an application section.
37623
+
37624
+ Examples:
37625
+ /swarm deep-dive auth
37626
+ /swarm deep dive src/commands --profile architecture
37627
+ /swarm deep-dive "settings page" --profile ux
37628
+ /swarm deep-dive src/security --profile security --max-explorers 5
37629
+
37630
+ Flags:
37631
+ --profile <name> standard, security, ux, architecture, or full
37632
+ --max-explorers <N> explorer runs per wave, 1..8
37633
+ --json include machine-readable JSON in the final report
37634
+ --skip-update skip the repo update-to-main preflight
37635
+ --allow-dirty allow audit to proceed with dirty worktree`;
37636
+ var init_deep_dive = __esm(() => {
37637
+ PROFILES = new Set([
37638
+ "standard",
37639
+ "security",
37640
+ "ux",
37641
+ "architecture",
37642
+ "full"
37643
+ ]);
37644
+ });
37645
+
37534
37646
  // src/config/cache-paths.ts
37535
37647
  import * as os5 from "os";
37536
37648
  import * as path18 from "path";
@@ -42308,7 +42420,7 @@ function validateAndSanitizeUrl(rawUrl) {
42308
42420
  return { error: "Invalid URL format" };
42309
42421
  }
42310
42422
  }
42311
- function parseArgs2(args) {
42423
+ function parseArgs3(args) {
42312
42424
  const out = {
42313
42425
  plan: false,
42314
42426
  trace: false,
@@ -42399,24 +42511,24 @@ function parseGitRemoteUrl(remoteUrl) {
42399
42511
  return null;
42400
42512
  }
42401
42513
  function handleIssueCommand(_directory, args) {
42402
- const parsed = parseArgs2(args);
42514
+ const parsed = parseArgs3(args);
42403
42515
  const rawInput = parsed.rest.join(" ").trim();
42404
42516
  if (!rawInput) {
42405
- return USAGE2;
42517
+ return USAGE3;
42406
42518
  }
42407
42519
  const isFullUrl = /^https?:\/\//i.test(rawInput);
42408
42520
  const issueInfo = parseIssueRef(isFullUrl ? sanitizeUrl(rawInput) : rawInput);
42409
42521
  if (!issueInfo) {
42410
42522
  return `Error: Could not parse issue reference from "${rawInput}"
42411
42523
 
42412
- ${USAGE2}`;
42524
+ ${USAGE3}`;
42413
42525
  }
42414
42526
  const issueUrl = `https://github.com/${issueInfo.owner}/${issueInfo.repo}/issues/${issueInfo.number}`;
42415
42527
  const result = validateAndSanitizeUrl(issueUrl);
42416
42528
  if ("error" in result) {
42417
42529
  return `Error: ${result.error}
42418
42530
 
42419
- ${USAGE2}`;
42531
+ ${USAGE3}`;
42420
42532
  }
42421
42533
  const flags = [];
42422
42534
  if (parsed.plan)
@@ -42428,9 +42540,9 @@ ${USAGE2}`;
42428
42540
  const flagsStr = flags.length > 0 ? ` ${flags.join(" ")}` : "";
42429
42541
  return `[MODE: ISSUE_INGEST issue="${result.sanitized}"${flagsStr}]`;
42430
42542
  }
42431
- var MAX_URL_LEN = 2048, USAGE2;
42543
+ var MAX_URL_LEN = 2048, USAGE3;
42432
42544
  var init_issue = __esm(() => {
42433
- USAGE2 = [
42545
+ USAGE3 = [
42434
42546
  "Usage: /swarm issue <url|owner/repo#N|N> [--plan] [--trace] [--no-repro]",
42435
42547
  "",
42436
42548
  "Ingest a GitHub issue into the swarm workflow.",
@@ -43047,7 +43159,7 @@ function validateAndSanitizeUrl2(rawUrl) {
43047
43159
  return { error: "Invalid URL format" };
43048
43160
  }
43049
43161
  }
43050
- function parseArgs3(args) {
43162
+ function parseArgs4(args) {
43051
43163
  const out = { council: false, rest: [] };
43052
43164
  for (const token of args) {
43053
43165
  if (token === "--council") {
@@ -43131,31 +43243,31 @@ function parseGitRemoteUrl2(remoteUrl) {
43131
43243
  return null;
43132
43244
  }
43133
43245
  function handlePrReviewCommand(_directory, args) {
43134
- const parsed = parseArgs3(args);
43246
+ const parsed = parseArgs4(args);
43135
43247
  const rawInput = parsed.rest.join(" ").trim();
43136
43248
  if (!rawInput) {
43137
- return USAGE3;
43249
+ return USAGE4;
43138
43250
  }
43139
43251
  const isFullUrl = /^https?:\/\//i.test(rawInput);
43140
43252
  const prInfo = parsePrRef(isFullUrl ? sanitizeUrl2(rawInput) : rawInput);
43141
43253
  if (!prInfo) {
43142
43254
  return `Error: Could not parse PR reference from "${rawInput}"
43143
43255
 
43144
- ${USAGE3}`;
43256
+ ${USAGE4}`;
43145
43257
  }
43146
43258
  const prUrl = `https://github.com/${prInfo.owner}/${prInfo.repo}/pull/${prInfo.number}`;
43147
43259
  const result = validateAndSanitizeUrl2(prUrl);
43148
43260
  if ("error" in result) {
43149
43261
  return `Error: ${result.error}
43150
43262
 
43151
- ${USAGE3}`;
43263
+ ${USAGE4}`;
43152
43264
  }
43153
43265
  const councilFlag = parsed.council ? "council=true" : "council=false";
43154
43266
  return `[MODE: PR_REVIEW pr="${result.sanitized}" ${councilFlag}]`;
43155
43267
  }
43156
- var MAX_URL_LEN2 = 2048, USAGE3;
43268
+ var MAX_URL_LEN2 = 2048, USAGE4;
43157
43269
  var init_pr_review = __esm(() => {
43158
- USAGE3 = [
43270
+ USAGE4 = [
43159
43271
  "Usage: /swarm pr-review <url|owner/repo#N|N> [--council]",
43160
43272
  "",
43161
43273
  "Run a full swarm PR review on a GitHub pull request.",
@@ -48560,6 +48672,7 @@ __export(exports_commands, {
48560
48672
  handleEvidenceCommand: () => handleEvidenceCommand,
48561
48673
  handleDoctorCommand: () => handleDoctorCommand,
48562
48674
  handleDiagnoseCommand: () => handleDiagnoseCommand,
48675
+ handleDeepDiveCommand: () => handleDeepDiveCommand,
48563
48676
  handleDarkMatterCommand: () => handleDarkMatterCommand,
48564
48677
  handleCurateCommand: () => handleCurateCommand,
48565
48678
  handleCouncilCommand: () => handleCouncilCommand,
@@ -48763,6 +48876,7 @@ var init_commands = __esm(() => {
48763
48876
  init_council();
48764
48877
  init_curate();
48765
48878
  init_dark_matter();
48879
+ init_deep_dive();
48766
48880
  init_diagnose();
48767
48881
  init_doctor();
48768
48882
  init_evidence();
@@ -48980,6 +49094,7 @@ var init_registry = __esm(() => {
48980
49094
  init_council();
48981
49095
  init_curate();
48982
49096
  init_dark_matter();
49097
+ init_deep_dive();
48983
49098
  init_diagnose();
48984
49099
  init_doctor();
48985
49100
  init_evidence();
@@ -49259,6 +49374,20 @@ var init_registry = __esm(() => {
49259
49374
  details: "Launches a structured PR review: reconstructs PR intent via obligation extraction cascade, runs 6 parallel explorer lanes (correctness, security, dependencies, docs-intent-vs-actual, tests, performance-architecture), validates findings through independent reviewer confirmation, applies critic challenge to HIGH/CRITICAL findings, synthesizes structured report. --council variant fires adversarial multi-model review. Supports full GitHub URL, owner/repo#N shorthand, or bare PR number (resolves against origin remote).",
49260
49375
  category: "agent"
49261
49376
  },
49377
+ "deep-dive": {
49378
+ handler: async (ctx) => handleDeepDiveCommand(ctx.directory, ctx.args),
49379
+ description: "Launch deep codebase audit with parallel explorer waves, dual reviewers, and critic challenge [scope]",
49380
+ args: "<scope> [--profile standard|security|ux|architecture|full] [--max-explorers 1..8] [--json] [--skip-update] [--allow-dirty]",
49381
+ details: "Runs a read-only deep audit of the specified scope using parallel explorer waves (8-file cap per mission, ~3500 line guardrail), always 2 parallel reviewers for verification, and sequential critic challenge on HIGH/CRITICAL findings. Profiles select explorer lanes: standard (5 lanes), security, ux, architecture, full (all 8 lanes). Emits a structured findings report without mutating source code.",
49382
+ category: "agent"
49383
+ },
49384
+ "deep dive": {
49385
+ handler: async (ctx) => handleDeepDiveCommand(ctx.directory, ctx.args),
49386
+ description: "Alias for /swarm deep-dive \u2014 launch deep codebase audit",
49387
+ args: "<scope> [--profile standard|security|ux|architecture|full] [--max-explorers 1..8] [--json] [--skip-update] [--allow-dirty]",
49388
+ category: "agent",
49389
+ aliasOf: "deep-dive"
49390
+ },
49262
49391
  issue: {
49263
49392
  handler: async (ctx) => handleIssueCommand(ctx.directory, ctx.args),
49264
49393
  description: "Ingest a GitHub issue into the swarm workflow [url] [--plan] [--trace] [--no-repro]",
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Handle /swarm deep-dive command.
3
+ * Sanitizes scope input, parses flags, and emits a DEEP_DIVE mode signal.
4
+ */
5
+ export declare function handleDeepDiveCommand(_directory: string, args: string[]): Promise<string>;
@@ -14,6 +14,7 @@ export { handleConfigCommand } from './config';
14
14
  export { handleCouncilCommand } from './council';
15
15
  export { handleCurateCommand } from './curate';
16
16
  export { handleDarkMatterCommand } from './dark-matter';
17
+ export { handleDeepDiveCommand } from './deep-dive';
17
18
  export { handleDiagnoseCommand } from './diagnose';
18
19
  export { handleDoctorCommand } from './doctor';
19
20
  export { handleEvidenceCommand, handleEvidenceSummaryCommand, } from './evidence';
@@ -293,6 +293,20 @@ export declare const COMMAND_REGISTRY: {
293
293
  readonly details: "Launches a structured PR review: reconstructs PR intent via obligation extraction cascade, runs 6 parallel explorer lanes (correctness, security, dependencies, docs-intent-vs-actual, tests, performance-architecture), validates findings through independent reviewer confirmation, applies critic challenge to HIGH/CRITICAL findings, synthesizes structured report. --council variant fires adversarial multi-model review. Supports full GitHub URL, owner/repo#N shorthand, or bare PR number (resolves against origin remote).";
294
294
  readonly category: "agent";
295
295
  };
296
+ readonly 'deep-dive': {
297
+ readonly handler: (ctx: CommandContext) => Promise<string>;
298
+ readonly description: "Launch deep codebase audit with parallel explorer waves, dual reviewers, and critic challenge [scope]";
299
+ readonly args: "<scope> [--profile standard|security|ux|architecture|full] [--max-explorers 1..8] [--json] [--skip-update] [--allow-dirty]";
300
+ readonly details: "Runs a read-only deep audit of the specified scope using parallel explorer waves (8-file cap per mission, ~3500 line guardrail), always 2 parallel reviewers for verification, and sequential critic challenge on HIGH/CRITICAL findings. Profiles select explorer lanes: standard (5 lanes), security, ux, architecture, full (all 8 lanes). Emits a structured findings report without mutating source code.";
301
+ readonly category: "agent";
302
+ };
303
+ readonly 'deep dive': {
304
+ readonly handler: (ctx: CommandContext) => Promise<string>;
305
+ readonly description: "Alias for /swarm deep-dive — launch deep codebase audit";
306
+ readonly args: "<scope> [--profile standard|security|ux|architecture|full] [--max-explorers 1..8] [--json] [--skip-update] [--allow-dirty]";
307
+ readonly category: "agent";
308
+ readonly aliasOf: "deep-dive";
309
+ };
296
310
  readonly issue: {
297
311
  readonly handler: (ctx: CommandContext) => Promise<string>;
298
312
  readonly description: "Ingest a GitHub issue into the swarm workflow [url] [--plan] [--trace] [--no-repro]";
package/dist/index.js CHANGED
@@ -33,7 +33,7 @@ var package_default;
33
33
  var init_package = __esm(() => {
34
34
  package_default = {
35
35
  name: "opencode-swarm",
36
- version: "7.13.2",
36
+ version: "7.14.0",
37
37
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
38
38
  main: "dist/index.js",
39
39
  types: "dist/index.d.ts",
@@ -46041,6 +46041,118 @@ var init_dark_matter = __esm(() => {
46041
46041
  init_co_change_analyzer();
46042
46042
  });
46043
46043
 
46044
+ // src/commands/deep-dive.ts
46045
+ function sanitizeScope(raw) {
46046
+ const collapsed = raw.replace(/\s+/g, " ").trim();
46047
+ const stripped = collapsed.replace(/\[\s*MODE\s*:[^\]]*\]/gi, "");
46048
+ const normalized = stripped.replace(/\s+/g, " ").trim();
46049
+ if (normalized.length <= MAX_SCOPE_LEN)
46050
+ return normalized;
46051
+ return `${normalized.slice(0, MAX_SCOPE_LEN)}…`;
46052
+ }
46053
+ function isValidPositiveInteger(raw) {
46054
+ if (!raw || !/^\d+$/.test(raw))
46055
+ return false;
46056
+ const n = Number(raw);
46057
+ if (!Number.isFinite(n) || !Number.isInteger(n) || n < 0)
46058
+ return false;
46059
+ return true;
46060
+ }
46061
+ function parseArgs2(args2) {
46062
+ const result = {
46063
+ profile: DEFAULT_PROFILE,
46064
+ maxExplorers: DEFAULT_MAX_EXPLORERS,
46065
+ output: "markdown",
46066
+ updateMain: true,
46067
+ allowDirty: false,
46068
+ rest: []
46069
+ };
46070
+ let i2 = 0;
46071
+ while (i2 < args2.length) {
46072
+ const token = args2[i2];
46073
+ if (token === "--profile") {
46074
+ if (i2 + 1 >= args2.length) {
46075
+ return { ...result, error: `Flag "${token}" requires a value` };
46076
+ }
46077
+ const value = args2[++i2];
46078
+ if (!PROFILES.has(value)) {
46079
+ return {
46080
+ ...result,
46081
+ error: `Invalid profile "${value}". Must be one of: standard, security, ux, architecture, full.`
46082
+ };
46083
+ }
46084
+ result.profile = value;
46085
+ } else if (token === "--max-explorers") {
46086
+ if (i2 + 1 >= args2.length) {
46087
+ return { ...result, error: `Flag "${token}" requires a value` };
46088
+ }
46089
+ const value = args2[++i2];
46090
+ if (!isValidPositiveInteger(value) || value.includes(".") || value.startsWith("0x") || value.startsWith("0X") || Number(value) < 1 || Number(value) > 8) {
46091
+ return {
46092
+ ...result,
46093
+ error: `Invalid --max-explorers value "${value}". Must be an integer between 1 and 8.`
46094
+ };
46095
+ }
46096
+ result.maxExplorers = Number(value);
46097
+ result.maxExplorersExplicit = true;
46098
+ } else if (token === "--json") {
46099
+ result.output = "json";
46100
+ } else if (token === "--skip-update") {
46101
+ result.updateMain = false;
46102
+ } else if (token === "--allow-dirty") {
46103
+ result.allowDirty = true;
46104
+ } else if (token.startsWith("--")) {
46105
+ return { ...result, error: `Unknown flag "${token}"` };
46106
+ } else {
46107
+ result.rest.push(token);
46108
+ }
46109
+ i2++;
46110
+ }
46111
+ return result;
46112
+ }
46113
+ async function handleDeepDiveCommand(_directory, args2) {
46114
+ const parsed = parseArgs2(args2);
46115
+ if (parsed.error) {
46116
+ return `Error: ${parsed.error}
46117
+
46118
+ ${USAGE2}`;
46119
+ }
46120
+ const scope = sanitizeScope(parsed.rest.join(" "));
46121
+ if (!scope) {
46122
+ return USAGE2;
46123
+ }
46124
+ if (parsed.profile === "full" && !parsed.maxExplorersExplicit) {
46125
+ parsed.maxExplorers = FULL_PROFILE_DEFAULT_MAX_EXPLORERS;
46126
+ }
46127
+ const header = `[MODE: DEEP_DIVE profile=${parsed.profile} max_explorers=${parsed.maxExplorers} output=${parsed.output} update_main=${parsed.updateMain} allow_dirty=${parsed.allowDirty}] ${scope}`;
46128
+ return header;
46129
+ }
46130
+ var MAX_SCOPE_LEN = 2000, PROFILES, DEFAULT_PROFILE = "standard", DEFAULT_MAX_EXPLORERS = 6, FULL_PROFILE_DEFAULT_MAX_EXPLORERS = 8, USAGE2 = `Usage: /swarm deep-dive <scope> [--profile standard|security|ux|architecture|full] [--max-explorers N] [--json] [--skip-update] [--allow-dirty]
46131
+
46132
+ Run a bounded, evidence-backed deep dive on an application section.
46133
+
46134
+ Examples:
46135
+ /swarm deep-dive auth
46136
+ /swarm deep dive src/commands --profile architecture
46137
+ /swarm deep-dive "settings page" --profile ux
46138
+ /swarm deep-dive src/security --profile security --max-explorers 5
46139
+
46140
+ Flags:
46141
+ --profile <name> standard, security, ux, architecture, or full
46142
+ --max-explorers <N> explorer runs per wave, 1..8
46143
+ --json include machine-readable JSON in the final report
46144
+ --skip-update skip the repo update-to-main preflight
46145
+ --allow-dirty allow audit to proceed with dirty worktree`;
46146
+ var init_deep_dive = __esm(() => {
46147
+ PROFILES = new Set([
46148
+ "standard",
46149
+ "security",
46150
+ "ux",
46151
+ "architecture",
46152
+ "full"
46153
+ ]);
46154
+ });
46155
+
46044
46156
  // src/config/cache-paths.ts
46045
46157
  import * as os5 from "node:os";
46046
46158
  import * as path25 from "node:path";
@@ -50995,7 +51107,7 @@ function validateAndSanitizeUrl(rawUrl) {
50995
51107
  return { error: "Invalid URL format" };
50996
51108
  }
50997
51109
  }
50998
- function parseArgs2(args2) {
51110
+ function parseArgs3(args2) {
50999
51111
  const out2 = {
51000
51112
  plan: false,
51001
51113
  trace: false,
@@ -51086,24 +51198,24 @@ function parseGitRemoteUrl(remoteUrl) {
51086
51198
  return null;
51087
51199
  }
51088
51200
  function handleIssueCommand(_directory, args2) {
51089
- const parsed = parseArgs2(args2);
51201
+ const parsed = parseArgs3(args2);
51090
51202
  const rawInput = parsed.rest.join(" ").trim();
51091
51203
  if (!rawInput) {
51092
- return USAGE2;
51204
+ return USAGE3;
51093
51205
  }
51094
51206
  const isFullUrl = /^https?:\/\//i.test(rawInput);
51095
51207
  const issueInfo = parseIssueRef(isFullUrl ? sanitizeUrl(rawInput) : rawInput);
51096
51208
  if (!issueInfo) {
51097
51209
  return `Error: Could not parse issue reference from "${rawInput}"
51098
51210
 
51099
- ${USAGE2}`;
51211
+ ${USAGE3}`;
51100
51212
  }
51101
51213
  const issueUrl = `https://github.com/${issueInfo.owner}/${issueInfo.repo}/issues/${issueInfo.number}`;
51102
51214
  const result = validateAndSanitizeUrl(issueUrl);
51103
51215
  if ("error" in result) {
51104
51216
  return `Error: ${result.error}
51105
51217
 
51106
- ${USAGE2}`;
51218
+ ${USAGE3}`;
51107
51219
  }
51108
51220
  const flags2 = [];
51109
51221
  if (parsed.plan)
@@ -51115,9 +51227,9 @@ ${USAGE2}`;
51115
51227
  const flagsStr = flags2.length > 0 ? ` ${flags2.join(" ")}` : "";
51116
51228
  return `[MODE: ISSUE_INGEST issue="${result.sanitized}"${flagsStr}]`;
51117
51229
  }
51118
- var MAX_URL_LEN = 2048, USAGE2;
51230
+ var MAX_URL_LEN = 2048, USAGE3;
51119
51231
  var init_issue = __esm(() => {
51120
- USAGE2 = [
51232
+ USAGE3 = [
51121
51233
  "Usage: /swarm issue <url|owner/repo#N|N> [--plan] [--trace] [--no-repro]",
51122
51234
  "",
51123
51235
  "Ingest a GitHub issue into the swarm workflow.",
@@ -51734,7 +51846,7 @@ function validateAndSanitizeUrl2(rawUrl) {
51734
51846
  return { error: "Invalid URL format" };
51735
51847
  }
51736
51848
  }
51737
- function parseArgs3(args2) {
51849
+ function parseArgs4(args2) {
51738
51850
  const out2 = { council: false, rest: [] };
51739
51851
  for (const token of args2) {
51740
51852
  if (token === "--council") {
@@ -51818,31 +51930,31 @@ function parseGitRemoteUrl2(remoteUrl) {
51818
51930
  return null;
51819
51931
  }
51820
51932
  function handlePrReviewCommand(_directory, args2) {
51821
- const parsed = parseArgs3(args2);
51933
+ const parsed = parseArgs4(args2);
51822
51934
  const rawInput = parsed.rest.join(" ").trim();
51823
51935
  if (!rawInput) {
51824
- return USAGE3;
51936
+ return USAGE4;
51825
51937
  }
51826
51938
  const isFullUrl = /^https?:\/\//i.test(rawInput);
51827
51939
  const prInfo = parsePrRef(isFullUrl ? sanitizeUrl2(rawInput) : rawInput);
51828
51940
  if (!prInfo) {
51829
51941
  return `Error: Could not parse PR reference from "${rawInput}"
51830
51942
 
51831
- ${USAGE3}`;
51943
+ ${USAGE4}`;
51832
51944
  }
51833
51945
  const prUrl = `https://github.com/${prInfo.owner}/${prInfo.repo}/pull/${prInfo.number}`;
51834
51946
  const result = validateAndSanitizeUrl2(prUrl);
51835
51947
  if ("error" in result) {
51836
51948
  return `Error: ${result.error}
51837
51949
 
51838
- ${USAGE3}`;
51950
+ ${USAGE4}`;
51839
51951
  }
51840
51952
  const councilFlag = parsed.council ? "council=true" : "council=false";
51841
51953
  return `[MODE: PR_REVIEW pr="${result.sanitized}" ${councilFlag}]`;
51842
51954
  }
51843
- var MAX_URL_LEN2 = 2048, USAGE3;
51955
+ var MAX_URL_LEN2 = 2048, USAGE4;
51844
51956
  var init_pr_review = __esm(() => {
51845
- USAGE3 = [
51957
+ USAGE4 = [
51846
51958
  "Usage: /swarm pr-review <url|owner/repo#N|N> [--council]",
51847
51959
  "",
51848
51960
  "Run a full swarm PR review on a GitHub pull request.",
@@ -57572,6 +57684,7 @@ __export(exports_commands, {
57572
57684
  handleEvidenceCommand: () => handleEvidenceCommand,
57573
57685
  handleDoctorCommand: () => handleDoctorCommand,
57574
57686
  handleDiagnoseCommand: () => handleDiagnoseCommand,
57687
+ handleDeepDiveCommand: () => handleDeepDiveCommand,
57575
57688
  handleDarkMatterCommand: () => handleDarkMatterCommand,
57576
57689
  handleCurateCommand: () => handleCurateCommand,
57577
57690
  handleCouncilCommand: () => handleCouncilCommand,
@@ -57775,6 +57888,7 @@ var init_commands = __esm(() => {
57775
57888
  init_council();
57776
57889
  init_curate();
57777
57890
  init_dark_matter();
57891
+ init_deep_dive();
57778
57892
  init_diagnose();
57779
57893
  init_doctor();
57780
57894
  init_evidence();
@@ -57992,6 +58106,7 @@ var init_registry = __esm(() => {
57992
58106
  init_council();
57993
58107
  init_curate();
57994
58108
  init_dark_matter();
58109
+ init_deep_dive();
57995
58110
  init_diagnose();
57996
58111
  init_doctor();
57997
58112
  init_evidence();
@@ -58271,6 +58386,20 @@ var init_registry = __esm(() => {
58271
58386
  details: "Launches a structured PR review: reconstructs PR intent via obligation extraction cascade, runs 6 parallel explorer lanes (correctness, security, dependencies, docs-intent-vs-actual, tests, performance-architecture), validates findings through independent reviewer confirmation, applies critic challenge to HIGH/CRITICAL findings, synthesizes structured report. --council variant fires adversarial multi-model review. Supports full GitHub URL, owner/repo#N shorthand, or bare PR number (resolves against origin remote).",
58272
58387
  category: "agent"
58273
58388
  },
58389
+ "deep-dive": {
58390
+ handler: async (ctx) => handleDeepDiveCommand(ctx.directory, ctx.args),
58391
+ description: "Launch deep codebase audit with parallel explorer waves, dual reviewers, and critic challenge [scope]",
58392
+ args: "<scope> [--profile standard|security|ux|architecture|full] [--max-explorers 1..8] [--json] [--skip-update] [--allow-dirty]",
58393
+ details: "Runs a read-only deep audit of the specified scope using parallel explorer waves (8-file cap per mission, ~3500 line guardrail), always 2 parallel reviewers for verification, and sequential critic challenge on HIGH/CRITICAL findings. Profiles select explorer lanes: standard (5 lanes), security, ux, architecture, full (all 8 lanes). Emits a structured findings report without mutating source code.",
58394
+ category: "agent"
58395
+ },
58396
+ "deep dive": {
58397
+ handler: async (ctx) => handleDeepDiveCommand(ctx.directory, ctx.args),
58398
+ description: "Alias for /swarm deep-dive — launch deep codebase audit",
58399
+ args: "<scope> [--profile standard|security|ux|architecture|full] [--max-explorers 1..8] [--json] [--skip-update] [--allow-dirty]",
58400
+ category: "agent",
58401
+ aliasOf: "deep-dive"
58402
+ },
58274
58403
  issue: {
58275
58404
  handler: async (ctx) => handleIssueCommand(ctx.directory, ctx.args),
58276
58405
  description: "Ingest a GitHub issue into the swarm workflow [url] [--plan] [--trace] [--no-repro]",
@@ -59767,7 +59896,130 @@ Do NOT share other agents' responses at this stage.
59767
59896
  - CITE THE STRONGEST SOURCES: link key claims with [title](url) format from the source list in the synthesis. Pick the most reputable source per claim; do not cite duplicates.
59768
59897
  - BE CONCISE: a few short paragraphs plus a bulleted summary. Expand only when the question genuinely requires it.
59769
59898
  - HARD CONSTRAINTS: You MUST NOT invent claims not present in the council's responses. You MUST NOT add new web research. You MUST NOT favor a position based on confidence alone.
59770
- Preface the answer with one line listing the participating models (reviewer model as generalist, critic model as skeptic, SME model as domain expert). Do NOT present raw per-member JSON.
59899
+ Preface the answer with one line listing the participating models (reviewer model as generalist, critic model as skeptic, SME model as domain expert). Do NOT present raw per-member JSON.
59900
+
59901
+ ### MODE: DEEP_DIVE
59902
+ Activates when: architect receives \`[MODE: DEEP_DIVE profile=X max_explorers=N output=X update_main=X allow_dirty=X] <scope>\` signal from the deep-dive command handler.
59903
+
59904
+ Purpose: Perform a read-only deep audit of the specified codebase scope using parallel explorer waves, always 2 parallel reviewers, and sequential critic challenge. This mode does NOT mutate source code, does NOT delegate to coder, and does NOT call declare_scope.
59905
+
59906
+ #### STEP 0 — PARSE HEADER
59907
+ Parse the MODE: DEEP_DIVE header to extract:
59908
+ - \`scope\`: the codebase area to audit (e.g., "auth", "payment flow", "src/hooks/")
59909
+ - \`profile\`: one of standard | security | ux | architecture | full (default: standard)
59910
+ - \`max_explorers\`: integer 1..8 (default: 6, or 8 for full profile)
59911
+ - \`output\`: markdown | json (default: markdown)
59912
+ - \`update_main\`: boolean (default: true) — whether to fetch/ff-only main before starting
59913
+ - \`allow_dirty\`: boolean (default: false) — whether to proceed with uncommitted changes
59914
+
59915
+ If the header is malformed or missing required fields, report the error and stop.
59916
+
59917
+ #### STEP 1 — REPO READINESS
59918
+ 1. Check git working tree status. If dirty and \`allow_dirty\` is false, warn the user and ask whether to proceed. Do NOT proceed automatically.
59919
+ 2. If \`update_main\` is true and tree is clean: check current branch. If not on \`main\`, report current branch to user and ASK FOR CONFIRMATION before switching. Only after explicit user approval: \`git fetch origin main && git checkout main && git merge --ff-only origin/main\`. If ff-only fails, warn the user and ask before proceeding.
59920
+ 3. Record the current HEAD commit hash for the report.
59921
+
59922
+ #### STEP 2 — SCOPE RESOLUTION
59923
+ Use the following tools to map the audit scope:
59924
+ 1. \`repo_map\` with action "build" to establish the code graph
59925
+ 2. \`repo_map\` with action "localization" for the scope target
59926
+ 3. \`symbols\` and \`batch_symbols\` on key files identified by localization
59927
+ 4. \`imports\` to trace dependency boundaries
59928
+ 5. \`doc_scan\` if documentation coverage is relevant
59929
+ 6. \`knowledge_recall\` with query matching the scope domain
59930
+
59931
+ Produce a SCOPE MAP: list of files, modules, and interfaces within the audit boundary. Cap at 50 files total.
59932
+
59933
+ #### STEP 3 — EXPLORER MISSIONS (Parallel Waves)
59934
+ Dispatch explorer waves using parallel Task calls. Each wave contains up to \`max_explorers\` missions.
59935
+
59936
+ **File caps per mission:**
59937
+ - 8 files maximum per mission
59938
+ - ~3500 total lines across all files in a mission
59939
+ - Group files by import proximity (files that import each other go in the same mission)
59940
+
59941
+ **Profile-based lane selection — each profile activates specific lanes:**
59942
+
59943
+ | Lane | Template | standard | security | ux | architecture | full |
59944
+ |------|----------|----------|----------|----|-------------|------|
59945
+ | SCOPE_MAP | Map structure, exports, boundaries | ✓ | ✓ | ✓ | ✓ | ✓ |
59946
+ | WIRING_DATAFLOW | Trace data flow, API contracts, state propagation | ✓ | ✓ | | ✓ | ✓ |
59947
+ | RUNTIME_BEHAVIOR | Error handling, edge cases, lifecycle, async patterns | ✓ | | | ✓ | ✓ |
59948
+ | UX_FLOW | User-facing behavior, accessibility, responsiveness | | | ✓ | | ✓ |
59949
+ | SECURITY_TRUST | Auth boundaries, input validation, trust transitions | | ✓ | | | ✓ |
59950
+ | TEST_COVERAGE | Coverage gaps, flaky tests, missing assertions | ✓ | | | | ✓ |
59951
+ | PERFORMANCE_RELIABILITY | Resource leaks, N+1 queries, race conditions | | | | ✓ | ✓ |
59952
+ | DOCS_CONFIG_DEPLOYMENT | Config consistency, docs accuracy, deployment drift | | | | | ✓ |
59953
+
59954
+ Each explorer mission receives:
59955
+ - Lane template name and description
59956
+ - Assigned files (8 max, grouped by import proximity)
59957
+ - The scope map context from Step 2
59958
+ - Instruction: "You are performing a [LANE] audit. Report findings as candidate observations with severity (INFO/LOW/MEDIUM/HIGH/CRITICAL), location, and evidence."
59959
+
59960
+ Explorer missions are dispatched in parallel waves. Wait for ALL missions in a wave to complete before dispatching the next wave.
59961
+
59962
+ Explorers generate CANDIDATE FINDINGS only — they do NOT make verdicts. All findings are unverified until Step 5.
59963
+
59964
+ #### STEP 4 — NORMALIZE CANDIDATES
59965
+ 1. Collect all candidate findings from all explorer missions.
59966
+ 2. Deduplicate: merge findings that reference the same location and issue.
59967
+ 3. Assign DD-C001 through DD-CNNN identifiers to unique findings.
59968
+ 4. Cap at 10 findings per shard (see Step 5 for sharding).
59969
+ 5. Sort by severity (CRITICAL → HIGH → MEDIUM → LOW → INFO).
59970
+
59971
+ #### STEP 5 — ALWAYS 2 PARALLEL REVIEWERS
59972
+ Split the verified candidates into 2 shards of ≤10 candidates each. Dispatch 2 parallel \`{{AGENT_PREFIX}}reviewer\` calls.
59973
+
59974
+ Each reviewer receives:
59975
+ - Their shard of candidates (up to 10)
59976
+ - The scope map context
59977
+ - The original scope description
59978
+ - Instruction: "Verify or reject each candidate finding. For each: verdict (VERIFIED / REJECTED / NEEDS_MORE_EVIDENCE), confidence (0-1), and brief reasoning."
59979
+
59980
+ Reviewers MUST NOT suggest fixes — they verify findings only.
59981
+
59982
+ #### STEP 5b — REVIEWER MERGE/DEDUP
59983
+ After both reviewers return, perform a lightweight sync pass:
59984
+ 1. Cross-reference findings between reviewers — flag correlations
59985
+ 2. Deduplicate any findings both reviewers verified independently
59986
+ 3. For NEEDS_MORE_EVIDENCE findings: if the other reviewer verified a related finding, merge
59987
+ 4. Produce a unified findings list with verified/rejected status
59988
+
59989
+ #### STEP 6 — CRITIC CHALLENGE (HIGH/CRITICAL only)
59990
+ For verified findings rated HIGH or CRITICAL, dispatch sequential critic passes:
59991
+
59992
+ **Pass 1 — False-positive / root-cause challenge:**
59993
+ - \`{{AGENT_PREFIX}}critic\` receives each HIGH/CRITICAL finding
59994
+ - Challenge: "Is this a false positive? Is the root cause correctly identified? Provide verdict: SURVIVES / DOWNGRADE / REJECT"
59995
+ - Only findings that SURVIVE proceed to Pass 2
59996
+
59997
+ **Pass 2 — Impact / severity challenge:**
59998
+ - \`{{AGENT_PREFIX}}critic\` receives surviving findings
59999
+ - Challenge: "Is the severity correctly rated? Could this be lower impact than claimed? Provide verdict: SURVIVES / DOWNGRADE / REJECT"
60000
+ - Final severity is the critic's assessed severity
60001
+
60002
+ CRITICAL: Do NOT challenge MEDIUM/LOW/INFO findings. Only HIGH and CRITICAL go through critic review.
60003
+
60004
+ #### STEP 7 — FINAL REPORT
60005
+ Assemble and present the audit report:
60006
+
60007
+ 1. **Wiring Map**: Visual summary of the scope's module structure and data flow
60008
+ 2. **Functionality Assessment**: High-level summary of what the scope does and how well
60009
+ 3. **Verified Findings Table**: DD-ID, severity, location, description, evidence
60010
+ 4. **Rejected Candidates**: Brief list with rejection reasons
60011
+ 5. **Enhancements**: Non-blocking improvement suggestions
60012
+ 6. **Recommended Implementation Phases**: If findings suggest follow-up work, outline phases
60013
+ 7. **JSON Block** (when output=json): Structured machine-readable findings
60014
+
60015
+ IMPORTANT CONSTRAINTS for MODE: DEEP_DIVE:
60016
+ - Do NOT mutate source code under any circumstances
60017
+ - Do NOT delegate to coder
60018
+ - Do NOT call declare_scope
60019
+ - Do NOT create or modify any files outside .swarm/
60020
+ - No final finding may appear in the report without reviewer verification
60021
+ - Explorers generate candidate findings only — reviewers verify or reject
60022
+ - Critics challenge only HIGH/CRITICAL findings — do NOT waste cycles on lower severity
59771
60023
 
59772
60024
  ### MODE: ISSUE_INGEST
59773
60025
  Activates when: user invokes \`/swarm issue <url>\`; OR architect receives \`[MODE: ISSUE_INGEST issue="<url>"]\` signal.
@@ -98204,6 +98456,10 @@ async function initializeOpenCodeSwarm(ctx) {
98204
98456
  template: "/swarm pr-review $ARGUMENTS",
98205
98457
  description: "Use /swarm pr-review to launch deep PR review with multi-lane analysis"
98206
98458
  },
98459
+ "swarm-deep-dive": {
98460
+ template: "/swarm deep-dive $ARGUMENTS",
98461
+ description: "Use /swarm deep-dive to launch a read-only deep audit with parallel explorer waves, dual reviewers, and critic challenge"
98462
+ },
98207
98463
  "swarm-issue": {
98208
98464
  template: "/swarm issue $ARGUMENTS",
98209
98465
  description: "Use /swarm issue to ingest a GitHub issue into the swarm workflow"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.13.2",
3
+ "version": "7.14.0",
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",