opencode-swarm 6.25.8 → 6.27.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.
@@ -0,0 +1 @@
1
+ export {};
package/dist/cli/index.js CHANGED
@@ -14281,7 +14281,10 @@ function sanitizeTaskId(taskId) {
14281
14281
  if (RETRO_TASK_ID_REGEX.test(taskId)) {
14282
14282
  return taskId;
14283
14283
  }
14284
- throw new Error(`Invalid task ID: must match pattern ^\\d+\\.\\d+(\\.\\d+)*$ or ^retro-\\d+$, got "${taskId}"`);
14284
+ if (INTERNAL_TOOL_ID_REGEX.test(taskId)) {
14285
+ return taskId;
14286
+ }
14287
+ throw new Error(`Invalid task ID: must match pattern ^\\d+\\.\\d+(\\.\\d+)*$, ^retro-\\d+$, or ^(?:sast_scan|quality_budget|syntax_check|placeholder_scan|sbom_generate|build)$, got "${taskId}"`);
14285
14288
  }
14286
14289
  async function saveEvidence(directory, taskId, evidence) {
14287
14290
  const sanitizedTaskId = sanitizeTaskId(taskId);
@@ -14491,7 +14494,7 @@ async function archiveEvidence(directory, maxAgeDays, maxBundles) {
14491
14494
  }
14492
14495
  return archived;
14493
14496
  }
14494
- var TASK_ID_REGEX, RETRO_TASK_ID_REGEX, LEGACY_TASK_COMPLEXITY_MAP;
14497
+ var TASK_ID_REGEX, RETRO_TASK_ID_REGEX, INTERNAL_TOOL_ID_REGEX, LEGACY_TASK_COMPLEXITY_MAP;
14495
14498
  var init_manager = __esm(() => {
14496
14499
  init_zod();
14497
14500
  init_evidence_schema();
@@ -14499,6 +14502,7 @@ var init_manager = __esm(() => {
14499
14502
  init_utils();
14500
14503
  TASK_ID_REGEX = /^\d+\.\d+(\.\d+)*$/;
14501
14504
  RETRO_TASK_ID_REGEX = /^retro-\d+$/;
14505
+ INTERNAL_TOOL_ID_REGEX = /^(?:sast_scan|quality_budget|syntax_check|placeholder_scan|sbom_generate|build)$/;
14502
14506
  LEGACY_TASK_COMPLEXITY_MAP = {
14503
14507
  low: "simple",
14504
14508
  medium: "moderate",
@@ -14506,6 +14510,57 @@ var init_manager = __esm(() => {
14506
14510
  };
14507
14511
  });
14508
14512
 
14513
+ // src/config/plan-schema.ts
14514
+ var TaskStatusSchema, TaskSizeSchema, PhaseStatusSchema, MigrationStatusSchema, TaskSchema, PhaseSchema, PlanSchema;
14515
+ var init_plan_schema = __esm(() => {
14516
+ init_zod();
14517
+ TaskStatusSchema = exports_external.enum([
14518
+ "pending",
14519
+ "in_progress",
14520
+ "completed",
14521
+ "blocked"
14522
+ ]);
14523
+ TaskSizeSchema = exports_external.enum(["small", "medium", "large"]);
14524
+ PhaseStatusSchema = exports_external.enum([
14525
+ "pending",
14526
+ "in_progress",
14527
+ "complete",
14528
+ "completed",
14529
+ "blocked"
14530
+ ]);
14531
+ MigrationStatusSchema = exports_external.enum([
14532
+ "native",
14533
+ "migrated",
14534
+ "migration_failed"
14535
+ ]);
14536
+ TaskSchema = exports_external.object({
14537
+ id: exports_external.string(),
14538
+ phase: exports_external.number().int().min(1),
14539
+ status: TaskStatusSchema.default("pending"),
14540
+ size: TaskSizeSchema.default("small"),
14541
+ description: exports_external.string().min(1),
14542
+ depends: exports_external.array(exports_external.string()).default([]),
14543
+ acceptance: exports_external.string().optional(),
14544
+ files_touched: exports_external.array(exports_external.string()).default([]),
14545
+ evidence_path: exports_external.string().optional(),
14546
+ blocked_reason: exports_external.string().optional()
14547
+ });
14548
+ PhaseSchema = exports_external.object({
14549
+ id: exports_external.number().int().min(1),
14550
+ name: exports_external.string().min(1),
14551
+ status: PhaseStatusSchema.default("pending"),
14552
+ tasks: exports_external.array(TaskSchema).default([])
14553
+ });
14554
+ PlanSchema = exports_external.object({
14555
+ schema_version: exports_external.literal("1.0.0"),
14556
+ title: exports_external.string().min(1),
14557
+ swarm: exports_external.string().min(1),
14558
+ current_phase: exports_external.number().int().min(1).optional(),
14559
+ phases: exports_external.array(PhaseSchema).min(1),
14560
+ migration_status: MigrationStatusSchema.optional()
14561
+ });
14562
+ });
14563
+
14509
14564
  // node_modules/graceful-fs/polyfills.js
14510
14565
  var require_polyfills = __commonJS((exports, module) => {
14511
14566
  var constants = __require("constants");
@@ -16026,57 +16081,6 @@ var require_proper_lockfile = __commonJS((exports, module) => {
16026
16081
  module.exports.checkSync = checkSync;
16027
16082
  });
16028
16083
 
16029
- // src/config/plan-schema.ts
16030
- var TaskStatusSchema, TaskSizeSchema, PhaseStatusSchema, MigrationStatusSchema, TaskSchema, PhaseSchema, PlanSchema;
16031
- var init_plan_schema = __esm(() => {
16032
- init_zod();
16033
- TaskStatusSchema = exports_external.enum([
16034
- "pending",
16035
- "in_progress",
16036
- "completed",
16037
- "blocked"
16038
- ]);
16039
- TaskSizeSchema = exports_external.enum(["small", "medium", "large"]);
16040
- PhaseStatusSchema = exports_external.enum([
16041
- "pending",
16042
- "in_progress",
16043
- "complete",
16044
- "completed",
16045
- "blocked"
16046
- ]);
16047
- MigrationStatusSchema = exports_external.enum([
16048
- "native",
16049
- "migrated",
16050
- "migration_failed"
16051
- ]);
16052
- TaskSchema = exports_external.object({
16053
- id: exports_external.string(),
16054
- phase: exports_external.number().int().min(1),
16055
- status: TaskStatusSchema.default("pending"),
16056
- size: TaskSizeSchema.default("small"),
16057
- description: exports_external.string().min(1),
16058
- depends: exports_external.array(exports_external.string()).default([]),
16059
- acceptance: exports_external.string().optional(),
16060
- files_touched: exports_external.array(exports_external.string()).default([]),
16061
- evidence_path: exports_external.string().optional(),
16062
- blocked_reason: exports_external.string().optional()
16063
- });
16064
- PhaseSchema = exports_external.object({
16065
- id: exports_external.number().int().min(1),
16066
- name: exports_external.string().min(1),
16067
- status: PhaseStatusSchema.default("pending"),
16068
- tasks: exports_external.array(TaskSchema).default([])
16069
- });
16070
- PlanSchema = exports_external.object({
16071
- schema_version: exports_external.literal("1.0.0"),
16072
- title: exports_external.string().min(1),
16073
- swarm: exports_external.string().min(1),
16074
- current_phase: exports_external.number().int().min(1).optional(),
16075
- phases: exports_external.array(PhaseSchema).min(1),
16076
- migration_status: MigrationStatusSchema.optional()
16077
- });
16078
- });
16079
-
16080
16084
  // src/plan/manager.ts
16081
16085
  import { renameSync as renameSync2, unlinkSync } from "fs";
16082
16086
  import * as path7 from "path";
@@ -17417,6 +17421,7 @@ async function handleArchiveCommand(directory, args) {
17417
17421
  init_manager();
17418
17422
 
17419
17423
  // src/state.ts
17424
+ init_plan_schema();
17420
17425
  var swarmState = {
17421
17426
  activeToolCalls: new Map,
17422
17427
  toolAggregates: new Map,
@@ -17425,6 +17430,17 @@ var swarmState = {
17425
17430
  pendingEvents: 0,
17426
17431
  agentSessions: new Map
17427
17432
  };
17433
+ function getAgentSession(sessionId) {
17434
+ return swarmState.agentSessions.get(sessionId);
17435
+ }
17436
+ function hasActiveTurboMode() {
17437
+ for (const [_sessionId, session] of swarmState.agentSessions) {
17438
+ if (session.turboMode === true) {
17439
+ return true;
17440
+ }
17441
+ }
17442
+ return false;
17443
+ }
17428
17444
 
17429
17445
  // src/commands/benchmark.ts
17430
17446
  init_utils();
@@ -30950,6 +30966,7 @@ function serializeAgentSession(s) {
30950
30966
  architectWriteCount: s.architectWriteCount ?? 0,
30951
30967
  lastCoderDelegationTaskId: s.lastCoderDelegationTaskId ?? null,
30952
30968
  currentTaskId: s.currentTaskId ?? null,
30969
+ turboMode: s.turboMode ?? false,
30953
30970
  gateLog,
30954
30971
  reviewerCallCount,
30955
30972
  lastGateFailure: s.lastGateFailure ?? null,
@@ -35635,7 +35652,8 @@ async function getStatusData(directory, agents) {
35635
35652
  completedTasks: completedTasks2,
35636
35653
  totalTasks: totalTasks2,
35637
35654
  agentCount: agentCount2,
35638
- isLegacy: false
35655
+ isLegacy: false,
35656
+ turboMode: hasActiveTurboMode()
35639
35657
  };
35640
35658
  }
35641
35659
  const planContent = await readSwarmFileAsync(directory, "plan.md");
@@ -35646,7 +35664,8 @@ async function getStatusData(directory, agents) {
35646
35664
  completedTasks: 0,
35647
35665
  totalTasks: 0,
35648
35666
  agentCount: Object.keys(agents).length,
35649
- isLegacy: true
35667
+ isLegacy: true,
35668
+ turboMode: hasActiveTurboMode()
35650
35669
  };
35651
35670
  }
35652
35671
  const currentPhase = extractCurrentPhase(planContent) || "Unknown";
@@ -35660,7 +35679,8 @@ async function getStatusData(directory, agents) {
35660
35679
  completedTasks,
35661
35680
  totalTasks,
35662
35681
  agentCount,
35663
- isLegacy: true
35682
+ isLegacy: true,
35683
+ turboMode: hasActiveTurboMode()
35664
35684
  };
35665
35685
  }
35666
35686
  function formatStatusMarkdown(status) {
@@ -35671,6 +35691,9 @@ function formatStatusMarkdown(status) {
35671
35691
  `**Tasks**: ${status.completedTasks}/${status.totalTasks} complete`,
35672
35692
  `**Agents**: ${status.agentCount} registered`
35673
35693
  ];
35694
+ if (status.turboMode) {
35695
+ lines.push("", `**TURBO MODE**: active`);
35696
+ }
35674
35697
  return lines.join(`
35675
35698
  `);
35676
35699
  }
@@ -35706,6 +35729,32 @@ No active swarm plan found. Nothing to sync.`;
35706
35729
  `);
35707
35730
  }
35708
35731
 
35732
+ // src/commands/turbo.ts
35733
+ async function handleTurboCommand(_directory, args, sessionID) {
35734
+ if (!sessionID || sessionID.trim() === "") {
35735
+ return "Error: No active session context. Turbo Mode requires an active session. Use /swarm turbo from within an OpenCode session, or start a session first.";
35736
+ }
35737
+ const session = getAgentSession(sessionID);
35738
+ if (!session) {
35739
+ return "Error: No active session. Turbo Mode requires an active session to operate.";
35740
+ }
35741
+ const arg = args[0]?.toLowerCase();
35742
+ let newTurboMode;
35743
+ let feedback;
35744
+ if (arg === "on") {
35745
+ newTurboMode = true;
35746
+ feedback = "Turbo Mode enabled";
35747
+ } else if (arg === "off") {
35748
+ newTurboMode = false;
35749
+ feedback = "Turbo Mode disabled";
35750
+ } else {
35751
+ newTurboMode = !session.turboMode;
35752
+ feedback = newTurboMode ? "Turbo Mode enabled" : "Turbo Mode disabled";
35753
+ }
35754
+ session.turboMode = newTurboMode;
35755
+ return feedback;
35756
+ }
35757
+
35709
35758
  // src/tools/write-retro.ts
35710
35759
  init_manager();
35711
35760
  async function executeWriteRetro(args, directory) {
@@ -35860,6 +35909,7 @@ var HELP_TEXT = [
35860
35909
  "- `/swarm knowledge migrate` \u2014 Migrate knowledge entries to the current format",
35861
35910
  '- `/swarm promote "<lesson>" | --category <cat> | --from-swarm <id> \u2014 Manually promote lesson to hive knowledge',
35862
35911
  "- `/swarm handoff` \u2014 Prepare state for clean model switch (new session)",
35912
+ "- `/swarm turbo [on|off]` \u2014 Toggle Turbo Mode for the active session (default: toggle)",
35863
35913
  "- `/swarm write-retro <json>` \u2014 Write a retrospective evidence bundle for a completed phase"
35864
35914
  ].join(`
35865
35915
  `);
@@ -36122,6 +36172,11 @@ Run "bunx opencode-swarm --help" for a list of commands.`);
36122
36172
  console.log(result);
36123
36173
  return 0;
36124
36174
  }
36175
+ case "turbo": {
36176
+ const result = await handleTurboCommand(cwd, args.slice(1), "");
36177
+ console.log(result);
36178
+ return 0;
36179
+ }
36125
36180
  case "knowledge": {
36126
36181
  const knowledgeSubcmd = args[1];
36127
36182
  if (knowledgeSubcmd === "migrate") {
@@ -24,6 +24,7 @@ export { handleSimulateCommand } from './simulate';
24
24
  export { handleSpecifyCommand } from './specify';
25
25
  export { handleStatusCommand } from './status';
26
26
  export { handleSyncPlanCommand } from './sync-plan';
27
+ export { handleTurboCommand } from './turbo';
27
28
  export { handleWriteRetroCommand } from './write_retro';
28
29
  /**
29
30
  * Creates a command.execute.before handler for /swarm commands.
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Tests for Task 3.12: Turbo Mode command registration in src/commands/index.ts
3
+ * Verifies import, export, help text, and switch case routing for /swarm turbo
4
+ */
5
+ export {};
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Tests for Task 3.13: Empty sessionID handling in handleTurboCommand
3
+ * Tests the CLI wiring fix where empty sessionID returns proper error message
4
+ */
5
+ export {};
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Handles the /swarm turbo command.
3
+ * Toggles Turbo Mode on or off for the active session.
4
+ *
5
+ * @param directory - Project directory (unused but kept for consistency with other commands)
6
+ * @param args - Optional argument: "on" | "off" | undefined (toggle behavior)
7
+ * @param sessionID - Session ID for accessing active session state
8
+ * @returns Feedback message about Turbo Mode state
9
+ */
10
+ export declare function handleTurboCommand(_directory: string, args: string[], sessionID: string): Promise<string>;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Regression Tests for Task 4: Turbo Mode Integration
3
+ *
4
+ * These tests verify that Turbo Mode is correctly integrated across all surfaces:
5
+ * 1. /swarm turbo command toggles turboMode correctly
6
+ * 2. checkReviewerGate bypasses Stage B when turboMode is active AND task is not Tier 3
7
+ * 3. Evidence records include turbo flag when recorded under turboMode
8
+ * 4. Architect prompt includes TURBO MODE ACTIVE banner when active
9
+ * 5. Status output shows TURBO MODE indicator when active
10
+ */
11
+ export {};
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Tests for Task 3.11: handleTurboCommand function
3
+ * Tests the /swarm turbo command toggle functionality
4
+ */
5
+ export {};
@@ -6,8 +6,8 @@ export declare const EvidenceTypeSchema: z.ZodEnum<{
6
6
  diff: "diff";
7
7
  quality_budget: "quality_budget";
8
8
  placeholder: "placeholder";
9
- review: "review";
10
9
  test: "test";
10
+ review: "review";
11
11
  approval: "approval";
12
12
  note: "note";
13
13
  retrospective: "retrospective";
@@ -31,8 +31,8 @@ export declare const BaseEvidenceSchema: z.ZodObject<{
31
31
  diff: "diff";
32
32
  quality_budget: "quality_budget";
33
33
  placeholder: "placeholder";
34
- review: "review";
35
34
  test: "test";
35
+ review: "review";
36
36
  approval: "approval";
37
37
  note: "note";
38
38
  retrospective: "retrospective";
@@ -69,8 +69,8 @@ export declare const ReviewEvidenceSchema: z.ZodObject<{
69
69
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
70
70
  type: z.ZodLiteral<"review">;
71
71
  risk: z.ZodEnum<{
72
- low: "low";
73
72
  medium: "medium";
73
+ low: "low";
74
74
  high: "high";
75
75
  critical: "critical";
76
76
  }>;
@@ -295,8 +295,8 @@ export declare const SastEvidenceSchema: z.ZodObject<{
295
295
  findings: z.ZodDefault<z.ZodArray<z.ZodObject<{
296
296
  rule_id: z.ZodString;
297
297
  severity: z.ZodEnum<{
298
- low: "low";
299
298
  medium: "medium";
299
+ low: "low";
300
300
  high: "high";
301
301
  critical: "critical";
302
302
  }>;
@@ -447,8 +447,8 @@ export declare const EvidenceSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
447
447
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
448
448
  type: z.ZodLiteral<"review">;
449
449
  risk: z.ZodEnum<{
450
- low: "low";
451
450
  medium: "medium";
451
+ low: "low";
452
452
  high: "high";
453
453
  critical: "critical";
454
454
  }>;
@@ -657,8 +657,8 @@ export declare const EvidenceSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
657
657
  findings: z.ZodDefault<z.ZodArray<z.ZodObject<{
658
658
  rule_id: z.ZodString;
659
659
  severity: z.ZodEnum<{
660
- low: "low";
661
660
  medium: "medium";
661
+ low: "low";
662
662
  high: "high";
663
663
  critical: "critical";
664
664
  }>;
@@ -806,8 +806,8 @@ export declare const EvidenceBundleSchema: z.ZodObject<{
806
806
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
807
807
  type: z.ZodLiteral<"review">;
808
808
  risk: z.ZodEnum<{
809
- low: "low";
810
809
  medium: "medium";
810
+ low: "low";
811
811
  high: "high";
812
812
  critical: "critical";
813
813
  }>;
@@ -1016,8 +1016,8 @@ export declare const EvidenceBundleSchema: z.ZodObject<{
1016
1016
  findings: z.ZodDefault<z.ZodArray<z.ZodObject<{
1017
1017
  rule_id: z.ZodString;
1018
1018
  severity: z.ZodEnum<{
1019
- low: "low";
1020
1019
  medium: "medium";
1020
+ low: "low";
1021
1021
  high: "high";
1022
1022
  critical: "critical";
1023
1023
  }>;
@@ -34,9 +34,10 @@ export declare function isBuildEvidence(evidence: Evidence): evidence is BuildEv
34
34
  export declare function isQualityBudgetEvidence(evidence: Evidence): evidence is QualityBudgetEvidence;
35
35
  /**
36
36
  * Validate and sanitize task ID.
37
- * Accepts two formats:
37
+ * Accepts three formats:
38
38
  * 1. Canonical N.M or N.M.P numeric format (matches TASK_ID_REGEX)
39
39
  * 2. Retrospective format: retro-<number> (matches RETRO_TASK_ID_REGEX)
40
+ * 3. Internal automated-tool format: specific tool IDs (sast_scan, quality_budget, syntax_check, placeholder_scan, sbom_generate, build)
40
41
  * Rejects: .., ../, null bytes, control characters, empty string, other non-numeric IDs
41
42
  * @throws Error with descriptive message on failure
42
43
  */
@@ -19,6 +19,7 @@ export interface TaskEvidence {
19
19
  taskId: string;
20
20
  required_gates: string[];
21
21
  gates: Record<string, GateEvidence>;
22
+ turbo?: boolean;
22
23
  }
23
24
  export declare const DEFAULT_REQUIRED_GATES: string[];
24
25
  /**
@@ -50,13 +51,13 @@ export declare function expandRequiredGates(existingGates: string[], newAgentTyp
50
51
  * If file exists: merges gate entry, expands required_gates via expandRequiredGates.
51
52
  * Atomic write: temp file + rename.
52
53
  */
53
- export declare function recordGateEvidence(directory: string, taskId: string, gate: string, sessionId: string): Promise<void>;
54
+ export declare function recordGateEvidence(directory: string, taskId: string, gate: string, sessionId: string, turbo?: boolean): Promise<void>;
54
55
  /**
55
56
  * Sets or expands required_gates WITHOUT recording a gate pass.
56
57
  * Used when non-gate agents are dispatched (coder, explorer, sme, etc.).
57
58
  * Creates evidence file if it doesn't exist yet.
58
59
  */
59
- export declare function recordAgentDispatch(directory: string, taskId: string, agentType: string): Promise<void>;
60
+ export declare function recordAgentDispatch(directory: string, taskId: string, agentType: string, turbo?: boolean): Promise<void>;
60
61
  /**
61
62
  * Returns the TaskEvidence for a task, or null if file missing or parse error.
62
63
  * Never throws.
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Adversarial security tests for getEvidenceTaskId plan.json fallback.
3
+ *
4
+ * Tests security-hardened fallback mechanism that reads .swarm/plan.json only after
5
+ * exhausting live task state. Focuses on attack vectors:
6
+ * - Path traversal via plan.json path
7
+ * - Malformed durable state (JSON bombs, circular refs)
8
+ * - Invalid directory inputs
9
+ * - Oversized/hostile inputs
10
+ * - Boundary violations
11
+ * - Symlink attacks
12
+ */
13
+ export {};
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Tests for getEvidenceTaskId plan.json fallback behavior.
3
+ * Verifies durable task ID recovery from .swarm/plan.json when in-memory state is empty.
4
+ */
5
+ export {};
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Tests for Task 3.16: Propagate turboMode through evidence recording
3
+ *
4
+ * This verifies that when a session has turboMode enabled, the turbo flag is
5
+ * recorded in the evidence JSON files for all agent delegations (reviewer,
6
+ * test_engineer, docs, designer, critic, explorer, sme, coder).
7
+ */
8
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};