@cleocode/cleo 2026.4.2 → 2026.4.3

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
@@ -25334,7 +25334,7 @@ async function endSession(options = {}, cwd, accessor) {
25334
25334
  session.endedAt = (/* @__PURE__ */ new Date()).toISOString();
25335
25335
  const duration3 = Math.floor((Date.now() - new Date(session.startedAt).getTime()) / 1e3);
25336
25336
  const { hooks: hooks2 } = await Promise.resolve().then(() => (init_registry(), registry_exports));
25337
- hooks2.dispatch("SessionEnd", cwd ?? process.cwd(), {
25337
+ await hooks2.dispatch("SessionEnd", cwd ?? process.cwd(), {
25338
25338
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
25339
25339
  sessionId: session.id,
25340
25340
  duration: duration3,
@@ -25343,7 +25343,7 @@ async function endSession(options = {}, cwd, accessor) {
25343
25343
  }).catch(() => {
25344
25344
  });
25345
25345
  const { bridgeSessionToMemory: bridgeSessionToMemory2 } = await Promise.resolve().then(() => (init_session_memory_bridge(), session_memory_bridge_exports));
25346
- bridgeSessionToMemory2(cwd ?? process.cwd(), {
25346
+ await bridgeSessionToMemory2(cwd ?? process.cwd(), {
25347
25347
  sessionId: session.id,
25348
25348
  scope: options.sessionId ? session.scope.type : session.scope.epicId ? `epic:${session.scope.epicId}` : session.scope.type,
25349
25349
  tasksCompleted: session.tasksCompleted || [],
@@ -25356,6 +25356,11 @@ async function endSession(options = {}, cwd, accessor) {
25356
25356
  }
25357
25357
  const acc = accessor ?? await getAccessor(cwd);
25358
25358
  await acc.upsertSingleSession(session);
25359
+ try {
25360
+ const { refreshMemoryBridge: refreshMemoryBridge2 } = await Promise.resolve().then(() => (init_memory_bridge(), memory_bridge_exports));
25361
+ await refreshMemoryBridge2(cwd ?? process.cwd());
25362
+ } catch {
25363
+ }
25359
25364
  return session;
25360
25365
  }
25361
25366
  async function sessionStatus(cwd, accessor) {
@@ -51528,6 +51533,208 @@ var init_complete = __esm({
51528
51533
  }
51529
51534
  });
51530
51535
 
51536
+ // packages/core/src/validation/validation-rules.ts
51537
+ var validation_rules_exports = {};
51538
+ __export(validation_rules_exports, {
51539
+ hasErrors: () => hasErrors,
51540
+ validateHierarchy: () => validateHierarchy,
51541
+ validateIdUniqueness: () => validateIdUniqueness,
51542
+ validateNewTask: () => validateNewTask,
51543
+ validateNoDuplicateDescription: () => validateNoDuplicateDescription,
51544
+ validateStatusTransition: () => validateStatusTransition,
51545
+ validateTimestamps: () => validateTimestamps,
51546
+ validateTitleDescription: () => validateTitleDescription
51547
+ });
51548
+ function validateTitleDescription(title, description) {
51549
+ const violations = [];
51550
+ if (!title || title.trim().length === 0) {
51551
+ violations.push({
51552
+ rule: "title-required",
51553
+ field: "title",
51554
+ message: "Title is required and cannot be empty",
51555
+ severity: "error"
51556
+ });
51557
+ }
51558
+ if (!description || description.trim().length === 0) {
51559
+ violations.push({
51560
+ rule: "description-required",
51561
+ field: "description",
51562
+ message: "Description is required and cannot be empty",
51563
+ severity: "error"
51564
+ });
51565
+ }
51566
+ if (title && description && title.trim().toLowerCase() === description.trim().toLowerCase()) {
51567
+ violations.push({
51568
+ rule: "title-description-different",
51569
+ field: "description",
51570
+ message: "Title and description must be different",
51571
+ severity: "error"
51572
+ });
51573
+ }
51574
+ return violations;
51575
+ }
51576
+ function validateTimestamps(task) {
51577
+ const violations = [];
51578
+ const now2 = /* @__PURE__ */ new Date();
51579
+ const threshold = new Date(now2.getTime() + 5 * 60 * 1e3);
51580
+ const timestampFields = [
51581
+ ["createdAt", task.createdAt],
51582
+ ["updatedAt", task.updatedAt],
51583
+ ["completedAt", task.completedAt],
51584
+ ["cancelledAt", task.cancelledAt]
51585
+ ];
51586
+ for (const [field, value] of timestampFields) {
51587
+ if (value) {
51588
+ const date6 = new Date(value);
51589
+ if (Number.isNaN(date6.getTime())) {
51590
+ violations.push({
51591
+ rule: "valid-timestamp",
51592
+ field,
51593
+ message: `Invalid timestamp format: ${value}`,
51594
+ severity: "error"
51595
+ });
51596
+ } else if (date6 > threshold) {
51597
+ violations.push({
51598
+ rule: "no-future-timestamps",
51599
+ field,
51600
+ message: `Timestamp ${value} is in the future`,
51601
+ severity: "error"
51602
+ });
51603
+ }
51604
+ }
51605
+ }
51606
+ return violations;
51607
+ }
51608
+ function validateIdUniqueness(taskId, existingIds) {
51609
+ if (existingIds.has(taskId)) {
51610
+ return [
51611
+ {
51612
+ rule: "unique-id",
51613
+ field: "id",
51614
+ message: `Task ID '${taskId}' already exists`,
51615
+ severity: "error"
51616
+ }
51617
+ ];
51618
+ }
51619
+ return [];
51620
+ }
51621
+ function validateNoDuplicateDescription(description, existingDescriptions, _excludeTaskId) {
51622
+ const normalizedNew = description.trim().toLowerCase();
51623
+ for (const existing of existingDescriptions) {
51624
+ if (existing.trim().toLowerCase() === normalizedNew) {
51625
+ return [
51626
+ {
51627
+ rule: "no-duplicate-description",
51628
+ field: "description",
51629
+ message: "A task with this exact description already exists",
51630
+ severity: "warning"
51631
+ }
51632
+ ];
51633
+ }
51634
+ }
51635
+ return [];
51636
+ }
51637
+ function validateHierarchy(parentId, tasks2, _taskType, limits) {
51638
+ const violations = [];
51639
+ if (!parentId) {
51640
+ return violations;
51641
+ }
51642
+ const maxDepth = limits?.maxDepth ?? 3;
51643
+ const maxSiblings = limits?.maxSiblings ?? 0;
51644
+ const parent = tasks2.find((t) => t.id === parentId);
51645
+ if (!parent) {
51646
+ violations.push({
51647
+ rule: "parent-exists",
51648
+ field: "parentId",
51649
+ message: `Parent task '${parentId}' not found`,
51650
+ severity: "error"
51651
+ });
51652
+ return violations;
51653
+ }
51654
+ let depth = 1;
51655
+ let current = parent;
51656
+ while (current.parentId) {
51657
+ depth++;
51658
+ const nextParent = tasks2.find((t) => t.id === current.parentId);
51659
+ if (!nextParent) break;
51660
+ current = nextParent;
51661
+ }
51662
+ if (depth > maxDepth - 1) {
51663
+ violations.push({
51664
+ rule: "max-depth",
51665
+ field: "parentId",
51666
+ message: `Maximum hierarchy depth of ${maxDepth} exceeded (epic -> task -> subtask)`,
51667
+ severity: "error"
51668
+ });
51669
+ }
51670
+ const siblingCount = tasks2.filter((t) => t.parentId === parentId).length;
51671
+ if (maxSiblings > 0 && siblingCount >= maxSiblings) {
51672
+ violations.push({
51673
+ rule: "max-siblings",
51674
+ field: "parentId",
51675
+ message: `Parent '${parentId}' already has ${siblingCount} children (max ${maxSiblings})`,
51676
+ severity: "error"
51677
+ });
51678
+ }
51679
+ return violations;
51680
+ }
51681
+ function validateStatusTransition(currentStatus, newStatus) {
51682
+ const validTransitions = {
51683
+ pending: ["active", "blocked", "done", "cancelled"],
51684
+ active: ["pending", "blocked", "done", "cancelled"],
51685
+ blocked: ["pending", "active", "done", "cancelled"],
51686
+ done: ["pending", "active"],
51687
+ // restore (alias: reopen)
51688
+ cancelled: ["pending"]
51689
+ // restore (alias: uncancel)
51690
+ };
51691
+ const allowed = validTransitions[currentStatus];
51692
+ if (!allowed) {
51693
+ return [
51694
+ {
51695
+ rule: "valid-status-transition",
51696
+ field: "status",
51697
+ message: `Unknown current status: '${currentStatus}'`,
51698
+ severity: "error"
51699
+ }
51700
+ ];
51701
+ }
51702
+ if (!allowed.includes(newStatus)) {
51703
+ return [
51704
+ {
51705
+ rule: "valid-status-transition",
51706
+ field: "status",
51707
+ message: `Cannot transition from '${currentStatus}' to '${newStatus}'. Valid: ${allowed.join(", ")}`,
51708
+ severity: "error"
51709
+ }
51710
+ ];
51711
+ }
51712
+ return [];
51713
+ }
51714
+ function validateNewTask(task, existingIds, existingDescriptions, existingTasks, limits) {
51715
+ const violations = [];
51716
+ violations.push(...validateTitleDescription(task.title, task.description));
51717
+ violations.push(...validateTimestamps(task));
51718
+ if (task.id) {
51719
+ violations.push(...validateIdUniqueness(task.id, existingIds));
51720
+ }
51721
+ if (task.description) {
51722
+ violations.push(...validateNoDuplicateDescription(task.description, existingDescriptions));
51723
+ }
51724
+ if (task.parentId) {
51725
+ violations.push(...validateHierarchy(task.parentId, existingTasks, task.type, limits));
51726
+ }
51727
+ return violations;
51728
+ }
51729
+ function hasErrors(violations) {
51730
+ return violations.some((v) => v.severity === "error");
51731
+ }
51732
+ var init_validation_rules = __esm({
51733
+ "packages/core/src/validation/validation-rules.ts"() {
51734
+ "use strict";
51735
+ }
51736
+ });
51737
+
51531
51738
  // packages/core/src/tasks/update.ts
51532
51739
  var update_exports = {};
51533
51740
  __export(update_exports, {
@@ -51577,6 +51784,11 @@ async function updateTask(options, cwd, accessor) {
51577
51784
  }
51578
51785
  if (options.status !== void 0) {
51579
51786
  validateStatus(options.status);
51787
+ const { validateStatusTransition: validateStatusTransition3 } = await Promise.resolve().then(() => (init_validation_rules(), validation_rules_exports));
51788
+ const transitionViolations = validateStatusTransition3(task.status, options.status);
51789
+ if (transitionViolations.length > 0) {
51790
+ throw new CleoError(6 /* VALIDATION_ERROR */, transitionViolations[0].message);
51791
+ }
51580
51792
  const oldStatus = task.status;
51581
51793
  task.status = options.status;
51582
51794
  changes.push("status");
@@ -68579,7 +68791,7 @@ function validateCancelReason(reason) {
68579
68791
  }
68580
68792
  return { valid: errors.length === 0, errors, warnings: [] };
68581
68793
  }
68582
- function validateStatusTransition(oldStatus, newStatus) {
68794
+ function validateStatusTransition2(oldStatus, newStatus) {
68583
68795
  if (oldStatus === newStatus) {
68584
68796
  return { valid: true, errors: [], warnings: [] };
68585
68797
  }
@@ -70038,7 +70250,7 @@ __export(validation_exports, {
70038
70250
  validatePhaseTimestamps: () => validatePhaseTimestamps,
70039
70251
  validateSessionNote: () => validateSessionNote,
70040
70252
  validateSingleActivePhase: () => validateSingleActivePhase,
70041
- validateStatusTransition: () => validateStatusTransition,
70253
+ validateStatusTransition: () => validateStatusTransition2,
70042
70254
  validateTask: () => validateTask,
70043
70255
  validateTitle: () => validateTitle2
70044
70256
  });
@@ -72085,6 +72297,7 @@ __export(src_exports, {
72085
72297
  });
72086
72298
  var init_src2 = __esm({
72087
72299
  "packages/core/src/index.ts"() {
72300
+ "use strict";
72088
72301
  init_src();
72089
72302
  init_adapters();
72090
72303
  init_admin();
@@ -81574,149 +81787,6 @@ var init_schema_validator = __esm({
81574
81787
  }
81575
81788
  });
81576
81789
 
81577
- // packages/core/src/validation/validation-rules.ts
81578
- function validateTitleDescription(title, description) {
81579
- const violations = [];
81580
- if (!title || title.trim().length === 0) {
81581
- violations.push({
81582
- rule: "title-required",
81583
- field: "title",
81584
- message: "Title is required and cannot be empty",
81585
- severity: "error"
81586
- });
81587
- }
81588
- if (!description || description.trim().length === 0) {
81589
- violations.push({
81590
- rule: "description-required",
81591
- field: "description",
81592
- message: "Description is required and cannot be empty",
81593
- severity: "error"
81594
- });
81595
- }
81596
- if (title && description && title.trim().toLowerCase() === description.trim().toLowerCase()) {
81597
- violations.push({
81598
- rule: "title-description-different",
81599
- field: "description",
81600
- message: "Title and description must be different",
81601
- severity: "error"
81602
- });
81603
- }
81604
- return violations;
81605
- }
81606
- function validateTimestamps(task) {
81607
- const violations = [];
81608
- const now2 = /* @__PURE__ */ new Date();
81609
- const threshold = new Date(now2.getTime() + 5 * 60 * 1e3);
81610
- const timestampFields = [
81611
- ["createdAt", task.createdAt],
81612
- ["updatedAt", task.updatedAt],
81613
- ["completedAt", task.completedAt],
81614
- ["cancelledAt", task.cancelledAt]
81615
- ];
81616
- for (const [field, value] of timestampFields) {
81617
- if (value) {
81618
- const date6 = new Date(value);
81619
- if (Number.isNaN(date6.getTime())) {
81620
- violations.push({
81621
- rule: "valid-timestamp",
81622
- field,
81623
- message: `Invalid timestamp format: ${value}`,
81624
- severity: "error"
81625
- });
81626
- } else if (date6 > threshold) {
81627
- violations.push({
81628
- rule: "no-future-timestamps",
81629
- field,
81630
- message: `Timestamp ${value} is in the future`,
81631
- severity: "error"
81632
- });
81633
- }
81634
- }
81635
- }
81636
- return violations;
81637
- }
81638
- function validateIdUniqueness(taskId, existingIds) {
81639
- if (existingIds.has(taskId)) {
81640
- return [
81641
- {
81642
- rule: "unique-id",
81643
- field: "id",
81644
- message: `Task ID '${taskId}' already exists`,
81645
- severity: "error"
81646
- }
81647
- ];
81648
- }
81649
- return [];
81650
- }
81651
- function validateNoDuplicateDescription(description, existingDescriptions, _excludeTaskId) {
81652
- const normalizedNew = description.trim().toLowerCase();
81653
- for (const existing of existingDescriptions) {
81654
- if (existing.trim().toLowerCase() === normalizedNew) {
81655
- return [
81656
- {
81657
- rule: "no-duplicate-description",
81658
- field: "description",
81659
- message: "A task with this exact description already exists",
81660
- severity: "warning"
81661
- }
81662
- ];
81663
- }
81664
- }
81665
- return [];
81666
- }
81667
- function validateHierarchy(parentId, tasks2, _taskType, limits) {
81668
- const violations = [];
81669
- if (!parentId) {
81670
- return violations;
81671
- }
81672
- const maxDepth = limits?.maxDepth ?? 3;
81673
- const maxSiblings = limits?.maxSiblings ?? 0;
81674
- const parent = tasks2.find((t) => t.id === parentId);
81675
- if (!parent) {
81676
- violations.push({
81677
- rule: "parent-exists",
81678
- field: "parentId",
81679
- message: `Parent task '${parentId}' not found`,
81680
- severity: "error"
81681
- });
81682
- return violations;
81683
- }
81684
- let depth = 1;
81685
- let current = parent;
81686
- while (current.parentId) {
81687
- depth++;
81688
- const nextParent = tasks2.find((t) => t.id === current.parentId);
81689
- if (!nextParent) break;
81690
- current = nextParent;
81691
- }
81692
- if (depth > maxDepth - 1) {
81693
- violations.push({
81694
- rule: "max-depth",
81695
- field: "parentId",
81696
- message: `Maximum hierarchy depth of ${maxDepth} exceeded (epic -> task -> subtask)`,
81697
- severity: "error"
81698
- });
81699
- }
81700
- const siblingCount = tasks2.filter((t) => t.parentId === parentId).length;
81701
- if (maxSiblings > 0 && siblingCount >= maxSiblings) {
81702
- violations.push({
81703
- rule: "max-siblings",
81704
- field: "parentId",
81705
- message: `Parent '${parentId}' already has ${siblingCount} children (max ${maxSiblings})`,
81706
- severity: "error"
81707
- });
81708
- }
81709
- return violations;
81710
- }
81711
- function hasErrors(violations) {
81712
- return violations.some((v) => v.severity === "error");
81713
- }
81714
- var init_validation_rules = __esm({
81715
- "packages/core/src/validation/validation-rules.ts"() {
81716
- "use strict";
81717
- }
81718
- });
81719
-
81720
81790
  // packages/core/src/validation/validate-ops.ts
81721
81791
  import { execFileSync as execFileSync12 } from "node:child_process";
81722
81792
  import { appendFileSync as appendFileSync10, existsSync as existsSync120, mkdirSync as mkdirSync25, readFileSync as readFileSync91 } from "node:fs";
@@ -83588,6 +83658,7 @@ __export(internal_exports, {
83588
83658
  getOtelSummary: () => getOtelSummary,
83589
83659
  getPackageRoot: () => getPackageRoot,
83590
83660
  getParallelStatus: () => getParallelStatus,
83661
+ getPipelineStageOrder: () => getPipelineStageOrder,
83591
83662
  getProjectInfo: () => getProjectInfo,
83592
83663
  getProjectInfoSync: () => getProjectInfoSync,
83593
83664
  getProjectRoot: () => getProjectRoot,
@@ -83667,6 +83738,7 @@ __export(internal_exports, {
83667
83738
  isLafsSuccess: () => isLafsSuccess,
83668
83739
  isNoChangeCode: () => isNoChangeCode,
83669
83740
  isOverloaded: () => isOverloaded,
83741
+ isPipelineTransitionForward: () => isPipelineTransitionForward,
83670
83742
  isProjectInitialized: () => isProjectInitialized,
83671
83743
  isProviderHookEvent: () => isProviderHookEvent,
83672
83744
  isRecoverableCode: () => isRecoverableCode,
@@ -84064,6 +84136,7 @@ var init_internal = __esm({
84064
84136
  init_add();
84065
84137
  init_graph_ops();
84066
84138
  init_list3();
84139
+ init_pipeline_stage();
84067
84140
  init_relates();
84068
84141
  init_task_ops();
84069
84142
  init_parser2();
@@ -88670,6 +88743,19 @@ async function lifecycleProgress(taskId, stage, status, notes, projectRoot) {
88670
88743
  }
88671
88744
  try {
88672
88745
  if (status === "in_progress" || status === "completed") {
88746
+ const { getLifecycleStatus: getLifecycleStatus2 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
88747
+ const current = await getLifecycleStatus2(taskId, projectRoot);
88748
+ if (current.currentStage) {
88749
+ const { isPipelineTransitionForward: isPipelineTransitionForward2, getPipelineStageOrder: getPipelineStageOrder2 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
88750
+ if (!isPipelineTransitionForward2(current.currentStage, stage)) {
88751
+ const currentOrder = getPipelineStageOrder2(current.currentStage);
88752
+ const newOrder = getPipelineStageOrder2(stage);
88753
+ return engineError(
88754
+ "E_LIFECYCLE_BACKWARD",
88755
+ `Cannot move backward from "${current.currentStage}" (stage ${currentOrder}) to "${stage}" (stage ${newOrder}). Pipeline stages are forward-only.`
88756
+ );
88757
+ }
88758
+ }
88673
88759
  const gateResult = await checkGate(taskId, stage, projectRoot);
88674
88760
  if (!gateResult.allowed) {
88675
88761
  return engineError("E_LIFECYCLE_GATE_FAILED", gateResult.message);
@@ -92088,14 +92174,28 @@ function initVerification2() {
92088
92174
  failureLog: []
92089
92175
  };
92090
92176
  }
92091
- function computePassed2(verification) {
92092
- for (const gate of DEFAULT_REQUIRED_GATES2) {
92177
+ function computePassed2(verification, requiredGates = DEFAULT_REQUIRED_GATES2) {
92178
+ for (const gate of requiredGates) {
92093
92179
  if (verification.gates[gate] !== true) return false;
92094
92180
  }
92095
92181
  return true;
92096
92182
  }
92097
- function getMissingGates2(verification) {
92098
- return DEFAULT_REQUIRED_GATES2.filter((g) => verification.gates[g] !== true);
92183
+ function getMissingGates2(verification, requiredGates = DEFAULT_REQUIRED_GATES2) {
92184
+ return requiredGates.filter((g) => verification.gates[g] !== true);
92185
+ }
92186
+ async function loadRequiredGates(projectRoot) {
92187
+ try {
92188
+ const { loadConfig: loadConfig4 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
92189
+ const config2 = await loadConfig4(projectRoot);
92190
+ const cfgGates = config2.verification?.requiredGates;
92191
+ if (Array.isArray(cfgGates) && cfgGates.length > 0) {
92192
+ return cfgGates.filter(
92193
+ (g) => DEFAULT_REQUIRED_GATES2.includes(g)
92194
+ );
92195
+ }
92196
+ } catch {
92197
+ }
92198
+ return [...DEFAULT_REQUIRED_GATES2];
92099
92199
  }
92100
92200
  async function validateGateVerify(params, projectRoot) {
92101
92201
  try {
@@ -92110,9 +92210,10 @@ async function validateGateVerify(params, projectRoot) {
92110
92210
  if (!task) {
92111
92211
  return engineError("E_NOT_FOUND", `Task ${taskId} not found`);
92112
92212
  }
92213
+ const configGates = await loadRequiredGates(root);
92113
92214
  if (!gate && !all && !reset) {
92114
92215
  const verification2 = task.verification ?? initVerification2();
92115
- const missing2 = getMissingGates2(verification2);
92216
+ const missing2 = getMissingGates2(verification2, configGates);
92116
92217
  return {
92117
92218
  success: true,
92118
92219
  data: {
@@ -92124,7 +92225,7 @@ async function validateGateVerify(params, projectRoot) {
92124
92225
  verificationStatus: verification2.passed ? "passed" : "pending",
92125
92226
  passed: verification2.passed,
92126
92227
  round: verification2.round,
92127
- requiredGates: DEFAULT_REQUIRED_GATES2,
92228
+ requiredGates: configGates,
92128
92229
  missingGates: missing2,
92129
92230
  action: "view"
92130
92231
  }
@@ -92137,7 +92238,7 @@ async function validateGateVerify(params, projectRoot) {
92137
92238
  verification = initVerification2();
92138
92239
  action = "reset";
92139
92240
  } else if (all) {
92140
- for (const g of DEFAULT_REQUIRED_GATES2) {
92241
+ for (const g of configGates) {
92141
92242
  verification.gates[g] = true;
92142
92243
  }
92143
92244
  if (agent) {
@@ -92168,11 +92269,11 @@ async function validateGateVerify(params, projectRoot) {
92168
92269
  }
92169
92270
  action = "set_gate";
92170
92271
  }
92171
- verification.passed = computePassed2(verification);
92272
+ verification.passed = computePassed2(verification, configGates);
92172
92273
  task.verification = verification;
92173
92274
  task.updatedAt = now2;
92174
92275
  await accessor.upsertSingleTask(task);
92175
- const missing = getMissingGates2(verification);
92276
+ const missing = getMissingGates2(verification, configGates);
92176
92277
  const result = {
92177
92278
  taskId,
92178
92279
  title: task.title,
@@ -92182,14 +92283,14 @@ async function validateGateVerify(params, projectRoot) {
92182
92283
  verificationStatus: verification.passed ? "passed" : "pending",
92183
92284
  passed: verification.passed,
92184
92285
  round: verification.round,
92185
- requiredGates: DEFAULT_REQUIRED_GATES2,
92286
+ requiredGates: configGates,
92186
92287
  missingGates: missing,
92187
92288
  action
92188
92289
  };
92189
92290
  if (action === "set_gate") {
92190
92291
  result.gateSet = gate;
92191
92292
  } else if (action === "set_all") {
92192
- result.gatesSet = DEFAULT_REQUIRED_GATES2;
92293
+ result.gatesSet = configGates;
92193
92294
  }
92194
92295
  return { success: true, data: result };
92195
92296
  } catch (err) {