@defend-tech/opencode-optima 0.1.67 → 0.1.69

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
@@ -108,17 +108,17 @@ var require_visit = __commonJS({
108
108
  visit.BREAK = BREAK;
109
109
  visit.SKIP = SKIP;
110
110
  visit.REMOVE = REMOVE;
111
- function visit_(key, node, visitor, path6) {
112
- const ctrl = callVisitor(key, node, visitor, path6);
111
+ function visit_(key, node, visitor, path7) {
112
+ const ctrl = callVisitor(key, node, visitor, path7);
113
113
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
114
- replaceNode(key, path6, ctrl);
115
- return visit_(key, ctrl, visitor, path6);
114
+ replaceNode(key, path7, ctrl);
115
+ return visit_(key, ctrl, visitor, path7);
116
116
  }
117
117
  if (typeof ctrl !== "symbol") {
118
118
  if (identity.isCollection(node)) {
119
- path6 = Object.freeze(path6.concat(node));
119
+ path7 = Object.freeze(path7.concat(node));
120
120
  for (let i = 0; i < node.items.length; ++i) {
121
- const ci = visit_(i, node.items[i], visitor, path6);
121
+ const ci = visit_(i, node.items[i], visitor, path7);
122
122
  if (typeof ci === "number")
123
123
  i = ci - 1;
124
124
  else if (ci === BREAK)
@@ -129,13 +129,13 @@ var require_visit = __commonJS({
129
129
  }
130
130
  }
131
131
  } else if (identity.isPair(node)) {
132
- path6 = Object.freeze(path6.concat(node));
133
- const ck = visit_("key", node.key, visitor, path6);
132
+ path7 = Object.freeze(path7.concat(node));
133
+ const ck = visit_("key", node.key, visitor, path7);
134
134
  if (ck === BREAK)
135
135
  return BREAK;
136
136
  else if (ck === REMOVE)
137
137
  node.key = null;
138
- const cv = visit_("value", node.value, visitor, path6);
138
+ const cv = visit_("value", node.value, visitor, path7);
139
139
  if (cv === BREAK)
140
140
  return BREAK;
141
141
  else if (cv === REMOVE)
@@ -156,17 +156,17 @@ var require_visit = __commonJS({
156
156
  visitAsync.BREAK = BREAK;
157
157
  visitAsync.SKIP = SKIP;
158
158
  visitAsync.REMOVE = REMOVE;
159
- async function visitAsync_(key, node, visitor, path6) {
160
- const ctrl = await callVisitor(key, node, visitor, path6);
159
+ async function visitAsync_(key, node, visitor, path7) {
160
+ const ctrl = await callVisitor(key, node, visitor, path7);
161
161
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
162
- replaceNode(key, path6, ctrl);
163
- return visitAsync_(key, ctrl, visitor, path6);
162
+ replaceNode(key, path7, ctrl);
163
+ return visitAsync_(key, ctrl, visitor, path7);
164
164
  }
165
165
  if (typeof ctrl !== "symbol") {
166
166
  if (identity.isCollection(node)) {
167
- path6 = Object.freeze(path6.concat(node));
167
+ path7 = Object.freeze(path7.concat(node));
168
168
  for (let i = 0; i < node.items.length; ++i) {
169
- const ci = await visitAsync_(i, node.items[i], visitor, path6);
169
+ const ci = await visitAsync_(i, node.items[i], visitor, path7);
170
170
  if (typeof ci === "number")
171
171
  i = ci - 1;
172
172
  else if (ci === BREAK)
@@ -177,13 +177,13 @@ var require_visit = __commonJS({
177
177
  }
178
178
  }
179
179
  } else if (identity.isPair(node)) {
180
- path6 = Object.freeze(path6.concat(node));
181
- const ck = await visitAsync_("key", node.key, visitor, path6);
180
+ path7 = Object.freeze(path7.concat(node));
181
+ const ck = await visitAsync_("key", node.key, visitor, path7);
182
182
  if (ck === BREAK)
183
183
  return BREAK;
184
184
  else if (ck === REMOVE)
185
185
  node.key = null;
186
- const cv = await visitAsync_("value", node.value, visitor, path6);
186
+ const cv = await visitAsync_("value", node.value, visitor, path7);
187
187
  if (cv === BREAK)
188
188
  return BREAK;
189
189
  else if (cv === REMOVE)
@@ -210,23 +210,23 @@ var require_visit = __commonJS({
210
210
  }
211
211
  return visitor;
212
212
  }
213
- function callVisitor(key, node, visitor, path6) {
213
+ function callVisitor(key, node, visitor, path7) {
214
214
  if (typeof visitor === "function")
215
- return visitor(key, node, path6);
215
+ return visitor(key, node, path7);
216
216
  if (identity.isMap(node))
217
- return visitor.Map?.(key, node, path6);
217
+ return visitor.Map?.(key, node, path7);
218
218
  if (identity.isSeq(node))
219
- return visitor.Seq?.(key, node, path6);
219
+ return visitor.Seq?.(key, node, path7);
220
220
  if (identity.isPair(node))
221
- return visitor.Pair?.(key, node, path6);
221
+ return visitor.Pair?.(key, node, path7);
222
222
  if (identity.isScalar(node))
223
- return visitor.Scalar?.(key, node, path6);
223
+ return visitor.Scalar?.(key, node, path7);
224
224
  if (identity.isAlias(node))
225
- return visitor.Alias?.(key, node, path6);
225
+ return visitor.Alias?.(key, node, path7);
226
226
  return void 0;
227
227
  }
228
- function replaceNode(key, path6, node) {
229
- const parent = path6[path6.length - 1];
228
+ function replaceNode(key, path7, node) {
229
+ const parent = path7[path7.length - 1];
230
230
  if (identity.isCollection(parent)) {
231
231
  parent.items[key] = node;
232
232
  } else if (identity.isPair(parent)) {
@@ -834,10 +834,10 @@ var require_Collection = __commonJS({
834
834
  var createNode = require_createNode();
835
835
  var identity = require_identity();
836
836
  var Node = require_Node();
837
- function collectionFromPath(schema, path6, value) {
837
+ function collectionFromPath(schema, path7, value) {
838
838
  let v = value;
839
- for (let i = path6.length - 1; i >= 0; --i) {
840
- const k = path6[i];
839
+ for (let i = path7.length - 1; i >= 0; --i) {
840
+ const k = path7[i];
841
841
  if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
842
842
  const a = [];
843
843
  a[k] = v;
@@ -856,7 +856,7 @@ var require_Collection = __commonJS({
856
856
  sourceObjects: /* @__PURE__ */ new Map()
857
857
  });
858
858
  }
859
- var isEmptyPath = (path6) => path6 == null || typeof path6 === "object" && !!path6[Symbol.iterator]().next().done;
859
+ var isEmptyPath = (path7) => path7 == null || typeof path7 === "object" && !!path7[Symbol.iterator]().next().done;
860
860
  var Collection = class extends Node.NodeBase {
861
861
  constructor(type, schema) {
862
862
  super(type);
@@ -886,11 +886,11 @@ var require_Collection = __commonJS({
886
886
  * be a Pair instance or a `{ key, value }` object, which may not have a key
887
887
  * that already exists in the map.
888
888
  */
889
- addIn(path6, value) {
890
- if (isEmptyPath(path6))
889
+ addIn(path7, value) {
890
+ if (isEmptyPath(path7))
891
891
  this.add(value);
892
892
  else {
893
- const [key, ...rest] = path6;
893
+ const [key, ...rest] = path7;
894
894
  const node = this.get(key, true);
895
895
  if (identity.isCollection(node))
896
896
  node.addIn(rest, value);
@@ -904,8 +904,8 @@ var require_Collection = __commonJS({
904
904
  * Removes a value from the collection.
905
905
  * @returns `true` if the item was found and removed.
906
906
  */
907
- deleteIn(path6) {
908
- const [key, ...rest] = path6;
907
+ deleteIn(path7) {
908
+ const [key, ...rest] = path7;
909
909
  if (rest.length === 0)
910
910
  return this.delete(key);
911
911
  const node = this.get(key, true);
@@ -919,8 +919,8 @@ var require_Collection = __commonJS({
919
919
  * scalar values from their surrounding node; to disable set `keepScalar` to
920
920
  * `true` (collections are always returned intact).
921
921
  */
922
- getIn(path6, keepScalar) {
923
- const [key, ...rest] = path6;
922
+ getIn(path7, keepScalar) {
923
+ const [key, ...rest] = path7;
924
924
  const node = this.get(key, true);
925
925
  if (rest.length === 0)
926
926
  return !keepScalar && identity.isScalar(node) ? node.value : node;
@@ -938,8 +938,8 @@ var require_Collection = __commonJS({
938
938
  /**
939
939
  * Checks if the collection includes a value with the key `key`.
940
940
  */
941
- hasIn(path6) {
942
- const [key, ...rest] = path6;
941
+ hasIn(path7) {
942
+ const [key, ...rest] = path7;
943
943
  if (rest.length === 0)
944
944
  return this.has(key);
945
945
  const node = this.get(key, true);
@@ -949,8 +949,8 @@ var require_Collection = __commonJS({
949
949
  * Sets a value in this collection. For `!!set`, `value` needs to be a
950
950
  * boolean to add/remove the item from the set.
951
951
  */
952
- setIn(path6, value) {
953
- const [key, ...rest] = path6;
952
+ setIn(path7, value) {
953
+ const [key, ...rest] = path7;
954
954
  if (rest.length === 0) {
955
955
  this.set(key, value);
956
956
  } else {
@@ -3454,9 +3454,9 @@ var require_Document = __commonJS({
3454
3454
  this.contents.add(value);
3455
3455
  }
3456
3456
  /** Adds a value to the document. */
3457
- addIn(path6, value) {
3457
+ addIn(path7, value) {
3458
3458
  if (assertCollection(this.contents))
3459
- this.contents.addIn(path6, value);
3459
+ this.contents.addIn(path7, value);
3460
3460
  }
3461
3461
  /**
3462
3462
  * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
@@ -3531,14 +3531,14 @@ var require_Document = __commonJS({
3531
3531
  * Removes a value from the document.
3532
3532
  * @returns `true` if the item was found and removed.
3533
3533
  */
3534
- deleteIn(path6) {
3535
- if (Collection.isEmptyPath(path6)) {
3534
+ deleteIn(path7) {
3535
+ if (Collection.isEmptyPath(path7)) {
3536
3536
  if (this.contents == null)
3537
3537
  return false;
3538
3538
  this.contents = null;
3539
3539
  return true;
3540
3540
  }
3541
- return assertCollection(this.contents) ? this.contents.deleteIn(path6) : false;
3541
+ return assertCollection(this.contents) ? this.contents.deleteIn(path7) : false;
3542
3542
  }
3543
3543
  /**
3544
3544
  * Returns item at `key`, or `undefined` if not found. By default unwraps
@@ -3553,10 +3553,10 @@ var require_Document = __commonJS({
3553
3553
  * scalar values from their surrounding node; to disable set `keepScalar` to
3554
3554
  * `true` (collections are always returned intact).
3555
3555
  */
3556
- getIn(path6, keepScalar) {
3557
- if (Collection.isEmptyPath(path6))
3556
+ getIn(path7, keepScalar) {
3557
+ if (Collection.isEmptyPath(path7))
3558
3558
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
3559
- return identity.isCollection(this.contents) ? this.contents.getIn(path6, keepScalar) : void 0;
3559
+ return identity.isCollection(this.contents) ? this.contents.getIn(path7, keepScalar) : void 0;
3560
3560
  }
3561
3561
  /**
3562
3562
  * Checks if the document includes a value with the key `key`.
@@ -3567,10 +3567,10 @@ var require_Document = __commonJS({
3567
3567
  /**
3568
3568
  * Checks if the document includes a value at `path`.
3569
3569
  */
3570
- hasIn(path6) {
3571
- if (Collection.isEmptyPath(path6))
3570
+ hasIn(path7) {
3571
+ if (Collection.isEmptyPath(path7))
3572
3572
  return this.contents !== void 0;
3573
- return identity.isCollection(this.contents) ? this.contents.hasIn(path6) : false;
3573
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path7) : false;
3574
3574
  }
3575
3575
  /**
3576
3576
  * Sets a value in this document. For `!!set`, `value` needs to be a
@@ -3587,13 +3587,13 @@ var require_Document = __commonJS({
3587
3587
  * Sets a value in this document. For `!!set`, `value` needs to be a
3588
3588
  * boolean to add/remove the item from the set.
3589
3589
  */
3590
- setIn(path6, value) {
3591
- if (Collection.isEmptyPath(path6)) {
3590
+ setIn(path7, value) {
3591
+ if (Collection.isEmptyPath(path7)) {
3592
3592
  this.contents = value;
3593
3593
  } else if (this.contents == null) {
3594
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path6), value);
3594
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path7), value);
3595
3595
  } else if (assertCollection(this.contents)) {
3596
- this.contents.setIn(path6, value);
3596
+ this.contents.setIn(path7, value);
3597
3597
  }
3598
3598
  }
3599
3599
  /**
@@ -5545,9 +5545,9 @@ var require_cst_visit = __commonJS({
5545
5545
  visit.BREAK = BREAK;
5546
5546
  visit.SKIP = SKIP;
5547
5547
  visit.REMOVE = REMOVE;
5548
- visit.itemAtPath = (cst, path6) => {
5548
+ visit.itemAtPath = (cst, path7) => {
5549
5549
  let item = cst;
5550
- for (const [field, index] of path6) {
5550
+ for (const [field, index] of path7) {
5551
5551
  const tok = item?.[field];
5552
5552
  if (tok && "items" in tok) {
5553
5553
  item = tok.items[index];
@@ -5556,23 +5556,23 @@ var require_cst_visit = __commonJS({
5556
5556
  }
5557
5557
  return item;
5558
5558
  };
5559
- visit.parentCollection = (cst, path6) => {
5560
- const parent = visit.itemAtPath(cst, path6.slice(0, -1));
5561
- const field = path6[path6.length - 1][0];
5559
+ visit.parentCollection = (cst, path7) => {
5560
+ const parent = visit.itemAtPath(cst, path7.slice(0, -1));
5561
+ const field = path7[path7.length - 1][0];
5562
5562
  const coll = parent?.[field];
5563
5563
  if (coll && "items" in coll)
5564
5564
  return coll;
5565
5565
  throw new Error("Parent collection not found");
5566
5566
  };
5567
- function _visit(path6, item, visitor) {
5568
- let ctrl = visitor(item, path6);
5567
+ function _visit(path7, item, visitor) {
5568
+ let ctrl = visitor(item, path7);
5569
5569
  if (typeof ctrl === "symbol")
5570
5570
  return ctrl;
5571
5571
  for (const field of ["key", "value"]) {
5572
5572
  const token = item[field];
5573
5573
  if (token && "items" in token) {
5574
5574
  for (let i = 0; i < token.items.length; ++i) {
5575
- const ci = _visit(Object.freeze(path6.concat([[field, i]])), token.items[i], visitor);
5575
+ const ci = _visit(Object.freeze(path7.concat([[field, i]])), token.items[i], visitor);
5576
5576
  if (typeof ci === "number")
5577
5577
  i = ci - 1;
5578
5578
  else if (ci === BREAK)
@@ -5583,10 +5583,10 @@ var require_cst_visit = __commonJS({
5583
5583
  }
5584
5584
  }
5585
5585
  if (typeof ctrl === "function" && field === "key")
5586
- ctrl = ctrl(item, path6);
5586
+ ctrl = ctrl(item, path7);
5587
5587
  }
5588
5588
  }
5589
- return typeof ctrl === "function" ? ctrl(item, path6) : ctrl;
5589
+ return typeof ctrl === "function" ? ctrl(item, path7) : ctrl;
5590
5590
  }
5591
5591
  exports.visit = visit;
5592
5592
  }
@@ -7550,17 +7550,17 @@ var require_ignore = __commonJS({
7550
7550
  var throwError = (message, Ctor) => {
7551
7551
  throw new Ctor(message);
7552
7552
  };
7553
- var checkPath = (path6, originalPath, doThrow) => {
7554
- if (!isString(path6)) {
7553
+ var checkPath = (path7, originalPath, doThrow) => {
7554
+ if (!isString(path7)) {
7555
7555
  return doThrow(
7556
7556
  `path must be a string, but got \`${originalPath}\``,
7557
7557
  TypeError
7558
7558
  );
7559
7559
  }
7560
- if (!path6) {
7560
+ if (!path7) {
7561
7561
  return doThrow(`path must not be empty`, TypeError);
7562
7562
  }
7563
- if (checkPath.isNotRelative(path6)) {
7563
+ if (checkPath.isNotRelative(path7)) {
7564
7564
  const r = "`path.relative()`d";
7565
7565
  return doThrow(
7566
7566
  `path should be a ${r} string, but got "${originalPath}"`,
@@ -7569,7 +7569,7 @@ var require_ignore = __commonJS({
7569
7569
  }
7570
7570
  return true;
7571
7571
  };
7572
- var isNotRelative = (path6) => REGEX_TEST_INVALID_PATH.test(path6);
7572
+ var isNotRelative = (path7) => REGEX_TEST_INVALID_PATH.test(path7);
7573
7573
  checkPath.isNotRelative = isNotRelative;
7574
7574
  checkPath.convert = (p) => p;
7575
7575
  var Ignore = class {
@@ -7628,7 +7628,7 @@ var require_ignore = __commonJS({
7628
7628
  // setting `checkUnignored` to `false` could reduce additional
7629
7629
  // path matching.
7630
7630
  // @returns {TestResult} true if a file is ignored
7631
- _testOne(path6, checkUnignored) {
7631
+ _testOne(path7, checkUnignored) {
7632
7632
  let ignored = false;
7633
7633
  let unignored = false;
7634
7634
  this._rules.forEach((rule) => {
@@ -7636,7 +7636,7 @@ var require_ignore = __commonJS({
7636
7636
  if (unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored) {
7637
7637
  return;
7638
7638
  }
7639
- const matched = rule.regex.test(path6);
7639
+ const matched = rule.regex.test(path7);
7640
7640
  if (matched) {
7641
7641
  ignored = !negative;
7642
7642
  unignored = negative;
@@ -7649,24 +7649,24 @@ var require_ignore = __commonJS({
7649
7649
  }
7650
7650
  // @returns {TestResult}
7651
7651
  _test(originalPath, cache, checkUnignored, slices) {
7652
- const path6 = originalPath && checkPath.convert(originalPath);
7652
+ const path7 = originalPath && checkPath.convert(originalPath);
7653
7653
  checkPath(
7654
- path6,
7654
+ path7,
7655
7655
  originalPath,
7656
7656
  this._allowRelativePaths ? RETURN_FALSE : throwError
7657
7657
  );
7658
- return this._t(path6, cache, checkUnignored, slices);
7658
+ return this._t(path7, cache, checkUnignored, slices);
7659
7659
  }
7660
- _t(path6, cache, checkUnignored, slices) {
7661
- if (path6 in cache) {
7662
- return cache[path6];
7660
+ _t(path7, cache, checkUnignored, slices) {
7661
+ if (path7 in cache) {
7662
+ return cache[path7];
7663
7663
  }
7664
7664
  if (!slices) {
7665
- slices = path6.split(SLASH);
7665
+ slices = path7.split(SLASH);
7666
7666
  }
7667
7667
  slices.pop();
7668
7668
  if (!slices.length) {
7669
- return cache[path6] = this._testOne(path6, checkUnignored);
7669
+ return cache[path7] = this._testOne(path7, checkUnignored);
7670
7670
  }
7671
7671
  const parent = this._t(
7672
7672
  slices.join(SLASH) + SLASH,
@@ -7674,24 +7674,24 @@ var require_ignore = __commonJS({
7674
7674
  checkUnignored,
7675
7675
  slices
7676
7676
  );
7677
- return cache[path6] = parent.ignored ? parent : this._testOne(path6, checkUnignored);
7677
+ return cache[path7] = parent.ignored ? parent : this._testOne(path7, checkUnignored);
7678
7678
  }
7679
- ignores(path6) {
7680
- return this._test(path6, this._ignoreCache, false).ignored;
7679
+ ignores(path7) {
7680
+ return this._test(path7, this._ignoreCache, false).ignored;
7681
7681
  }
7682
7682
  createFilter() {
7683
- return (path6) => !this.ignores(path6);
7683
+ return (path7) => !this.ignores(path7);
7684
7684
  }
7685
7685
  filter(paths) {
7686
7686
  return makeArray(paths).filter(this.createFilter());
7687
7687
  }
7688
7688
  // @returns {TestResult}
7689
- test(path6) {
7690
- return this._test(path6, this._testCache, true);
7689
+ test(path7) {
7690
+ return this._test(path7, this._testCache, true);
7691
7691
  }
7692
7692
  };
7693
7693
  var factory = (options) => new Ignore(options);
7694
- var isPathValid = (path6) => checkPath(path6 && checkPath.convert(path6), path6, RETURN_FALSE);
7694
+ var isPathValid = (path7) => checkPath(path7 && checkPath.convert(path7), path7, RETURN_FALSE);
7695
7695
  factory.isPathValid = isPathValid;
7696
7696
  factory.default = factory;
7697
7697
  module.exports = factory;
@@ -7702,7 +7702,7 @@ var require_ignore = __commonJS({
7702
7702
  const makePosix = (str) => /^\\\\\?\\/.test(str) || /["<>|\u0000-\u001F]+/u.test(str) ? str : str.replace(/\\/g, "/");
7703
7703
  checkPath.convert = makePosix;
7704
7704
  const REGIX_IS_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i;
7705
- checkPath.isNotRelative = (path6) => REGIX_IS_WINDOWS_PATH_ABSOLUTE.test(path6) || isNotRelative(path6);
7705
+ checkPath.isNotRelative = (path7) => REGIX_IS_WINDOWS_PATH_ABSOLUTE.test(path7) || isNotRelative(path7);
7706
7706
  }
7707
7707
  }
7708
7708
  });
@@ -7714,8 +7714,7 @@ import crypto from "node:crypto";
7714
7714
  import fs5 from "node:fs";
7715
7715
  import http from "node:http";
7716
7716
  import os from "node:os";
7717
- import path5 from "node:path";
7718
- import { fileURLToPath } from "node:url";
7717
+ import path6 from "node:path";
7719
7718
  import { tool } from "@opencode-ai/plugin/tool";
7720
7719
 
7721
7720
  // src/git_utils.js
@@ -8486,7 +8485,9 @@ async function optima_validate_logic(worktree) {
8486
8485
  };
8487
8486
  }
8488
8487
 
8489
- // src/index.js
8488
+ // src/constants.js
8489
+ import path5 from "node:path";
8490
+ import { fileURLToPath } from "node:url";
8490
8491
  var PKG_ROOT = path5.resolve(path5.dirname(fileURLToPath(import.meta.url)), "..");
8491
8492
  var BUNDLE_ASSETS_DIR = path5.join(PKG_ROOT, "assets");
8492
8493
  var BUNDLE_AGENTS_DIR = path5.join(BUNDLE_ASSETS_DIR, "agents");
@@ -8527,6 +8528,8 @@ var CLICKUP_WEBHOOK_REQUEST_TIMEOUT_MS = 1e4;
8527
8528
  var CLICKUP_WEBHOOK_STARTUP_TASK_LIMIT = 50;
8528
8529
  var CLICKUP_WEBHOOK_STARTUP_COMMENT_LIMIT = 100;
8529
8530
  var CLICKUP_WEBHOOK_STARTUP_RECONCILIATION_DELAY_MS = 3e4;
8531
+ var CLICKUP_WEBHOOK_STARTUP_COMMENT_LOOKBACK_MS = 6 * 60 * 60 * 1e3;
8532
+ var CLICKUP_ASSIGNMENT_WATCHDOG_INTERVAL_MS = 5 * 60 * 1e3;
8530
8533
  var CLICKUP_WORKTREE_FAILURE_COMMENT_DEDUPE_MS = 10 * 60 * 1e3;
8531
8534
  var CLICKUP_WEBHOOK_LOG_LEVELS = /* @__PURE__ */ new Set(["error", "info", "verbose"]);
8532
8535
  var CLICKUP_WEBHOOK_REDACTED = "[REDACTED]";
@@ -8615,20 +8618,22 @@ var REPO_LOCAL_POLICIES_README = [
8615
8618
  "Only files in `.optima/policies/` affect runtime prompt behavior.",
8616
8619
  ""
8617
8620
  ].join("\n");
8621
+ var CLICKUP_WEBHOOK_CLEANUP_TIMEOUT_MS = 8e3;
8622
+ var CLICKUP_WEBHOOK_SIGNAL_STATE = Symbol.for("opencode-optima.clickup-webhook.signal-state");
8623
+
8624
+ // src/index.js
8618
8625
  var activeWorkflows = /* @__PURE__ */ new Map();
8619
8626
  var activeClickUpWebhookListeners = /* @__PURE__ */ new Map();
8620
8627
  var activeClickUpWebhookLifecycleRegistry = /* @__PURE__ */ new Map();
8621
- var CLICKUP_WEBHOOK_CLEANUP_TIMEOUT_MS = 8e3;
8622
- var CLICKUP_WEBHOOK_SIGNAL_STATE = Symbol.for("opencode-optima.clickup-webhook.signal-state");
8623
8628
  var activeClickUpTaskRoutes = /* @__PURE__ */ new Map();
8624
8629
  function isRootDirectory(candidate) {
8625
- const resolved = path5.resolve(candidate);
8626
- return resolved === path5.parse(resolved).root;
8630
+ const resolved = path6.resolve(candidate);
8631
+ return resolved === path6.parse(resolved).root;
8627
8632
  }
8628
8633
  function isSafeWritableDirectory(candidate) {
8629
8634
  if (typeof candidate !== "string" || !candidate.trim()) return false;
8630
- if (!path5.isAbsolute(candidate)) return false;
8631
- const resolved = path5.resolve(candidate);
8635
+ if (!path6.isAbsolute(candidate)) return false;
8636
+ const resolved = path6.resolve(candidate);
8632
8637
  if (isRootDirectory(resolved)) return false;
8633
8638
  try {
8634
8639
  const stat = fs5.statSync(resolved);
@@ -8649,7 +8654,7 @@ function resolveSafeWorktree(context = {}, pluginWorktree = null) {
8649
8654
  ];
8650
8655
  for (const candidate of candidates) {
8651
8656
  if (typeof candidate !== "string" || !candidate.trim()) continue;
8652
- const resolved = path5.resolve(candidate);
8657
+ const resolved = path6.resolve(candidate);
8653
8658
  if (isSafeWritableDirectory(resolved)) return resolved;
8654
8659
  }
8655
8660
  throw new Error(SAFE_WORKTREE_FAILURE);
@@ -8664,13 +8669,13 @@ function safeWorktreeOrFailure(context, pluginWorktree) {
8664
8669
  function explicitSafeInputWorktree(input = {}) {
8665
8670
  for (const candidate of [input?.worktree, input?.directory]) {
8666
8671
  if (typeof candidate !== "string" || !candidate.trim()) continue;
8667
- const resolved = path5.resolve(candidate);
8672
+ const resolved = path6.resolve(candidate);
8668
8673
  if (isSafeWritableDirectory(resolved)) return resolved;
8669
8674
  }
8670
8675
  return null;
8671
8676
  }
8672
8677
  function isGitRepository(worktree) {
8673
- return fs5.existsSync(path5.join(worktree, ".git"));
8678
+ return fs5.existsSync(path6.join(worktree, ".git"));
8674
8679
  }
8675
8680
  function normalizeLooseToken(value) {
8676
8681
  return String(value ?? "").trim().normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
@@ -9165,7 +9170,7 @@ function buildClickUpSummaryPayload({ summaryMarkdown = "", summaryPath = "", ta
9165
9170
  function deriveClickUpWorktree({ baseWorktree = "", taskId, taskType, parentTaskId, subtaskId } = {}) {
9166
9171
  const branch = deriveClickUpBranchName({ taskType, parentTaskId, subtaskId, taskId });
9167
9172
  const root = baseWorktree || process.cwd();
9168
- return path5.join(path5.dirname(root), `${path5.basename(root)}-${branch.replace(/\//g, "-")}`);
9173
+ return path6.join(path6.dirname(root), `${path6.basename(root)}-${branch.replace(/\//g, "-")}`);
9169
9174
  }
9170
9175
  function clickUpCustomFieldValue(task = {}, names = []) {
9171
9176
  const fields = Array.isArray(task.custom_fields) ? task.custom_fields : [];
@@ -9189,12 +9194,12 @@ function safeExistingClickUpWorktree({ metadata = {}, branch = "" } = {}) {
9189
9194
  const taskMetadata = metadataTaskRouting(metadata);
9190
9195
  const existingWorktree = typeof taskMetadata.worktree === "string" ? taskMetadata.worktree.trim() : "";
9191
9196
  const existingBranch = typeof taskMetadata.branch === "string" ? taskMetadata.branch.trim() : "";
9192
- if (!existingWorktree || !path5.isAbsolute(existingWorktree) || !fs5.existsSync(existingWorktree)) return null;
9197
+ if (!existingWorktree || !path6.isAbsolute(existingWorktree) || !fs5.existsSync(existingWorktree)) return null;
9193
9198
  try {
9194
9199
  const stat = fs5.statSync(existingWorktree);
9195
9200
  if (!stat.isDirectory()) return null;
9196
9201
  if (branch && existingBranch && existingBranch !== branch) return null;
9197
- return { branch: existingBranch || branch, worktree: path5.resolve(existingWorktree), reused: true };
9202
+ return { branch: existingBranch || branch, worktree: path6.resolve(existingWorktree), reused: true };
9198
9203
  } catch {
9199
9204
  return null;
9200
9205
  }
@@ -9280,17 +9285,17 @@ function openChamberEntryBranch(entry) {
9280
9285
  return String(entry?.branch || entry?.branchName || entry?.branch_name || entry?.worktree?.branch || "").replace(/^refs\/heads\//, "");
9281
9286
  }
9282
9287
  function openChamberListIncludesDirectory(list, directory) {
9283
- const resolved = path5.resolve(directory);
9288
+ const resolved = path6.resolve(directory);
9284
9289
  return normalizeOpenChamberCollection(list).some((entry) => {
9285
9290
  const entryDirectory = openChamberEntryDirectory(entry);
9286
- return entryDirectory && path5.resolve(entryDirectory) === resolved;
9291
+ return entryDirectory && path6.resolve(entryDirectory) === resolved;
9287
9292
  });
9288
9293
  }
9289
9294
  function openChamberListIncludesBranch(list, directory, branch) {
9290
- const resolved = path5.resolve(directory);
9295
+ const resolved = path6.resolve(directory);
9291
9296
  return normalizeOpenChamberCollection(list).some((entry) => {
9292
9297
  const entryDirectory = openChamberEntryDirectory(entry);
9293
- if (!entryDirectory || path5.resolve(entryDirectory) !== resolved) return false;
9298
+ if (!entryDirectory || path6.resolve(entryDirectory) !== resolved) return false;
9294
9299
  const entryBranch = openChamberEntryBranch(entry);
9295
9300
  return !entryBranch || entryBranch === branch;
9296
9301
  });
@@ -9298,8 +9303,8 @@ function openChamberListIncludesBranch(list, directory, branch) {
9298
9303
  async function findOpenChamberProject({ opencodeBaseUrl, baseWorktree, fetchImpl = globalThis.fetch } = {}) {
9299
9304
  const projects = await requestOpenCodeJson({ baseUrl: opencodeBaseUrl, endpoint: "/project", directory: baseWorktree, fetchImpl });
9300
9305
  if (!Array.isArray(projects)) return null;
9301
- const resolvedBase = path5.resolve(baseWorktree);
9302
- return projects.find((project) => path5.resolve(String(project?.worktree || project?.path || "")) === resolvedBase) || null;
9306
+ const resolvedBase = path6.resolve(baseWorktree);
9307
+ return projects.find((project) => path6.resolve(String(project?.worktree || project?.path || "")) === resolvedBase) || null;
9303
9308
  }
9304
9309
  async function refreshOpenChamberProjectCopy({ opencodeBaseUrl, projectId, fetchImpl = globalThis.fetch } = {}) {
9305
9310
  if (!projectId) return { refreshed: false, reason: "project_id_unavailable" };
@@ -9354,18 +9359,18 @@ async function createOpenChamberClickUpWorktree({ openchamberBaseUrl, baseUrl, b
9354
9359
  }
9355
9360
  const createdDirectory = openChamberEntryDirectory(created);
9356
9361
  const createdBranch = openChamberEntryBranch(created);
9357
- if (!createdDirectory || !path5.isAbsolute(createdDirectory)) {
9362
+ if (!createdDirectory || !path6.isAbsolute(createdDirectory)) {
9358
9363
  throw new Error(`OpenChamber did not return an absolute worktree path for ${branch}.`);
9359
9364
  }
9360
9365
  if (createdBranch !== branch) {
9361
9366
  throw new Error(`OpenChamber created unexpected branch ${createdBranch || "<unknown>"}; expected ${branch}.`);
9362
9367
  }
9363
9368
  const verified = await verifyOpenChamberGitWorktree({ openchamberBaseUrl: effectiveOpenChamberBaseUrl, baseWorktree, worktreePath: createdDirectory, branch, fetchImpl });
9364
- return { created, worktree: path5.resolve(createdDirectory), branch: createdBranch, verified };
9369
+ return { created, worktree: path6.resolve(createdDirectory), branch: createdBranch, verified };
9365
9370
  }
9366
9371
  async function registerOpenChamberClickUpWorktree({ openchamberBaseUrl, opencodeBaseUrl, baseUrl, baseWorktree, branch, worktreePath, fetchImpl = globalThis.fetch, source = "reuse" } = {}) {
9367
9372
  const visibility = await syncOpenChamberWorktreeVisibility({ openchamberBaseUrl: openchamberBaseUrl || baseUrl, opencodeBaseUrl: opencodeBaseUrl || baseUrl, baseWorktree, worktreePath, branch, fetchImpl });
9368
- return { branch, worktree: path5.resolve(worktreePath), reused: true, provider: "openchamber", openChamber: { source, visibility } };
9373
+ return { branch, worktree: path6.resolve(worktreePath), reused: true, provider: "openchamber", openChamber: { source, visibility } };
9369
9374
  }
9370
9375
  async function ensureClickUpTaskWorktreeOpenChamber({ baseWorktree = "", taskId, taskType = "Tarea", parentTaskId = "", subtaskId = "", existingMetadata = {}, runGitFn = runGit, openchamberBaseUrl = "", opencodeBaseUrl = "", baseUrl = "", fetchImpl = globalThis.fetch, log = null } = {}) {
9371
9376
  const effectiveOpenChamberBaseUrl = openchamberBaseUrl || baseUrl;
@@ -9428,10 +9433,10 @@ function ensureClickUpTaskWorktree({ baseWorktree = "", taskId, taskType = "Tare
9428
9433
  const existing = safeExistingClickUpWorktree({ metadata: existingMetadata, branch });
9429
9434
  if (existing) return { ...existing, branch, parentBranch: parentBranch || void 0, prTarget: parentBranch || "dev" };
9430
9435
  const worktreePath = deriveClickUpWorktree({ baseWorktree, taskId, taskType, parentTaskId: effectiveParent, subtaskId });
9431
- if (fs5.existsSync(worktreePath)) return { branch, worktree: path5.resolve(worktreePath), reused: true, parentBranch: parentBranch || void 0, prTarget: parentBranch || "dev" };
9436
+ if (fs5.existsSync(worktreePath)) return { branch, worktree: path6.resolve(worktreePath), reused: true, parentBranch: parentBranch || void 0, prTarget: parentBranch || "dev" };
9432
9437
  if (allowNonGitFallback) {
9433
9438
  fs5.mkdirSync(worktreePath, { recursive: true });
9434
- return { branch, worktree: path5.resolve(worktreePath), reused: false, fallback: "non_git", parentBranch: parentBranch || void 0, prTarget: parentBranch || "dev", startPoint: parentBranch || "dev" };
9439
+ return { branch, worktree: path6.resolve(worktreePath), reused: false, fallback: "non_git", parentBranch: parentBranch || void 0, prTarget: parentBranch || "dev", startPoint: parentBranch || "dev" };
9435
9440
  }
9436
9441
  let parentBootstrap = null;
9437
9442
  if (isSubtask) {
@@ -9440,14 +9445,14 @@ function ensureClickUpTaskWorktree({ baseWorktree = "", taskId, taskType = "Tare
9440
9445
  const parentStartPoint = resolveClickUpDevStartPoint(baseWorktree, runGitFn);
9441
9446
  const parentBranchExists = clickUpGitRefExists(baseWorktree, parentBranch, runGitFn);
9442
9447
  addClickUpWorktreeForBranch({ baseWorktree, branch: parentBranch, worktreePath: parentWorktree, startPoint: parentStartPoint, runGitFn });
9443
- parentBootstrap = { branch: parentBranch, worktree: path5.resolve(parentWorktree), startPoint: parentBranchExists ? parentBranch : parentStartPoint, reused: parentBranchExists };
9448
+ parentBootstrap = { branch: parentBranch, worktree: path6.resolve(parentWorktree), startPoint: parentBranchExists ? parentBranch : parentStartPoint, reused: parentBranchExists };
9444
9449
  } else {
9445
- parentBootstrap = { branch: parentBranch, worktree: path5.resolve(parentWorktree), reused: true };
9450
+ parentBootstrap = { branch: parentBranch, worktree: path6.resolve(parentWorktree), reused: true };
9446
9451
  }
9447
9452
  }
9448
9453
  const startPoint = isSubtask ? parentBranch : resolveClickUpDevStartPoint(baseWorktree, runGitFn);
9449
9454
  addClickUpWorktreeForBranch({ baseWorktree, branch, worktreePath, startPoint, runGitFn });
9450
- return { branch, worktree: path5.resolve(worktreePath), reused: false, startPoint, parentBranch: parentBranch || void 0, prTarget: parentBranch || "dev", parentBootstrap: parentBootstrap || void 0 };
9455
+ return { branch, worktree: path6.resolve(worktreePath), reused: false, startPoint, parentBranch: parentBranch || void 0, prTarget: parentBranch || "dev", parentBootstrap: parentBootstrap || void 0 };
9451
9456
  }
9452
9457
  function normalizeClickUpDefinitionDocParent(parent = {}) {
9453
9458
  const docId = String(parent.doc_id || parent.docId || CLICKUP_DEFINITION_DOC_PARENT.doc_id).trim();
@@ -9597,7 +9602,7 @@ function buildClickUpTransitionPayload({ fromStatus, toStatus, validationPassed
9597
9602
  }
9598
9603
  function ensureOptimaGitignoreRules(worktree) {
9599
9604
  if (!isGitRepository(worktree)) return { touched: false, added: [] };
9600
- const gitignorePath = path5.join(worktree, ".gitignore");
9605
+ const gitignorePath = path6.join(worktree, ".gitignore");
9601
9606
  const existing = fs5.existsSync(gitignorePath) ? fs5.readFileSync(gitignorePath, "utf8") : "";
9602
9607
  const existingRules = new Set(existing.split(/\r?\n/).map((line) => line.trim()).filter(Boolean));
9603
9608
  const missingRules = OPTIMA_GITIGNORE_RULES.filter((rule) => !existingRules.has(rule));
@@ -9613,40 +9618,40 @@ function ensureOptimaGitignoreRules(worktree) {
9613
9618
  return { touched: true, added: missingRules };
9614
9619
  }
9615
9620
  function optimaDir(worktree) {
9616
- return path5.join(worktree, OPTIMA_DIRNAME);
9621
+ return path6.join(worktree, OPTIMA_DIRNAME);
9617
9622
  }
9618
9623
  function optimaLocalConfigDir(worktree) {
9619
- return path5.join(optimaDir(worktree), ".config");
9624
+ return path6.join(optimaDir(worktree), ".config");
9620
9625
  }
9621
9626
  function optimaConfigDir(worktree) {
9622
9627
  return optimaLocalConfigDir(worktree);
9623
9628
  }
9624
9629
  function optimaCodemapPath(worktree) {
9625
- return path5.join(optimaDir(worktree), "codemap.yml");
9630
+ return path6.join(optimaDir(worktree), "codemap.yml");
9626
9631
  }
9627
9632
  function optimaTasksDir(worktree) {
9628
- return path5.join(optimaDir(worktree), "tasks");
9633
+ return path6.join(optimaDir(worktree), "tasks");
9629
9634
  }
9630
9635
  function optimaEvidencesDir(worktree) {
9631
- return path5.join(optimaDir(worktree), "evidences");
9636
+ return path6.join(optimaDir(worktree), "evidences");
9632
9637
  }
9633
9638
  function optimaScrsDir(worktree) {
9634
- return path5.join(optimaDir(worktree), "docs", "scrs");
9639
+ return path6.join(optimaDir(worktree), "docs", "scrs");
9635
9640
  }
9636
9641
  function legacyNomadworkDir(worktree) {
9637
- return path5.join(worktree, LEGACY_NOMADWORK_DIRNAME);
9642
+ return path6.join(worktree, LEGACY_NOMADWORK_DIRNAME);
9638
9643
  }
9639
9644
  function legacyNomadworksDir(worktree) {
9640
- return path5.join(worktree, LEGACY_NOMADWORKS_DIRNAME);
9645
+ return path6.join(worktree, LEGACY_NOMADWORKS_DIRNAME);
9641
9646
  }
9642
9647
  function legacyOrbitaDir(worktree) {
9643
- return path5.join(worktree, LEGACY_ORBITA_DIRNAME);
9648
+ return path6.join(worktree, LEGACY_ORBITA_DIRNAME);
9644
9649
  }
9645
9650
  function legacyStaticEngDir(worktree) {
9646
- return path5.join(worktree, LEGACY_STATICENG_DIRNAME);
9651
+ return path6.join(worktree, LEGACY_STATICENG_DIRNAME);
9647
9652
  }
9648
9653
  function repoConfigPath(worktree) {
9649
- return path5.join(optimaConfigDir(worktree), "optima.yaml");
9654
+ return path6.join(optimaConfigDir(worktree), "optima.yaml");
9650
9655
  }
9651
9656
  function normalizeLegacyDiscussionEntry(entry) {
9652
9657
  if (!entry || typeof entry !== "object") return entry;
@@ -9659,25 +9664,25 @@ function normalizeLegacyDiscussionEntry(entry) {
9659
9664
  return next;
9660
9665
  }
9661
9666
  function repoPoliciesDir(worktree) {
9662
- return path5.join(optimaDir(worktree), "policies");
9667
+ return path6.join(optimaDir(worktree), "policies");
9663
9668
  }
9664
9669
  function generatedPoliciesDir(worktree) {
9665
- return path5.join(optimaLocalConfigDir(worktree), "generated", "policies");
9670
+ return path6.join(optimaLocalConfigDir(worktree), "generated", "policies");
9666
9671
  }
9667
9672
  function generatedAgentsDir(worktree) {
9668
- return path5.join(optimaLocalConfigDir(worktree), "generated", "agents");
9673
+ return path6.join(optimaLocalConfigDir(worktree), "generated", "agents");
9669
9674
  }
9670
9675
  function repoAgentsDir(worktree) {
9671
- return path5.join(optimaDir(worktree), "agents");
9676
+ return path6.join(optimaDir(worktree), "agents");
9672
9677
  }
9673
9678
  function repoAgentAdditionsDir(worktree) {
9674
- return path5.join(optimaDir(worktree), "agent-additions");
9679
+ return path6.join(optimaDir(worktree), "agent-additions");
9675
9680
  }
9676
9681
  function legacyRepoAgentsDir(worktree) {
9677
- return path5.join(legacyNomadworksDir(worktree), "agents");
9682
+ return path6.join(legacyNomadworksDir(worktree), "agents");
9678
9683
  }
9679
9684
  function runtimeDiscussionRegistryPath(worktree) {
9680
- return path5.join(optimaLocalConfigDir(worktree), "runtime", "discussions.json");
9685
+ return path6.join(optimaLocalConfigDir(worktree), "runtime", "discussions.json");
9681
9686
  }
9682
9687
  function resolveConfigPath(worktree) {
9683
9688
  return repoConfigPath(worktree);
@@ -9720,32 +9725,32 @@ function mergeClickUpAgentMetadata(existing, update = {}) {
9720
9725
  return JSON.stringify(sortJsonValue(merged), null, 2);
9721
9726
  }
9722
9727
  function optimaRuntimeDir(worktree) {
9723
- return path5.join(optimaLocalConfigDir(worktree), "runtime");
9728
+ return path6.join(optimaLocalConfigDir(worktree), "runtime");
9724
9729
  }
9725
9730
  function clickUpWebhookStatePath(worktree) {
9726
- return path5.join(optimaRuntimeDir(worktree), "clickup-webhook.json");
9731
+ return path6.join(optimaRuntimeDir(worktree), "clickup-webhook.json");
9727
9732
  }
9728
9733
  function clickUpCommentLedgerPath(worktree) {
9729
- return path5.join(optimaRuntimeDir(worktree), "clickup-comment-ledger.jsonl");
9734
+ return path6.join(optimaRuntimeDir(worktree), "clickup-comment-ledger.jsonl");
9730
9735
  }
9731
9736
  function clickUpWebhookLogPath(worktree) {
9732
- return path5.join(optimaRuntimeDir(worktree), "clickup-webhook.log.jsonl");
9737
+ return path6.join(optimaRuntimeDir(worktree), "clickup-webhook.log.jsonl");
9733
9738
  }
9734
9739
  function normalizeClickUpWebhookLogLevel(value) {
9735
9740
  const level = String(value || "info").trim().toLowerCase();
9736
9741
  return CLICKUP_WEBHOOK_LOG_LEVELS.has(level) ? level : "info";
9737
9742
  }
9738
9743
  function clickUpWebhookAuditLogDir() {
9739
- const dataHome = process.env.XDG_DATA_HOME && path5.isAbsolute(process.env.XDG_DATA_HOME) ? process.env.XDG_DATA_HOME : path5.join(os.homedir(), ".local", "share", "opencode");
9740
- return path5.join(dataHome, "opencode-optima");
9744
+ const dataHome = process.env.XDG_DATA_HOME && path6.isAbsolute(process.env.XDG_DATA_HOME) ? process.env.XDG_DATA_HOME : path6.join(os.homedir(), ".local", "share", "opencode");
9745
+ return path6.join(dataHome, "opencode-optima");
9741
9746
  }
9742
9747
  function clickUpWebhookAuditLogPath(at = /* @__PURE__ */ new Date(), logDir = clickUpWebhookAuditLogDir()) {
9743
- return path5.join(logDir, `clickup-webhook-${at.toISOString().slice(0, 10)}.jsonl`);
9748
+ return path6.join(logDir, `clickup-webhook-${at.toISOString().slice(0, 10)}.jsonl`);
9744
9749
  }
9745
9750
  function clickUpWebhookRequestFilePath(at = /* @__PURE__ */ new Date(), logDir = clickUpWebhookAuditLogDir()) {
9746
9751
  const stamp = at.toISOString().replace(/:/g, "-").replace(/\./g, "-");
9747
9752
  const shortId = crypto.randomBytes(4).toString("hex");
9748
- return path5.join(logDir, "requests", `clickup-webhook-${stamp}-${shortId}.json`);
9753
+ return path6.join(logDir, "requests", `clickup-webhook-${stamp}-${shortId}.json`);
9749
9754
  }
9750
9755
  function findOptimaPluginTupleOptions(pluginEntries = []) {
9751
9756
  if (!Array.isArray(pluginEntries)) return null;
@@ -9807,6 +9812,10 @@ function normalizeClickUpWebhookConfig(rawClickUp = null, worktree = process.cwd
9807
9812
  startupReconciliationDelayMs: normalizeNonNegativeInteger(
9808
9813
  opencode.startup_reconciliation_delay_ms ?? opencode.startupReconciliationDelayMs ?? raw.startup_reconciliation_delay_ms ?? raw.startupReconciliationDelayMs,
9809
9814
  CLICKUP_WEBHOOK_STARTUP_RECONCILIATION_DELAY_MS
9815
+ ),
9816
+ assignmentWatchdogIntervalMs: normalizeNonNegativeInteger(
9817
+ opencode.assignment_watchdog_interval_ms ?? opencode.assignmentWatchdogIntervalMs ?? raw.assignment_watchdog_interval_ms ?? raw.assignmentWatchdogIntervalMs,
9818
+ CLICKUP_ASSIGNMENT_WATCHDOG_INTERVAL_MS
9810
9819
  )
9811
9820
  },
9812
9821
  openchamber: {
@@ -9840,7 +9849,7 @@ function normalizeClickUpWebhookConfig(rawClickUp = null, worktree = process.cwd
9840
9849
  };
9841
9850
  const errors = [];
9842
9851
  if (!config.enabled) errors.push("clickup.enabled must be true");
9843
- if (!config.basePath || !path5.isAbsolute(config.basePath)) errors.push("clickup.base_path must be an absolute path");
9852
+ if (!config.basePath || !path6.isAbsolute(config.basePath)) errors.push("clickup.base_path must be an absolute path");
9844
9853
  if (!config.teamId) errors.push("clickup.team_id is required");
9845
9854
  if (!config.apiToken) errors.push("clickup.api_token is required");
9846
9855
  if (!config.webhook.publicUrl) errors.push("clickup.webhook.public_url is required");
@@ -9898,7 +9907,7 @@ function readClickUpWebhookState(worktree, config = null) {
9898
9907
  }
9899
9908
  function writeClickUpWebhookState(worktree, state, config = null) {
9900
9909
  const statePath = clickUpWebhookStatePath(worktree);
9901
- fs5.mkdirSync(path5.dirname(statePath), { recursive: true, mode: 448 });
9910
+ fs5.mkdirSync(path6.dirname(statePath), { recursive: true, mode: 448 });
9902
9911
  const next = sanitizeClickUpWebhookState(state, config);
9903
9912
  fs5.writeFileSync(statePath, `${JSON.stringify(next, null, 2)}
9904
9913
  `, { encoding: "utf8", mode: 384 });
@@ -9919,7 +9928,7 @@ function isClickUpWebhookStateActive(state, config) {
9919
9928
  function expandHomePath(value = "") {
9920
9929
  const input = String(value || "").trim();
9921
9930
  if (input === "~") return os.homedir();
9922
- if (input.startsWith("~/")) return path5.join(os.homedir(), input.slice(2));
9931
+ if (input.startsWith("~/")) return path6.join(os.homedir(), input.slice(2));
9923
9932
  return input;
9924
9933
  }
9925
9934
  function resolveSecretReference(value = "") {
@@ -10295,7 +10304,7 @@ function readClickUpCommentLedger(ledgerPath) {
10295
10304
  }
10296
10305
  function appendClickUpCommentLedgerEntry(ledgerPath, entry = {}) {
10297
10306
  if (!ledgerPath || !entry.key) return;
10298
- fs5.mkdirSync(path5.dirname(ledgerPath), { recursive: true, mode: 448 });
10307
+ fs5.mkdirSync(path6.dirname(ledgerPath), { recursive: true, mode: 448 });
10299
10308
  fs5.appendFileSync(ledgerPath, `${JSON.stringify(entry)}
10300
10309
  `, { encoding: "utf8", mode: 384 });
10301
10310
  try {
@@ -10772,17 +10781,87 @@ function openCodeResultSummary(result) {
10772
10781
  status: result?.status || result?.response?.status || null
10773
10782
  };
10774
10783
  }
10784
+ function openCodeMessagePayload(message = {}) {
10785
+ if (!isPlainObject(message)) return {};
10786
+ const rawData = message.data;
10787
+ if (isPlainObject(rawData)) {
10788
+ return {
10789
+ ...rawData,
10790
+ id: rawData.id || message.id,
10791
+ time_created: rawData.time_created ?? message.time_created,
10792
+ time_updated: rawData.time_updated ?? message.time_updated
10793
+ };
10794
+ }
10795
+ if (typeof rawData === "string" && rawData.trim()) {
10796
+ try {
10797
+ const parsed = JSON.parse(rawData);
10798
+ if (isPlainObject(parsed)) {
10799
+ return {
10800
+ ...parsed,
10801
+ id: parsed.id || message.id,
10802
+ time_created: parsed.time_created ?? message.time_created,
10803
+ time_updated: parsed.time_updated ?? message.time_updated
10804
+ };
10805
+ }
10806
+ } catch {
10807
+ }
10808
+ }
10809
+ return message;
10810
+ }
10775
10811
  function normalizeOpenCodeMessageRole(message = {}) {
10776
- return message.role || message.info?.role || message.author?.role || message.type || "";
10812
+ const payload = openCodeMessagePayload(message);
10813
+ return payload.role || payload.info?.role || payload.author?.role || payload.type || "";
10777
10814
  }
10778
10815
  function normalizeOpenCodeMessageAgent(message = {}) {
10779
- return message.agent || message.info?.agent || message.mode?.agent || message.author?.agent || "";
10816
+ const payload = openCodeMessagePayload(message);
10817
+ return payload.agent || payload.info?.agent || payload.mode?.agent || payload.author?.agent || "";
10780
10818
  }
10781
10819
  function normalizeOpenCodeMessageMode(message = {}) {
10782
- return message.mode || message.info?.mode || message.metadata?.mode || "";
10820
+ const payload = openCodeMessagePayload(message);
10821
+ return payload.mode || payload.info?.mode || payload.metadata?.mode || "";
10783
10822
  }
10784
10823
  function normalizeOpenCodeMessageId(message = {}) {
10785
- return message.id || message.messageID || message.messageId || message.info?.id || message.data?.id || null;
10824
+ const payload = openCodeMessagePayload(message);
10825
+ return payload.id || payload.messageID || payload.messageId || payload.info?.id || payload.data?.id || message.id || null;
10826
+ }
10827
+ function openCodeMessageTimestampMs(message = {}, key = "updated") {
10828
+ const payload = openCodeMessagePayload(message);
10829
+ const time = payload.time || payload.info?.time || {};
10830
+ const value = key === "completed" ? payload.time_completed ?? payload.timeCompleted ?? time.completed : key === "created" ? payload.time_created ?? payload.timeCreated ?? time.created : payload.time_updated ?? payload.timeUpdated ?? time.updated ?? payload.time_created ?? payload.timeCreated ?? time.created;
10831
+ const number = Number(value);
10832
+ return Number.isFinite(number) && number > 0 ? number : 0;
10833
+ }
10834
+ function isOpenCodeAssistantMessageRunning(message = {}) {
10835
+ if (normalizeLooseToken(normalizeOpenCodeMessageRole(message)) !== "assistant") return false;
10836
+ const started = openCodeMessageTimestampMs(message, "created") > 0;
10837
+ if (!started) return false;
10838
+ return openCodeMessageTimestampMs(message, "completed") === 0;
10839
+ }
10840
+ async function inspectOpenCodeSessionActivity(client, { sessionId, directory, limit = 10 } = {}) {
10841
+ const messages = await readOpenCodeSessionMessages(client, { sessionId, directory, limit });
10842
+ if (!messages) return { ok: false, reason: "message_inspection_unavailable", sessionId, directory };
10843
+ const enriched = messages.map((message, index) => ({
10844
+ message,
10845
+ index,
10846
+ sortTime: openCodeMessageTimestampMs(message, "updated") || index,
10847
+ createdAt: openCodeMessageTimestampMs(message, "created"),
10848
+ completedAt: openCodeMessageTimestampMs(message, "completed")
10849
+ })).sort((a, b) => a.sortTime - b.sortTime || a.index - b.index);
10850
+ const assistantMessages = enriched.filter((entry) => normalizeLooseToken(normalizeOpenCodeMessageRole(entry.message)) === "assistant");
10851
+ const latestAssistant = assistantMessages.at(-1) || null;
10852
+ const latest = enriched.at(-1) || null;
10853
+ const running = latestAssistant ? isOpenCodeAssistantMessageRunning(latestAssistant.message) : false;
10854
+ return {
10855
+ ok: true,
10856
+ sessionId,
10857
+ directory,
10858
+ count: messages.length,
10859
+ running,
10860
+ latestMessageId: latest ? normalizeOpenCodeMessageId(latest.message) : null,
10861
+ latestAssistantMessageId: latestAssistant ? normalizeOpenCodeMessageId(latestAssistant.message) : null,
10862
+ latestAssistantCreatedAt: latestAssistant?.createdAt || 0,
10863
+ latestAssistantCompletedAt: latestAssistant?.completedAt || 0
10864
+ };
10786
10865
  }
10787
10866
  function summarizeOpenCodeMessages(messages = [], { snippetLength = 160, maxMessages = 50 } = {}) {
10788
10867
  const list = Array.isArray(messages) ? messages.slice(0, maxMessages) : [];
@@ -10922,8 +11001,9 @@ async function probeOpenCodeSessionControl(client, { directory, agent, omitAgent
10922
11001
  };
10923
11002
  }
10924
11003
  function openCodeMessageText(message) {
10925
- const parts = [message?.text, message?.content, message?.message, message?.body?.text, message?.data?.text];
10926
- const partList = Array.isArray(message?.parts) ? message.parts : Array.isArray(message?.body?.parts) ? message.body.parts : [];
11004
+ const payload = openCodeMessagePayload(message);
11005
+ const parts = [payload?.text, payload?.content, payload?.message, payload?.body?.text, payload?.data?.text];
11006
+ const partList = Array.isArray(payload?.parts) ? payload.parts : Array.isArray(payload?.body?.parts) ? payload.body.parts : [];
10927
11007
  for (const part of partList) parts.push(part?.text, part?.content);
10928
11008
  return parts.filter((value) => typeof value === "string").join("\n");
10929
11009
  }
@@ -11087,7 +11167,7 @@ function formatClickUpWebhookPrompt({ eventType, taskId, payload, branch = "", w
11087
11167
  }
11088
11168
  function appendClickUpWebhookLocalLog(worktree, entry) {
11089
11169
  const logPath = clickUpWebhookLogPath(worktree);
11090
- fs5.mkdirSync(path5.dirname(logPath), { recursive: true });
11170
+ fs5.mkdirSync(path6.dirname(logPath), { recursive: true });
11091
11171
  const safeEntry = { ...entry, at: entry.at || (/* @__PURE__ */ new Date()).toISOString() };
11092
11172
  fs5.appendFileSync(logPath, `${JSON.stringify(safeEntry)}
11093
11173
  `, "utf8");
@@ -11118,7 +11198,7 @@ function closeClickUpWebhookServer(server) {
11118
11198
  });
11119
11199
  }
11120
11200
  function managedClickUpWebhookKey({ worktree, state, config } = {}) {
11121
- return [path5.resolve(worktree || process.cwd()), state?.webhookId || "", config?.webhook?.publicUrl || ""].join("|");
11201
+ return [path6.resolve(worktree || process.cwd()), state?.webhookId || "", config?.webhook?.publicUrl || ""].join("|");
11122
11202
  }
11123
11203
  async function deleteClickUpWebhookBestEffort({ webhookId, clickupClient, worktree, reason = "cleanup" } = {}) {
11124
11204
  const id = String(webhookId || "").trim();
@@ -11141,6 +11221,7 @@ async function cleanupManagedClickUpWebhook(entry = {}, { timeoutMs = CLICKUP_WE
11141
11221
  entry.cleaning = true;
11142
11222
  const cleanup = (async () => {
11143
11223
  clickUpWebhookLifecycleLog(entry.worktree, { type: "cleanup_started", reason, key: entry.key, webhookId: entry.state?.webhookId });
11224
+ if (entry.assignmentWatchdog?.interval) clearInterval(entry.assignmentWatchdog.interval);
11144
11225
  const closeResult = await closeClickUpWebhookServer(entry.listener?.server);
11145
11226
  if (entry.listenerRegistry && entry.listener?.key) entry.listenerRegistry.delete(entry.listener.key);
11146
11227
  const preservedResult = { ok: true, skipped: true, reason: "remote_webhook_preserved" };
@@ -11154,10 +11235,10 @@ async function cleanupManagedClickUpWebhook(entry = {}, { timeoutMs = CLICKUP_WE
11154
11235
  if (result?.timeout) clickUpWebhookLifecycleLog(entry.worktree, { type: "cleanup_timeout", reason, webhookId: entry.state?.webhookId });
11155
11236
  return result;
11156
11237
  }
11157
- function registerClickUpWebhookLifecycle({ config, state, worktree, clickupClient, listener, listenerRegistry = activeClickUpWebhookListeners } = {}) {
11238
+ function registerClickUpWebhookLifecycle({ config, state, worktree, clickupClient, listener, listenerRegistry = activeClickUpWebhookListeners, assignmentWatchdog = null } = {}) {
11158
11239
  if (!isClickUpWebhookStateActive(state, config)) return null;
11159
11240
  const key = managedClickUpWebhookKey({ worktree, state, config });
11160
- const entry = { key, config, state, worktree, clickupClient, listener, listenerRegistry, registeredAt: (/* @__PURE__ */ new Date()).toISOString() };
11241
+ const entry = { key, config, state, worktree, clickupClient, listener, listenerRegistry, assignmentWatchdog, registeredAt: (/* @__PURE__ */ new Date()).toISOString() };
11161
11242
  activeClickUpWebhookLifecycleRegistry.set(key, entry);
11162
11243
  installClickUpWebhookSignalHandlers();
11163
11244
  clickUpWebhookLifecycleLog(worktree, { type: "lifecycle_registered", key, webhookId: state.webhookId });
@@ -11222,8 +11303,8 @@ function writeClickUpWebhookAuditLog({ method, url, headers = {}, rawBody = "",
11222
11303
  let requestFile;
11223
11304
  if (level === "verbose") {
11224
11305
  const absoluteRequestFile = clickUpWebhookRequestFilePath(at, logDir);
11225
- fs5.mkdirSync(path5.dirname(absoluteRequestFile), { recursive: true });
11226
- requestFile = path5.relative(logDir, absoluteRequestFile).split(path5.sep).join("/");
11306
+ fs5.mkdirSync(path6.dirname(absoluteRequestFile), { recursive: true });
11307
+ requestFile = path6.relative(logDir, absoluteRequestFile).split(path6.sep).join("/");
11227
11308
  const parsedBody = payload || (() => {
11228
11309
  try {
11229
11310
  return JSON.parse(Buffer.isBuffer(rawBody) ? rawBody.toString("utf8") : String(rawBody || ""));
@@ -11447,19 +11528,54 @@ function scheduleClickUpStartupReconciliation({ config, state = {}, worktree = p
11447
11528
  timer?.unref?.();
11448
11529
  return { scheduled: true, delayMs: normalizedDelayMs, timer };
11449
11530
  }
11450
- async function reconcileClickUpStartup({ config, state = {}, worktree = process.cwd(), clickupClient, openCodeClient, sessionExists = openCodeSessionExists, createSession = createOpenCodeSession, sendSessionEvent = sendOpenCodeSessionEvent, verifySessionEventDelivery = verifyOpenCodeSessionEventDelivery, waitForReadiness = waitForOpenCodeReadiness, saveState = null, now = () => /* @__PURE__ */ new Date(), limit = CLICKUP_WEBHOOK_STARTUP_TASK_LIMIT } = {}) {
11451
- clickUpWebhookLifecycleLog(worktree, { type: "startup_reconciliation_started", lastWebhookAt: state.lastWebhookAt || null });
11531
+ function scheduleClickUpAssignmentWatchdog({ config, state = {}, worktree = process.cwd(), clickupClient, openCodeClient, scheduler = setInterval, intervalMs = config?.opencode?.assignmentWatchdogIntervalMs ?? CLICKUP_ASSIGNMENT_WATCHDOG_INTERVAL_MS, saveState = null, reconcile = reconcileClickUpStartup } = {}) {
11532
+ const normalizedIntervalMs = normalizeNonNegativeInteger(intervalMs, CLICKUP_ASSIGNMENT_WATCHDOG_INTERVAL_MS);
11533
+ if (!normalizedIntervalMs) {
11534
+ clickUpWebhookLifecycleLog(worktree, { type: "assignment_watchdog_disabled", webhookId: state?.webhookId || null });
11535
+ return { scheduled: false, intervalMs: 0, reason: "disabled" };
11536
+ }
11537
+ let running = false;
11538
+ const run = () => {
11539
+ if (running) {
11540
+ appendClickUpWebhookLocalLog(worktree, { type: "assignment_watchdog_tick_skipped", reason: "previous_tick_running" });
11541
+ return;
11542
+ }
11543
+ running = true;
11544
+ const latestState = readClickUpWebhookState(worktree, config);
11545
+ Promise.resolve().then(() => reconcile({
11546
+ config,
11547
+ state: latestState?.webhookId ? latestState : state,
11548
+ worktree,
11549
+ clickupClient,
11550
+ openCodeClient,
11551
+ saveState,
11552
+ assignmentMode: "watchdog"
11553
+ })).catch((error) => {
11554
+ clickUpWebhookLifecycleLog(worktree, { type: "assignment_watchdog_failed", message: error.message });
11555
+ appendClickUpWebhookLocalLog(worktree, { type: "assignment_watchdog_failed", message: error.message });
11556
+ }).finally(() => {
11557
+ running = false;
11558
+ });
11559
+ };
11560
+ const interval = scheduler(run, normalizedIntervalMs);
11561
+ interval?.unref?.();
11562
+ clickUpWebhookLifecycleLog(worktree, { type: "assignment_watchdog_scheduled", intervalMs: normalizedIntervalMs, webhookId: state?.webhookId || null });
11563
+ return { scheduled: true, intervalMs: normalizedIntervalMs, interval };
11564
+ }
11565
+ async function reconcileClickUpStartup({ config, state = {}, worktree = process.cwd(), clickupClient, openCodeClient, sessionExists = openCodeSessionExists, createSession = createOpenCodeSession, sendSessionEvent = sendOpenCodeSessionEvent, verifySessionEventDelivery = verifyOpenCodeSessionEventDelivery, waitForReadiness = waitForOpenCodeReadiness, saveState = null, now = () => /* @__PURE__ */ new Date(), limit = CLICKUP_WEBHOOK_STARTUP_TASK_LIMIT, assignmentMode = "startup" } = {}) {
11566
+ const watchdogMode = assignmentMode === "watchdog";
11567
+ clickUpWebhookLifecycleLog(worktree, { type: watchdogMode ? "assignment_watchdog_started" : "startup_reconciliation_started", lastWebhookAt: state.lastWebhookAt || null });
11452
11568
  if (!config || !clickupClient?.listAssignedTasks) {
11453
11569
  const skipped = { ok: true, skipped: true, reason: "clickup_task_listing_unavailable", assigned: 0, comments: 0 };
11454
- clickUpWebhookLifecycleLog(worktree, { type: "startup_reconciliation_finished", ...skipped });
11570
+ clickUpWebhookLifecycleLog(worktree, { type: watchdogMode ? "assignment_watchdog_finished" : "startup_reconciliation_finished", ...skipped });
11455
11571
  return skipped;
11456
11572
  }
11457
11573
  const readiness = await waitForReadiness(openCodeClient, { worktree, now, opencodeBaseUrl: config.opencode?.baseUrl });
11458
11574
  appendClickUpWebhookLocalLog(worktree, { type: readiness.ok ? "startup_reconciliation_readiness_ready" : "startup_reconciliation_readiness_failed", ...readiness });
11459
11575
  if (!readiness.ok) {
11460
11576
  const failed = { ok: false, skipped: true, reason: "opencode_not_ready", readiness, assigned: 0, comments: 0, ignored: 0, errors: 1, undelivered: 1, tasks: [], validation: { undelivered: 1, emptyPromptSessions: [] } };
11461
- clickUpWebhookLifecycleLog(worktree, { type: "startup_reconciliation_failed", reason: failed.reason, readiness });
11462
- clickUpWebhookLifecycleLog(worktree, { type: "startup_reconciliation_finished", ...failed });
11577
+ clickUpWebhookLifecycleLog(worktree, { type: watchdogMode ? "assignment_watchdog_failed" : "startup_reconciliation_failed", reason: failed.reason, readiness });
11578
+ clickUpWebhookLifecycleLog(worktree, { type: watchdogMode ? "assignment_watchdog_finished" : "startup_reconciliation_finished", ...failed });
11463
11579
  return failed;
11464
11580
  }
11465
11581
  let authorizedUserId = "";
@@ -11477,6 +11593,7 @@ async function reconcileClickUpStartup({ config, state = {}, worktree = process.
11477
11593
  if (saveState) saveState(nextState);
11478
11594
  };
11479
11595
  const lastWebhookMs = clickUpTimestampMs(mutableState.lastWebhookAt);
11596
+ const startupCommentStartMs = lastWebhookMs || Math.max(0, now().getTime() - CLICKUP_WEBHOOK_STARTUP_COMMENT_LOOKBACK_MS);
11480
11597
  const ignored = new Set((config.routing?.ignoredStatuses || CLICKUP_WEBHOOK_TERMINAL_STATUSES).map(normalizeClickUpStatus));
11481
11598
  const routed = { assigned: 0, comments: 0, ignored: 0, errors: 0, undelivered: 0, tasks: [] };
11482
11599
  const listed = await clickupClient.listAssignedTasks({ assigneeId: config.routing.productManagerAssigneeId, limit });
@@ -11495,9 +11612,29 @@ async function reconcileClickUpStartup({ config, state = {}, worktree = process.
11495
11612
  routed.ignored += 1;
11496
11613
  continue;
11497
11614
  }
11615
+ if (watchdogMode) {
11616
+ const existingMetadata = clickUpTaskAgentMetadata(task, config.routing.metadataFieldId);
11617
+ const metadata = normalizeAgentMetadataJson(existingMetadata);
11618
+ const rawSessionId = getNestedMetadataValue(metadata, config.routing.metadataKey);
11619
+ const sessionId = typeof rawSessionId === "string" && rawSessionId.startsWith("ses_") ? rawSessionId : "";
11620
+ const directory = String(getNestedMetadataValue(metadata, "task.worktree") || "").trim();
11621
+ if (sessionId) {
11622
+ try {
11623
+ const activity = await inspectOpenCodeSessionActivity(openCodeClient, { sessionId, directory });
11624
+ appendClickUpWebhookLocalLog(worktree, { type: "assignment_watchdog_session_activity", taskId, sessionId, directory: directory || null, ...activity });
11625
+ if (activity.running) {
11626
+ routed.ignored += 1;
11627
+ routed.tasks.push({ taskId, action: "ignored", ok: true, sessionId, branch: getNestedMetadataValue(metadata, "task.branch") || null, worktree: directory || null, verification: "session_running", delivered: false });
11628
+ continue;
11629
+ }
11630
+ } catch (error) {
11631
+ appendClickUpWebhookLocalLog(worktree, { type: "assignment_watchdog_session_activity_failed", taskId, sessionId, directory: directory || null, message: error.message });
11632
+ }
11633
+ }
11634
+ }
11498
11635
  try {
11499
11636
  const result = await routeClickUpWebhookEvent({
11500
- payload: { webhook_id: mutableState.webhookId || "startup", event: "taskAssigneeUpdated", task_id: taskId, task, startup_reconciliation: true },
11637
+ payload: { webhook_id: mutableState.webhookId || "startup", event: "taskAssigneeUpdated", task_id: taskId, task, startup_reconciliation: true, assignment_watchdog: watchdogMode },
11501
11638
  config,
11502
11639
  state: mutableState,
11503
11640
  worktree,
@@ -11547,12 +11684,12 @@ async function reconcileClickUpStartup({ config, state = {}, worktree = process.
11547
11684
  appendClickUpWebhookLocalLog(worktree, { type: "startup_reconciliation_task_undelivered", taskId, action: "error", sessionId: null, reason: "startup_reconciliation_task_failed" });
11548
11685
  await applyClickUpBlockerTag({ clickupClient, worktree, taskId, reason: "startup_reconciliation_task_failed", source: "startup_reconciliation_task" });
11549
11686
  }
11550
- if (!lastWebhookMs || !clickupClient?.getTaskComments) continue;
11687
+ if (!startupCommentStartMs || !clickupClient?.getTaskComments) continue;
11551
11688
  try {
11552
- const commentsResponse = await clickupClient.getTaskComments({ taskId, start: lastWebhookMs, limit: CLICKUP_WEBHOOK_STARTUP_COMMENT_LIMIT });
11689
+ const commentsResponse = await clickupClient.getTaskComments({ taskId, start: startupCommentStartMs, limit: CLICKUP_WEBHOOK_STARTUP_COMMENT_LIMIT });
11553
11690
  for (const comment of clickUpCommentListItems(commentsResponse).slice(0, CLICKUP_WEBHOOK_STARTUP_COMMENT_LIMIT)) {
11554
11691
  const commentMs = clickUpCommentUpdatedMs(comment);
11555
- if (!commentMs || commentMs <= lastWebhookMs) continue;
11692
+ if (!commentMs || commentMs <= startupCommentStartMs) continue;
11556
11693
  const authorId = clickUpCommentAuthorId(comment);
11557
11694
  if (authorId && (authorId === config.routing.ignoredCommentAuthorId || authorId === authorizedUserId)) continue;
11558
11695
  if (!clickUpCommentMentionsProductManager(comment, config.routing)) continue;
@@ -11579,11 +11716,11 @@ async function reconcileClickUpStartup({ config, state = {}, worktree = process.
11579
11716
  await applyClickUpBlockerTag({ clickupClient, worktree, taskId, reason: "startup_reconciliation_comments_failed", source: "startup_reconciliation_comments" });
11580
11717
  }
11581
11718
  }
11582
- const emptyPromptSessions = routed.tasks.filter((task) => task.delivered === false && task.sessionId);
11719
+ const emptyPromptSessions = routed.tasks.filter((task) => task.delivered === false && task.sessionId && task.verification !== "session_running");
11583
11720
  if (emptyPromptSessions.length > 0) {
11584
11721
  appendClickUpWebhookLocalLog(worktree, { type: "startup_reconciliation_validation_failed", tasks: emptyPromptSessions });
11585
11722
  }
11586
- clickUpWebhookLifecycleLog(worktree, { type: "startup_reconciliation_finished", ...routed });
11723
+ clickUpWebhookLifecycleLog(worktree, { type: watchdogMode ? "assignment_watchdog_finished" : "startup_reconciliation_finished", ...routed });
11587
11724
  return { ok: routed.errors === 0 && routed.undelivered === 0, ...routed, validation: { undelivered: routed.undelivered, emptyPromptSessions } };
11588
11725
  }
11589
11726
  function clickUpWebhookExpectedPath(config) {
@@ -11778,17 +11915,17 @@ function startClickUpWebhookListener({ config, state, worktree, clickupClient, o
11778
11915
  return result;
11779
11916
  }
11780
11917
  function legacyVariantPath(destinationPath) {
11781
- const parsed = path5.parse(destinationPath);
11918
+ const parsed = path6.parse(destinationPath);
11782
11919
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[-:TZ.]/g, "").slice(0, 14);
11783
- if (parsed.ext) return path5.join(parsed.dir, `${parsed.name}.legacy-${stamp}${parsed.ext}`);
11784
- return path5.join(parsed.dir, `${parsed.base}.legacy-${stamp}`);
11920
+ if (parsed.ext) return path6.join(parsed.dir, `${parsed.name}.legacy-${stamp}${parsed.ext}`);
11921
+ return path6.join(parsed.dir, `${parsed.base}.legacy-${stamp}`);
11785
11922
  }
11786
11923
  function normalizeWorkflowTaskPath(taskPath) {
11787
11924
  if (typeof taskPath !== "string") return { ok: false, message: "Error: task_path is required." };
11788
11925
  const trimmed = taskPath.trim();
11789
11926
  if (!trimmed) return { ok: false, message: "Error: task_path is required." };
11790
11927
  const normalized = trimmed.replace(/\\/g, "/");
11791
- if (path5.isAbsolute(trimmed)) return { ok: true, taskPath: trimmed };
11928
+ if (path6.isAbsolute(trimmed)) return { ok: true, taskPath: trimmed };
11792
11929
  if (normalized === "tasks" || normalized.startsWith("tasks/")) {
11793
11930
  return {
11794
11931
  ok: false,
@@ -11807,12 +11944,12 @@ function mergeFileIntoDestination(sourcePath, destinationPath, relativeSource, g
11807
11944
  const sourceWasTracked = isGitTracked(gitState, sourcePath);
11808
11945
  if (gitAwareMoveIfTracked(sourcePath, destinationPath, gitState)) return;
11809
11946
  if (!fs5.existsSync(destinationPath)) {
11810
- fs5.mkdirSync(path5.dirname(destinationPath), { recursive: true });
11947
+ fs5.mkdirSync(path6.dirname(destinationPath), { recursive: true });
11811
11948
  fs5.renameSync(sourcePath, destinationPath);
11812
11949
  if (sourceWasTracked) stageGitAwareMerge(sourcePath, destinationPath, gitState);
11813
11950
  return;
11814
11951
  }
11815
- const ext = path5.extname(destinationPath).toLowerCase();
11952
+ const ext = path6.extname(destinationPath).toLowerCase();
11816
11953
  if ([".yaml", ".yml", ".json"].includes(ext)) {
11817
11954
  const sourceRaw = fs5.readFileSync(sourcePath, "utf8");
11818
11955
  const destRaw = fs5.readFileSync(destinationPath, "utf8");
@@ -11847,14 +11984,14 @@ ${sourceRaw}
11847
11984
  fs5.renameSync(sourcePath, preservedPath);
11848
11985
  stageGitAwareMerge(sourcePath, preservedPath, gitState);
11849
11986
  }
11850
- function mergePathIntoDestination(sourcePath, destinationPath, relativeSource = path5.basename(sourcePath), gitState = null) {
11987
+ function mergePathIntoDestination(sourcePath, destinationPath, relativeSource = path6.basename(sourcePath), gitState = null) {
11851
11988
  if (!fs5.existsSync(sourcePath)) return;
11852
11989
  const stat = fs5.statSync(sourcePath);
11853
11990
  if (stat.isDirectory()) {
11854
11991
  const sourceWasTracked = isGitTracked(gitState, sourcePath) || hasGitTrackedChildren(gitState, sourcePath);
11855
11992
  if (gitAwareMoveIfTracked(sourcePath, destinationPath, gitState)) return;
11856
11993
  if (!fs5.existsSync(destinationPath)) {
11857
- fs5.mkdirSync(path5.dirname(destinationPath), { recursive: true });
11994
+ fs5.mkdirSync(path6.dirname(destinationPath), { recursive: true });
11858
11995
  fs5.renameSync(sourcePath, destinationPath);
11859
11996
  if (sourceWasTracked) stageGitAwareMerge(sourcePath, destinationPath, gitState);
11860
11997
  return;
@@ -11862,9 +11999,9 @@ function mergePathIntoDestination(sourcePath, destinationPath, relativeSource =
11862
11999
  fs5.mkdirSync(destinationPath, { recursive: true });
11863
12000
  for (const entry of fs5.readdirSync(sourcePath)) {
11864
12001
  mergePathIntoDestination(
11865
- path5.join(sourcePath, entry),
11866
- path5.join(destinationPath, entry),
11867
- path5.join(relativeSource, entry),
12002
+ path6.join(sourcePath, entry),
12003
+ path6.join(destinationPath, entry),
12004
+ path6.join(relativeSource, entry),
11868
12005
  gitState
11869
12006
  );
11870
12007
  }
@@ -11874,7 +12011,7 @@ function mergePathIntoDestination(sourcePath, destinationPath, relativeSource =
11874
12011
  mergeFileIntoDestination(sourcePath, destinationPath, relativeSource, gitState);
11875
12012
  }
11876
12013
  function isOptimaPluginPackageWorktree(worktree) {
11877
- const packageJsonPath = path5.join(worktree, "package.json");
12014
+ const packageJsonPath = path6.join(worktree, "package.json");
11878
12015
  if (!fs5.existsSync(packageJsonPath)) return false;
11879
12016
  try {
11880
12017
  const pkg = JSON.parse(fs5.readFileSync(packageJsonPath, "utf8"));
@@ -11886,51 +12023,51 @@ function isOptimaPluginPackageWorktree(worktree) {
11886
12023
  function migrateLegacyOptimaLayout(worktree) {
11887
12024
  const gitState = gitMigrationState(worktree);
11888
12025
  const migrations = [
11889
- [path5.join(legacyOrbitaDir(worktree), "orbita.yaml"), repoConfigPath(worktree), path5.join(".orbita", "orbita.yaml")],
11890
- [path5.join(legacyOrbitaDir(worktree), "staticeng.yaml"), repoConfigPath(worktree), path5.join(".orbita", "staticeng.yaml")],
11891
- [path5.join(legacyOrbitaDir(worktree), ".config"), optimaLocalConfigDir(worktree), path5.join(".orbita", ".config")],
11892
- [path5.join(legacyOrbitaDir(worktree), "config"), optimaLocalConfigDir(worktree), path5.join(".orbita", "config")],
11893
- [path5.join(legacyOrbitaDir(worktree), "runtime"), path5.join(optimaLocalConfigDir(worktree), "runtime"), path5.join(".orbita", "runtime")],
11894
- [path5.join(legacyOrbitaDir(worktree), "generated"), path5.join(optimaLocalConfigDir(worktree), "generated"), path5.join(".orbita", "generated")],
12026
+ [path6.join(legacyOrbitaDir(worktree), "orbita.yaml"), repoConfigPath(worktree), path6.join(".orbita", "orbita.yaml")],
12027
+ [path6.join(legacyOrbitaDir(worktree), "staticeng.yaml"), repoConfigPath(worktree), path6.join(".orbita", "staticeng.yaml")],
12028
+ [path6.join(legacyOrbitaDir(worktree), ".config"), optimaLocalConfigDir(worktree), path6.join(".orbita", ".config")],
12029
+ [path6.join(legacyOrbitaDir(worktree), "config"), optimaLocalConfigDir(worktree), path6.join(".orbita", "config")],
12030
+ [path6.join(legacyOrbitaDir(worktree), "runtime"), path6.join(optimaLocalConfigDir(worktree), "runtime"), path6.join(".orbita", "runtime")],
12031
+ [path6.join(legacyOrbitaDir(worktree), "generated"), path6.join(optimaLocalConfigDir(worktree), "generated"), path6.join(".orbita", "generated")],
11895
12032
  [legacyOrbitaDir(worktree), optimaDir(worktree), ".orbita"],
11896
- [path5.join(legacyStaticEngDir(worktree), "staticeng.yaml"), repoConfigPath(worktree), path5.join(".staticeng", "staticeng.yaml")],
11897
- [path5.join(legacyStaticEngDir(worktree), "orbita.yaml"), repoConfigPath(worktree), path5.join(".staticeng", "orbita.yaml")],
11898
- [path5.join(legacyStaticEngDir(worktree), ".config"), optimaLocalConfigDir(worktree), path5.join(".staticeng", ".config")],
11899
- [path5.join(legacyStaticEngDir(worktree), "config"), optimaLocalConfigDir(worktree), path5.join(".staticeng", "config")],
11900
- [path5.join(legacyStaticEngDir(worktree), "runtime"), path5.join(optimaLocalConfigDir(worktree), "runtime"), path5.join(".staticeng", "runtime")],
11901
- [path5.join(legacyStaticEngDir(worktree), "generated"), path5.join(optimaLocalConfigDir(worktree), "generated"), path5.join(".staticeng", "generated")],
12033
+ [path6.join(legacyStaticEngDir(worktree), "staticeng.yaml"), repoConfigPath(worktree), path6.join(".staticeng", "staticeng.yaml")],
12034
+ [path6.join(legacyStaticEngDir(worktree), "orbita.yaml"), repoConfigPath(worktree), path6.join(".staticeng", "orbita.yaml")],
12035
+ [path6.join(legacyStaticEngDir(worktree), ".config"), optimaLocalConfigDir(worktree), path6.join(".staticeng", ".config")],
12036
+ [path6.join(legacyStaticEngDir(worktree), "config"), optimaLocalConfigDir(worktree), path6.join(".staticeng", "config")],
12037
+ [path6.join(legacyStaticEngDir(worktree), "runtime"), path6.join(optimaLocalConfigDir(worktree), "runtime"), path6.join(".staticeng", "runtime")],
12038
+ [path6.join(legacyStaticEngDir(worktree), "generated"), path6.join(optimaLocalConfigDir(worktree), "generated"), path6.join(".staticeng", "generated")],
11902
12039
  [legacyStaticEngDir(worktree), optimaDir(worktree), ".staticeng"],
11903
- [path5.join(legacyNomadworkDir(worktree), "nomadworks.yaml"), repoConfigPath(worktree), path5.join(".nomadwork", "nomadworks.yaml")],
11904
- [path5.join(legacyNomadworksDir(worktree), "nomadworks.yaml"), repoConfigPath(worktree), path5.join(".nomadworks", "nomadworks.yaml")],
11905
- [path5.join(legacyNomadworkDir(worktree), "staticeng.yaml"), repoConfigPath(worktree), path5.join(".nomadwork", "staticeng.yaml")],
11906
- [path5.join(legacyNomadworksDir(worktree), "staticeng.yaml"), repoConfigPath(worktree), path5.join(".nomadworks", "staticeng.yaml")],
11907
- [path5.join(legacyNomadworkDir(worktree), "orbita.yaml"), repoConfigPath(worktree), path5.join(".nomadwork", "orbita.yaml")],
11908
- [path5.join(legacyNomadworksDir(worktree), "orbita.yaml"), repoConfigPath(worktree), path5.join(".nomadworks", "orbita.yaml")],
11909
- [path5.join(legacyNomadworkDir(worktree), "runtime"), path5.join(optimaLocalConfigDir(worktree), "runtime"), path5.join(".nomadwork", "runtime")],
11910
- [path5.join(legacyNomadworksDir(worktree), "runtime"), path5.join(optimaLocalConfigDir(worktree), "runtime"), path5.join(".nomadworks", "runtime")],
11911
- [path5.join(legacyNomadworkDir(worktree), "generated"), path5.join(optimaLocalConfigDir(worktree), "generated"), path5.join(".nomadwork", "generated")],
11912
- [path5.join(legacyNomadworksDir(worktree), "generated"), path5.join(optimaLocalConfigDir(worktree), "generated"), path5.join(".nomadworks", "generated")],
11913
- [path5.join(legacyNomadworkDir(worktree), "config"), optimaLocalConfigDir(worktree), path5.join(".nomadwork", "config")],
11914
- [path5.join(legacyNomadworksDir(worktree), "config"), optimaLocalConfigDir(worktree), path5.join(".nomadworks", "config")],
12040
+ [path6.join(legacyNomadworkDir(worktree), "nomadworks.yaml"), repoConfigPath(worktree), path6.join(".nomadwork", "nomadworks.yaml")],
12041
+ [path6.join(legacyNomadworksDir(worktree), "nomadworks.yaml"), repoConfigPath(worktree), path6.join(".nomadworks", "nomadworks.yaml")],
12042
+ [path6.join(legacyNomadworkDir(worktree), "staticeng.yaml"), repoConfigPath(worktree), path6.join(".nomadwork", "staticeng.yaml")],
12043
+ [path6.join(legacyNomadworksDir(worktree), "staticeng.yaml"), repoConfigPath(worktree), path6.join(".nomadworks", "staticeng.yaml")],
12044
+ [path6.join(legacyNomadworkDir(worktree), "orbita.yaml"), repoConfigPath(worktree), path6.join(".nomadwork", "orbita.yaml")],
12045
+ [path6.join(legacyNomadworksDir(worktree), "orbita.yaml"), repoConfigPath(worktree), path6.join(".nomadworks", "orbita.yaml")],
12046
+ [path6.join(legacyNomadworkDir(worktree), "runtime"), path6.join(optimaLocalConfigDir(worktree), "runtime"), path6.join(".nomadwork", "runtime")],
12047
+ [path6.join(legacyNomadworksDir(worktree), "runtime"), path6.join(optimaLocalConfigDir(worktree), "runtime"), path6.join(".nomadworks", "runtime")],
12048
+ [path6.join(legacyNomadworkDir(worktree), "generated"), path6.join(optimaLocalConfigDir(worktree), "generated"), path6.join(".nomadwork", "generated")],
12049
+ [path6.join(legacyNomadworksDir(worktree), "generated"), path6.join(optimaLocalConfigDir(worktree), "generated"), path6.join(".nomadworks", "generated")],
12050
+ [path6.join(legacyNomadworkDir(worktree), "config"), optimaLocalConfigDir(worktree), path6.join(".nomadwork", "config")],
12051
+ [path6.join(legacyNomadworksDir(worktree), "config"), optimaLocalConfigDir(worktree), path6.join(".nomadworks", "config")],
11915
12052
  [legacyNomadworkDir(worktree), optimaDir(worktree), ".nomadwork"],
11916
12053
  [legacyNomadworksDir(worktree), optimaDir(worktree), ".nomadworks"],
11917
- [path5.join(worktree, "tasks"), optimaTasksDir(worktree), "tasks"],
11918
- [path5.join(worktree, "evidences"), optimaEvidencesDir(worktree), "evidences"],
11919
- [path5.join(worktree, "docs", "scrs"), optimaScrsDir(worktree), path5.join("docs", "scrs")],
11920
- [path5.join(worktree, "codemap.yml"), optimaCodemapPath(worktree), "codemap.yml"],
11921
- [path5.join(worktree, "codemap.yaml"), optimaCodemapPath(worktree), "codemap.yaml"]
12054
+ [path6.join(worktree, "tasks"), optimaTasksDir(worktree), "tasks"],
12055
+ [path6.join(worktree, "evidences"), optimaEvidencesDir(worktree), "evidences"],
12056
+ [path6.join(worktree, "docs", "scrs"), optimaScrsDir(worktree), path6.join("docs", "scrs")],
12057
+ [path6.join(worktree, "codemap.yml"), optimaCodemapPath(worktree), "codemap.yml"],
12058
+ [path6.join(worktree, "codemap.yaml"), optimaCodemapPath(worktree), "codemap.yaml"]
11922
12059
  ];
11923
12060
  if (!isOptimaPluginPackageWorktree(worktree)) {
11924
- migrations.push([path5.join(worktree, "policies"), repoPoliciesDir(worktree), "policies"]);
12061
+ migrations.push([path6.join(worktree, "policies"), repoPoliciesDir(worktree), "policies"]);
11925
12062
  }
11926
12063
  for (const [source, destination, relativeSource] of migrations) {
11927
12064
  if (fs5.existsSync(source)) mergePathIntoDestination(source, destination, relativeSource, gitState);
11928
12065
  }
11929
12066
  for (const [source, destination, relativeSource] of [
11930
- [path5.join(optimaDir(worktree), "optima.yaml"), repoConfigPath(worktree), path5.join(".optima", "optima.yaml")],
11931
- [path5.join(optimaDir(worktree), "config"), optimaLocalConfigDir(worktree), path5.join(".optima", "config")],
11932
- [path5.join(optimaDir(worktree), "runtime"), path5.join(optimaLocalConfigDir(worktree), "runtime"), path5.join(".optima", "runtime")],
11933
- [path5.join(optimaDir(worktree), "generated"), path5.join(optimaLocalConfigDir(worktree), "generated"), path5.join(".optima", "generated")]
12067
+ [path6.join(optimaDir(worktree), "optima.yaml"), repoConfigPath(worktree), path6.join(".optima", "optima.yaml")],
12068
+ [path6.join(optimaDir(worktree), "config"), optimaLocalConfigDir(worktree), path6.join(".optima", "config")],
12069
+ [path6.join(optimaDir(worktree), "runtime"), path6.join(optimaLocalConfigDir(worktree), "runtime"), path6.join(".optima", "runtime")],
12070
+ [path6.join(optimaDir(worktree), "generated"), path6.join(optimaLocalConfigDir(worktree), "generated"), path6.join(".optima", "generated")]
11934
12071
  ]) {
11935
12072
  if (fs5.existsSync(source)) mergePathIntoDestination(source, destination, relativeSource, gitState);
11936
12073
  }
@@ -11979,7 +12116,7 @@ function toModelString(provider, model) {
11979
12116
  }
11980
12117
  function readTaskMetadata(taskPath, worktree) {
11981
12118
  if (!taskPath) return {};
11982
- const absoluteTaskPath = path5.isAbsolute(taskPath) ? taskPath : path5.join(worktree, taskPath);
12119
+ const absoluteTaskPath = path6.isAbsolute(taskPath) ? taskPath : path6.join(worktree, taskPath);
11983
12120
  if (!fs5.existsSync(absoluteTaskPath)) return {};
11984
12121
  try {
11985
12122
  const raw = fs5.readFileSync(absoluteTaskPath, "utf8");
@@ -12024,18 +12161,18 @@ function loadDiscussionRegistry(worktree) {
12024
12161
  }
12025
12162
  function saveDiscussionRegistry(worktree, registry) {
12026
12163
  const registryPath = runtimeDiscussionRegistryPath(worktree);
12027
- const runtimeDir = path5.dirname(registryPath);
12164
+ const runtimeDir = path6.dirname(registryPath);
12028
12165
  if (!fs5.existsSync(runtimeDir)) fs5.mkdirSync(runtimeDir, { recursive: true });
12029
12166
  fs5.writeFileSync(registryPath, JSON.stringify(registry, null, 2), "utf8");
12030
12167
  }
12031
12168
  function runtimeDiscussionsDir(worktree) {
12032
- return path5.join(optimaLocalConfigDir(worktree), "runtime", "discussions");
12169
+ return path6.join(optimaLocalConfigDir(worktree), "runtime", "discussions");
12033
12170
  }
12034
12171
  function archivedRuntimeDiscussionsDir(worktree) {
12035
- return path5.join(runtimeDiscussionsDir(worktree), "archive");
12172
+ return path6.join(runtimeDiscussionsDir(worktree), "archive");
12036
12173
  }
12037
12174
  function finalDiscussionsDir(worktree) {
12038
- return path5.join(optimaTasksDir(worktree), "discussions");
12175
+ return path6.join(optimaTasksDir(worktree), "discussions");
12039
12176
  }
12040
12177
  function nextDiscussionIdentity(worktree, title) {
12041
12178
  const discussionsDir = finalDiscussionsDir(worktree);
@@ -12046,11 +12183,11 @@ function nextDiscussionIdentity(worktree, title) {
12046
12183
  while (true) {
12047
12184
  const id = `DISCUSSION-${String(sequence).padStart(3, "0")}`;
12048
12185
  const filename = `${id}-${slugifyTitle(title)}.md`;
12049
- const summaryRelativePath = path5.join(".optima", "tasks", "discussions", filename);
12050
- const summaryAbsolutePath = path5.join(worktree, summaryRelativePath);
12186
+ const summaryRelativePath = path6.join(".optima", "tasks", "discussions", filename);
12187
+ const summaryAbsolutePath = path6.join(worktree, summaryRelativePath);
12051
12188
  const transcriptFilename = `${id}-transcript.md`;
12052
- const transcriptRelativePath = path5.join(".optima", ".config", "runtime", "discussions", transcriptFilename);
12053
- const transcriptAbsolutePath = path5.join(worktree, transcriptRelativePath);
12189
+ const transcriptRelativePath = path6.join(".optima", ".config", "runtime", "discussions", transcriptFilename);
12190
+ const transcriptAbsolutePath = path6.join(worktree, transcriptRelativePath);
12054
12191
  if (!fs5.existsSync(summaryAbsolutePath) && !fs5.existsSync(transcriptAbsolutePath)) {
12055
12192
  return {
12056
12193
  id,
@@ -12075,11 +12212,11 @@ function findDiscussionById(worktree, discussionID) {
12075
12212
  return {
12076
12213
  id: discussionID,
12077
12214
  filename,
12078
- summaryRelativePath: path5.join(".optima", "tasks", "discussions", filename),
12079
- summaryAbsolutePath: path5.join(discussionsDir, filename),
12215
+ summaryRelativePath: path6.join(".optima", "tasks", "discussions", filename),
12216
+ summaryAbsolutePath: path6.join(discussionsDir, filename),
12080
12217
  transcriptFilename,
12081
- transcriptRelativePath: path5.join(".optima", ".config", "runtime", "discussions", transcriptFilename),
12082
- transcriptAbsolutePath: path5.join(runtimeDiscussionsDir(worktree), transcriptFilename)
12218
+ transcriptRelativePath: path6.join(".optima", ".config", "runtime", "discussions", transcriptFilename),
12219
+ transcriptAbsolutePath: path6.join(runtimeDiscussionsDir(worktree), transcriptFilename)
12083
12220
  };
12084
12221
  }
12085
12222
  function parseDiscussionFile(filePath) {
@@ -12162,15 +12299,15 @@ async function appendMessageIfNeeded(client, worktree, registry, sessionID, mess
12162
12299
  });
12163
12300
  const text = extractTextParts(response.data.parts || []);
12164
12301
  if (!text) return;
12165
- appendDiscussionMessage(path5.join(worktree, discussion.transcriptPath), speaker, text, messageID);
12302
+ appendDiscussionMessage(path6.join(worktree, discussion.transcriptPath), speaker, text, messageID);
12166
12303
  discussion.appendedMessageIDs ??= [];
12167
12304
  discussion.appendedMessageIDs.push(messageID);
12168
12305
  saveDiscussionRegistry(worktree, registry);
12169
12306
  }
12170
12307
  async function summarizeDiscussionWithBA(client, worktree, discussion) {
12171
- const transcriptPath = path5.join(worktree, discussion.transcriptPath);
12172
- const summaryPath = path5.join(worktree, discussion.summaryPath);
12173
- const summaryDir = path5.dirname(summaryPath);
12308
+ const transcriptPath = path6.join(worktree, discussion.transcriptPath);
12309
+ const summaryPath = path6.join(worktree, discussion.summaryPath);
12310
+ const summaryDir = path6.dirname(summaryPath);
12174
12311
  if (!fs5.existsSync(summaryDir)) fs5.mkdirSync(summaryDir, { recursive: true });
12175
12312
  const hasExistingSummary = fs5.existsSync(summaryPath);
12176
12313
  const priorMtimeMs = hasExistingSummary ? fs5.statSync(summaryPath).mtimeMs : null;
@@ -12273,11 +12410,11 @@ async function summarizeDiscussionWithBA(client, worktree, discussion) {
12273
12410
  return { confirmation, summaryPath, transcriptPath, hasExistingSummary, priorMtimeMs };
12274
12411
  }
12275
12412
  function archiveDiscussionTranscript(worktree, transcriptRelativePath) {
12276
- const sourcePath = path5.join(worktree, transcriptRelativePath);
12413
+ const sourcePath = path6.join(worktree, transcriptRelativePath);
12277
12414
  if (!fs5.existsSync(sourcePath)) return null;
12278
12415
  const archiveDir = archivedRuntimeDiscussionsDir(worktree);
12279
12416
  if (!fs5.existsSync(archiveDir)) fs5.mkdirSync(archiveDir, { recursive: true });
12280
- const targetPath = path5.join(archiveDir, path5.basename(sourcePath));
12417
+ const targetPath = path6.join(archiveDir, path6.basename(sourcePath));
12281
12418
  fs5.renameSync(sourcePath, targetPath);
12282
12419
  return targetPath;
12283
12420
  }
@@ -12296,7 +12433,7 @@ async function finalizeClosingDiscussion(client, worktree, registry, sessionID,
12296
12433
  if (!summaryContent) {
12297
12434
  throw new Error(`Discussion summary file is empty at ${discussion.summaryPath}`);
12298
12435
  }
12299
- const transcriptPath = path5.join(worktree, discussion.transcriptPath);
12436
+ const transcriptPath = path6.join(worktree, discussion.transcriptPath);
12300
12437
  setDiscussionStatus(transcriptPath, "closed");
12301
12438
  const archivedTranscriptPath = archiveDiscussionTranscript(worktree, discussion.transcriptPath);
12302
12439
  delete registry.active[sessionID];
@@ -12304,7 +12441,7 @@ async function finalizeClosingDiscussion(client, worktree, registry, sessionID,
12304
12441
  return {
12305
12442
  confirmation,
12306
12443
  summaryPath: discussion.summaryPath,
12307
- archivedTranscriptPath: archivedTranscriptPath ? path5.relative(worktree, archivedTranscriptPath) : path5.join(".optima", ".config", "runtime", "discussions", "archive", path5.basename(discussion.transcriptPath))
12444
+ archivedTranscriptPath: archivedTranscriptPath ? path6.relative(worktree, archivedTranscriptPath) : path6.join(".optima", ".config", "runtime", "discussions", "archive", path6.basename(discussion.transcriptPath))
12308
12445
  };
12309
12446
  }
12310
12447
  function normalizeTeamMode(value) {
@@ -12376,7 +12513,7 @@ function syncGeneratedPolicies(worktree, repoCfg) {
12376
12513
  if (!fs5.existsSync(generatedDir)) fs5.mkdirSync(generatedDir, { recursive: true });
12377
12514
  const policyFiles = fs5.readdirSync(BUNDLE_POLICIES_DIR).filter((file) => file.endsWith(".md") && file !== "README.md");
12378
12515
  for (const file of policyFiles) {
12379
- const sourcePath = path5.join(BUNDLE_POLICIES_DIR, file);
12516
+ const sourcePath = path6.join(BUNDLE_POLICIES_DIR, file);
12380
12517
  const source = fs5.readFileSync(sourcePath, "utf8").trimEnd();
12381
12518
  const generated = [
12382
12519
  "<!--",
@@ -12388,18 +12525,18 @@ function syncGeneratedPolicies(worktree, repoCfg) {
12388
12525
  source,
12389
12526
  ""
12390
12527
  ].join("\n");
12391
- fs5.writeFileSync(path5.join(generatedDir, file), generated, "utf8");
12528
+ fs5.writeFileSync(path6.join(generatedDir, file), generated, "utf8");
12392
12529
  }
12393
12530
  }
12394
12531
  function ensureReadmeFile(dirPath, content) {
12395
12532
  if (!fs5.existsSync(dirPath)) fs5.mkdirSync(dirPath, { recursive: true });
12396
- const readmePath = path5.join(dirPath, "README.md");
12533
+ const readmePath = path6.join(dirPath, "README.md");
12397
12534
  if (!fs5.existsSync(readmePath)) {
12398
12535
  fs5.writeFileSync(readmePath, content, "utf8");
12399
12536
  }
12400
12537
  }
12401
12538
  function ensureFileIfMissing(filePath, content) {
12402
- if (!fs5.existsSync(path5.dirname(filePath))) fs5.mkdirSync(path5.dirname(filePath), { recursive: true });
12539
+ if (!fs5.existsSync(path6.dirname(filePath))) fs5.mkdirSync(path6.dirname(filePath), { recursive: true });
12403
12540
  if (!fs5.existsSync(filePath)) fs5.writeFileSync(filePath, content, "utf8");
12404
12541
  }
12405
12542
  function currentTasksRegistryContent() {
@@ -12486,13 +12623,13 @@ Never place implementation evidence under root \`evidences/\`.
12486
12623
  }
12487
12624
  function ensureOptimaTaskTemplates(worktree) {
12488
12625
  const tasksDir = optimaTasksDir(worktree);
12489
- ensureFileIfMissing(path5.join(tasksDir, "task-template.md"), taskTemplateContent());
12490
- ensureFileIfMissing(path5.join(tasksDir, "subtask-template.md"), subtaskTemplateContent());
12626
+ ensureFileIfMissing(path6.join(tasksDir, "task-template.md"), taskTemplateContent());
12627
+ ensureFileIfMissing(path6.join(tasksDir, "subtask-template.md"), subtaskTemplateContent());
12491
12628
  }
12492
12629
  function scaffoldOptimaConfig(worktree, teamMode = "full") {
12493
12630
  const configPath = repoConfigPath(worktree);
12494
12631
  if (fs5.existsSync(configPath)) return false;
12495
- const templatePath = path5.join(TEMPLATES_DIR, "optima.yaml.template");
12632
+ const templatePath = path6.join(TEMPLATES_DIR, "optima.yaml.template");
12496
12633
  if (!fs5.existsSync(templatePath)) return false;
12497
12634
  const agentIds = fs5.existsSync(BUNDLE_AGENTS_DIR) ? fs5.readdirSync(BUNDLE_AGENTS_DIR).filter((f) => f.endsWith(".md")).map((f) => f.replace(".md", "")) : [];
12498
12635
  let optimaConfig = fs5.readFileSync(templatePath, "utf8");
@@ -12511,9 +12648,9 @@ function scaffoldOptimaConfig(worktree, teamMode = "full") {
12511
12648
  function scaffoldOptimaRootCodemap(worktree) {
12512
12649
  const rootCodemapPath = optimaCodemapPath(worktree);
12513
12650
  if (fs5.existsSync(rootCodemapPath)) return false;
12514
- const templatePath = path5.join(TEMPLATES_DIR, "codemap.yml.template");
12651
+ const templatePath = path6.join(TEMPLATES_DIR, "codemap.yml.template");
12515
12652
  if (!fs5.existsSync(templatePath)) return false;
12516
- const codemapConfig = fs5.readFileSync(templatePath, "utf8").replace("{{projectName}}", path5.basename(worktree));
12653
+ const codemapConfig = fs5.readFileSync(templatePath, "utf8").replace("{{projectName}}", path6.basename(worktree));
12517
12654
  ensureFileIfMissing(rootCodemapPath, codemapConfig);
12518
12655
  return fs5.existsSync(rootCodemapPath);
12519
12656
  }
@@ -12522,10 +12659,10 @@ function ensureOptimaRegistries(worktree) {
12522
12659
  const scrsDir = optimaScrsDir(worktree);
12523
12660
  if (!fs5.existsSync(tasksDir)) fs5.mkdirSync(tasksDir, { recursive: true });
12524
12661
  if (!fs5.existsSync(scrsDir)) fs5.mkdirSync(scrsDir, { recursive: true });
12525
- ensureFileIfMissing(path5.join(tasksDir, "current.md"), currentTasksRegistryContent());
12526
- ensureFileIfMissing(path5.join(tasksDir, "done.md"), doneTasksRegistryContent());
12527
- ensureFileIfMissing(path5.join(scrsDir, "current.md"), currentScrRegistryContent());
12528
- ensureFileIfMissing(path5.join(scrsDir, "done.md"), doneScrRegistryContent());
12662
+ ensureFileIfMissing(path6.join(tasksDir, "current.md"), currentTasksRegistryContent());
12663
+ ensureFileIfMissing(path6.join(tasksDir, "done.md"), doneTasksRegistryContent());
12664
+ ensureFileIfMissing(path6.join(scrsDir, "current.md"), currentScrRegistryContent());
12665
+ ensureFileIfMissing(path6.join(scrsDir, "done.md"), doneScrRegistryContent());
12529
12666
  }
12530
12667
  function scaffoldOptimaReadmes(worktree) {
12531
12668
  ensureReadmeFile(repoPoliciesDir(worktree), REPO_LOCAL_POLICIES_README);
@@ -12687,12 +12824,12 @@ function shouldRegisterWorkflowProductManager(options = {}, worktree = process.c
12687
12824
  }
12688
12825
  function isClickUpDerivedWorktreeSibling(candidate, basePath) {
12689
12826
  if (typeof candidate !== "string" || typeof basePath !== "string" || !candidate.trim() || !basePath.trim()) return false;
12690
- const resolvedCandidate = path5.resolve(candidate);
12691
- const resolvedBase = path5.resolve(basePath);
12692
- const baseParent = path5.dirname(resolvedBase);
12693
- if (path5.dirname(resolvedCandidate) !== baseParent) return false;
12694
- const baseName = path5.basename(resolvedBase);
12695
- const candidateName = path5.basename(resolvedCandidate);
12827
+ const resolvedCandidate = path6.resolve(candidate);
12828
+ const resolvedBase = path6.resolve(basePath);
12829
+ const baseParent = path6.dirname(resolvedBase);
12830
+ if (path6.dirname(resolvedCandidate) !== baseParent) return false;
12831
+ const baseName = path6.basename(resolvedBase);
12832
+ const candidateName = path6.basename(resolvedCandidate);
12696
12833
  if (!candidateName.startsWith(`${baseName}-`)) return false;
12697
12834
  const branchSlug = candidateName.slice(baseName.length + 1);
12698
12835
  const parts = branchSlug.split("-").filter(Boolean);
@@ -12704,7 +12841,7 @@ function isClickUpDerivedWorktreeSibling(candidate, basePath) {
12704
12841
  if (!candidateStat.isDirectory() || candidateStat.isSymbolicLink()) return false;
12705
12842
  const realCandidate = fs5.realpathSync.native(resolvedCandidate);
12706
12843
  const realBaseParent = fs5.realpathSync.native(baseParent);
12707
- return path5.dirname(realCandidate) === realBaseParent && path5.basename(realCandidate) === candidateName;
12844
+ return path6.dirname(realCandidate) === realBaseParent && path6.basename(realCandidate) === candidateName;
12708
12845
  } catch {
12709
12846
  return false;
12710
12847
  }
@@ -12712,15 +12849,15 @@ function isClickUpDerivedWorktreeSibling(candidate, basePath) {
12712
12849
  function resolveSessionToolDirectory({ requestedDirectory, context, pluginWorktree, clickUpWebhookValidation } = {}) {
12713
12850
  const safe = safeWorktreeOrFailure(context, pluginWorktree);
12714
12851
  if (!safe.ok) return { ok: false, error: safe.message };
12715
- const requested = String(requestedDirectory || "").trim() ? path5.resolve(safe.worktree, String(requestedDirectory).trim()) : safe.worktree;
12852
+ const requested = String(requestedDirectory || "").trim() ? path6.resolve(safe.worktree, String(requestedDirectory).trim()) : safe.worktree;
12716
12853
  if (!isSafeWritableDirectory(requested)) return { ok: false, error: `Directory is not a safe writable directory: ${requested}` };
12717
12854
  if (isSameOrNestedPath(requested, safe.worktree)) return { ok: true, directory: requested, safeWorktree: safe.worktree, scope: "context_worktree" };
12718
12855
  const clickUpBasePath = clickUpWebhookValidation?.complete === true && clickUpWebhookValidation?.ok !== false ? clickUpWebhookValidation.config?.basePath : "";
12719
12856
  if (clickUpBasePath && isSameOrNestedPath(requested, clickUpBasePath)) {
12720
- return { ok: true, directory: requested, safeWorktree: safe.worktree, scope: "clickup_base_path", clickupBasePath: path5.resolve(clickUpBasePath) };
12857
+ return { ok: true, directory: requested, safeWorktree: safe.worktree, scope: "clickup_base_path", clickupBasePath: path6.resolve(clickUpBasePath) };
12721
12858
  }
12722
12859
  if (clickUpBasePath && isClickUpDerivedWorktreeSibling(requested, clickUpBasePath)) {
12723
- return { ok: true, directory: requested, safeWorktree: safe.worktree, scope: "clickup_derived_worktree", clickupBasePath: path5.resolve(clickUpBasePath) };
12860
+ return { ok: true, directory: requested, safeWorktree: safe.worktree, scope: "clickup_derived_worktree", clickupBasePath: path6.resolve(clickUpBasePath) };
12724
12861
  }
12725
12862
  return {
12726
12863
  ok: false,
@@ -12754,8 +12891,8 @@ function buildOptimaAgents(repoCfg, operatingTeamMode, worktree, debugDir, optio
12754
12891
  if (!enabled) continue;
12755
12892
  }
12756
12893
  const promptOptions = { preferCompactPromptDocs: repoCfg.features?.compact_prompt_docs !== false };
12757
- const bundledDefinition = loadAgentDefinition(path5.join(BUNDLE_AGENTS_DIR, file), worktree, promptOptions);
12758
- const repoDefinition = loadAgentDefinition(path5.join(repoAgentDefinitions, file), worktree, promptOptions) || loadAgentDefinition(path5.join(legacyAgentsDir, file), worktree, promptOptions);
12894
+ const bundledDefinition = loadAgentDefinition(path6.join(BUNDLE_AGENTS_DIR, file), worktree, promptOptions);
12895
+ const repoDefinition = loadAgentDefinition(path6.join(repoAgentDefinitions, file), worktree, promptOptions) || loadAgentDefinition(path6.join(legacyAgentsDir, file), worktree, promptOptions);
12759
12896
  const activeDefinition = repoDefinition || bundledDefinition;
12760
12897
  if (!activeDefinition) continue;
12761
12898
  const { data } = activeDefinition;
@@ -12764,7 +12901,7 @@ function buildOptimaAgents(repoCfg, operatingTeamMode, worktree, debugDir, optio
12764
12901
  if (modePromptFragment) finalPrompt = `${finalPrompt}
12765
12902
 
12766
12903
  ${modePromptFragment}`;
12767
- const additionFragment = loadMarkdownFragment(path5.join(repoAgentAdditions, file), worktree);
12904
+ const additionFragment = loadMarkdownFragment(path6.join(repoAgentAdditions, file), worktree);
12768
12905
  if (additionFragment) {
12769
12906
  finalPrompt = `${finalPrompt}
12770
12907
 
@@ -12817,7 +12954,7 @@ Use this Optima-provided fallback when the current task worktree lacks docs/core
12817
12954
  }
12818
12955
  ourAgents[id] = agentConfig;
12819
12956
  if (repoCfg.features?.debug_dumps !== false) {
12820
- const debugPath = path5.join(debugDir, `${id}.md`);
12957
+ const debugPath = path6.join(debugDir, `${id}.md`);
12821
12958
  const { prompt, ...dumpConfig } = agentConfig;
12822
12959
  const debugHeader = `---
12823
12960
  ${import_yaml3.default.stringify(dumpConfig).trim()}
@@ -12897,7 +13034,17 @@ async function OptimaPlugin(input = {}, pluginOptions = {}) {
12897
13034
  ...listenerState,
12898
13035
  listener: { bindHost: clickUpWebhookValidation.config.webhook.bindHost, bindPort: clickUpWebhookValidation.config.webhook.bindPort, startedAt: (/* @__PURE__ */ new Date()).toISOString() }
12899
13036
  }, clickUpWebhookValidation.config);
12900
- registerClickUpWebhookLifecycle({ config: clickUpWebhookValidation.config, state: activeState, worktree, clickupClient: lifecycleClickUpClient, listener: readyListener, listenerRegistry });
13037
+ const assignmentWatchdog = scheduleClickUpAssignmentWatchdog({
13038
+ config: clickUpWebhookValidation.config,
13039
+ state: activeState,
13040
+ worktree,
13041
+ clickupClient: lifecycleClickUpClient,
13042
+ openCodeClient: input.client,
13043
+ scheduler: input.assignmentWatchdogScheduler,
13044
+ intervalMs: input.assignmentWatchdogIntervalMs,
13045
+ saveState: (nextState) => writeClickUpWebhookState(worktree, nextState, clickUpWebhookValidation.config)
13046
+ });
13047
+ registerClickUpWebhookLifecycle({ config: clickUpWebhookValidation.config, state: activeState, worktree, clickupClient: lifecycleClickUpClient, listener: readyListener, listenerRegistry, assignmentWatchdog });
12901
13048
  scheduleClickUpStartupReconciliation({
12902
13049
  config: clickUpWebhookValidation.config,
12903
13050
  state: activeState,
@@ -12959,8 +13106,8 @@ async function OptimaPlugin(input = {}, pluginOptions = {}) {
12959
13106
  migrateLegacyOptimaLayout(toolWorktree);
12960
13107
  const cfgDir = optimaConfigDir(toolWorktree);
12961
13108
  if (!fs5.existsSync(cfgDir)) fs5.mkdirSync(cfgDir, { recursive: true });
12962
- const optimaTmplPath = path5.join(TEMPLATES_DIR, "optima.yaml.template");
12963
- const codemapTmplPath = path5.join(TEMPLATES_DIR, "codemap.yml.template");
13109
+ const optimaTmplPath = path6.join(TEMPLATES_DIR, "optima.yaml.template");
13110
+ const codemapTmplPath = path6.join(TEMPLATES_DIR, "codemap.yml.template");
12964
13111
  if (!fs5.existsSync(optimaTmplPath) || !fs5.existsSync(codemapTmplPath)) {
12965
13112
  return "Error: Initialization templates not found in plugin.";
12966
13113
  }
@@ -13082,14 +13229,14 @@ Restart or reload OpenCode manually if the newly scaffolded config or agents are
13082
13229
  async execute(args, context) {
13083
13230
  const safe = safeWorktreeOrFailure(context, worktree);
13084
13231
  if (!safe.ok) return safe.message;
13085
- const summaryPath = path5.resolve(safe.worktree, args.summary_path || "");
13232
+ const summaryPath = path6.resolve(safe.worktree, args.summary_path || "");
13086
13233
  if (!fs5.existsSync(summaryPath)) return `FAIL: summary_path not found: ${summaryPath}`;
13087
- const taskPath = args.task_path ? path5.resolve(safe.worktree, args.task_path) : "";
13234
+ const taskPath = args.task_path ? path6.resolve(safe.worktree, args.task_path) : "";
13088
13235
  const payload = buildClickUpSummaryPayload({
13089
13236
  summaryMarkdown: fs5.readFileSync(summaryPath, "utf8"),
13090
- summaryPath: path5.relative(safe.worktree, summaryPath),
13237
+ summaryPath: path6.relative(safe.worktree, summaryPath),
13091
13238
  taskMarkdown: taskPath && fs5.existsSync(taskPath) ? fs5.readFileSync(taskPath, "utf8") : "",
13092
- taskPath: taskPath ? path5.relative(safe.worktree, taskPath) : "",
13239
+ taskPath: taskPath ? path6.relative(safe.worktree, taskPath) : "",
13093
13240
  branch: args.branch,
13094
13241
  worktree: args.worktree,
13095
13242
  pr: args.pr
@@ -13168,12 +13315,12 @@ Restart or reload OpenCode manually if the newly scaffolded config or agents are
13168
13315
  async execute(args, context) {
13169
13316
  const safe = safeWorktreeOrFailure(context, worktree);
13170
13317
  if (!safe.ok) return safe.message;
13171
- const markdownPath = path5.resolve(safe.worktree, args.markdown_path || "");
13318
+ const markdownPath = path6.resolve(safe.worktree, args.markdown_path || "");
13172
13319
  if (!fs5.existsSync(markdownPath)) return `FAIL: markdown_path not found: ${markdownPath}`;
13173
13320
  const payload = buildClickUpCreateSubtasksPayload({
13174
13321
  parentTaskId: args.parent_task_id,
13175
13322
  markdown: fs5.readFileSync(markdownPath, "utf8"),
13176
- sourcePath: path5.relative(safe.worktree, markdownPath),
13323
+ sourcePath: path6.relative(safe.worktree, markdownPath),
13177
13324
  parentBranch: args.parent_branch,
13178
13325
  parentTaskType: args.parent_task_type || "Tarea",
13179
13326
  apply: String(args.apply || "").toLowerCase() === "true"
@@ -13372,7 +13519,7 @@ Backfilled messages: ${backfilled}`;
13372
13519
  if (!existing) {
13373
13520
  return "FAIL: No active discussion exists for this session.";
13374
13521
  }
13375
- const discussionPath = path5.join(toolWorktree, existing.transcriptPath);
13522
+ const discussionPath = path6.join(toolWorktree, existing.transcriptPath);
13376
13523
  setDiscussionStatus(discussionPath, "summarizing");
13377
13524
  existing.status = "summarizing";
13378
13525
  saveDiscussionRegistry(toolWorktree, toolRegistry);
@@ -13424,7 +13571,7 @@ Reason: ${err.message}`;
13424
13571
  try {
13425
13572
  const sessionResult = await client.session.create({
13426
13573
  query: { directory: workflowDirectory },
13427
- body: { title: `Workflow Run: ${path5.basename(workflowTaskPath)}` }
13574
+ body: { title: `Workflow Run: ${path6.basename(workflowTaskPath)}` }
13428
13575
  });
13429
13576
  const sessionId = sessionResult.data.id;
13430
13577
  activeWorkflows.set(sessionId, { pmaSessionId, taskPath: workflowTaskPath, track: workflowTrack, directory: workflowDirectory });
@@ -13553,7 +13700,7 @@ Follow-up: use optima_prompt_workflow with session_id '${sessionId}' to check in
13553
13700
  }
13554
13701
  };
13555
13702
  }
13556
- OptimaPlugin.__internals = { BUNDLE_AGENTS_DIR, BUNDLE_ASSETS_DIR, CLICKUP_DEFINITION_DOC_PARENT, activeClickUpWebhookLifecycleRegistry, cleanupManagedClickUpWebhook, deleteClickUpWebhookBestEffort, BUNDLE_POLICIES_DIR, buildClickUpApplyPayloadResult, buildClickUpCreateSubtasksPayload, buildClickUpStartTaskPayload, buildClickUpSummaryPayload, buildClickUpTransitionPayload, buildOptimaAgents, clickUpCommentLedgerKey, clickUpCommentMentionsProductManager, clickUpWebhookAuditLogDir, clickUpWebhookAuditLogPath, compactPromptPath, createClickUpApiClient, createTestClickUpApiClient, createOpenCodeSession, createOpenCodeSessionControl, deliveryEvidencePathForClickUpTask, ensureClickUpTaskWorktree, ensureClickUpTaskWorktreeForWebhook, ensureClickUpTaskWorktreeOpenChamber, ensureClickUpWebhookSubscription, handleClickUpWebhookRequest, isClickUpDerivedWorktreeSibling, isClickUpSubtaskRoute, isClickUpWebhookStateActive, isSameOrNestedPath, normalizeClickUpWebhookConfig, normalizeClickUpWebhookLogLevel, normalizeOpenCodeBaseUrl, openCodeSessionExists, promptOpenCodeSessionControl, probeOpenCodeSessionControl, readClickUpCommentLedger, readClickUpWebhookState, readOpenCodeSessionControl, readOpenCodeSessionMessages, reconcileClickUpStartup, registerOpenChamberClickUpWorktree, scheduleClickUpStartupReconciliation, syncOpenChamberWorktreeVisibility, waitForOpenCodeReadiness, recordClickUpCommentVersionProcessed, resyncClickUpWebhookForSignatureDrift, resolveIncludeFile, resolveIncludes, resolveOptimaPluginOptions, resolveSecretReference, routeClickUpWebhookEvent, sendOpenCodeSessionEvent, sendOpenCodeSessionEventDirect, summarizeOpenCodeMessages, verifyOpenCodeSessionEventDelivery, stableClickUpCommentVersionMarker, startClickUpWebhookListener, validateClickUpWebhookState, verifyClickUpSignature, writeClickUpWebhookState, decideClickUpStatusAction, deriveClickUpBranchName, deriveClickUpPendingSubtaskBranch, deriveClickUpPrTarget, deriveClickUpWorktree, determineClickUpMergeAuthority, ensureOptimaGitignoreRules, explicitSafeInputWorktree, finalApprovalAssignees, formatRepairResult, formatValidationResult, isIgnoredClickUpTaskType, isOptimaPluginPackageWorktree, isSafeWritableDirectory, loadHumansRegistry, mergeClickUpAgentMetadata, mergeClickUpSessionMetadata, migrateLegacyOptimaLayout, normalizeAgentMetadataJson, normalizeClickUpStatus, normalizeClickUpTaskType, normalizePromptResponseParts, normalizeWorkflowTaskPath, optimaRepairDependencies, parseClickUpSubtasksMarkdown, parseHumansRegistry, parseMarkdownArtifact, parseMarkdownSections, planOptimaRepair, preEstimateClickUpWork, readMarkdownArtifact, resolveHumanRoles, resolveSafeWorktree, safeWorktreeOrFailure, stripRawLogSections, validateMainWorkspaceBranchSafety, workflowFinalMessageFromPromptResponse };
13703
+ OptimaPlugin.__internals = { BUNDLE_AGENTS_DIR, BUNDLE_ASSETS_DIR, CLICKUP_DEFINITION_DOC_PARENT, activeClickUpWebhookLifecycleRegistry, cleanupManagedClickUpWebhook, deleteClickUpWebhookBestEffort, BUNDLE_POLICIES_DIR, buildClickUpApplyPayloadResult, buildClickUpCreateSubtasksPayload, buildClickUpStartTaskPayload, buildClickUpSummaryPayload, buildClickUpTransitionPayload, buildOptimaAgents, clickUpCommentLedgerKey, clickUpCommentMentionsProductManager, clickUpWebhookAuditLogDir, clickUpWebhookAuditLogPath, compactPromptPath, createClickUpApiClient, createTestClickUpApiClient, createOpenCodeSession, createOpenCodeSessionControl, deliveryEvidencePathForClickUpTask, ensureClickUpTaskWorktree, ensureClickUpTaskWorktreeForWebhook, ensureClickUpTaskWorktreeOpenChamber, ensureClickUpWebhookSubscription, handleClickUpWebhookRequest, inspectOpenCodeSessionActivity, isClickUpDerivedWorktreeSibling, isClickUpSubtaskRoute, isClickUpWebhookStateActive, isSameOrNestedPath, normalizeClickUpWebhookConfig, normalizeClickUpWebhookLogLevel, normalizeOpenCodeBaseUrl, openCodeSessionExists, promptOpenCodeSessionControl, probeOpenCodeSessionControl, readClickUpCommentLedger, readClickUpWebhookState, readOpenCodeSessionControl, readOpenCodeSessionMessages, reconcileClickUpStartup, registerOpenChamberClickUpWorktree, scheduleClickUpAssignmentWatchdog, scheduleClickUpStartupReconciliation, syncOpenChamberWorktreeVisibility, waitForOpenCodeReadiness, recordClickUpCommentVersionProcessed, resyncClickUpWebhookForSignatureDrift, resolveIncludeFile, resolveIncludes, resolveOptimaPluginOptions, resolveSecretReference, routeClickUpWebhookEvent, sendOpenCodeSessionEvent, sendOpenCodeSessionEventDirect, summarizeOpenCodeMessages, verifyOpenCodeSessionEventDelivery, stableClickUpCommentVersionMarker, startClickUpWebhookListener, validateClickUpWebhookState, verifyClickUpSignature, writeClickUpWebhookState, decideClickUpStatusAction, deriveClickUpBranchName, deriveClickUpPendingSubtaskBranch, deriveClickUpPrTarget, deriveClickUpWorktree, determineClickUpMergeAuthority, ensureOptimaGitignoreRules, explicitSafeInputWorktree, finalApprovalAssignees, formatRepairResult, formatValidationResult, isIgnoredClickUpTaskType, isOptimaPluginPackageWorktree, isSafeWritableDirectory, loadHumansRegistry, mergeClickUpAgentMetadata, mergeClickUpSessionMetadata, migrateLegacyOptimaLayout, normalizeAgentMetadataJson, normalizeClickUpStatus, normalizeClickUpTaskType, normalizePromptResponseParts, normalizeWorkflowTaskPath, optimaRepairDependencies, parseClickUpSubtasksMarkdown, parseHumansRegistry, parseMarkdownArtifact, parseMarkdownSections, planOptimaRepair, preEstimateClickUpWork, readMarkdownArtifact, resolveHumanRoles, resolveSafeWorktree, safeWorktreeOrFailure, stripRawLogSections, validateMainWorkspaceBranchSafety, workflowFinalMessageFromPromptResponse };
13557
13704
  export {
13558
13705
  OptimaPlugin as default
13559
13706
  };