@defend-tech/opencode-optima 0.1.76 → 0.1.77

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, path7) {
112
- const ctrl = callVisitor(key, node, visitor, path7);
111
+ function visit_(key, node, visitor, path9) {
112
+ const ctrl = callVisitor(key, node, visitor, path9);
113
113
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
114
- replaceNode(key, path7, ctrl);
115
- return visit_(key, ctrl, visitor, path7);
114
+ replaceNode(key, path9, ctrl);
115
+ return visit_(key, ctrl, visitor, path9);
116
116
  }
117
117
  if (typeof ctrl !== "symbol") {
118
118
  if (identity.isCollection(node)) {
119
- path7 = Object.freeze(path7.concat(node));
119
+ path9 = Object.freeze(path9.concat(node));
120
120
  for (let i = 0; i < node.items.length; ++i) {
121
- const ci = visit_(i, node.items[i], visitor, path7);
121
+ const ci = visit_(i, node.items[i], visitor, path9);
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
- path7 = Object.freeze(path7.concat(node));
133
- const ck = visit_("key", node.key, visitor, path7);
132
+ path9 = Object.freeze(path9.concat(node));
133
+ const ck = visit_("key", node.key, visitor, path9);
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, path7);
138
+ const cv = visit_("value", node.value, visitor, path9);
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, path7) {
160
- const ctrl = await callVisitor(key, node, visitor, path7);
159
+ async function visitAsync_(key, node, visitor, path9) {
160
+ const ctrl = await callVisitor(key, node, visitor, path9);
161
161
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
162
- replaceNode(key, path7, ctrl);
163
- return visitAsync_(key, ctrl, visitor, path7);
162
+ replaceNode(key, path9, ctrl);
163
+ return visitAsync_(key, ctrl, visitor, path9);
164
164
  }
165
165
  if (typeof ctrl !== "symbol") {
166
166
  if (identity.isCollection(node)) {
167
- path7 = Object.freeze(path7.concat(node));
167
+ path9 = Object.freeze(path9.concat(node));
168
168
  for (let i = 0; i < node.items.length; ++i) {
169
- const ci = await visitAsync_(i, node.items[i], visitor, path7);
169
+ const ci = await visitAsync_(i, node.items[i], visitor, path9);
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
- path7 = Object.freeze(path7.concat(node));
181
- const ck = await visitAsync_("key", node.key, visitor, path7);
180
+ path9 = Object.freeze(path9.concat(node));
181
+ const ck = await visitAsync_("key", node.key, visitor, path9);
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, path7);
186
+ const cv = await visitAsync_("value", node.value, visitor, path9);
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, path7) {
213
+ function callVisitor(key, node, visitor, path9) {
214
214
  if (typeof visitor === "function")
215
- return visitor(key, node, path7);
215
+ return visitor(key, node, path9);
216
216
  if (identity.isMap(node))
217
- return visitor.Map?.(key, node, path7);
217
+ return visitor.Map?.(key, node, path9);
218
218
  if (identity.isSeq(node))
219
- return visitor.Seq?.(key, node, path7);
219
+ return visitor.Seq?.(key, node, path9);
220
220
  if (identity.isPair(node))
221
- return visitor.Pair?.(key, node, path7);
221
+ return visitor.Pair?.(key, node, path9);
222
222
  if (identity.isScalar(node))
223
- return visitor.Scalar?.(key, node, path7);
223
+ return visitor.Scalar?.(key, node, path9);
224
224
  if (identity.isAlias(node))
225
- return visitor.Alias?.(key, node, path7);
225
+ return visitor.Alias?.(key, node, path9);
226
226
  return void 0;
227
227
  }
228
- function replaceNode(key, path7, node) {
229
- const parent = path7[path7.length - 1];
228
+ function replaceNode(key, path9, node) {
229
+ const parent = path9[path9.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, path7, value) {
837
+ function collectionFromPath(schema, path9, value) {
838
838
  let v = value;
839
- for (let i = path7.length - 1; i >= 0; --i) {
840
- const k = path7[i];
839
+ for (let i = path9.length - 1; i >= 0; --i) {
840
+ const k = path9[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 = (path7) => path7 == null || typeof path7 === "object" && !!path7[Symbol.iterator]().next().done;
859
+ var isEmptyPath = (path9) => path9 == null || typeof path9 === "object" && !!path9[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(path7, value) {
890
- if (isEmptyPath(path7))
889
+ addIn(path9, value) {
890
+ if (isEmptyPath(path9))
891
891
  this.add(value);
892
892
  else {
893
- const [key, ...rest] = path7;
893
+ const [key, ...rest] = path9;
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(path7) {
908
- const [key, ...rest] = path7;
907
+ deleteIn(path9) {
908
+ const [key, ...rest] = path9;
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(path7, keepScalar) {
923
- const [key, ...rest] = path7;
922
+ getIn(path9, keepScalar) {
923
+ const [key, ...rest] = path9;
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(path7) {
942
- const [key, ...rest] = path7;
941
+ hasIn(path9) {
942
+ const [key, ...rest] = path9;
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(path7, value) {
953
- const [key, ...rest] = path7;
952
+ setIn(path9, value) {
953
+ const [key, ...rest] = path9;
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(path7, value) {
3457
+ addIn(path9, value) {
3458
3458
  if (assertCollection(this.contents))
3459
- this.contents.addIn(path7, value);
3459
+ this.contents.addIn(path9, 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(path7) {
3535
- if (Collection.isEmptyPath(path7)) {
3534
+ deleteIn(path9) {
3535
+ if (Collection.isEmptyPath(path9)) {
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(path7) : false;
3541
+ return assertCollection(this.contents) ? this.contents.deleteIn(path9) : 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(path7, keepScalar) {
3557
- if (Collection.isEmptyPath(path7))
3556
+ getIn(path9, keepScalar) {
3557
+ if (Collection.isEmptyPath(path9))
3558
3558
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
3559
- return identity.isCollection(this.contents) ? this.contents.getIn(path7, keepScalar) : void 0;
3559
+ return identity.isCollection(this.contents) ? this.contents.getIn(path9, 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(path7) {
3571
- if (Collection.isEmptyPath(path7))
3570
+ hasIn(path9) {
3571
+ if (Collection.isEmptyPath(path9))
3572
3572
  return this.contents !== void 0;
3573
- return identity.isCollection(this.contents) ? this.contents.hasIn(path7) : false;
3573
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path9) : 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(path7, value) {
3591
- if (Collection.isEmptyPath(path7)) {
3590
+ setIn(path9, value) {
3591
+ if (Collection.isEmptyPath(path9)) {
3592
3592
  this.contents = value;
3593
3593
  } else if (this.contents == null) {
3594
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path7), value);
3594
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path9), value);
3595
3595
  } else if (assertCollection(this.contents)) {
3596
- this.contents.setIn(path7, value);
3596
+ this.contents.setIn(path9, 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, path7) => {
5548
+ visit.itemAtPath = (cst, path9) => {
5549
5549
  let item = cst;
5550
- for (const [field, index] of path7) {
5550
+ for (const [field, index] of path9) {
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, path7) => {
5560
- const parent = visit.itemAtPath(cst, path7.slice(0, -1));
5561
- const field = path7[path7.length - 1][0];
5559
+ visit.parentCollection = (cst, path9) => {
5560
+ const parent = visit.itemAtPath(cst, path9.slice(0, -1));
5561
+ const field = path9[path9.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(path7, item, visitor) {
5568
- let ctrl = visitor(item, path7);
5567
+ function _visit(path9, item, visitor) {
5568
+ let ctrl = visitor(item, path9);
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(path7.concat([[field, i]])), token.items[i], visitor);
5575
+ const ci = _visit(Object.freeze(path9.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, path7);
5586
+ ctrl = ctrl(item, path9);
5587
5587
  }
5588
5588
  }
5589
- return typeof ctrl === "function" ? ctrl(item, path7) : ctrl;
5589
+ return typeof ctrl === "function" ? ctrl(item, path9) : ctrl;
5590
5590
  }
5591
5591
  exports.visit = visit;
5592
5592
  }
@@ -6871,14 +6871,14 @@ var require_parser = __commonJS({
6871
6871
  case "scalar":
6872
6872
  case "single-quoted-scalar":
6873
6873
  case "double-quoted-scalar": {
6874
- const fs6 = this.flowScalar(this.type);
6874
+ const fs9 = this.flowScalar(this.type);
6875
6875
  if (atNextItem || it.value) {
6876
- map.items.push({ start, key: fs6, sep: [] });
6876
+ map.items.push({ start, key: fs9, sep: [] });
6877
6877
  this.onKeyLine = true;
6878
6878
  } else if (it.sep) {
6879
- this.stack.push(fs6);
6879
+ this.stack.push(fs9);
6880
6880
  } else {
6881
- Object.assign(it, { key: fs6, sep: [] });
6881
+ Object.assign(it, { key: fs9, sep: [] });
6882
6882
  this.onKeyLine = true;
6883
6883
  }
6884
6884
  return;
@@ -7006,13 +7006,13 @@ var require_parser = __commonJS({
7006
7006
  case "scalar":
7007
7007
  case "single-quoted-scalar":
7008
7008
  case "double-quoted-scalar": {
7009
- const fs6 = this.flowScalar(this.type);
7009
+ const fs9 = this.flowScalar(this.type);
7010
7010
  if (!it || it.value)
7011
- fc.items.push({ start: [], key: fs6, sep: [] });
7011
+ fc.items.push({ start: [], key: fs9, sep: [] });
7012
7012
  else if (it.sep)
7013
- this.stack.push(fs6);
7013
+ this.stack.push(fs9);
7014
7014
  else
7015
- Object.assign(it, { key: fs6, sep: [] });
7015
+ Object.assign(it, { key: fs9, sep: [] });
7016
7016
  return;
7017
7017
  }
7018
7018
  case "flow-map-end":
@@ -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 = (path7, originalPath, doThrow) => {
7554
- if (!isString(path7)) {
7553
+ var checkPath = (path9, originalPath, doThrow) => {
7554
+ if (!isString(path9)) {
7555
7555
  return doThrow(
7556
7556
  `path must be a string, but got \`${originalPath}\``,
7557
7557
  TypeError
7558
7558
  );
7559
7559
  }
7560
- if (!path7) {
7560
+ if (!path9) {
7561
7561
  return doThrow(`path must not be empty`, TypeError);
7562
7562
  }
7563
- if (checkPath.isNotRelative(path7)) {
7563
+ if (checkPath.isNotRelative(path9)) {
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 = (path7) => REGEX_TEST_INVALID_PATH.test(path7);
7572
+ var isNotRelative = (path9) => REGEX_TEST_INVALID_PATH.test(path9);
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(path7, checkUnignored) {
7631
+ _testOne(path9, 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(path7);
7639
+ const matched = rule.regex.test(path9);
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 path7 = originalPath && checkPath.convert(originalPath);
7652
+ const path9 = originalPath && checkPath.convert(originalPath);
7653
7653
  checkPath(
7654
- path7,
7654
+ path9,
7655
7655
  originalPath,
7656
7656
  this._allowRelativePaths ? RETURN_FALSE : throwError
7657
7657
  );
7658
- return this._t(path7, cache, checkUnignored, slices);
7658
+ return this._t(path9, cache, checkUnignored, slices);
7659
7659
  }
7660
- _t(path7, cache, checkUnignored, slices) {
7661
- if (path7 in cache) {
7662
- return cache[path7];
7660
+ _t(path9, cache, checkUnignored, slices) {
7661
+ if (path9 in cache) {
7662
+ return cache[path9];
7663
7663
  }
7664
7664
  if (!slices) {
7665
- slices = path7.split(SLASH);
7665
+ slices = path9.split(SLASH);
7666
7666
  }
7667
7667
  slices.pop();
7668
7668
  if (!slices.length) {
7669
- return cache[path7] = this._testOne(path7, checkUnignored);
7669
+ return cache[path9] = this._testOne(path9, 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[path7] = parent.ignored ? parent : this._testOne(path7, checkUnignored);
7677
+ return cache[path9] = parent.ignored ? parent : this._testOne(path9, checkUnignored);
7678
7678
  }
7679
- ignores(path7) {
7680
- return this._test(path7, this._ignoreCache, false).ignored;
7679
+ ignores(path9) {
7680
+ return this._test(path9, this._ignoreCache, false).ignored;
7681
7681
  }
7682
7682
  createFilter() {
7683
- return (path7) => !this.ignores(path7);
7683
+ return (path9) => !this.ignores(path9);
7684
7684
  }
7685
7685
  filter(paths) {
7686
7686
  return makeArray(paths).filter(this.createFilter());
7687
7687
  }
7688
7688
  // @returns {TestResult}
7689
- test(path7) {
7690
- return this._test(path7, this._testCache, true);
7689
+ test(path9) {
7690
+ return this._test(path9, this._testCache, true);
7691
7691
  }
7692
7692
  };
7693
7693
  var factory = (options) => new Ignore(options);
7694
- var isPathValid = (path7) => checkPath(path7 && checkPath.convert(path7), path7, RETURN_FALSE);
7694
+ var isPathValid = (path9) => checkPath(path9 && checkPath.convert(path9), path9, 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 = (path7) => REGIX_IS_WINDOWS_PATH_ABSOLUTE.test(path7) || isNotRelative(path7);
7705
+ checkPath.isNotRelative = (path9) => REGIX_IS_WINDOWS_PATH_ABSOLUTE.test(path9) || isNotRelative(path9);
7706
7706
  }
7707
7707
  }
7708
7708
  });
@@ -7710,13 +7710,45 @@ var require_ignore = __commonJS({
7710
7710
  // src/index.js
7711
7711
  var import_yaml3 = __toESM(require_dist(), 1);
7712
7712
  var import_ignore3 = __toESM(require_ignore(), 1);
7713
- import crypto from "node:crypto";
7714
- import fs5 from "node:fs";
7713
+ import crypto2 from "node:crypto";
7714
+ import fs8 from "node:fs";
7715
7715
  import http from "node:http";
7716
- import os from "node:os";
7717
- import path6 from "node:path";
7716
+ import os2 from "node:os";
7717
+ import path8 from "node:path";
7718
7718
  import { tool } from "@opencode-ai/plugin/tool";
7719
7719
 
7720
+ // src/clickup_comments.js
7721
+ var COMMENT_TEXT_KEYS = /* @__PURE__ */ new Set(["comment", "body", "description"]);
7722
+ function normalizeClickUpMarkdown(value = "") {
7723
+ return String(value ?? "").replace(/\\r\\n/g, "\n").replace(/\\n/g, "\n").replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n").map((line) => line.trimEnd()).join("\n").replace(/\n{3,}/g, "\n\n").trim();
7724
+ }
7725
+ function formatClickUpStatusComment({ title = "", summary = "", sections = [], context = [] } = {}) {
7726
+ const lines = [];
7727
+ const heading = normalizeClickUpMarkdown(title);
7728
+ if (heading) lines.push(`## ${heading}`, "");
7729
+ const intro = normalizeClickUpMarkdown(summary);
7730
+ if (intro) lines.push(intro, "");
7731
+ for (const section of sections) {
7732
+ const sectionTitle = normalizeClickUpMarkdown(section?.title);
7733
+ const sectionBody = normalizeClickUpMarkdown(section?.body);
7734
+ if (!sectionTitle || !sectionBody) continue;
7735
+ lines.push(`### ${sectionTitle}`, sectionBody, "");
7736
+ }
7737
+ const contextLines = context.map(normalizeClickUpMarkdown).filter(Boolean);
7738
+ if (contextLines.length > 0) lines.push("### Context", contextLines.map((item) => item.startsWith("- ") ? item : `- ${item}`).join("\n"));
7739
+ return normalizeClickUpMarkdown(lines.join("\n"));
7740
+ }
7741
+ function normalizeClickUpPayloadComments(value) {
7742
+ if (Array.isArray(value)) return value.map(normalizeClickUpPayloadComments);
7743
+ if (!value || typeof value !== "object") return value;
7744
+ return Object.fromEntries(
7745
+ Object.entries(value).map(([key, entry]) => [
7746
+ key,
7747
+ COMMENT_TEXT_KEYS.has(key) && typeof entry === "string" ? normalizeClickUpMarkdown(entry) : normalizeClickUpPayloadComments(entry)
7748
+ ])
7749
+ );
7750
+ }
7751
+
7720
7752
  // src/git_utils.js
7721
7753
  import fs from "node:fs";
7722
7754
  import path from "node:path";
@@ -7795,224 +7827,691 @@ function stageGitAwareMerge(sourcePath, destinationPath, gitState) {
7795
7827
  }
7796
7828
  }
7797
7829
 
7798
- // src/include_resolver.js
7830
+ // src/github.js
7831
+ import crypto from "node:crypto";
7832
+ import fs3 from "node:fs";
7833
+ import path3 from "node:path";
7834
+
7835
+ // src/secrets.js
7799
7836
  import fs2 from "node:fs";
7837
+ import os from "node:os";
7800
7838
  import path2 from "node:path";
7801
- function compactPromptPath(filePath) {
7802
- if (!filePath.endsWith(".md") || filePath.endsWith(".prompt.md")) return null;
7803
- return filePath.replace(/\.md$/, ".prompt.md");
7804
- }
7805
- function isSameOrNestedPath(candidate, root) {
7806
- if (typeof candidate !== "string" || typeof root !== "string" || !candidate.trim() || !root.trim()) return false;
7807
- const resolvedCandidate = path2.resolve(candidate);
7808
- const resolvedRoot = path2.resolve(root);
7809
- const relative = path2.relative(resolvedRoot, resolvedCandidate);
7810
- return relative === "" || !!relative && !relative.startsWith("..") && !path2.isAbsolute(relative);
7811
- }
7812
- function resolveWithin(baseDir, relativePath) {
7813
- if (!relativePath) return null;
7814
- if (path2.isAbsolute(relativePath)) return null;
7815
- const resolved = path2.resolve(baseDir, relativePath);
7816
- return isSameOrNestedPath(resolved, baseDir) ? resolved : null;
7817
- }
7818
- function withCompactPreference(paths, options = {}) {
7819
- if (!options.preferCompactPromptDocs) return paths;
7820
- const compactPaths = paths.map((filePath) => filePath ? compactPromptPath(filePath) : null).filter(Boolean);
7821
- return [...compactPaths, ...paths];
7839
+ function expandHomePath(value = "") {
7840
+ const input = String(value || "").trim();
7841
+ if (input === "~") return os.homedir();
7842
+ if (input.startsWith("~/")) return path2.join(os.homedir(), input.slice(2));
7843
+ return input;
7822
7844
  }
7823
- function resolveIncludeFile(includeRef, repoRoot, bundleRoot, options = {}) {
7824
- const trimmed = String(includeRef || "").trim();
7825
- const scopedMatch = trimmed.match(/^([a-z]+):(.*)$/i);
7826
- const scope = scopedMatch?.[1]?.toLowerCase();
7827
- const target = scopedMatch ? scopedMatch[2].trim() : trimmed;
7828
- const optimaRoot = options.optimaRoot || path2.join(repoRoot, ".optima");
7829
- const repoPolicyRoot = options.repoPolicyRoot || path2.join(optimaRoot, "policies");
7830
- const bundlePolicyRoot = options.bundlePolicyRoot || path2.join(bundleRoot, "assets", "policies");
7831
- if (scope === "plugin") {
7832
- for (const filePath of withCompactPreference([resolveWithin(bundleRoot, target)], options)) {
7833
- if (filePath && fs2.existsSync(filePath)) return filePath;
7834
- }
7835
- return null;
7836
- }
7837
- if (scope === "repo") {
7838
- for (const filePath of withCompactPreference([resolveWithin(optimaRoot, target)], options)) {
7839
- if (filePath && fs2.existsSync(filePath)) return filePath;
7840
- }
7841
- return null;
7842
- }
7843
- if (scope === "policy") {
7844
- const candidates2 = withCompactPreference([
7845
- resolveWithin(repoPolicyRoot, target),
7846
- resolveWithin(bundlePolicyRoot, target)
7847
- ], options);
7848
- for (const filePath of candidates2) {
7849
- if (filePath && fs2.existsSync(filePath)) return filePath;
7845
+ function resolveSecretReference(value = "") {
7846
+ const raw = String(value || "").trim();
7847
+ const envMatch = raw.match(/^\{env:([A-Za-z_][A-Za-z0-9_]*)\}$/);
7848
+ if (envMatch) return process.env[envMatch[1]] || "";
7849
+ const fileMatch = raw.match(/^\{file:(.+)\}$/);
7850
+ if (fileMatch) {
7851
+ try {
7852
+ return fs2.readFileSync(expandHomePath(fileMatch[1]), "utf8").trim();
7853
+ } catch {
7854
+ return "";
7850
7855
  }
7851
- return null;
7852
7856
  }
7853
- const candidates = withCompactPreference([
7854
- resolveWithin(repoRoot, target),
7855
- resolveWithin(bundleRoot, target)
7856
- ], options);
7857
- for (const filePath of candidates) {
7858
- if (filePath && fs2.existsSync(filePath)) return filePath;
7859
- }
7860
- return null;
7857
+ return raw;
7861
7858
  }
7862
- function resolveIncludes(text, repoRoot, bundleRoot, options = {}) {
7863
- const includeDepth = Number(options.includeDepth || 0);
7864
- const maxIncludeDepth = Number(options.maxIncludeDepth || 20);
7865
- if (includeDepth > maxIncludeDepth) {
7866
- return "\n\n# ERROR: Include recursion limit exceeded.\n\n";
7867
- }
7868
- const includeRegex = /<include:(.*?)>/g;
7869
- return String(text || "").replace(includeRegex, (match, includeRef) => {
7870
- const filePath = resolveIncludeFile(includeRef, repoRoot, bundleRoot, options);
7871
- if (!filePath) {
7872
- console.warn(`[Optima] Include file not found: ${includeRef}`);
7873
- return `
7874
7859
 
7875
- # ERROR: Include file not found: ${includeRef}
7876
-
7877
- `;
7878
- }
7879
- const content = fs2.readFileSync(filePath, "utf8");
7880
- return resolveIncludes(content, repoRoot, bundleRoot, { ...options, includeDepth: includeDepth + 1, maxIncludeDepth });
7881
- });
7860
+ // src/github.js
7861
+ function base64UrlJson(value) {
7862
+ return Buffer.from(JSON.stringify(value)).toString("base64url");
7882
7863
  }
7883
-
7884
- // src/repair.js
7885
- var import_yaml = __toESM(require_dist(), 1);
7886
- var import_ignore = __toESM(require_ignore(), 1);
7887
- import fs3 from "node:fs";
7888
- import path3 from "node:path";
7889
- var CODEMAP_SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
7890
- ".js",
7891
- ".ts",
7892
- ".tsx",
7893
- ".jsx",
7894
- ".dart",
7895
- ".py",
7896
- ".go",
7897
- ".rs",
7898
- ".java",
7899
- ".c",
7900
- ".cpp",
7901
- ".cs",
7902
- ".php",
7903
- ".rb",
7904
- ".swift",
7905
- ".kt",
7906
- ".m",
7907
- ".sh",
7908
- ".sql",
7909
- ".yaml",
7910
- ".yml",
7911
- ".json",
7912
- ".md"
7913
- ]);
7914
- var LEGACY_OPERATIONAL_ROOTS = /* @__PURE__ */ new Set([
7915
- "tasks",
7916
- "evidences",
7917
- ".orbita",
7918
- ".staticeng",
7919
- ".nomadworks",
7920
- ".nomadwork",
7921
- "nomadworks",
7922
- ".codenomad"
7923
- ]);
7924
- var OPTIMA_OPERATIONAL_FOLDERS = [".optima", "templates", "dist"];
7925
- function relPath(worktree, targetPath) {
7926
- return path3.relative(worktree, targetPath).split(path3.sep).join("/") || ".";
7864
+ function resolveGitHubAppPrivateKey(app = {}) {
7865
+ const direct = resolveSecretReference(app.privateKey || "");
7866
+ if (direct) return direct.replace(/\\n/g, "\n");
7867
+ const file = expandHomePath(app.privateKeyFile || "");
7868
+ if (!file) return "";
7869
+ try {
7870
+ return fs3.readFileSync(file, "utf8").trim().replace(/\\n/g, "\n");
7871
+ } catch {
7872
+ return "";
7873
+ }
7927
7874
  }
7928
- function normalizeCodemapRelPath(relPathValue) {
7929
- return path3.normalize(relPathValue).replace(/\\/g, "/").replace(/\/$/, "");
7875
+ function createGitHubAppJwt({ appId, privateKey, now = () => /* @__PURE__ */ new Date() } = {}) {
7876
+ const key = String(privateKey || "").trim();
7877
+ const issuer = String(appId || "").trim();
7878
+ if (!issuer || !key) throw new Error("GitHub App app_id and private key are required");
7879
+ const nowSeconds = Math.floor(now().getTime() / 1e3);
7880
+ const header = base64UrlJson({ alg: "RS256", typ: "JWT" });
7881
+ const payload = base64UrlJson({ iat: nowSeconds - 60, exp: nowSeconds + 540, iss: issuer });
7882
+ const unsigned = `${header}.${payload}`;
7883
+ const signature = crypto.createSign("RSA-SHA256").update(unsigned).end().sign(key, "base64url");
7884
+ return `${unsigned}.${signature}`;
7930
7885
  }
7931
- function firstPathSegment(relPathValue) {
7932
- return normalizeCodemapRelPath(relPathValue).split("/").filter(Boolean)[0] || "";
7886
+ function encodeGitHubPathSegment(value) {
7887
+ return encodeURIComponent(String(value || ""));
7933
7888
  }
7934
- function isOperationalRelPath(relPathValue) {
7935
- if (!relPathValue) return false;
7936
- const normalized = normalizeCodemapRelPath(relPathValue);
7937
- const firstSegment = firstPathSegment(normalized);
7938
- if (LEGACY_OPERATIONAL_ROOTS.has(firstSegment)) return true;
7939
- return OPTIMA_OPERATIONAL_FOLDERS.some((folder) => normalized === folder || normalized.startsWith(`${folder}/`));
7889
+ function encodeGitHubBranchRef(branch = "") {
7890
+ return String(branch || "").split("/").map(encodeGitHubPathSegment).join("/");
7940
7891
  }
7941
- function isHiddenTree(relPathValue) {
7942
- if (!relPathValue) return false;
7943
- return normalizeCodemapRelPath(relPathValue).split("/").some((part) => part.startsWith("."));
7892
+ function parseNullSeparatedGitOutput(output = "") {
7893
+ return String(output || "").split("\0").map((item) => item.trim()).filter(Boolean);
7944
7894
  }
7945
- function loadGitIgnoreMatcher(worktree) {
7946
- const ig = (0, import_ignore.default)();
7947
- ig.add(".git");
7948
- const gitignorePath = path3.join(worktree, ".gitignore");
7949
- if (fs3.existsSync(gitignorePath)) ig.add(fs3.readFileSync(gitignorePath, "utf8"));
7950
- return ig;
7895
+ function listWorktreeChangedPaths(worktree, runGitFn = runGit) {
7896
+ const tracked = parseNullSeparatedGitOutput(runGitFn(worktree, ["diff", "--name-only", "-z", "HEAD", "--"]));
7897
+ const untracked = parseNullSeparatedGitOutput(runGitFn(worktree, ["ls-files", "--others", "--exclude-standard", "-z", "--"]));
7898
+ return [.../* @__PURE__ */ new Set([...tracked, ...untracked])].filter((item) => item && !item.startsWith("../") && !path3.isAbsolute(item));
7951
7899
  }
7952
- function codemapSectionEntries(value) {
7953
- if (Array.isArray(value)) return value;
7954
- if (value && typeof value === "object") return Object.values(value);
7955
- return [];
7900
+ function currentGitBranch(worktree, runGitFn = runGit) {
7901
+ return String(runGitFn(worktree, ["rev-parse", "--abbrev-ref", "HEAD"]) || "").trim();
7956
7902
  }
7957
- function codemapIndexedPaths(map) {
7958
- const indexed = /* @__PURE__ */ new Set();
7959
- for (const section of ["modules", "entrypoints", "sources_of_truth", "links", "internals"]) {
7960
- for (const item of codemapSectionEntries(map?.[section])) {
7961
- if (item?.path) indexed.add(normalizeCodemapRelPath(item.path));
7962
- }
7903
+ function treeEntryForWorktreePath(worktree, gitPath) {
7904
+ const absolutePath = path3.join(worktree, ...String(gitPath || "").split("/"));
7905
+ if (!fs3.existsSync(absolutePath)) return { path: gitPath, mode: "100644", type: "blob", sha: null, deleted: true };
7906
+ const stat = fs3.lstatSync(absolutePath);
7907
+ if (stat.isDirectory()) return null;
7908
+ if (stat.isSymbolicLink()) {
7909
+ return {
7910
+ path: gitPath,
7911
+ mode: "120000",
7912
+ type: "blob",
7913
+ content: fs3.readlinkSync(absolutePath),
7914
+ encoding: "utf-8"
7915
+ };
7963
7916
  }
7964
- return indexed;
7917
+ return {
7918
+ path: gitPath,
7919
+ mode: stat.mode & 73 ? "100755" : "100644",
7920
+ type: "blob",
7921
+ content: fs3.readFileSync(absolutePath).toString("base64"),
7922
+ encoding: "base64"
7923
+ };
7965
7924
  }
7966
- function readCodemap(filePath, unresolved, worktree) {
7967
- try {
7968
- const parsed = import_yaml.default.parse(fs3.readFileSync(filePath, "utf8"));
7969
- if (!parsed || typeof parsed !== "object") {
7970
- unresolved.push({ category: "codemap", path: relPath(worktree, filePath), message: "CodeMap is empty or invalid; manual repair required." });
7971
- return null;
7972
- }
7973
- return parsed;
7974
- } catch {
7975
- unresolved.push({ category: "codemap", path: relPath(worktree, filePath), message: "CodeMap has invalid YAML; manual repair required." });
7976
- return null;
7925
+ function appendGitHubQuery(pathname, params = {}) {
7926
+ const query = new URLSearchParams();
7927
+ for (const [key, value] of Object.entries(params || {})) {
7928
+ if (value === void 0 || value === null || value === "") continue;
7929
+ query.set(key, String(value));
7977
7930
  }
7931
+ const suffix = query.toString();
7932
+ return suffix ? `${pathname}?${suffix}` : pathname;
7978
7933
  }
7979
- function writeCodemap(filePath, map) {
7980
- fs3.writeFileSync(filePath, import_yaml.default.stringify(map), "utf8");
7934
+ function timestampMs(value = "") {
7935
+ const parsed = Date.parse(String(value || ""));
7936
+ return Number.isFinite(parsed) ? parsed : 0;
7981
7937
  }
7982
- function isIgnoredPath(ig, relativePath) {
7983
- const normalized = normalizeCodemapRelPath(relativePath);
7984
- return Boolean(normalized) && ig.ignores(normalized);
7938
+ function sortNewestFirst(items = []) {
7939
+ return [...items].sort((a, b) => {
7940
+ const bTime = Math.max(timestampMs(b?.updated_at), timestampMs(b?.created_at));
7941
+ const aTime = Math.max(timestampMs(a?.updated_at), timestampMs(a?.created_at));
7942
+ return bTime - aTime;
7943
+ });
7985
7944
  }
7986
- function hasImmediateSourceFile(dirPath, ig, worktree) {
7987
- if (!fs3.existsSync(dirPath)) return false;
7988
- for (const item of fs3.readdirSync(dirPath, { withFileTypes: true })) {
7989
- const childPath = path3.join(dirPath, item.name);
7990
- const relative = path3.relative(worktree, childPath);
7991
- if (isIgnoredPath(ig, relative) || isOperationalRelPath(relative)) continue;
7992
- if (item.isFile() && CODEMAP_SOURCE_EXTENSIONS.has(path3.extname(item.name))) return true;
7993
- }
7994
- return false;
7945
+ function matchesVercelStatusContext(context = "", expected = "") {
7946
+ const actual = String(context || "").trim();
7947
+ const wanted = String(expected || "").trim();
7948
+ if (wanted && actual === wanted) return true;
7949
+ const lower = actual.toLowerCase();
7950
+ if (!lower.includes("vercel")) return false;
7951
+ if (!wanted) return lower.includes("preproduction") || lower.includes("defend-preproduction");
7952
+ const wantedLower = wanted.toLowerCase();
7953
+ return wantedLower.split(/\s+|–|-/).filter((part) => part && part !== "vercel").every((part) => lower.includes(part));
7995
7954
  }
7996
- function containsSource(dirPath, ig, worktree) {
7997
- if (!fs3.existsSync(dirPath)) return false;
7998
- const dirRelPath = path3.relative(worktree, dirPath);
7999
- if (isOperationalRelPath(dirRelPath) || isHiddenTree(dirRelPath)) return false;
8000
- for (const item of fs3.readdirSync(dirPath, { withFileTypes: true })) {
8001
- const childPath = path3.join(dirPath, item.name);
8002
- const relative = path3.relative(worktree, childPath);
8003
- if (isIgnoredPath(ig, relative) || isOperationalRelPath(relative) || isHiddenTree(relative)) continue;
8004
- if (item.isFile() && CODEMAP_SOURCE_EXTENSIONS.has(path3.extname(item.name))) return true;
8005
- if (item.isDirectory() && containsSource(childPath, ig, worktree)) return true;
8006
- }
8007
- return false;
7955
+ function selectFunctionalDeploymentUrl(status = {}, deployment = {}) {
7956
+ for (const candidate of [
7957
+ status?.environment_url,
7958
+ deployment?.environment_url,
7959
+ status?.target_url,
7960
+ deployment?.target_url
7961
+ ]) {
7962
+ const value = String(candidate || "").trim();
7963
+ if (!value) continue;
7964
+ try {
7965
+ const url = new URL(value);
7966
+ if (url.protocol === "http:" || url.protocol === "https:") return value;
7967
+ } catch {
7968
+ }
7969
+ }
7970
+ return "";
7971
+ }
7972
+ async function checkFunctionalDeploymentUrl(url, fetchImpl = globalThis.fetch) {
7973
+ const target = String(url || "").trim();
7974
+ if (!target) return { ok: false, reason: "url_missing" };
7975
+ if (typeof fetchImpl !== "function") return { ok: false, reason: "fetch_unavailable", url: target };
7976
+ const signal = typeof AbortSignal !== "undefined" && typeof AbortSignal.timeout === "function" ? AbortSignal.timeout(8e3) : void 0;
7977
+ const probe = async (method) => {
7978
+ const response = await fetchImpl(target, { method, redirect: "follow", signal });
7979
+ return {
7980
+ ok: response.status >= 200 && response.status < 400,
7981
+ status: response.status,
7982
+ statusText: response.statusText || "",
7983
+ url: response.url || target,
7984
+ method
7985
+ };
7986
+ };
7987
+ try {
7988
+ const head = await probe("HEAD");
7989
+ if (head.ok) return head;
7990
+ const get = await probe("GET");
7991
+ return get.ok ? get : { ...get, reason: "http_not_ok" };
7992
+ } catch (error) {
7993
+ try {
7994
+ const get = await probe("GET");
7995
+ return get.ok ? get : { ...get, reason: "http_not_ok" };
7996
+ } catch (secondError) {
7997
+ return { ok: false, reason: "request_failed", url: target, error: secondError.message || error.message };
7998
+ }
7999
+ }
8000
+ }
8001
+ function createGitHubApiClient(config = {}, fetchImpl = globalThis.fetch) {
8002
+ const staticToken = resolveSecretReference(config?.apiToken);
8003
+ const appConfig = typeof config?.app === "object" && config.app !== null ? config.app : {};
8004
+ const appId = resolveSecretReference(appConfig.appId || appConfig.app_id || "");
8005
+ const installationId = resolveSecretReference(appConfig.installationId || appConfig.installation_id || "");
8006
+ const appEnabled = appConfig.enabled === true || Boolean(appId && installationId && (appConfig.privateKey || appConfig.privateKeyFile));
8007
+ const privateKey = resolveGitHubAppPrivateKey(appConfig);
8008
+ const owner = String(config?.owner || "").trim();
8009
+ const repo = String(config?.repo || "").trim();
8010
+ let installationToken = null;
8011
+ let installationTokenExpiresAt = 0;
8012
+ const requestJson = async (url, { method = "GET", headers = {}, body = void 0 } = {}) => {
8013
+ if (typeof fetchImpl !== "function") throw new Error("fetch is unavailable; inject a GitHub client for live PR lookup");
8014
+ const response = await fetchImpl(url, {
8015
+ method,
8016
+ headers: {
8017
+ Accept: "application/vnd.github+json",
8018
+ "X-GitHub-Api-Version": "2022-11-28",
8019
+ ...body === void 0 ? {} : { "Content-Type": "application/json" },
8020
+ ...headers
8021
+ },
8022
+ ...body === void 0 ? {} : { body: JSON.stringify(body) }
8023
+ });
8024
+ if (!response.ok) throw new Error(`GitHub API request failed: ${response.status}`);
8025
+ return response.status === 204 ? null : response.json();
8026
+ };
8027
+ const getAuthToken = async () => {
8028
+ if (!appEnabled) return staticToken || "";
8029
+ const nowMs = Date.now();
8030
+ if (installationToken && installationTokenExpiresAt - 6e4 > nowMs) return installationToken;
8031
+ const jwt = createGitHubAppJwt({ appId, privateKey });
8032
+ const installation = await requestJson(`https://api.github.com/app/installations/${encodeURIComponent(installationId)}/access_tokens`, {
8033
+ method: "POST",
8034
+ headers: { Authorization: `Bearer ${jwt}` }
8035
+ });
8036
+ installationToken = String(installation?.token || "").trim();
8037
+ installationTokenExpiresAt = Date.parse(installation?.expires_at || "") || nowMs + 3e6;
8038
+ if (!installationToken) throw new Error("GitHub App installation token response did not include a token");
8039
+ return installationToken;
8040
+ };
8041
+ const request = async (pathname, { method = "GET", body = void 0 } = {}) => {
8042
+ if (!owner || !repo) throw new Error("GitHub repository owner/repo is not configured");
8043
+ const token = await getAuthToken();
8044
+ return requestJson(`https://api.github.com/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}${pathname}`, {
8045
+ method,
8046
+ body,
8047
+ headers: token ? { Authorization: `Bearer ${token}` } : {}
8048
+ });
8049
+ };
8050
+ const getRef = async (branch) => request(`/git/ref/heads/${encodeGitHubBranchRef(branch)}`);
8051
+ const getCommitObject = async (sha) => request(`/git/commits/${encodeURIComponent(sha)}`);
8052
+ const createBlob = async ({ content, encoding }) => request("/git/blobs", { method: "POST", body: { content, encoding } });
8053
+ const createTree = async ({ baseTree, tree }) => request("/git/trees", { method: "POST", body: { base_tree: baseTree, tree } });
8054
+ const createCommit = async ({ message, treeSha, parents }) => request("/git/commits", { method: "POST", body: { message, tree: treeSha, parents } });
8055
+ const updateRef = async ({ branch, sha, force = false }) => request(`/git/refs/heads/${encodeGitHubBranchRef(branch)}`, { method: "PATCH", body: { sha, force } });
8056
+ return {
8057
+ async getPullRequest(number) {
8058
+ return request(`/pulls/${encodeURIComponent(number)}`);
8059
+ },
8060
+ async createPullRequest({ title, head, base, body = "", draft = false, maintainerCanModify = true }) {
8061
+ return request("/pulls", {
8062
+ method: "POST",
8063
+ body: {
8064
+ title: String(title || ""),
8065
+ head: String(head || ""),
8066
+ base: String(base || ""),
8067
+ body: String(body || ""),
8068
+ draft: draft === true,
8069
+ maintainer_can_modify: maintainerCanModify !== false
8070
+ }
8071
+ });
8072
+ },
8073
+ async createIssueComment({ issueNumber, body }) {
8074
+ return request(`/issues/${encodeURIComponent(issueNumber)}/comments`, { method: "POST", body: { body: String(body || "") } });
8075
+ },
8076
+ async replyToReviewComment({ commentId, body }) {
8077
+ return request(`/pulls/comments/${encodeURIComponent(commentId)}/replies`, { method: "POST", body: { body: String(body || "") } });
8078
+ },
8079
+ async createPullRequestReview({ pullNumber, body, event = "COMMENT" }) {
8080
+ return request(`/pulls/${encodeURIComponent(pullNumber)}/reviews`, { method: "POST", body: { body: String(body || ""), event: String(event || "COMMENT").toUpperCase() } });
8081
+ },
8082
+ async mergePullRequest({ pullNumber, commitTitle = "", commitMessage = "", mergeMethod = "squash" }) {
8083
+ const body = { merge_method: String(mergeMethod || "squash") };
8084
+ if (commitTitle) body.commit_title = String(commitTitle);
8085
+ if (commitMessage) body.commit_message = String(commitMessage);
8086
+ return request(`/pulls/${encodeURIComponent(pullNumber)}/merge`, { method: "PUT", body });
8087
+ },
8088
+ async getCombinedStatus(ref) {
8089
+ return request(`/commits/${encodeURIComponent(String(ref || ""))}/status`);
8090
+ },
8091
+ async listDeployments({ sha = "", ref = "", environment = "", perPage = 30 } = {}) {
8092
+ return request(appendGitHubQuery("/deployments", { sha, ref, environment, per_page: perPage }));
8093
+ },
8094
+ async listDeploymentStatuses(deploymentId) {
8095
+ return request(`/deployments/${encodeURIComponent(deploymentId)}/statuses`);
8096
+ },
8097
+ async verifyVercelPullRequestDeployment({
8098
+ pullNumber,
8099
+ context = "Vercel \u2013 defend-preproduction",
8100
+ environment = "Preview \u2013 defend-preproduction",
8101
+ requireFunctionalUrl = true
8102
+ } = {}) {
8103
+ const pr = await this.getPullRequest(pullNumber);
8104
+ const headSha = String(pr?.head?.sha || "").trim();
8105
+ if (!headSha) return { ok: true, ready: false, reason: "pr_head_sha_missing", pull_request: { number: pullNumber } };
8106
+ const combined = await this.getCombinedStatus(headSha);
8107
+ const statuses = Array.isArray(combined?.statuses) ? combined.statuses : [];
8108
+ const selectedStatus = sortNewestFirst(statuses.filter((status) => matchesVercelStatusContext(status?.context, context)))[0] || null;
8109
+ if (!selectedStatus) {
8110
+ return {
8111
+ ok: true,
8112
+ ready: false,
8113
+ reason: "vercel_status_missing",
8114
+ pull_request: { number: pr.number, url: pr.html_url, head_sha: headSha },
8115
+ required_context: context,
8116
+ combined_state: combined?.state || null
8117
+ };
8118
+ }
8119
+ if (String(selectedStatus.state || "").toLowerCase() !== "success") {
8120
+ return {
8121
+ ok: true,
8122
+ ready: false,
8123
+ reason: "vercel_status_not_success",
8124
+ pull_request: { number: pr.number, url: pr.html_url, head_sha: headSha },
8125
+ required_context: context,
8126
+ status: selectedStatus,
8127
+ combined_state: combined?.state || null
8128
+ };
8129
+ }
8130
+ let deployments = await this.listDeployments({ sha: headSha, environment });
8131
+ if (!Array.isArray(deployments) || deployments.length === 0) deployments = await this.listDeployments({ sha: headSha });
8132
+ const newestDeployments = sortNewestFirst(Array.isArray(deployments) ? deployments : []);
8133
+ const selectedDeployment = newestDeployments.find((deployment) => !environment || String(deployment?.environment || "") === environment) || newestDeployments[0] || null;
8134
+ if (!selectedDeployment?.id) {
8135
+ return {
8136
+ ok: true,
8137
+ ready: false,
8138
+ reason: "vercel_deployment_missing",
8139
+ pull_request: { number: pr.number, url: pr.html_url, head_sha: headSha },
8140
+ required_environment: environment,
8141
+ status: selectedStatus
8142
+ };
8143
+ }
8144
+ const deploymentStatuses = await this.listDeploymentStatuses(selectedDeployment.id);
8145
+ const selectedDeploymentStatus = sortNewestFirst(Array.isArray(deploymentStatuses) ? deploymentStatuses : [])[0] || null;
8146
+ if (!selectedDeploymentStatus || String(selectedDeploymentStatus.state || "").toLowerCase() !== "success") {
8147
+ return {
8148
+ ok: true,
8149
+ ready: false,
8150
+ reason: "vercel_deployment_not_success",
8151
+ pull_request: { number: pr.number, url: pr.html_url, head_sha: headSha },
8152
+ required_environment: environment,
8153
+ status: selectedStatus,
8154
+ deployment: selectedDeployment,
8155
+ deployment_status: selectedDeploymentStatus
8156
+ };
8157
+ }
8158
+ const url = selectFunctionalDeploymentUrl(selectedDeploymentStatus, selectedDeployment);
8159
+ const urlCheck = requireFunctionalUrl ? await checkFunctionalDeploymentUrl(url, fetchImpl) : { ok: Boolean(url), reason: url ? void 0 : "url_missing", url };
8160
+ if (requireFunctionalUrl && !urlCheck.ok) {
8161
+ return {
8162
+ ok: true,
8163
+ ready: false,
8164
+ reason: "vercel_url_not_functional",
8165
+ pull_request: { number: pr.number, url: pr.html_url, head_sha: headSha },
8166
+ required_environment: environment,
8167
+ status: selectedStatus,
8168
+ deployment: selectedDeployment,
8169
+ deployment_status: selectedDeploymentStatus,
8170
+ url,
8171
+ url_check: urlCheck
8172
+ };
8173
+ }
8174
+ return {
8175
+ ok: true,
8176
+ ready: true,
8177
+ reason: "vercel_pr_deployment_ready",
8178
+ pull_request: { number: pr.number, url: pr.html_url, head_sha: headSha },
8179
+ required_context: context,
8180
+ required_environment: environment,
8181
+ status: selectedStatus,
8182
+ deployment: selectedDeployment,
8183
+ deployment_status: selectedDeploymentStatus,
8184
+ url,
8185
+ url_check: urlCheck
8186
+ };
8187
+ },
8188
+ async commitWorktree({ worktree, branch = "", message = "", runGitFn = runGit, syncLocal = false } = {}) {
8189
+ const directory = path3.resolve(String(worktree || ""));
8190
+ if (!directory || !fs3.existsSync(directory)) throw new Error("worktree does not exist");
8191
+ const targetBranch = String(branch || currentGitBranch(directory, runGitFn)).trim();
8192
+ if (!targetBranch || targetBranch === "HEAD") throw new Error("target branch is required for GitHub API commit");
8193
+ const commitMessage = String(message || "").trim();
8194
+ if (!commitMessage) throw new Error("commit message is required");
8195
+ const changedPaths = listWorktreeChangedPaths(directory, runGitFn);
8196
+ if (changedPaths.length === 0) return { ok: true, action: "no_changes", branch: targetBranch, changedPaths: [] };
8197
+ const ref = await getRef(targetBranch);
8198
+ const headSha = ref?.object?.sha;
8199
+ if (!headSha) throw new Error(`GitHub ref for ${targetBranch} did not include a head sha`);
8200
+ const headCommit = await getCommitObject(headSha);
8201
+ const baseTree = headCommit?.tree?.sha;
8202
+ if (!baseTree) throw new Error(`GitHub commit ${headSha} did not include a tree sha`);
8203
+ const tree = [];
8204
+ for (const gitPath of changedPaths) {
8205
+ const entry = treeEntryForWorktreePath(directory, gitPath);
8206
+ if (!entry) continue;
8207
+ if (entry.deleted) {
8208
+ tree.push({ path: entry.path, mode: entry.mode, type: entry.type, sha: null });
8209
+ continue;
8210
+ }
8211
+ const blob = await createBlob({ content: entry.content, encoding: entry.encoding });
8212
+ if (!blob?.sha) throw new Error(`GitHub blob creation failed for ${gitPath}`);
8213
+ tree.push({ path: entry.path, mode: entry.mode, type: entry.type, sha: blob.sha });
8214
+ }
8215
+ if (tree.length === 0) return { ok: true, action: "no_changes", branch: targetBranch, changedPaths: [] };
8216
+ const nextTree = await createTree({ baseTree, tree });
8217
+ const nextCommit = await createCommit({ message: commitMessage, treeSha: nextTree.sha, parents: [headSha] });
8218
+ if (!nextCommit?.sha) throw new Error("GitHub commit creation did not return a sha");
8219
+ const updatedRef = await updateRef({ branch: targetBranch, sha: nextCommit.sha, force: false });
8220
+ if (syncLocal) {
8221
+ runGitFn(directory, ["fetch", "origin", targetBranch]);
8222
+ runGitFn(directory, ["reset", "--hard", "FETCH_HEAD"]);
8223
+ }
8224
+ return {
8225
+ ok: true,
8226
+ action: "committed",
8227
+ branch: targetBranch,
8228
+ before: headSha,
8229
+ after: nextCommit.sha,
8230
+ changedPaths,
8231
+ treeEntries: tree.length,
8232
+ verification: nextCommit.verification || null,
8233
+ ref: updatedRef
8234
+ };
8235
+ },
8236
+ async authMode() {
8237
+ if (appEnabled) return { mode: "github_app", appId, installationId };
8238
+ if (staticToken) return { mode: "token" };
8239
+ return { mode: "anonymous" };
8240
+ }
8241
+ };
8242
+ }
8243
+
8244
+ // src/include_resolver.js
8245
+ import fs4 from "node:fs";
8246
+ import path4 from "node:path";
8247
+ function compactPromptPath(filePath) {
8248
+ if (!filePath.endsWith(".md") || filePath.endsWith(".prompt.md")) return null;
8249
+ return filePath.replace(/\.md$/, ".prompt.md");
8250
+ }
8251
+ function isSameOrNestedPath(candidate, root) {
8252
+ if (typeof candidate !== "string" || typeof root !== "string" || !candidate.trim() || !root.trim()) return false;
8253
+ const resolvedCandidate = path4.resolve(candidate);
8254
+ const resolvedRoot = path4.resolve(root);
8255
+ const relative = path4.relative(resolvedRoot, resolvedCandidate);
8256
+ return relative === "" || !!relative && !relative.startsWith("..") && !path4.isAbsolute(relative);
8257
+ }
8258
+ function resolveWithin(baseDir, relativePath) {
8259
+ if (!relativePath) return null;
8260
+ if (path4.isAbsolute(relativePath)) return null;
8261
+ const resolved = path4.resolve(baseDir, relativePath);
8262
+ return isSameOrNestedPath(resolved, baseDir) ? resolved : null;
8263
+ }
8264
+ function withCompactPreference(paths, options = {}) {
8265
+ if (!options.preferCompactPromptDocs) return paths;
8266
+ const compactPaths = paths.map((filePath) => filePath ? compactPromptPath(filePath) : null).filter(Boolean);
8267
+ return [...compactPaths, ...paths];
8268
+ }
8269
+ function resolveIncludeFile(includeRef, repoRoot, bundleRoot, options = {}) {
8270
+ const trimmed = String(includeRef || "").trim();
8271
+ const scopedMatch = trimmed.match(/^([a-z]+):(.*)$/i);
8272
+ const scope = scopedMatch?.[1]?.toLowerCase();
8273
+ const target = scopedMatch ? scopedMatch[2].trim() : trimmed;
8274
+ const optimaRoot = options.optimaRoot || path4.join(repoRoot, ".optima");
8275
+ const repoPolicyRoot = options.repoPolicyRoot || path4.join(optimaRoot, "policies");
8276
+ const bundlePolicyRoot = options.bundlePolicyRoot || path4.join(bundleRoot, "assets", "policies");
8277
+ if (scope === "plugin") {
8278
+ for (const filePath of withCompactPreference([resolveWithin(bundleRoot, target)], options)) {
8279
+ if (filePath && fs4.existsSync(filePath)) return filePath;
8280
+ }
8281
+ return null;
8282
+ }
8283
+ if (scope === "repo") {
8284
+ for (const filePath of withCompactPreference([resolveWithin(optimaRoot, target)], options)) {
8285
+ if (filePath && fs4.existsSync(filePath)) return filePath;
8286
+ }
8287
+ return null;
8288
+ }
8289
+ if (scope === "policy") {
8290
+ const candidates2 = withCompactPreference([
8291
+ resolveWithin(repoPolicyRoot, target),
8292
+ resolveWithin(bundlePolicyRoot, target)
8293
+ ], options);
8294
+ for (const filePath of candidates2) {
8295
+ if (filePath && fs4.existsSync(filePath)) return filePath;
8296
+ }
8297
+ return null;
8298
+ }
8299
+ const candidates = withCompactPreference([
8300
+ resolveWithin(repoRoot, target),
8301
+ resolveWithin(bundleRoot, target)
8302
+ ], options);
8303
+ for (const filePath of candidates) {
8304
+ if (filePath && fs4.existsSync(filePath)) return filePath;
8305
+ }
8306
+ return null;
8307
+ }
8308
+ function resolveIncludes(text, repoRoot, bundleRoot, options = {}) {
8309
+ const includeDepth = Number(options.includeDepth || 0);
8310
+ const maxIncludeDepth = Number(options.maxIncludeDepth || 20);
8311
+ if (includeDepth > maxIncludeDepth) {
8312
+ return "\n\n# ERROR: Include recursion limit exceeded.\n\n";
8313
+ }
8314
+ const includeRegex = /<include:(.*?)>/g;
8315
+ return String(text || "").replace(includeRegex, (match, includeRef) => {
8316
+ const filePath = resolveIncludeFile(includeRef, repoRoot, bundleRoot, options);
8317
+ if (!filePath) {
8318
+ console.warn(`[Optima] Include file not found: ${includeRef}`);
8319
+ return `
8320
+
8321
+ # ERROR: Include file not found: ${includeRef}
8322
+
8323
+ `;
8324
+ }
8325
+ const content = fs4.readFileSync(filePath, "utf8");
8326
+ return resolveIncludes(content, repoRoot, bundleRoot, { ...options, includeDepth: includeDepth + 1, maxIncludeDepth });
8327
+ });
8328
+ }
8329
+
8330
+ // src/markdown_artifacts.js
8331
+ import fs5 from "node:fs";
8332
+ var CLICKUP_REQUIRED_SUMMARY_SECTIONS = [
8333
+ "Summary",
8334
+ "Work Performed",
8335
+ "AC Coverage",
8336
+ "Verification Results",
8337
+ "Documentation Impact",
8338
+ "Open Risks",
8339
+ "Recommended Next Step"
8340
+ ];
8341
+ var RAW_LOG_SECTION_NAMES = /* @__PURE__ */ new Set(["Raw Logs", "Logs", "Full Logs", "Command Output", "Transcript"]);
8342
+ function parseMarkdownSections(markdown = "") {
8343
+ const sections = {};
8344
+ let current = null;
8345
+ let buffer = [];
8346
+ const flush = () => {
8347
+ if (!current) return;
8348
+ sections[current] = buffer.join("\n").trim();
8349
+ };
8350
+ for (const line of String(markdown).split(/\r?\n/)) {
8351
+ const heading = /^(#{2,3})\s+(.+?)\s*$/.exec(line);
8352
+ if (heading) {
8353
+ flush();
8354
+ current = heading[2].trim();
8355
+ buffer = [];
8356
+ continue;
8357
+ }
8358
+ if (current) buffer.push(line);
8359
+ }
8360
+ flush();
8361
+ return sections;
8362
+ }
8363
+ function parseMarkdownArtifact(markdown = "", { requiredSections = [] } = {}) {
8364
+ const sections = parseMarkdownSections(markdown);
8365
+ const missing = requiredSections.filter((section) => !sections[section]);
8366
+ return {
8367
+ ok: missing.length === 0,
8368
+ sections,
8369
+ missing,
8370
+ message: missing.length ? `Missing required section(s): ${missing.join(", ")}` : "ok"
8371
+ };
8372
+ }
8373
+ function readMarkdownArtifact(filePath, options = {}) {
8374
+ const markdown = fs5.readFileSync(filePath, "utf8");
8375
+ return parseMarkdownArtifact(markdown, options);
8376
+ }
8377
+ function stripRawLogSections(sections = {}) {
8378
+ return Object.fromEntries(
8379
+ Object.entries(sections).filter(([name]) => !RAW_LOG_SECTION_NAMES.has(name))
8380
+ );
8381
+ }
8382
+
8383
+ // src/repair.js
8384
+ var import_yaml = __toESM(require_dist(), 1);
8385
+ var import_ignore = __toESM(require_ignore(), 1);
8386
+ import fs6 from "node:fs";
8387
+ import path5 from "node:path";
8388
+ var CODEMAP_SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
8389
+ ".js",
8390
+ ".ts",
8391
+ ".tsx",
8392
+ ".jsx",
8393
+ ".dart",
8394
+ ".py",
8395
+ ".go",
8396
+ ".rs",
8397
+ ".java",
8398
+ ".c",
8399
+ ".cpp",
8400
+ ".cs",
8401
+ ".php",
8402
+ ".rb",
8403
+ ".swift",
8404
+ ".kt",
8405
+ ".m",
8406
+ ".sh",
8407
+ ".sql",
8408
+ ".yaml",
8409
+ ".yml",
8410
+ ".json",
8411
+ ".md"
8412
+ ]);
8413
+ var LEGACY_OPERATIONAL_ROOTS = /* @__PURE__ */ new Set([
8414
+ "tasks",
8415
+ "evidences",
8416
+ ".orbita",
8417
+ ".staticeng",
8418
+ ".nomadworks",
8419
+ ".nomadwork",
8420
+ "nomadworks",
8421
+ ".codenomad"
8422
+ ]);
8423
+ var OPTIMA_OPERATIONAL_FOLDERS = [".optima", "templates", "dist"];
8424
+ function relPath(worktree, targetPath) {
8425
+ return path5.relative(worktree, targetPath).split(path5.sep).join("/") || ".";
8426
+ }
8427
+ function normalizeCodemapRelPath(relPathValue) {
8428
+ return path5.normalize(relPathValue).replace(/\\/g, "/").replace(/\/$/, "");
8429
+ }
8430
+ function firstPathSegment(relPathValue) {
8431
+ return normalizeCodemapRelPath(relPathValue).split("/").filter(Boolean)[0] || "";
8432
+ }
8433
+ function isOperationalRelPath(relPathValue) {
8434
+ if (!relPathValue) return false;
8435
+ const normalized = normalizeCodemapRelPath(relPathValue);
8436
+ const firstSegment = firstPathSegment(normalized);
8437
+ if (LEGACY_OPERATIONAL_ROOTS.has(firstSegment)) return true;
8438
+ return OPTIMA_OPERATIONAL_FOLDERS.some((folder) => normalized === folder || normalized.startsWith(`${folder}/`));
8439
+ }
8440
+ function isHiddenTree(relPathValue) {
8441
+ if (!relPathValue) return false;
8442
+ return normalizeCodemapRelPath(relPathValue).split("/").some((part) => part.startsWith("."));
8443
+ }
8444
+ function loadGitIgnoreMatcher(worktree) {
8445
+ const ig = (0, import_ignore.default)();
8446
+ ig.add(".git");
8447
+ const gitignorePath = path5.join(worktree, ".gitignore");
8448
+ if (fs6.existsSync(gitignorePath)) ig.add(fs6.readFileSync(gitignorePath, "utf8"));
8449
+ return ig;
8450
+ }
8451
+ function codemapSectionEntries(value) {
8452
+ if (Array.isArray(value)) return value;
8453
+ if (value && typeof value === "object") return Object.values(value);
8454
+ return [];
8455
+ }
8456
+ function codemapIndexedPaths(map) {
8457
+ const indexed = /* @__PURE__ */ new Set();
8458
+ for (const section of ["modules", "entrypoints", "sources_of_truth", "links", "internals"]) {
8459
+ for (const item of codemapSectionEntries(map?.[section])) {
8460
+ if (item?.path) indexed.add(normalizeCodemapRelPath(item.path));
8461
+ }
8462
+ }
8463
+ return indexed;
8464
+ }
8465
+ function readCodemap(filePath, unresolved, worktree) {
8466
+ try {
8467
+ const parsed = import_yaml.default.parse(fs6.readFileSync(filePath, "utf8"));
8468
+ if (!parsed || typeof parsed !== "object") {
8469
+ unresolved.push({ category: "codemap", path: relPath(worktree, filePath), message: "CodeMap is empty or invalid; manual repair required." });
8470
+ return null;
8471
+ }
8472
+ return parsed;
8473
+ } catch {
8474
+ unresolved.push({ category: "codemap", path: relPath(worktree, filePath), message: "CodeMap has invalid YAML; manual repair required." });
8475
+ return null;
8476
+ }
8477
+ }
8478
+ function writeCodemap(filePath, map) {
8479
+ fs6.writeFileSync(filePath, import_yaml.default.stringify(map), "utf8");
8480
+ }
8481
+ function isIgnoredPath(ig, relativePath) {
8482
+ const normalized = normalizeCodemapRelPath(relativePath);
8483
+ return Boolean(normalized) && ig.ignores(normalized);
8484
+ }
8485
+ function hasImmediateSourceFile(dirPath, ig, worktree) {
8486
+ if (!fs6.existsSync(dirPath)) return false;
8487
+ for (const item of fs6.readdirSync(dirPath, { withFileTypes: true })) {
8488
+ const childPath = path5.join(dirPath, item.name);
8489
+ const relative = path5.relative(worktree, childPath);
8490
+ if (isIgnoredPath(ig, relative) || isOperationalRelPath(relative)) continue;
8491
+ if (item.isFile() && CODEMAP_SOURCE_EXTENSIONS.has(path5.extname(item.name))) return true;
8492
+ }
8493
+ return false;
8494
+ }
8495
+ function containsSource(dirPath, ig, worktree) {
8496
+ if (!fs6.existsSync(dirPath)) return false;
8497
+ const dirRelPath = path5.relative(worktree, dirPath);
8498
+ if (isOperationalRelPath(dirRelPath) || isHiddenTree(dirRelPath)) return false;
8499
+ for (const item of fs6.readdirSync(dirPath, { withFileTypes: true })) {
8500
+ const childPath = path5.join(dirPath, item.name);
8501
+ const relative = path5.relative(worktree, childPath);
8502
+ if (isIgnoredPath(ig, relative) || isOperationalRelPath(relative) || isHiddenTree(relative)) continue;
8503
+ if (item.isFile() && CODEMAP_SOURCE_EXTENSIONS.has(path5.extname(item.name))) return true;
8504
+ if (item.isDirectory() && containsSource(childPath, ig, worktree)) return true;
8505
+ }
8506
+ return false;
8008
8507
  }
8009
8508
  function createModuleCodemap(dirPath, worktree, deps) {
8010
- const entries = fs3.readdirSync(dirPath, { withFileTypes: true });
8509
+ const entries = fs6.readdirSync(dirPath, { withFileTypes: true });
8011
8510
  const entrypoints = [];
8012
8511
  const internals = [];
8013
- const relToRoot = path3.relative(dirPath, deps.optimaCodemapPath(worktree)).split(path3.sep).join("/");
8512
+ const relToRoot = path5.relative(dirPath, deps.optimaCodemapPath(worktree)).split(path5.sep).join("/");
8014
8513
  for (const item of entries) {
8015
- if (!item.isFile() || item.name === "codemap.yml" || !CODEMAP_SOURCE_EXTENSIONS.has(path3.extname(item.name))) continue;
8514
+ if (!item.isFile() || item.name === "codemap.yml" || !CODEMAP_SOURCE_EXTENSIONS.has(path5.extname(item.name))) continue;
8016
8515
  const bucket = /^index\.(js|ts|tsx|jsx)$|^main\.(js|ts|tsx|jsx|py|go|rs|java)$/.test(item.name) ? entrypoints : internals;
8017
8516
  bucket.push({ path: item.name });
8018
8517
  }
@@ -8025,7 +8524,7 @@ function repairSingleCodemap(codemapPath, worktree, apply, registerAction, unres
8025
8524
  const map = readCodemap(codemapPath, unresolved, worktree);
8026
8525
  if (!map) return;
8027
8526
  const isRootMap = codemapPath === deps.optimaCodemapPath(worktree);
8028
- const mapDir = path3.dirname(codemapPath);
8527
+ const mapDir = path5.dirname(codemapPath);
8029
8528
  const pathBase = isRootMap ? worktree : mapDir;
8030
8529
  let changed = false;
8031
8530
  for (const section of ["modules", "entrypoints", "sources_of_truth", "links", "internals"]) {
@@ -8036,13 +8535,13 @@ function repairSingleCodemap(codemapPath, worktree, apply, registerAction, unres
8036
8535
  }
8037
8536
  const nextEntries = [];
8038
8537
  for (const entry of originalEntries) {
8039
- if (!entry?.path || entry.path.startsWith("http://") || entry.path.startsWith("https://") || path3.isAbsolute(entry.path)) {
8538
+ if (!entry?.path || entry.path.startsWith("http://") || entry.path.startsWith("https://") || path5.isAbsolute(entry.path)) {
8040
8539
  nextEntries.push(entry);
8041
8540
  continue;
8042
8541
  }
8043
8542
  const normalizedPath = normalizeCodemapRelPath(entry.path);
8044
- const absPath = path3.join(pathBase, normalizedPath);
8045
- if (!fs3.existsSync(absPath)) {
8543
+ const absPath = path5.join(pathBase, normalizedPath);
8544
+ if (!fs6.existsSync(absPath)) {
8046
8545
  registerAction({ category: "codemap", action: apply ? "removed" : "would_remove", path: relPath(worktree, codemapPath), detail: `Remove broken ${section.slice(0, -1)} reference '${entry.path}'.` });
8047
8546
  changed = true;
8048
8547
  continue;
@@ -8051,8 +8550,8 @@ function repairSingleCodemap(codemapPath, worktree, apply, registerAction, unres
8051
8550
  const maxParts = isRootMap ? 2 : 1;
8052
8551
  if (parts.length > maxParts) {
8053
8552
  const localPath = isRootMap ? parts.slice(0, 2).join("/") : parts[0];
8054
- const localAbs = path3.join(pathBase, localPath);
8055
- if (fs3.existsSync(localAbs)) {
8553
+ const localAbs = path5.join(pathBase, localPath);
8554
+ if (fs6.existsSync(localAbs)) {
8056
8555
  nextEntries.push({ ...entry, path: localPath });
8057
8556
  changed = true;
8058
8557
  registerAction({ category: "codemap", action: apply ? "updated" : "would_update", path: relPath(worktree, codemapPath), detail: `Shorten '${entry.path}' to local path '${localPath}'.` });
@@ -8066,11 +8565,11 @@ function repairSingleCodemap(codemapPath, worktree, apply, registerAction, unres
8066
8565
  }
8067
8566
  if (Array.isArray(map[section])) map[section] = nextEntries;
8068
8567
  }
8069
- if (map.scope === "module" && !isOperationalRelPath(path3.relative(worktree, mapDir))) {
8568
+ if (map.scope === "module" && !isOperationalRelPath(path5.relative(worktree, mapDir))) {
8070
8569
  const indexed = codemapIndexedPaths(map);
8071
8570
  const internals = Array.isArray(map.internals) ? map.internals : [];
8072
- for (const item of fs3.readdirSync(mapDir, { withFileTypes: true })) {
8073
- if (!item.isFile() || item.name === "codemap.yml" || !CODEMAP_SOURCE_EXTENSIONS.has(path3.extname(item.name))) continue;
8571
+ for (const item of fs6.readdirSync(mapDir, { withFileTypes: true })) {
8572
+ if (!item.isFile() || item.name === "codemap.yml" || !CODEMAP_SOURCE_EXTENSIONS.has(path5.extname(item.name))) continue;
8074
8573
  if (indexed.has(item.name)) continue;
8075
8574
  internals.push({ path: item.name });
8076
8575
  indexed.add(item.name);
@@ -8084,13 +8583,13 @@ function repairSingleCodemap(codemapPath, worktree, apply, registerAction, unres
8084
8583
  function repairCodemaps(worktree, apply, actions, unresolved, deps) {
8085
8584
  const ig = loadGitIgnoreMatcher(worktree);
8086
8585
  const rootCodemapPath = deps.optimaCodemapPath(worktree);
8087
- const rootCodemapMissing = !fs3.existsSync(rootCodemapPath);
8586
+ const rootCodemapMissing = !fs6.existsSync(rootCodemapPath);
8088
8587
  if (rootCodemapMissing) {
8089
8588
  actions.push({ category: "codemap", action: apply ? "created" : "would_create", path: ".optima/codemap.yml", detail: "Create missing root CodeMap from template." });
8090
8589
  if (apply) deps.scaffoldOptimaRootCodemap(worktree);
8091
8590
  }
8092
- if (fs3.existsSync(rootCodemapPath)) repairSingleCodemap(rootCodemapPath, worktree, apply, (action) => actions.push(action), unresolved, deps);
8093
- const rootMap = fs3.existsSync(rootCodemapPath) ? readCodemap(rootCodemapPath, unresolved, worktree) : null;
8591
+ if (fs6.existsSync(rootCodemapPath)) repairSingleCodemap(rootCodemapPath, worktree, apply, (action) => actions.push(action), unresolved, deps);
8592
+ const rootMap = fs6.existsSync(rootCodemapPath) ? readCodemap(rootCodemapPath, unresolved, worktree) : null;
8094
8593
  let rootChanged = false;
8095
8594
  const rootModulesRepairable = rootMap && (rootMap.modules === void 0 || Array.isArray(rootMap.modules));
8096
8595
  if (rootMap) {
@@ -8102,10 +8601,10 @@ function repairCodemaps(worktree, apply, actions, unresolved, deps) {
8102
8601
  }
8103
8602
  }
8104
8603
  function walk(dirPath) {
8105
- const relative = path3.relative(worktree, dirPath);
8604
+ const relative = path5.relative(worktree, dirPath);
8106
8605
  if (relative && (isIgnoredPath(ig, relative) || isOperationalRelPath(relative) || isHiddenTree(relative))) return;
8107
- const codemapPath = path3.join(dirPath, "codemap.yml");
8108
- const hasCodemap = fs3.existsSync(codemapPath);
8606
+ const codemapPath = path5.join(dirPath, "codemap.yml");
8607
+ const hasCodemap = fs6.existsSync(codemapPath);
8109
8608
  const sourceDir = relative && containsSource(dirPath, ig, worktree);
8110
8609
  if (sourceDir && !hasCodemap && dirPath !== worktree) {
8111
8610
  if (hasImmediateSourceFile(dirPath, ig, worktree)) {
@@ -8124,19 +8623,19 @@ function repairCodemaps(worktree, apply, actions, unresolved, deps) {
8124
8623
  actions.push({ category: "codemap", action: apply ? "updated" : "would_update", path: ".optima/codemap.yml", detail: `Register top-level source module '${normalizeCodemapRelPath(relative)}'.` });
8125
8624
  }
8126
8625
  }
8127
- if (fs3.existsSync(codemapPath) && codemapPath !== rootCodemapPath) repairSingleCodemap(codemapPath, worktree, apply, (action) => actions.push(action), unresolved, deps);
8128
- for (const item of fs3.readdirSync(dirPath, { withFileTypes: true })) {
8129
- if (item.isDirectory()) walk(path3.join(dirPath, item.name));
8626
+ if (fs6.existsSync(codemapPath) && codemapPath !== rootCodemapPath) repairSingleCodemap(codemapPath, worktree, apply, (action) => actions.push(action), unresolved, deps);
8627
+ for (const item of fs6.readdirSync(dirPath, { withFileTypes: true })) {
8628
+ if (item.isDirectory()) walk(path5.join(dirPath, item.name));
8130
8629
  }
8131
8630
  }
8132
- if (fs3.existsSync(worktree)) walk(worktree);
8631
+ if (fs6.existsSync(worktree)) walk(worktree);
8133
8632
  if (rootMap && rootChanged && apply) writeCodemap(rootCodemapPath, rootMap);
8134
8633
  }
8135
8634
  function walkMarkdownFiles(dirPath) {
8136
- if (!fs3.existsSync(dirPath)) return [];
8635
+ if (!fs6.existsSync(dirPath)) return [];
8137
8636
  const files = [];
8138
- for (const entry of fs3.readdirSync(dirPath, { withFileTypes: true })) {
8139
- const entryPath = path3.join(dirPath, entry.name);
8637
+ for (const entry of fs6.readdirSync(dirPath, { withFileTypes: true })) {
8638
+ const entryPath = path5.join(dirPath, entry.name);
8140
8639
  if (entry.isDirectory()) {
8141
8640
  files.push(...walkMarkdownFiles(entryPath));
8142
8641
  } else if (entry.isFile() && entry.name.endsWith(".md")) {
@@ -8175,7 +8674,7 @@ function rewriteOptimaMarkdownReferences(content, evidenceBasePath = null) {
8175
8674
  }
8176
8675
  function optimaEvidenceBaseForFile(worktree, filePath, deps) {
8177
8676
  const evidenceRoot = deps.optimaEvidencesDir(worktree);
8178
- const relative = path3.relative(evidenceRoot, filePath).split(path3.sep).join("/");
8677
+ const relative = path5.relative(evidenceRoot, filePath).split(path5.sep).join("/");
8179
8678
  const [taskId] = relative.split("/");
8180
8679
  if (!taskId || taskId === ".." || relative.startsWith("../")) return null;
8181
8680
  return `.optima/evidences/${taskId}`;
@@ -8188,11 +8687,11 @@ function normalizeOptimaMarkdownReferences(worktree, deps) {
8188
8687
  ];
8189
8688
  const changed = [];
8190
8689
  for (const filePath of scanRoots.flatMap(walkMarkdownFiles)) {
8191
- const raw = fs3.readFileSync(filePath, "utf8");
8192
- const evidenceBasePath = filePath.startsWith(deps.optimaEvidencesDir(worktree) + path3.sep) ? optimaEvidenceBaseForFile(worktree, filePath, deps) : null;
8690
+ const raw = fs6.readFileSync(filePath, "utf8");
8691
+ const evidenceBasePath = filePath.startsWith(deps.optimaEvidencesDir(worktree) + path5.sep) ? optimaEvidenceBaseForFile(worktree, filePath, deps) : null;
8193
8692
  const rewritten = rewriteOptimaMarkdownReferences(raw, evidenceBasePath);
8194
8693
  if (rewritten !== raw) {
8195
- fs3.writeFileSync(filePath, rewritten, "utf8");
8694
+ fs6.writeFileSync(filePath, rewritten, "utf8");
8196
8695
  changed.push(relPath(worktree, filePath));
8197
8696
  }
8198
8697
  }
@@ -8200,8 +8699,8 @@ function normalizeOptimaMarkdownReferences(worktree, deps) {
8200
8699
  }
8201
8700
  function missingOptimaGitignoreRules(worktree, deps) {
8202
8701
  if (!deps.isGitRepository(worktree)) return [];
8203
- const gitignorePath = path3.join(worktree, ".gitignore");
8204
- const existing = fs3.existsSync(gitignorePath) ? fs3.readFileSync(gitignorePath, "utf8") : "";
8702
+ const gitignorePath = path5.join(worktree, ".gitignore");
8703
+ const existing = fs6.existsSync(gitignorePath) ? fs6.readFileSync(gitignorePath, "utf8") : "";
8205
8704
  const existingRules = new Set(existing.split(/\r?\n/).map((line) => line.trim()).filter(Boolean));
8206
8705
  return deps.optimaGitignoreRules.filter((rule) => !existingRules.has(rule));
8207
8706
  }
@@ -8218,11 +8717,11 @@ function planOptimaRepair(worktree, args = {}, deps) {
8218
8717
  const apply = mode === "apply";
8219
8718
  const actions = [];
8220
8719
  const unresolved = [];
8221
- const hadOptima = fs3.existsSync(deps.optimaDir(worktree));
8720
+ const hadOptima = fs6.existsSync(deps.optimaDir(worktree));
8222
8721
  const missingGitignoreRules = missingOptimaGitignoreRules(worktree, deps);
8223
8722
  const markdownBefore = apply ? [] : walkMarkdownFiles(deps.optimaDir(worktree)).filter((filePath) => {
8224
- const raw = fs3.readFileSync(filePath, "utf8");
8225
- const evidenceBasePath = filePath.startsWith(deps.optimaEvidencesDir(worktree) + path3.sep) ? optimaEvidenceBaseForFile(worktree, filePath, deps) : null;
8723
+ const raw = fs6.readFileSync(filePath, "utf8");
8724
+ const evidenceBasePath = filePath.startsWith(deps.optimaEvidencesDir(worktree) + path5.sep) ? optimaEvidenceBaseForFile(worktree, filePath, deps) : null;
8226
8725
  return rewriteOptimaMarkdownReferences(raw, evidenceBasePath) !== raw;
8227
8726
  }).map((filePath) => relPath(worktree, filePath));
8228
8727
  if (!hadOptima) pushRepairAction(actions, "operational", apply ? "created" : "would_create", ".optima/", "Create Optima operational root.");
@@ -8231,31 +8730,31 @@ function planOptimaRepair(worktree, args = {}, deps) {
8231
8730
  [".staticeng/", deps.legacyStaticEngDir(worktree)],
8232
8731
  [".nomadwork/", deps.legacyNomadworkDir(worktree)],
8233
8732
  [".nomadworks/", deps.legacyNomadworksDir(worktree)],
8234
- ["tasks/", path3.join(worktree, "tasks")],
8235
- ["evidences/", path3.join(worktree, "evidences")],
8236
- ["docs/scrs/", path3.join(worktree, "docs", "scrs")],
8237
- ["codemap.yml", path3.join(worktree, "codemap.yml")],
8238
- ["codemap.yaml", path3.join(worktree, "codemap.yaml")]
8733
+ ["tasks/", path5.join(worktree, "tasks")],
8734
+ ["evidences/", path5.join(worktree, "evidences")],
8735
+ ["docs/scrs/", path5.join(worktree, "docs", "scrs")],
8736
+ ["codemap.yml", path5.join(worktree, "codemap.yml")],
8737
+ ["codemap.yaml", path5.join(worktree, "codemap.yaml")]
8239
8738
  ];
8240
- if (!deps.isOptimaPluginPackageWorktree(worktree)) legacySources.push(["policies/", path3.join(worktree, "policies")]);
8739
+ if (!deps.isOptimaPluginPackageWorktree(worktree)) legacySources.push(["policies/", path5.join(worktree, "policies")]);
8241
8740
  for (const [display, sourcePath] of legacySources) {
8242
- if (fs3.existsSync(sourcePath)) pushRepairAction(actions, "legacy", apply ? "migrated" : "would_migrate", display, "Move or merge legacy/root Optima artifact into .optima using preservation safeguards.");
8741
+ if (fs6.existsSync(sourcePath)) pushRepairAction(actions, "legacy", apply ? "migrated" : "would_migrate", display, "Move or merge legacy/root Optima artifact into .optima using preservation safeguards.");
8243
8742
  }
8244
8743
  if (apply) deps.migrateLegacyOptimaLayout(worktree);
8245
- const configMissing = !fs3.existsSync(deps.repoConfigPath(worktree));
8744
+ const configMissing = !fs6.existsSync(deps.repoConfigPath(worktree));
8246
8745
  if (configMissing) pushRepairAction(actions, "config", apply ? "created" : "would_create", ".optima/.config/optima.yaml", "Create missing local Optima config from template.");
8247
8746
  if (apply) deps.scaffoldOptimaConfig(worktree, args.team_mode || "full");
8248
8747
  const requiredFiles = [
8249
- [path3.join(deps.optimaTasksDir(worktree), "current.md"), "registry", ".optima/tasks/current.md", deps.currentTasksRegistryContent()],
8250
- [path3.join(deps.optimaTasksDir(worktree), "done.md"), "registry", ".optima/tasks/done.md", deps.doneTasksRegistryContent()],
8251
- [path3.join(deps.optimaScrsDir(worktree), "current.md"), "registry", ".optima/docs/scrs/current.md", deps.currentScrRegistryContent()],
8252
- [path3.join(deps.optimaScrsDir(worktree), "done.md"), "registry", ".optima/docs/scrs/done.md", deps.doneScrRegistryContent()],
8253
- [path3.join(deps.optimaTasksDir(worktree), "task-template.md"), "template", ".optima/tasks/task-template.md", deps.taskTemplateContent()],
8254
- [path3.join(deps.optimaTasksDir(worktree), "subtask-template.md"), "template", ".optima/tasks/subtask-template.md", deps.subtaskTemplateContent()],
8255
- [path3.join(deps.repoPoliciesDir(worktree), "README.md"), "policy", ".optima/policies/README.md", deps.repoLocalPoliciesReadme]
8748
+ [path5.join(deps.optimaTasksDir(worktree), "current.md"), "registry", ".optima/tasks/current.md", deps.currentTasksRegistryContent()],
8749
+ [path5.join(deps.optimaTasksDir(worktree), "done.md"), "registry", ".optima/tasks/done.md", deps.doneTasksRegistryContent()],
8750
+ [path5.join(deps.optimaScrsDir(worktree), "current.md"), "registry", ".optima/docs/scrs/current.md", deps.currentScrRegistryContent()],
8751
+ [path5.join(deps.optimaScrsDir(worktree), "done.md"), "registry", ".optima/docs/scrs/done.md", deps.doneScrRegistryContent()],
8752
+ [path5.join(deps.optimaTasksDir(worktree), "task-template.md"), "template", ".optima/tasks/task-template.md", deps.taskTemplateContent()],
8753
+ [path5.join(deps.optimaTasksDir(worktree), "subtask-template.md"), "template", ".optima/tasks/subtask-template.md", deps.subtaskTemplateContent()],
8754
+ [path5.join(deps.repoPoliciesDir(worktree), "README.md"), "policy", ".optima/policies/README.md", deps.repoLocalPoliciesReadme]
8256
8755
  ];
8257
8756
  for (const [filePath, category, displayPath, content] of requiredFiles) {
8258
- if (!fs3.existsSync(filePath)) {
8757
+ if (!fs6.existsSync(filePath)) {
8259
8758
  pushRepairAction(actions, category, apply ? "created" : "would_create", displayPath, "Create missing Optima scaffold file without overwriting existing content.");
8260
8759
  if (apply) deps.ensureFileIfMissing(filePath, content);
8261
8760
  }
@@ -8309,18 +8808,18 @@ function formatRepairResult(plan, validationResult = null, formatValidationResul
8309
8808
  // src/validate_logic.js
8310
8809
  var import_yaml2 = __toESM(require_dist(), 1);
8311
8810
  var import_ignore2 = __toESM(require_ignore(), 1);
8312
- import fs4 from "node:fs";
8313
- import path4 from "node:path";
8811
+ import fs7 from "node:fs";
8812
+ import path6 from "node:path";
8314
8813
  async function optima_validate_logic(worktree) {
8315
- const rootCodemapPath = path4.join(worktree, ".optima", "codemap.yml");
8316
- if (!fs4.existsSync(rootCodemapPath)) return { ok: false, errors: [".optima/codemap.yml not found."], warnings: [] };
8814
+ const rootCodemapPath = path6.join(worktree, ".optima", "codemap.yml");
8815
+ if (!fs7.existsSync(rootCodemapPath)) return { ok: false, errors: [".optima/codemap.yml not found."], warnings: [] };
8317
8816
  const errors = [];
8318
8817
  const warnings = [];
8319
8818
  const ig = (0, import_ignore2.default)();
8320
8819
  ig.add(".git");
8321
- const gitignorePath = path4.join(worktree, ".gitignore");
8322
- if (fs4.existsSync(gitignorePath)) {
8323
- ig.add(fs4.readFileSync(gitignorePath, "utf8"));
8820
+ const gitignorePath = path6.join(worktree, ".gitignore");
8821
+ if (fs7.existsSync(gitignorePath)) {
8822
+ ig.add(fs7.readFileSync(gitignorePath, "utf8"));
8324
8823
  }
8325
8824
  const sourceExtensions = [
8326
8825
  ".js",
@@ -8360,30 +8859,30 @@ async function optima_validate_logic(worktree) {
8360
8859
  const operationalFolders = [".optima", "templates", "dist"];
8361
8860
  const isHiddenTree2 = (relPath2) => {
8362
8861
  if (!relPath2) return false;
8363
- return relPath2.split(path4.sep).some((part) => part.startsWith("."));
8862
+ return relPath2.split(path6.sep).some((part) => part.startsWith("."));
8364
8863
  };
8365
- const firstPathSegment2 = (relPath2) => relPath2.split(path4.sep).filter(Boolean)[0] || "";
8864
+ const firstPathSegment2 = (relPath2) => relPath2.split(path6.sep).filter(Boolean)[0] || "";
8366
8865
  const isOperationalRelPath2 = (relPath2) => {
8367
8866
  if (!relPath2) return false;
8368
8867
  const firstSegment = firstPathSegment2(relPath2);
8369
8868
  if (legacyOperationalRoots.has(firstSegment)) return true;
8370
- return operationalFolders.some((f) => relPath2 === f || relPath2.startsWith(f + path4.sep));
8869
+ return operationalFolders.some((f) => relPath2 === f || relPath2.startsWith(f + path6.sep));
8371
8870
  };
8372
8871
  const getSectionEntries = (value) => {
8373
8872
  if (Array.isArray(value)) return value;
8374
8873
  if (value && typeof value === "object") return Object.values(value);
8375
8874
  return [];
8376
8875
  };
8377
- const normalizeRelativePath = (relPath2) => path4.normalize(relPath2).replace(/\\/g, "/").replace(/\/$/, "");
8876
+ const normalizeRelativePath = (relPath2) => path6.normalize(relPath2).replace(/\\/g, "/").replace(/\/$/, "");
8378
8877
  const isSourceDir = (dirPath) => {
8379
- const dirRelPath = path4.relative(worktree, dirPath);
8878
+ const dirRelPath = path6.relative(worktree, dirPath);
8380
8879
  if (isOperationalRelPath2(dirRelPath)) return false;
8381
- const items = fs4.readdirSync(dirPath, { withFileTypes: true });
8880
+ const items = fs7.readdirSync(dirPath, { withFileTypes: true });
8382
8881
  for (const item of items) {
8383
- const childPath = path4.join(dirPath, item.name);
8384
- const relPath2 = path4.relative(worktree, childPath);
8882
+ const childPath = path6.join(dirPath, item.name);
8883
+ const relPath2 = path6.relative(worktree, childPath);
8385
8884
  if (ig.ignores(relPath2) || isOperationalRelPath2(relPath2)) continue;
8386
- if (item.isFile() && sourceExtensions.includes(path4.extname(item.name))) return true;
8885
+ if (item.isFile() && sourceExtensions.includes(path6.extname(item.name))) return true;
8387
8886
  if (item.isDirectory()) {
8388
8887
  if (isSourceDir(childPath)) return true;
8389
8888
  }
@@ -8391,7 +8890,7 @@ async function optima_validate_logic(worktree) {
8391
8890
  return false;
8392
8891
  };
8393
8892
  function validateMap(filePath) {
8394
- const content = fs4.readFileSync(filePath, "utf8");
8893
+ const content = fs7.readFileSync(filePath, "utf8");
8395
8894
  let map;
8396
8895
  try {
8397
8896
  map = import_yaml2.default.parse(content);
@@ -8403,32 +8902,32 @@ async function optima_validate_logic(worktree) {
8403
8902
  errors.push(`${filePath}: Invalid YAML.`);
8404
8903
  return;
8405
8904
  }
8406
- const dir = path4.dirname(filePath);
8905
+ const dir = path6.dirname(filePath);
8407
8906
  const pathBase = filePath === rootCodemapPath ? worktree : dir;
8408
8907
  const indexedPaths = /* @__PURE__ */ new Set();
8409
8908
  const sectionsToVerify = ["modules", "entrypoints", "sources_of_truth", "links", "internals"];
8410
8909
  for (const section of sectionsToVerify) {
8411
8910
  for (const item of getSectionEntries(map[section])) {
8412
8911
  if (item?.path) {
8413
- indexedPaths.add(path4.normalize(item.path));
8912
+ indexedPaths.add(path6.normalize(item.path));
8414
8913
  if (section === "links" && (item.path.startsWith("http://") || item.path.startsWith("https://"))) {
8415
8914
  continue;
8416
8915
  }
8417
- const absPath = path4.isAbsolute(item.path) ? item.path : path4.join(pathBase, item.path);
8418
- if (!fs4.existsSync(absPath)) {
8916
+ const absPath = path6.isAbsolute(item.path) ? item.path : path6.join(pathBase, item.path);
8917
+ if (!fs7.existsSync(absPath)) {
8419
8918
  errors.push(`${filePath}: ${section.slice(0, -1)} path does not exist: ${item.path}`);
8420
8919
  }
8421
8920
  }
8422
8921
  }
8423
8922
  }
8424
- const relDir = path4.relative(worktree, dir);
8923
+ const relDir = path6.relative(worktree, dir);
8425
8924
  const isOperational = isOperationalRelPath2(relDir);
8426
8925
  if (map.scope === "module" && !isOperational) {
8427
- const items = fs4.readdirSync(dir, { withFileTypes: true });
8926
+ const items = fs7.readdirSync(dir, { withFileTypes: true });
8428
8927
  for (const item of items) {
8429
- if (item.isFile() && sourceExtensions.includes(path4.extname(item.name))) {
8928
+ if (item.isFile() && sourceExtensions.includes(path6.extname(item.name))) {
8430
8929
  if (item.name === "codemap.yml") continue;
8431
- if (!indexedPaths.has(path4.normalize(item.name))) {
8930
+ if (!indexedPaths.has(path6.normalize(item.name))) {
8432
8931
  errors.push(`${filePath}: Unindexed source file found: '${item.name}'. Every source file must be categorized in a section (e.g., 'internals').`);
8433
8932
  }
8434
8933
  }
@@ -8438,7 +8937,7 @@ async function optima_validate_logic(worktree) {
8438
8937
  for (const key of pathKeys) {
8439
8938
  for (const entry of getSectionEntries(map[key])) {
8440
8939
  if (!entry?.path || entry.path.startsWith("http://") || entry.path.startsWith("https://")) continue;
8441
- if (path4.isAbsolute(entry.path)) continue;
8940
+ if (path6.isAbsolute(entry.path)) continue;
8442
8941
  const normalizedPath = normalizeRelativePath(entry.path);
8443
8942
  if (!normalizedPath || normalizedPath === ".") continue;
8444
8943
  const parts = normalizedPath.split("/").filter((p) => p && p !== ".");
@@ -8450,18 +8949,18 @@ async function optima_validate_logic(worktree) {
8450
8949
  }
8451
8950
  }
8452
8951
  const walk = (dir) => {
8453
- const relDir = path4.relative(worktree, dir);
8952
+ const relDir = path6.relative(worktree, dir);
8454
8953
  if (relDir && ig.ignores(relDir)) return;
8455
8954
  if (isOperationalRelPath2(relDir)) return;
8456
8955
  if (isHiddenTree2(relDir)) return;
8457
- const hasCodemap = fs4.existsSync(path4.join(dir, "codemap.yml"));
8458
- const items = fs4.readdirSync(dir, { withFileTypes: true });
8459
- if (!relDir.startsWith(path4.join(".optima", "tasks", "done"))) {
8956
+ const hasCodemap = fs7.existsSync(path6.join(dir, "codemap.yml"));
8957
+ const items = fs7.readdirSync(dir, { withFileTypes: true });
8958
+ if (!relDir.startsWith(path6.join(".optima", "tasks", "done"))) {
8460
8959
  for (const item of items) {
8461
8960
  if (item.isFile() && item.name.endsWith(".md")) {
8462
- const content = fs4.readFileSync(path4.join(dir, item.name), "utf8");
8961
+ const content = fs7.readFileSync(path6.join(dir, item.name), "utf8");
8463
8962
  if (content.includes("[To be defined]") || content.includes("[Insert ")) {
8464
- const relFilePath = path4.join(relDir, item.name);
8963
+ const relFilePath = path6.join(relDir, item.name);
8465
8964
  errors.push(`Documentation Placeholder found: '${relFilePath}' still contains [To be defined] or [Insert ...] placeholders.`);
8466
8965
  }
8467
8966
  }
@@ -8471,9 +8970,9 @@ async function optima_validate_logic(worktree) {
8471
8970
  if (relDir !== "" && !hasCodemap && isSourceDir(dir) && !isOperational) {
8472
8971
  errors.push(`Missing CodeMap: Directory '${relDir}' contains source but has no codemap.yml.`);
8473
8972
  }
8474
- if (hasCodemap) validateMap(path4.join(dir, "codemap.yml"));
8973
+ if (hasCodemap) validateMap(path6.join(dir, "codemap.yml"));
8475
8974
  for (const item of items) {
8476
- if (item.isDirectory()) walk(path4.join(dir, item.name));
8975
+ if (item.isDirectory()) walk(path6.join(dir, item.name));
8477
8976
  }
8478
8977
  };
8479
8978
  validateMap(rootCodemapPath);
@@ -8486,14 +8985,14 @@ async function optima_validate_logic(worktree) {
8486
8985
  }
8487
8986
 
8488
8987
  // src/constants.js
8489
- import path5 from "node:path";
8988
+ import path7 from "node:path";
8490
8989
  import { fileURLToPath } from "node:url";
8491
- var PKG_ROOT = path5.resolve(path5.dirname(fileURLToPath(import.meta.url)), "..");
8492
- var BUNDLE_ASSETS_DIR = path5.join(PKG_ROOT, "assets");
8493
- var BUNDLE_AGENTS_DIR = path5.join(BUNDLE_ASSETS_DIR, "agents");
8494
- var BUNDLE_POLICIES_DIR = path5.join(BUNDLE_ASSETS_DIR, "policies");
8495
- var TEMPLATES_DIR = path5.join(PKG_ROOT, "templates");
8496
- var HUMANS_REGISTRY_PATH = path5.join(PKG_ROOT, "docs", "core", "humans.md");
8990
+ var PKG_ROOT = path7.resolve(path7.dirname(fileURLToPath(import.meta.url)), "..");
8991
+ var BUNDLE_ASSETS_DIR = path7.join(PKG_ROOT, "assets");
8992
+ var BUNDLE_AGENTS_DIR = path7.join(BUNDLE_ASSETS_DIR, "agents");
8993
+ var BUNDLE_POLICIES_DIR = path7.join(BUNDLE_ASSETS_DIR, "policies");
8994
+ var TEMPLATES_DIR = path7.join(PKG_ROOT, "templates");
8995
+ var HUMANS_REGISTRY_PATH = path7.join(PKG_ROOT, "docs", "core", "humans.md");
8497
8996
  var MANDATORY_AGENTS = /* @__PURE__ */ new Set(["product_manager", "business_analyst", "tech_lead"]);
8498
8997
  var MINI_MODE_AGENTS = /* @__PURE__ */ new Set(["product_manager", "business_analyst", "tech_lead"]);
8499
8998
  var CLICKUP_IGNORED_TASK_TYPES = ["Idea", "Backlog", "Hito", "Nota de reuni\xF3n", "Respuesta del formulario"];
@@ -8631,18 +9130,18 @@ var GITHUB_WEBHOOK_EVENTS = ["pull_request", "pull_request_review", "pull_reques
8631
9130
  var OPTIMA_GITHUB_COMMITTER_NAME = "Optima Product Manager";
8632
9131
  var OPTIMA_GITHUB_COMMITTER_EMAIL = "optima-product-manager[bot]@users.noreply.github.com";
8633
9132
  function isRootDirectory(candidate) {
8634
- const resolved = path6.resolve(candidate);
8635
- return resolved === path6.parse(resolved).root;
9133
+ const resolved = path8.resolve(candidate);
9134
+ return resolved === path8.parse(resolved).root;
8636
9135
  }
8637
9136
  function isSafeWritableDirectory(candidate) {
8638
9137
  if (typeof candidate !== "string" || !candidate.trim()) return false;
8639
- if (!path6.isAbsolute(candidate)) return false;
8640
- const resolved = path6.resolve(candidate);
9138
+ if (!path8.isAbsolute(candidate)) return false;
9139
+ const resolved = path8.resolve(candidate);
8641
9140
  if (isRootDirectory(resolved)) return false;
8642
9141
  try {
8643
- const stat = fs5.statSync(resolved);
9142
+ const stat = fs8.statSync(resolved);
8644
9143
  if (!stat.isDirectory()) return false;
8645
- fs5.accessSync(resolved, fs5.constants.W_OK);
9144
+ fs8.accessSync(resolved, fs8.constants.W_OK);
8646
9145
  return true;
8647
9146
  } catch {
8648
9147
  return false;
@@ -8654,11 +9153,11 @@ function resolveSafeWorktree(context = {}, pluginWorktree = null) {
8654
9153
  context?.directory,
8655
9154
  pluginWorktree,
8656
9155
  process.cwd(),
8657
- os.homedir()
9156
+ os2.homedir()
8658
9157
  ];
8659
9158
  for (const candidate of candidates) {
8660
9159
  if (typeof candidate !== "string" || !candidate.trim()) continue;
8661
- const resolved = path6.resolve(candidate);
9160
+ const resolved = path8.resolve(candidate);
8662
9161
  if (isSafeWritableDirectory(resolved)) return resolved;
8663
9162
  }
8664
9163
  throw new Error(SAFE_WORKTREE_FAILURE);
@@ -8673,13 +9172,13 @@ function safeWorktreeOrFailure(context, pluginWorktree) {
8673
9172
  function explicitSafeInputWorktree(input = {}) {
8674
9173
  for (const candidate of [input?.worktree, input?.directory]) {
8675
9174
  if (typeof candidate !== "string" || !candidate.trim()) continue;
8676
- const resolved = path6.resolve(candidate);
9175
+ const resolved = path8.resolve(candidate);
8677
9176
  if (isSafeWritableDirectory(resolved)) return resolved;
8678
9177
  }
8679
9178
  return null;
8680
9179
  }
8681
9180
  function isGitRepository(worktree) {
8682
- return fs5.existsSync(path6.join(worktree, ".git"));
9181
+ return fs8.existsSync(path8.join(worktree, ".git"));
8683
9182
  }
8684
9183
  function normalizeLooseToken(value) {
8685
9184
  return String(value ?? "").trim().normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
@@ -8713,8 +9212,8 @@ function parseHumansRegistry(markdown = "") {
8713
9212
  return roles;
8714
9213
  }
8715
9214
  function loadHumansRegistry(registryPath = HUMANS_REGISTRY_PATH) {
8716
- if (!fs5.existsSync(registryPath)) return {};
8717
- return parseHumansRegistry(fs5.readFileSync(registryPath, "utf8"));
9215
+ if (!fs8.existsSync(registryPath)) return {};
9216
+ return parseHumansRegistry(fs8.readFileSync(registryPath, "utf8"));
8718
9217
  }
8719
9218
  function resolveHumanRoles(roles = CLICKUP_FINAL_APPROVER_ROLES, registry = loadHumansRegistry()) {
8720
9219
  return [...new Set(roles.map((role) => registry[String(role ?? "").trim()] || "").filter(Boolean))];
@@ -8890,74 +9389,24 @@ function validateMainWorkspaceBranchSafety({ currentBranch, requiredBranch = "de
8890
9389
  const normalized = String(currentBranch ?? "").trim();
8891
9390
  if (!normalized) {
8892
9391
  return { ok: false, branch: normalized, message: "Unable to determine the current branch; expected main workspace on dev." };
8893
- }
8894
- if (normalized === forbiddenBranch) {
8895
- return { ok: false, branch: normalized, message: "Unsafe workspace branch: main is never allowed for Optima delivery work." };
8896
- }
8897
- if (normalized !== requiredBranch) {
8898
- return { ok: false, branch: normalized, message: `Unsafe workspace branch: expected ${requiredBranch}, got ${normalized}.` };
8899
- }
8900
- return { ok: true, branch: normalized, message: `Workspace branch is safe on ${requiredBranch}.` };
8901
- }
8902
- var CLICKUP_REQUIRED_SUMMARY_SECTIONS = [
8903
- "Summary",
8904
- "Work Performed",
8905
- "AC Coverage",
8906
- "Verification Results",
8907
- "Documentation Impact",
8908
- "Open Risks",
8909
- "Recommended Next Step"
8910
- ];
8911
- var CLICKUP_RAW_LOG_SECTION_NAMES = /* @__PURE__ */ new Set(["Raw Logs", "Logs", "Full Logs", "Command Output", "Transcript"]);
8912
- var CLICKUP_TRANSITIONS = /* @__PURE__ */ new Map([
8913
- ["plan->in progress", { status: "in progress", comment: "Plan complete; moving to implementation without generic CTO/PO assignment." }],
8914
- ["in progress->validation", { status: "validation", comment: "Implementation complete; ready for validation." }],
8915
- ["validation->merge", { status: "merge", assignFinalApprovers: true, parentOnlyFinalApproval: true, comment: "Parent validation passed with a functional preview URL; ready for CTO/PO approval flow." }],
8916
- ["validation->in progress", { status: "in progress", comment: "Validation failed; returning to implementation." }],
8917
- ["merge->completed", { status: "completed", comment: "Merge complete; closing delivery task." }],
8918
- ["completed->in progress", { status: "in progress", comment: "Task reopened; returning to implementation." }],
8919
- ["closed->in progress", { status: "in progress", comment: "Task reopened; returning to implementation." }]
8920
- ]);
8921
- function parseMarkdownSections(markdown = "") {
8922
- const sections = {};
8923
- let current = null;
8924
- let buffer = [];
8925
- const flush = () => {
8926
- if (!current) return;
8927
- sections[current] = buffer.join("\n").trim();
8928
- };
8929
- for (const line of String(markdown).split(/\r?\n/)) {
8930
- const heading = /^(#{2,3})\s+(.+?)\s*$/.exec(line);
8931
- if (heading) {
8932
- flush();
8933
- current = heading[2].trim();
8934
- buffer = [];
8935
- continue;
8936
- }
8937
- if (current) buffer.push(line);
8938
- }
8939
- flush();
8940
- return sections;
8941
- }
8942
- function parseMarkdownArtifact(markdown = "", { requiredSections = [] } = {}) {
8943
- const sections = parseMarkdownSections(markdown);
8944
- const missing = requiredSections.filter((section) => !sections[section]);
8945
- return {
8946
- ok: missing.length === 0,
8947
- sections,
8948
- missing,
8949
- message: missing.length ? `Missing required section(s): ${missing.join(", ")}` : "ok"
8950
- };
8951
- }
8952
- function readMarkdownArtifact(filePath, options = {}) {
8953
- const markdown = fs5.readFileSync(filePath, "utf8");
8954
- return parseMarkdownArtifact(markdown, options);
8955
- }
8956
- function stripRawLogSections(sections = {}) {
8957
- return Object.fromEntries(
8958
- Object.entries(sections).filter(([name]) => !CLICKUP_RAW_LOG_SECTION_NAMES.has(name))
8959
- );
9392
+ }
9393
+ if (normalized === forbiddenBranch) {
9394
+ return { ok: false, branch: normalized, message: "Unsafe workspace branch: main is never allowed for Optima delivery work." };
9395
+ }
9396
+ if (normalized !== requiredBranch) {
9397
+ return { ok: false, branch: normalized, message: `Unsafe workspace branch: expected ${requiredBranch}, got ${normalized}.` };
9398
+ }
9399
+ return { ok: true, branch: normalized, message: `Workspace branch is safe on ${requiredBranch}.` };
8960
9400
  }
9401
+ var CLICKUP_TRANSITIONS = /* @__PURE__ */ new Map([
9402
+ ["plan->in progress", { status: "in progress", comment: "Plan complete; moving to implementation without generic CTO/PO assignment." }],
9403
+ ["in progress->validation", { status: "validation", comment: "Implementation complete; ready for validation." }],
9404
+ ["validation->merge", { status: "merge", assignFinalApprovers: true, parentOnlyFinalApproval: true, comment: "Parent validation passed with a functional preview URL; ready for CTO/PO approval flow." }],
9405
+ ["validation->in progress", { status: "in progress", comment: "Validation failed; returning to implementation." }],
9406
+ ["merge->completed", { status: "completed", comment: "Merge complete; closing delivery task." }],
9407
+ ["completed->in progress", { status: "in progress", comment: "Task reopened; returning to implementation." }],
9408
+ ["closed->in progress", { status: "in progress", comment: "Task reopened; returning to implementation." }]
9409
+ ]);
8961
9410
  var CLICKUP_SUBTASK_REQUIRED_FIELDS = ["Type", "Owner Role", "Story Points", "Slice", "Acceptance Criteria"];
8962
9411
  var CLICKUP_SUBTASK_OPTIONAL_FIELDS = ["Depends On", "Branch", "Description", "Definition", "Documentation"];
8963
9412
  var CLICKUP_SUBTASK_KNOWN_FIELDS = /* @__PURE__ */ new Set([...CLICKUP_SUBTASK_REQUIRED_FIELDS, ...CLICKUP_SUBTASK_OPTIONAL_FIELDS]);
@@ -9161,7 +9610,7 @@ function buildClickUpApplyPayloadResult({ payload, apply = false } = {}) {
9161
9610
  noop: true,
9162
9611
  applied: false,
9163
9612
  message: "Dry-run only. Payload validated; no ClickUp calls were made.",
9164
- payload: parsed
9613
+ payload: normalizeClickUpPayloadComments(parsed)
9165
9614
  };
9166
9615
  }
9167
9616
  return {
@@ -9171,7 +9620,7 @@ function buildClickUpApplyPayloadResult({ payload, apply = false } = {}) {
9171
9620
  applyRequested: true,
9172
9621
  applied: false,
9173
9622
  message: "Live ClickUp execution is not implemented/configured in this safe boundary; no ClickUp calls were made.",
9174
- payload: parsed
9623
+ payload: normalizeClickUpPayloadComments(parsed)
9175
9624
  };
9176
9625
  }
9177
9626
  function sectionValue(sections, names) {
@@ -9181,7 +9630,7 @@ function sectionValue(sections, names) {
9181
9630
  return "";
9182
9631
  }
9183
9632
  function compactMarkdownValue(value = "") {
9184
- return String(value).split(/\r?\n/).map((line) => line.trimEnd()).join("\n").replace(/\n{3,}/g, "\n\n").trim();
9633
+ return normalizeClickUpMarkdown(value);
9185
9634
  }
9186
9635
  function buildClickUpSummaryPayload({ summaryMarkdown = "", summaryPath = "", taskMarkdown = "", taskPath = "", branch = "", worktree = "", pr = "" } = {}) {
9187
9636
  const parsedSummary = parseMarkdownArtifact(summaryMarkdown, { requiredSections: CLICKUP_REQUIRED_SUMMARY_SECTIONS });
@@ -9206,13 +9655,12 @@ function buildClickUpSummaryPayload({ summaryMarkdown = "", summaryPath = "", ta
9206
9655
  deliveryPath ? `- Delivery evidence: ${compactMarkdownValue(deliveryPath)}` : null,
9207
9656
  prValue ? `- PR: ${compactMarkdownValue(prValue)}` : null
9208
9657
  ].filter(Boolean);
9209
- const comment = [
9210
- "ClickUp sync payload generated from Optima Markdown artifacts.",
9211
- "",
9212
- ...commentParts.flatMap(([title, value]) => [`## ${title}`, compactMarkdownValue(value) || "Not specified.", ""]),
9213
- contextParts.length ? "## PR/Branch/Worktree" : null,
9214
- contextParts.length ? contextParts.join("\n") : null
9215
- ].filter((part) => part !== null).join("\n").trim();
9658
+ const comment = formatClickUpStatusComment({
9659
+ title: "Optima Delivery Summary",
9660
+ summary: "ClickUp sync payload generated from Optima Markdown artifacts.",
9661
+ sections: commentParts.map(([title, value]) => ({ title, body: compactMarkdownValue(value) || "Not specified." })),
9662
+ context: contextParts
9663
+ });
9216
9664
  return {
9217
9665
  ok: true,
9218
9666
  mode: "payload",
@@ -9238,7 +9686,7 @@ function buildClickUpSummaryPayload({ summaryMarkdown = "", summaryPath = "", ta
9238
9686
  function deriveClickUpWorktree({ baseWorktree = "", taskId, taskType, parentTaskId, subtaskId } = {}) {
9239
9687
  const branch = deriveClickUpBranchName({ taskType, parentTaskId, subtaskId, taskId });
9240
9688
  const root = baseWorktree || process.cwd();
9241
- return path6.join(path6.dirname(root), `${path6.basename(root)}-${branch.replace(/\//g, "-")}`);
9689
+ return path8.join(path8.dirname(root), `${path8.basename(root)}-${branch.replace(/\//g, "-")}`);
9242
9690
  }
9243
9691
  function clickUpCustomFieldValue(task = {}, names = []) {
9244
9692
  const fields = Array.isArray(task.custom_fields) ? task.custom_fields : [];
@@ -9262,12 +9710,12 @@ function safeExistingClickUpWorktree({ metadata = {}, branch = "" } = {}) {
9262
9710
  const taskMetadata = metadataTaskRouting(metadata);
9263
9711
  const existingWorktree = typeof taskMetadata.worktree === "string" ? taskMetadata.worktree.trim() : "";
9264
9712
  const existingBranch = typeof taskMetadata.branch === "string" ? taskMetadata.branch.trim() : "";
9265
- if (!existingWorktree || !path6.isAbsolute(existingWorktree) || !fs5.existsSync(existingWorktree)) return null;
9713
+ if (!existingWorktree || !path8.isAbsolute(existingWorktree) || !fs8.existsSync(existingWorktree)) return null;
9266
9714
  try {
9267
- const stat = fs5.statSync(existingWorktree);
9715
+ const stat = fs8.statSync(existingWorktree);
9268
9716
  if (!stat.isDirectory()) return null;
9269
9717
  if (branch && existingBranch && existingBranch !== branch) return null;
9270
- return { branch: existingBranch || branch, worktree: path6.resolve(existingWorktree), reused: true };
9718
+ return { branch: existingBranch || branch, worktree: path8.resolve(existingWorktree), reused: true };
9271
9719
  } catch {
9272
9720
  return null;
9273
9721
  }
@@ -9301,7 +9749,7 @@ function normalizeOptimaGitIdentity(identity = {}) {
9301
9749
  };
9302
9750
  }
9303
9751
  function configureOptimaWorktreeGitIdentity({ worktreePath, identity = {}, runGitFn = runGit } = {}) {
9304
- if (!worktreePath || !fs5.existsSync(worktreePath)) return { configured: false, reason: "worktree_missing" };
9752
+ if (!worktreePath || !fs8.existsSync(worktreePath)) return { configured: false, reason: "worktree_missing" };
9305
9753
  const normalized = normalizeOptimaGitIdentity(identity);
9306
9754
  if (!normalized.name || !normalized.email) return { configured: false, reason: "identity_missing" };
9307
9755
  try {
@@ -9387,17 +9835,17 @@ function openChamberEntryBranch(entry) {
9387
9835
  return String(entry?.branch || entry?.branchName || entry?.branch_name || entry?.worktree?.branch || "").replace(/^refs\/heads\//, "");
9388
9836
  }
9389
9837
  function openChamberListIncludesDirectory(list, directory) {
9390
- const resolved = path6.resolve(directory);
9838
+ const resolved = path8.resolve(directory);
9391
9839
  return normalizeOpenChamberCollection(list).some((entry) => {
9392
9840
  const entryDirectory = openChamberEntryDirectory(entry);
9393
- return entryDirectory && path6.resolve(entryDirectory) === resolved;
9841
+ return entryDirectory && path8.resolve(entryDirectory) === resolved;
9394
9842
  });
9395
9843
  }
9396
9844
  function openChamberListIncludesBranch(list, directory, branch) {
9397
- const resolved = path6.resolve(directory);
9845
+ const resolved = path8.resolve(directory);
9398
9846
  return normalizeOpenChamberCollection(list).some((entry) => {
9399
9847
  const entryDirectory = openChamberEntryDirectory(entry);
9400
- if (!entryDirectory || path6.resolve(entryDirectory) !== resolved) return false;
9848
+ if (!entryDirectory || path8.resolve(entryDirectory) !== resolved) return false;
9401
9849
  const entryBranch = openChamberEntryBranch(entry);
9402
9850
  return !entryBranch || entryBranch === branch;
9403
9851
  });
@@ -9405,8 +9853,8 @@ function openChamberListIncludesBranch(list, directory, branch) {
9405
9853
  async function findOpenChamberProject({ opencodeBaseUrl, baseWorktree, fetchImpl = globalThis.fetch } = {}) {
9406
9854
  const projects = await requestOpenCodeJson({ baseUrl: opencodeBaseUrl, endpoint: "/project", directory: baseWorktree, fetchImpl });
9407
9855
  if (!Array.isArray(projects)) return null;
9408
- const resolvedBase = path6.resolve(baseWorktree);
9409
- return projects.find((project) => path6.resolve(String(project?.worktree || project?.path || "")) === resolvedBase) || null;
9856
+ const resolvedBase = path8.resolve(baseWorktree);
9857
+ return projects.find((project) => path8.resolve(String(project?.worktree || project?.path || "")) === resolvedBase) || null;
9410
9858
  }
9411
9859
  async function refreshOpenChamberProjectCopy({ opencodeBaseUrl, projectId, fetchImpl = globalThis.fetch } = {}) {
9412
9860
  if (!projectId) return { refreshed: false, reason: "project_id_unavailable" };
@@ -9461,18 +9909,18 @@ async function createOpenChamberClickUpWorktree({ openchamberBaseUrl, baseUrl, b
9461
9909
  }
9462
9910
  const createdDirectory = openChamberEntryDirectory(created);
9463
9911
  const createdBranch = openChamberEntryBranch(created);
9464
- if (!createdDirectory || !path6.isAbsolute(createdDirectory)) {
9912
+ if (!createdDirectory || !path8.isAbsolute(createdDirectory)) {
9465
9913
  throw new Error(`OpenChamber did not return an absolute worktree path for ${branch}.`);
9466
9914
  }
9467
9915
  if (createdBranch !== branch) {
9468
9916
  throw new Error(`OpenChamber created unexpected branch ${createdBranch || "<unknown>"}; expected ${branch}.`);
9469
9917
  }
9470
9918
  const verified = await verifyOpenChamberGitWorktree({ openchamberBaseUrl: effectiveOpenChamberBaseUrl, baseWorktree, worktreePath: createdDirectory, branch, fetchImpl });
9471
- return { created, worktree: path6.resolve(createdDirectory), branch: createdBranch, verified };
9919
+ return { created, worktree: path8.resolve(createdDirectory), branch: createdBranch, verified };
9472
9920
  }
9473
9921
  async function registerOpenChamberClickUpWorktree({ openchamberBaseUrl, opencodeBaseUrl, baseUrl, baseWorktree, branch, worktreePath, fetchImpl = globalThis.fetch, source = "reuse" } = {}) {
9474
9922
  const visibility = await syncOpenChamberWorktreeVisibility({ openchamberBaseUrl: openchamberBaseUrl || baseUrl, opencodeBaseUrl: opencodeBaseUrl || baseUrl, baseWorktree, worktreePath, branch, fetchImpl });
9475
- return { branch, worktree: path6.resolve(worktreePath), reused: true, provider: "openchamber", openChamber: { source, visibility } };
9923
+ return { branch, worktree: path8.resolve(worktreePath), reused: true, provider: "openchamber", openChamber: { source, visibility } };
9476
9924
  }
9477
9925
  async function ensureClickUpTaskWorktreeOpenChamber({ baseWorktree = "", taskId, taskType = "Tarea", parentTaskId = "", subtaskId = "", existingMetadata = {}, runGitFn = runGit, openchamberBaseUrl = "", opencodeBaseUrl = "", baseUrl = "", fetchImpl = globalThis.fetch, log = null, gitIdentity = {} } = {}) {
9478
9926
  const effectiveOpenChamberBaseUrl = openchamberBaseUrl || baseUrl;
@@ -9490,7 +9938,7 @@ async function ensureClickUpTaskWorktreeOpenChamber({ baseWorktree = "", taskId,
9490
9938
  return { ...registered, parentBranch: parentBranch || void 0, prTarget, gitIdentity: identity2 };
9491
9939
  }
9492
9940
  const worktreePath = deriveClickUpWorktree({ baseWorktree, taskId, taskType, parentTaskId: effectiveParent, subtaskId });
9493
- if (fs5.existsSync(worktreePath)) {
9941
+ if (fs8.existsSync(worktreePath)) {
9494
9942
  const registered = await registerOpenChamberClickUpWorktree({ openchamberBaseUrl: effectiveOpenChamberBaseUrl, opencodeBaseUrl: effectiveOpenCodeBaseUrl, baseWorktree, branch, worktreePath, fetchImpl, source: "existing_directory" });
9495
9943
  const identity2 = configureOptimaWorktreeGitIdentity({ worktreePath: registered.worktree, identity: gitIdentity, runGitFn });
9496
9944
  log?.({ type: "openchamber_worktree_registered", taskId, branch, worktree: registered.worktree, source: "existing_directory", visibility: registered.openChamber.visibility });
@@ -9499,7 +9947,7 @@ async function ensureClickUpTaskWorktreeOpenChamber({ baseWorktree = "", taskId,
9499
9947
  let parentBootstrap = null;
9500
9948
  if (isSubtask) {
9501
9949
  const parentWorktree = deriveClickUpWorktree({ baseWorktree, taskId: effectiveParent, taskType, parentTaskId: effectiveParent });
9502
- if (fs5.existsSync(parentWorktree)) {
9950
+ if (fs8.existsSync(parentWorktree)) {
9503
9951
  const registeredParent = await registerOpenChamberClickUpWorktree({ openchamberBaseUrl: effectiveOpenChamberBaseUrl, opencodeBaseUrl: effectiveOpenCodeBaseUrl, baseWorktree, branch: parentBranch, worktreePath: parentWorktree, fetchImpl, source: "parent_existing_directory" });
9504
9952
  const parentIdentity = configureOptimaWorktreeGitIdentity({ worktreePath: registeredParent.worktree, identity: gitIdentity, runGitFn });
9505
9953
  parentBootstrap = { branch: parentBranch, worktree: registeredParent.worktree, reused: true, provider: "openchamber", visibility: registeredParent.openChamber.visibility };
@@ -9542,33 +9990,33 @@ function ensureClickUpTaskWorktree({ baseWorktree = "", taskId, taskType = "Tare
9542
9990
  const existing = safeExistingClickUpWorktree({ metadata: existingMetadata, branch });
9543
9991
  if (existing) return { ...existing, branch, parentBranch: parentBranch || void 0, prTarget: parentBranch || "dev", gitIdentity: configureOptimaWorktreeGitIdentity({ worktreePath: existing.worktree, identity: gitIdentity, runGitFn }) };
9544
9992
  const worktreePath = deriveClickUpWorktree({ baseWorktree, taskId, taskType, parentTaskId: effectiveParent, subtaskId });
9545
- if (fs5.existsSync(worktreePath)) {
9546
- const resolvedWorktree2 = path6.resolve(worktreePath);
9993
+ if (fs8.existsSync(worktreePath)) {
9994
+ const resolvedWorktree2 = path8.resolve(worktreePath);
9547
9995
  return { branch, worktree: resolvedWorktree2, reused: true, parentBranch: parentBranch || void 0, prTarget: parentBranch || "dev", gitIdentity: configureOptimaWorktreeGitIdentity({ worktreePath: resolvedWorktree2, identity: gitIdentity, runGitFn }) };
9548
9996
  }
9549
9997
  if (allowNonGitFallback) {
9550
- fs5.mkdirSync(worktreePath, { recursive: true });
9551
- return { branch, worktree: path6.resolve(worktreePath), reused: false, fallback: "non_git", parentBranch: parentBranch || void 0, prTarget: parentBranch || "dev", startPoint: parentBranch || "dev" };
9998
+ fs8.mkdirSync(worktreePath, { recursive: true });
9999
+ return { branch, worktree: path8.resolve(worktreePath), reused: false, fallback: "non_git", parentBranch: parentBranch || void 0, prTarget: parentBranch || "dev", startPoint: parentBranch || "dev" };
9552
10000
  }
9553
10001
  let parentBootstrap = null;
9554
10002
  if (isSubtask) {
9555
10003
  const parentWorktree = deriveClickUpWorktree({ baseWorktree, taskId: effectiveParent, taskType, parentTaskId: effectiveParent });
9556
- if (!fs5.existsSync(parentWorktree)) {
10004
+ if (!fs8.existsSync(parentWorktree)) {
9557
10005
  const parentStartPoint = resolveClickUpDevStartPoint(baseWorktree, runGitFn);
9558
10006
  const parentBranchExists = clickUpGitRefExists(baseWorktree, parentBranch, runGitFn);
9559
10007
  addClickUpWorktreeForBranch({ baseWorktree, branch: parentBranch, worktreePath: parentWorktree, startPoint: parentStartPoint, runGitFn });
9560
- parentBootstrap = { branch: parentBranch, worktree: path6.resolve(parentWorktree), startPoint: parentBranchExists ? parentBranch : parentStartPoint, reused: parentBranchExists };
10008
+ parentBootstrap = { branch: parentBranch, worktree: path8.resolve(parentWorktree), startPoint: parentBranchExists ? parentBranch : parentStartPoint, reused: parentBranchExists };
9561
10009
  const parentIdentity = configureOptimaWorktreeGitIdentity({ worktreePath: parentBootstrap.worktree, identity: gitIdentity, runGitFn });
9562
10010
  if (parentIdentity.configured) parentBootstrap.gitIdentity = parentIdentity;
9563
10011
  } else {
9564
- parentBootstrap = { branch: parentBranch, worktree: path6.resolve(parentWorktree), reused: true };
10012
+ parentBootstrap = { branch: parentBranch, worktree: path8.resolve(parentWorktree), reused: true };
9565
10013
  const parentIdentity = configureOptimaWorktreeGitIdentity({ worktreePath: parentBootstrap.worktree, identity: gitIdentity, runGitFn });
9566
10014
  if (parentIdentity.configured) parentBootstrap.gitIdentity = parentIdentity;
9567
10015
  }
9568
10016
  }
9569
10017
  const startPoint = isSubtask ? parentBranch : resolveClickUpDevStartPoint(baseWorktree, runGitFn);
9570
10018
  addClickUpWorktreeForBranch({ baseWorktree, branch, worktreePath, startPoint, runGitFn });
9571
- const resolvedWorktree = path6.resolve(worktreePath);
10019
+ const resolvedWorktree = path8.resolve(worktreePath);
9572
10020
  return { branch, worktree: resolvedWorktree, reused: false, startPoint, parentBranch: parentBranch || void 0, prTarget: parentBranch || "dev", parentBootstrap: parentBootstrap || void 0, gitIdentity: configureOptimaWorktreeGitIdentity({ worktreePath: resolvedWorktree, identity: gitIdentity, runGitFn }) };
9573
10021
  }
9574
10022
  function normalizeClickUpDefinitionDocParent(parent = {}) {
@@ -9651,7 +10099,17 @@ function buildClickUpStartTaskPayload({ taskId, taskType = "Tarea", parentTaskId
9651
10099
  wouldCreate: true
9652
10100
  },
9653
10101
  clickup: {
9654
- comment: `Starting task from ${startFrom}. Branch: ${branch}. Worktree: ${worktree}. Validation PR target: ${requiredPullRequest.targetBranch}. Delivery evidence: ${deliveryEvidencePathForClickUpTask(taskId || subtaskId || effectiveParent)}.`,
10102
+ comment: formatClickUpStatusComment({
10103
+ title: "Task Workspace Ready",
10104
+ summary: "Optima prepared the task workspace and validation target.",
10105
+ context: [
10106
+ `Branch: ${branch}`,
10107
+ `Start from: ${startFrom}`,
10108
+ `Worktree: ${worktree}`,
10109
+ `Validation PR target: ${requiredPullRequest.targetBranch}`,
10110
+ `Delivery evidence: ${deliveryEvidencePathForClickUpTask(taskId || subtaskId || effectiveParent)}`
10111
+ ]
10112
+ }),
9655
10113
  description,
9656
10114
  fields: {
9657
10115
  Definition: definitionContent,
@@ -9737,7 +10195,18 @@ function buildClickUpTransitionPayload({ fromStatus, toStatus, validationPassed
9737
10195
  remove: removalTargets,
9738
10196
  objective: assignsFinalApprovers ? "zero_product_manager_assigned_tasks" : "preserve_existing_owner_policy"
9739
10197
  },
9740
- comment: rule.comment,
10198
+ comment: formatClickUpStatusComment({
10199
+ title: "Workflow Status Update",
10200
+ summary: rule.comment,
10201
+ context: [
10202
+ `From: ${from}`,
10203
+ `To: ${rule.status}`,
10204
+ requiredPullRequest?.prUrl ? `PR: ${requiredPullRequest.prUrl}` : null,
10205
+ requiredPullRequest?.prNumber ? `PR number: ${requiredPullRequest.prNumber}` : null,
10206
+ requiredPullRequest?.sourceBranch ? `Source branch: ${requiredPullRequest.sourceBranch}` : null,
10207
+ requiredPullRequest?.targetBranch ? `Target branch: ${requiredPullRequest.targetBranch}` : null
10208
+ ].filter(Boolean)
10209
+ }),
9741
10210
  description,
9742
10211
  fields,
9743
10212
  definition_doc: definitionContent ? {
@@ -9750,8 +10219,8 @@ function buildClickUpTransitionPayload({ fromStatus, toStatus, validationPassed
9750
10219
  }
9751
10220
  function ensureOptimaGitignoreRules(worktree) {
9752
10221
  if (!isGitRepository(worktree)) return { touched: false, added: [] };
9753
- const gitignorePath = path6.join(worktree, ".gitignore");
9754
- const existing = fs5.existsSync(gitignorePath) ? fs5.readFileSync(gitignorePath, "utf8") : "";
10222
+ const gitignorePath = path8.join(worktree, ".gitignore");
10223
+ const existing = fs8.existsSync(gitignorePath) ? fs8.readFileSync(gitignorePath, "utf8") : "";
9755
10224
  const existingRules = new Set(existing.split(/\r?\n/).map((line) => line.trim()).filter(Boolean));
9756
10225
  const missingRules = OPTIMA_GITIGNORE_RULES.filter((rule) => !existingRules.has(rule));
9757
10226
  if (missingRules.length === 0) return { touched: false, added: [] };
@@ -9761,45 +10230,45 @@ function ensureOptimaGitignoreRules(worktree) {
9761
10230
  "# Optima local/private state",
9762
10231
  ...missingRules
9763
10232
  ].join("\n");
9764
- fs5.writeFileSync(gitignorePath, `${existing}${prefix}${separator}${block}
10233
+ fs8.writeFileSync(gitignorePath, `${existing}${prefix}${separator}${block}
9765
10234
  `, "utf8");
9766
10235
  return { touched: true, added: missingRules };
9767
10236
  }
9768
10237
  function optimaDir(worktree) {
9769
- return path6.join(worktree, OPTIMA_DIRNAME);
10238
+ return path8.join(worktree, OPTIMA_DIRNAME);
9770
10239
  }
9771
10240
  function optimaLocalConfigDir(worktree) {
9772
- return path6.join(optimaDir(worktree), ".config");
10241
+ return path8.join(optimaDir(worktree), ".config");
9773
10242
  }
9774
10243
  function optimaConfigDir(worktree) {
9775
10244
  return optimaLocalConfigDir(worktree);
9776
10245
  }
9777
10246
  function optimaCodemapPath(worktree) {
9778
- return path6.join(optimaDir(worktree), "codemap.yml");
10247
+ return path8.join(optimaDir(worktree), "codemap.yml");
9779
10248
  }
9780
10249
  function optimaTasksDir(worktree) {
9781
- return path6.join(optimaDir(worktree), "tasks");
10250
+ return path8.join(optimaDir(worktree), "tasks");
9782
10251
  }
9783
10252
  function optimaEvidencesDir(worktree) {
9784
- return path6.join(optimaDir(worktree), "evidences");
10253
+ return path8.join(optimaDir(worktree), "evidences");
9785
10254
  }
9786
10255
  function optimaScrsDir(worktree) {
9787
- return path6.join(optimaDir(worktree), "docs", "scrs");
10256
+ return path8.join(optimaDir(worktree), "docs", "scrs");
9788
10257
  }
9789
10258
  function legacyNomadworkDir(worktree) {
9790
- return path6.join(worktree, LEGACY_NOMADWORK_DIRNAME);
10259
+ return path8.join(worktree, LEGACY_NOMADWORK_DIRNAME);
9791
10260
  }
9792
10261
  function legacyNomadworksDir(worktree) {
9793
- return path6.join(worktree, LEGACY_NOMADWORKS_DIRNAME);
10262
+ return path8.join(worktree, LEGACY_NOMADWORKS_DIRNAME);
9794
10263
  }
9795
10264
  function legacyOrbitaDir(worktree) {
9796
- return path6.join(worktree, LEGACY_ORBITA_DIRNAME);
10265
+ return path8.join(worktree, LEGACY_ORBITA_DIRNAME);
9797
10266
  }
9798
10267
  function legacyStaticEngDir(worktree) {
9799
- return path6.join(worktree, LEGACY_STATICENG_DIRNAME);
10268
+ return path8.join(worktree, LEGACY_STATICENG_DIRNAME);
9800
10269
  }
9801
10270
  function repoConfigPath(worktree) {
9802
- return path6.join(optimaConfigDir(worktree), "optima.yaml");
10271
+ return path8.join(optimaConfigDir(worktree), "optima.yaml");
9803
10272
  }
9804
10273
  function normalizeLegacyDiscussionEntry(entry) {
9805
10274
  if (!entry || typeof entry !== "object") return entry;
@@ -9812,25 +10281,25 @@ function normalizeLegacyDiscussionEntry(entry) {
9812
10281
  return next;
9813
10282
  }
9814
10283
  function repoPoliciesDir(worktree) {
9815
- return path6.join(optimaDir(worktree), "policies");
10284
+ return path8.join(optimaDir(worktree), "policies");
9816
10285
  }
9817
10286
  function generatedPoliciesDir(worktree) {
9818
- return path6.join(optimaLocalConfigDir(worktree), "generated", "policies");
10287
+ return path8.join(optimaLocalConfigDir(worktree), "generated", "policies");
9819
10288
  }
9820
10289
  function generatedAgentsDir(worktree) {
9821
- return path6.join(optimaLocalConfigDir(worktree), "generated", "agents");
10290
+ return path8.join(optimaLocalConfigDir(worktree), "generated", "agents");
9822
10291
  }
9823
10292
  function repoAgentsDir(worktree) {
9824
- return path6.join(optimaDir(worktree), "agents");
10293
+ return path8.join(optimaDir(worktree), "agents");
9825
10294
  }
9826
10295
  function repoAgentAdditionsDir(worktree) {
9827
- return path6.join(optimaDir(worktree), "agent-additions");
10296
+ return path8.join(optimaDir(worktree), "agent-additions");
9828
10297
  }
9829
10298
  function legacyRepoAgentsDir(worktree) {
9830
- return path6.join(legacyNomadworksDir(worktree), "agents");
10299
+ return path8.join(legacyNomadworksDir(worktree), "agents");
9831
10300
  }
9832
10301
  function runtimeDiscussionRegistryPath(worktree) {
9833
- return path6.join(optimaLocalConfigDir(worktree), "runtime", "discussions.json");
10302
+ return path8.join(optimaLocalConfigDir(worktree), "runtime", "discussions.json");
9834
10303
  }
9835
10304
  function resolveConfigPath(worktree) {
9836
10305
  return repoConfigPath(worktree);
@@ -9873,32 +10342,32 @@ function mergeClickUpAgentMetadata(existing, update = {}) {
9873
10342
  return JSON.stringify(sortJsonValue(merged), null, 2);
9874
10343
  }
9875
10344
  function optimaRuntimeDir(worktree) {
9876
- return path6.join(optimaLocalConfigDir(worktree), "runtime");
10345
+ return path8.join(optimaLocalConfigDir(worktree), "runtime");
9877
10346
  }
9878
10347
  function clickUpWebhookStatePath(worktree) {
9879
- return path6.join(optimaRuntimeDir(worktree), "clickup-webhook.json");
10348
+ return path8.join(optimaRuntimeDir(worktree), "clickup-webhook.json");
9880
10349
  }
9881
10350
  function clickUpCommentLedgerPath(worktree) {
9882
- return path6.join(optimaRuntimeDir(worktree), "clickup-comment-ledger.jsonl");
10351
+ return path8.join(optimaRuntimeDir(worktree), "clickup-comment-ledger.jsonl");
9883
10352
  }
9884
10353
  function clickUpWebhookLogPath(worktree) {
9885
- return path6.join(optimaRuntimeDir(worktree), "clickup-webhook.log.jsonl");
10354
+ return path8.join(optimaRuntimeDir(worktree), "clickup-webhook.log.jsonl");
9886
10355
  }
9887
10356
  function normalizeClickUpWebhookLogLevel(value) {
9888
10357
  const level = String(value || "info").trim().toLowerCase();
9889
10358
  return CLICKUP_WEBHOOK_LOG_LEVELS.has(level) ? level : "info";
9890
10359
  }
9891
10360
  function clickUpWebhookAuditLogDir() {
9892
- 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");
9893
- return path6.join(dataHome, "opencode-optima");
10361
+ const dataHome = process.env.XDG_DATA_HOME && path8.isAbsolute(process.env.XDG_DATA_HOME) ? process.env.XDG_DATA_HOME : path8.join(os2.homedir(), ".local", "share", "opencode");
10362
+ return path8.join(dataHome, "opencode-optima");
9894
10363
  }
9895
10364
  function clickUpWebhookAuditLogPath(at = /* @__PURE__ */ new Date(), logDir = clickUpWebhookAuditLogDir()) {
9896
- return path6.join(logDir, `clickup-webhook-${at.toISOString().slice(0, 10)}.jsonl`);
10365
+ return path8.join(logDir, `clickup-webhook-${at.toISOString().slice(0, 10)}.jsonl`);
9897
10366
  }
9898
10367
  function clickUpWebhookRequestFilePath(at = /* @__PURE__ */ new Date(), logDir = clickUpWebhookAuditLogDir()) {
9899
10368
  const stamp = at.toISOString().replace(/:/g, "-").replace(/\./g, "-");
9900
- const shortId = crypto.randomBytes(4).toString("hex");
9901
- return path6.join(logDir, "requests", `clickup-webhook-${stamp}-${shortId}.json`);
10369
+ const shortId = crypto2.randomBytes(4).toString("hex");
10370
+ return path8.join(logDir, "requests", `clickup-webhook-${stamp}-${shortId}.json`);
9902
10371
  }
9903
10372
  function findOptimaPluginTupleOptions(pluginEntries = []) {
9904
10373
  if (!Array.isArray(pluginEntries)) return null;
@@ -10058,7 +10527,7 @@ function normalizeClickUpWebhookConfig(rawClickUp = null, worktree = process.cwd
10058
10527
  };
10059
10528
  const errors = [];
10060
10529
  if (!config.enabled) errors.push("clickup.enabled must be true");
10061
- if (!config.basePath || !path6.isAbsolute(config.basePath)) errors.push("clickup.base_path must be an absolute path");
10530
+ if (!config.basePath || !path8.isAbsolute(config.basePath)) errors.push("clickup.base_path must be an absolute path");
10062
10531
  if (!config.teamId) errors.push("clickup.team_id is required");
10063
10532
  if (!config.apiToken) errors.push("clickup.api_token is required");
10064
10533
  if (!config.webhook.publicUrl) errors.push("clickup.webhook.public_url is required");
@@ -10121,503 +10590,94 @@ function sanitizeClickUpWebhookState(state = {}, config = null) {
10121
10590
  }
10122
10591
  function readClickUpWebhookState(worktree, config = null) {
10123
10592
  const statePath = clickUpWebhookStatePath(worktree);
10124
- if (!fs5.existsSync(statePath)) return sanitizeClickUpWebhookState({}, config);
10593
+ if (!fs8.existsSync(statePath)) return sanitizeClickUpWebhookState({}, config);
10125
10594
  try {
10126
- return sanitizeClickUpWebhookState(JSON.parse(fs5.readFileSync(statePath, "utf8")), config);
10595
+ return sanitizeClickUpWebhookState(JSON.parse(fs8.readFileSync(statePath, "utf8")), config);
10127
10596
  } catch {
10128
10597
  return sanitizeClickUpWebhookState({}, config);
10129
10598
  }
10130
10599
  }
10131
10600
  function writeClickUpWebhookState(worktree, state, config = null) {
10132
10601
  const statePath = clickUpWebhookStatePath(worktree);
10133
- fs5.mkdirSync(path6.dirname(statePath), { recursive: true, mode: 448 });
10602
+ fs8.mkdirSync(path8.dirname(statePath), { recursive: true, mode: 448 });
10134
10603
  const next = sanitizeClickUpWebhookState(state, config);
10135
- fs5.writeFileSync(statePath, `${JSON.stringify(next, null, 2)}
10604
+ fs8.writeFileSync(statePath, `${JSON.stringify(next, null, 2)}
10136
10605
  `, { encoding: "utf8", mode: 384 });
10137
10606
  try {
10138
- fs5.chmodSync(statePath, 384);
10607
+ fs8.chmodSync(statePath, 384);
10139
10608
  } catch {
10140
10609
  }
10141
10610
  return next;
10142
10611
  }
10143
10612
  function isClickUpWebhookStateActive(state, config) {
10144
- const expectedEvents = new Set(config?.webhook?.events || []);
10145
- const actualEvents = new Set(state?.events || []);
10146
- const hasEvents = [...expectedEvents].every((event) => actualEvents.has(event));
10147
- return Boolean(
10148
- state?.active && state?.webhookId && state?.secret && state?.publicUrl === config?.webhook?.publicUrl && hasEvents
10149
- );
10150
- }
10151
- function expandHomePath(value = "") {
10152
- const input = String(value || "").trim();
10153
- if (input === "~") return os.homedir();
10154
- if (input.startsWith("~/")) return path6.join(os.homedir(), input.slice(2));
10155
- return input;
10156
- }
10157
- function resolveSecretReference(value = "") {
10158
- const raw = String(value || "").trim();
10159
- const envMatch = raw.match(/^\{env:([A-Za-z_][A-Za-z0-9_]*)\}$/);
10160
- if (envMatch) return process.env[envMatch[1]] || "";
10161
- const fileMatch = raw.match(/^\{file:(.+)\}$/);
10162
- if (fileMatch) {
10163
- try {
10164
- return fs5.readFileSync(expandHomePath(fileMatch[1]), "utf8").trim();
10165
- } catch {
10166
- return "";
10167
- }
10168
- }
10169
- return raw;
10170
- }
10171
- function createClickUpApiClient(config, fetchImpl = globalThis.fetch) {
10172
- const token = resolveSecretReference(config?.apiToken);
10173
- const request = async (url, options = {}) => {
10174
- if (typeof fetchImpl !== "function") throw new Error("fetch is unavailable; inject a ClickUp client for live webhook setup");
10175
- if (!token) throw new Error("ClickUp API token is not available");
10176
- const response = await fetchImpl(url, {
10177
- ...options,
10178
- headers: {
10179
- Authorization: token,
10180
- "Content-Type": "application/json",
10181
- ...options.headers || {}
10182
- }
10183
- });
10184
- if (!response.ok) throw new Error(`ClickUp API request failed: ${response.status}`);
10185
- return response.json();
10186
- };
10187
- return {
10188
- async createWebhook({ endpoint, events, location }) {
10189
- const body = { endpoint, events, ...Object.fromEntries(Object.entries(location || {}).filter(([, value]) => value)) };
10190
- return request(`https://api.clickup.com/api/v2/team/${encodeURIComponent(config.teamId)}/webhook`, {
10191
- method: "POST",
10192
- body: JSON.stringify(body)
10193
- });
10194
- },
10195
- async listWebhooks() {
10196
- return request(`https://api.clickup.com/api/v2/team/${encodeURIComponent(config.teamId)}/webhook`);
10197
- },
10198
- async deleteWebhook(webhookId) {
10199
- return request(`https://api.clickup.com/api/v2/webhook/${encodeURIComponent(webhookId)}`, { method: "DELETE" });
10200
- },
10201
- async getAuthorizedUser() {
10202
- return request("https://api.clickup.com/api/v2/user");
10203
- },
10204
- async getTask(taskId) {
10205
- return request(`https://api.clickup.com/api/v2/task/${encodeURIComponent(taskId)}`);
10206
- },
10207
- async updateTaskMetadata({ taskId, fieldId, value }) {
10208
- return request(`https://api.clickup.com/api/v2/task/${encodeURIComponent(taskId)}/field/${encodeURIComponent(fieldId)}`, {
10209
- method: "POST",
10210
- body: JSON.stringify({ value })
10211
- });
10212
- },
10213
- async postTaskComment() {
10214
- throw new Error("Optima runtime does not post ClickUp task comments; use local logs for process failures.");
10215
- },
10216
- async addTaskTag() {
10217
- throw new Error("Optima runtime does not add ClickUp task tags; use local logs for process failures.");
10218
- },
10219
- async listAssignedTasks({ assigneeId, statuses = [], limit = CLICKUP_WEBHOOK_STARTUP_TASK_LIMIT } = {}) {
10220
- const params = new URLSearchParams();
10221
- if (assigneeId) params.append("assignees[]", assigneeId);
10222
- for (const status of statuses) if (status) params.append("statuses[]", status);
10223
- if (limit) params.append("limit", String(limit));
10224
- return request(`https://api.clickup.com/api/v2/team/${encodeURIComponent(config.teamId)}/task?${params.toString()}`);
10225
- },
10226
- async getTaskComments({ taskId, start, limit = CLICKUP_WEBHOOK_STARTUP_COMMENT_LIMIT } = {}) {
10227
- const params = new URLSearchParams();
10228
- if (start) params.set("start", String(start));
10229
- if (limit) params.set("limit", String(limit));
10230
- const suffix = params.toString() ? `?${params.toString()}` : "";
10231
- return request(`https://api.clickup.com/api/v2/task/${encodeURIComponent(taskId)}/comment${suffix}`);
10232
- }
10233
- };
10234
- }
10235
- function base64UrlJson(value) {
10236
- return Buffer.from(JSON.stringify(value)).toString("base64url");
10237
- }
10238
- function resolveGitHubAppPrivateKey(app = {}) {
10239
- const direct = resolveSecretReference(app.privateKey || "");
10240
- if (direct) return direct.replace(/\\n/g, "\n");
10241
- const file = expandHomePath(app.privateKeyFile || "");
10242
- if (!file) return "";
10243
- try {
10244
- return fs5.readFileSync(file, "utf8").trim().replace(/\\n/g, "\n");
10245
- } catch {
10246
- return "";
10247
- }
10248
- }
10249
- function createGitHubAppJwt({ appId, privateKey, now = () => /* @__PURE__ */ new Date() } = {}) {
10250
- const key = String(privateKey || "").trim();
10251
- const issuer = String(appId || "").trim();
10252
- if (!issuer || !key) throw new Error("GitHub App app_id and private key are required");
10253
- const nowSeconds = Math.floor(now().getTime() / 1e3);
10254
- const header = base64UrlJson({ alg: "RS256", typ: "JWT" });
10255
- const payload = base64UrlJson({ iat: nowSeconds - 60, exp: nowSeconds + 540, iss: issuer });
10256
- const unsigned = `${header}.${payload}`;
10257
- const signature = crypto.createSign("RSA-SHA256").update(unsigned).end().sign(key, "base64url");
10258
- return `${unsigned}.${signature}`;
10259
- }
10260
- function encodeGitHubPathSegment(value) {
10261
- return encodeURIComponent(String(value || ""));
10262
- }
10263
- function encodeGitHubBranchRef(branch = "") {
10264
- return String(branch || "").split("/").map(encodeGitHubPathSegment).join("/");
10265
- }
10266
- function parseNullSeparatedGitOutput(output = "") {
10267
- return String(output || "").split("\0").map((item) => item.trim()).filter(Boolean);
10268
- }
10269
- function listWorktreeChangedPaths(worktree, runGitFn = runGit) {
10270
- const tracked = parseNullSeparatedGitOutput(runGitFn(worktree, ["diff", "--name-only", "-z", "HEAD", "--"]));
10271
- const untracked = parseNullSeparatedGitOutput(runGitFn(worktree, ["ls-files", "--others", "--exclude-standard", "-z", "--"]));
10272
- return [.../* @__PURE__ */ new Set([...tracked, ...untracked])].filter((item) => item && !item.startsWith("../") && !path6.isAbsolute(item));
10273
- }
10274
- function currentGitBranch(worktree, runGitFn = runGit) {
10275
- return String(runGitFn(worktree, ["rev-parse", "--abbrev-ref", "HEAD"]) || "").trim();
10276
- }
10277
- function treeEntryForWorktreePath(worktree, gitPath) {
10278
- const absolutePath = path6.join(worktree, ...String(gitPath || "").split("/"));
10279
- if (!fs5.existsSync(absolutePath)) return { path: gitPath, mode: "100644", type: "blob", sha: null, deleted: true };
10280
- const stat = fs5.lstatSync(absolutePath);
10281
- if (stat.isDirectory()) return null;
10282
- if (stat.isSymbolicLink()) {
10283
- return {
10284
- path: gitPath,
10285
- mode: "120000",
10286
- type: "blob",
10287
- content: fs5.readlinkSync(absolutePath),
10288
- encoding: "utf-8"
10289
- };
10290
- }
10291
- return {
10292
- path: gitPath,
10293
- mode: stat.mode & 73 ? "100755" : "100644",
10294
- type: "blob",
10295
- content: fs5.readFileSync(absolutePath).toString("base64"),
10296
- encoding: "base64"
10297
- };
10298
- }
10299
- function appendGitHubQuery(pathname, params = {}) {
10300
- const query = new URLSearchParams();
10301
- for (const [key, value] of Object.entries(params || {})) {
10302
- if (value === void 0 || value === null || value === "") continue;
10303
- query.set(key, String(value));
10304
- }
10305
- const suffix = query.toString();
10306
- return suffix ? `${pathname}?${suffix}` : pathname;
10307
- }
10308
- function timestampMs(value = "") {
10309
- const parsed = Date.parse(String(value || ""));
10310
- return Number.isFinite(parsed) ? parsed : 0;
10311
- }
10312
- function sortNewestFirst(items = []) {
10313
- return [...items].sort((a, b) => {
10314
- const bTime = Math.max(timestampMs(b?.updated_at), timestampMs(b?.created_at));
10315
- const aTime = Math.max(timestampMs(a?.updated_at), timestampMs(a?.created_at));
10316
- return bTime - aTime;
10317
- });
10318
- }
10319
- function matchesVercelStatusContext(context = "", expected = "") {
10320
- const actual = String(context || "").trim();
10321
- const wanted = String(expected || "").trim();
10322
- if (wanted && actual === wanted) return true;
10323
- const lower = actual.toLowerCase();
10324
- if (!lower.includes("vercel")) return false;
10325
- if (!wanted) return lower.includes("preproduction") || lower.includes("defend-preproduction");
10326
- const wantedLower = wanted.toLowerCase();
10327
- return wantedLower.split(/\s+|–|-/).filter((part) => part && part !== "vercel").every((part) => lower.includes(part));
10328
- }
10329
- function selectFunctionalDeploymentUrl(status = {}, deployment = {}) {
10330
- for (const candidate of [
10331
- status?.environment_url,
10332
- deployment?.environment_url,
10333
- status?.target_url,
10334
- deployment?.target_url
10335
- ]) {
10336
- const value = String(candidate || "").trim();
10337
- if (!value) continue;
10338
- try {
10339
- const url = new URL(value);
10340
- if (url.protocol === "http:" || url.protocol === "https:") return value;
10341
- } catch {
10342
- }
10343
- }
10344
- return "";
10345
- }
10346
- async function checkFunctionalDeploymentUrl(url, fetchImpl = globalThis.fetch) {
10347
- const target = String(url || "").trim();
10348
- if (!target) return { ok: false, reason: "url_missing" };
10349
- if (typeof fetchImpl !== "function") return { ok: false, reason: "fetch_unavailable", url: target };
10350
- const signal = typeof AbortSignal !== "undefined" && typeof AbortSignal.timeout === "function" ? AbortSignal.timeout(8e3) : void 0;
10351
- const probe = async (method) => {
10352
- const response = await fetchImpl(target, { method, redirect: "follow", signal });
10353
- return {
10354
- ok: response.status >= 200 && response.status < 400,
10355
- status: response.status,
10356
- statusText: response.statusText || "",
10357
- url: response.url || target,
10358
- method
10359
- };
10360
- };
10361
- try {
10362
- const head = await probe("HEAD");
10363
- if (head.ok) return head;
10364
- const get = await probe("GET");
10365
- return get.ok ? get : { ...get, reason: "http_not_ok" };
10366
- } catch (error) {
10367
- try {
10368
- const get = await probe("GET");
10369
- return get.ok ? get : { ...get, reason: "http_not_ok" };
10370
- } catch (secondError) {
10371
- return { ok: false, reason: "request_failed", url: target, error: secondError.message || error.message };
10372
- }
10373
- }
10374
- }
10375
- function createGitHubApiClient(config = {}, fetchImpl = globalThis.fetch) {
10376
- const staticToken = resolveSecretReference(config?.apiToken);
10377
- const appConfig = isPlainObject(config?.app) ? config.app : {};
10378
- const appId = resolveSecretReference(appConfig.appId || appConfig.app_id || "");
10379
- const installationId = resolveSecretReference(appConfig.installationId || appConfig.installation_id || "");
10380
- const appEnabled = appConfig.enabled === true || Boolean(appId && installationId && (appConfig.privateKey || appConfig.privateKeyFile));
10381
- const privateKey = resolveGitHubAppPrivateKey(appConfig);
10382
- const owner = String(config?.owner || "").trim();
10383
- const repo = String(config?.repo || "").trim();
10384
- let installationToken = null;
10385
- let installationTokenExpiresAt = 0;
10386
- const requestJson = async (url, { method = "GET", headers = {}, body = void 0 } = {}) => {
10387
- if (typeof fetchImpl !== "function") throw new Error("fetch is unavailable; inject a GitHub client for live PR lookup");
10613
+ const expectedEvents = new Set(config?.webhook?.events || []);
10614
+ const actualEvents = new Set(state?.events || []);
10615
+ const hasEvents = [...expectedEvents].every((event) => actualEvents.has(event));
10616
+ return Boolean(
10617
+ state?.active && state?.webhookId && state?.secret && state?.publicUrl === config?.webhook?.publicUrl && hasEvents
10618
+ );
10619
+ }
10620
+ function createClickUpApiClient(config, fetchImpl = globalThis.fetch) {
10621
+ const token = resolveSecretReference(config?.apiToken);
10622
+ const request = async (url, options = {}) => {
10623
+ if (typeof fetchImpl !== "function") throw new Error("fetch is unavailable; inject a ClickUp client for live webhook setup");
10624
+ if (!token) throw new Error("ClickUp API token is not available");
10388
10625
  const response = await fetchImpl(url, {
10389
- method,
10626
+ ...options,
10390
10627
  headers: {
10391
- Accept: "application/vnd.github+json",
10392
- "X-GitHub-Api-Version": "2022-11-28",
10393
- ...body === void 0 ? {} : { "Content-Type": "application/json" },
10394
- ...headers
10395
- },
10396
- ...body === void 0 ? {} : { body: JSON.stringify(body) }
10397
- });
10398
- if (!response.ok) throw new Error(`GitHub API request failed: ${response.status}`);
10399
- return response.status === 204 ? null : response.json();
10400
- };
10401
- const getAuthToken = async () => {
10402
- if (!appEnabled) return staticToken || "";
10403
- const nowMs = Date.now();
10404
- if (installationToken && installationTokenExpiresAt - 6e4 > nowMs) return installationToken;
10405
- const jwt = createGitHubAppJwt({ appId, privateKey });
10406
- const installation = await requestJson(`https://api.github.com/app/installations/${encodeURIComponent(installationId)}/access_tokens`, {
10407
- method: "POST",
10408
- headers: { Authorization: `Bearer ${jwt}` }
10409
- });
10410
- installationToken = String(installation?.token || "").trim();
10411
- installationTokenExpiresAt = Date.parse(installation?.expires_at || "") || nowMs + 3e6;
10412
- if (!installationToken) throw new Error("GitHub App installation token response did not include a token");
10413
- return installationToken;
10414
- };
10415
- const request = async (pathname, { method = "GET", body = void 0 } = {}) => {
10416
- if (!owner || !repo) throw new Error("GitHub repository owner/repo is not configured");
10417
- const token = await getAuthToken();
10418
- return requestJson(`https://api.github.com/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}${pathname}`, {
10419
- method,
10420
- body,
10421
- headers: token ? { Authorization: `Bearer ${token}` } : {}
10628
+ Authorization: token,
10629
+ "Content-Type": "application/json",
10630
+ ...options.headers || {}
10631
+ }
10422
10632
  });
10633
+ if (!response.ok) throw new Error(`ClickUp API request failed: ${response.status}`);
10634
+ return response.json();
10423
10635
  };
10424
- const getRef = async (branch) => request(`/git/ref/heads/${encodeGitHubBranchRef(branch)}`);
10425
- const getCommitObject = async (sha) => request(`/git/commits/${encodeURIComponent(sha)}`);
10426
- const createBlob = async ({ content, encoding }) => request("/git/blobs", { method: "POST", body: { content, encoding } });
10427
- const createTree = async ({ baseTree, tree }) => request("/git/trees", { method: "POST", body: { base_tree: baseTree, tree } });
10428
- const createCommit = async ({ message, treeSha, parents }) => request("/git/commits", { method: "POST", body: { message, tree: treeSha, parents } });
10429
- const updateRef = async ({ branch, sha, force = false }) => request(`/git/refs/heads/${encodeGitHubBranchRef(branch)}`, { method: "PATCH", body: { sha, force } });
10430
10636
  return {
10431
- async getPullRequest(number) {
10432
- return request(`/pulls/${encodeURIComponent(number)}`);
10433
- },
10434
- async createPullRequest({ title, head, base, body = "", draft = false, maintainerCanModify = true }) {
10435
- return request("/pulls", {
10637
+ async createWebhook({ endpoint, events, location }) {
10638
+ const body = { endpoint, events, ...Object.fromEntries(Object.entries(location || {}).filter(([, value]) => value)) };
10639
+ return request(`https://api.clickup.com/api/v2/team/${encodeURIComponent(config.teamId)}/webhook`, {
10436
10640
  method: "POST",
10437
- body: {
10438
- title: String(title || ""),
10439
- head: String(head || ""),
10440
- base: String(base || ""),
10441
- body: String(body || ""),
10442
- draft: draft === true,
10443
- maintainer_can_modify: maintainerCanModify !== false
10444
- }
10641
+ body: JSON.stringify(body)
10445
10642
  });
10446
10643
  },
10447
- async createIssueComment({ issueNumber, body }) {
10448
- return request(`/issues/${encodeURIComponent(issueNumber)}/comments`, { method: "POST", body: { body: String(body || "") } });
10449
- },
10450
- async replyToReviewComment({ commentId, body }) {
10451
- return request(`/pulls/comments/${encodeURIComponent(commentId)}/replies`, { method: "POST", body: { body: String(body || "") } });
10644
+ async listWebhooks() {
10645
+ return request(`https://api.clickup.com/api/v2/team/${encodeURIComponent(config.teamId)}/webhook`);
10452
10646
  },
10453
- async createPullRequestReview({ pullNumber, body, event = "COMMENT" }) {
10454
- return request(`/pulls/${encodeURIComponent(pullNumber)}/reviews`, { method: "POST", body: { body: String(body || ""), event: String(event || "COMMENT").toUpperCase() } });
10647
+ async deleteWebhook(webhookId) {
10648
+ return request(`https://api.clickup.com/api/v2/webhook/${encodeURIComponent(webhookId)}`, { method: "DELETE" });
10455
10649
  },
10456
- async mergePullRequest({ pullNumber, commitTitle = "", commitMessage = "", mergeMethod = "squash" }) {
10457
- const body = {
10458
- merge_method: String(mergeMethod || "squash")
10459
- };
10460
- if (commitTitle) body.commit_title = String(commitTitle);
10461
- if (commitMessage) body.commit_message = String(commitMessage);
10462
- return request(`/pulls/${encodeURIComponent(pullNumber)}/merge`, { method: "PUT", body });
10650
+ async getAuthorizedUser() {
10651
+ return request("https://api.clickup.com/api/v2/user");
10463
10652
  },
10464
- async getCombinedStatus(ref) {
10465
- return request(`/commits/${encodeURIComponent(String(ref || ""))}/status`);
10653
+ async getTask(taskId) {
10654
+ return request(`https://api.clickup.com/api/v2/task/${encodeURIComponent(taskId)}`);
10466
10655
  },
10467
- async listDeployments({ sha = "", ref = "", environment = "", perPage = 30 } = {}) {
10468
- return request(appendGitHubQuery("/deployments", {
10469
- sha,
10470
- ref,
10471
- environment,
10472
- per_page: perPage
10473
- }));
10656
+ async updateTaskMetadata({ taskId, fieldId, value }) {
10657
+ return request(`https://api.clickup.com/api/v2/task/${encodeURIComponent(taskId)}/field/${encodeURIComponent(fieldId)}`, {
10658
+ method: "POST",
10659
+ body: JSON.stringify({ value })
10660
+ });
10474
10661
  },
10475
- async listDeploymentStatuses(deploymentId) {
10476
- return request(`/deployments/${encodeURIComponent(deploymentId)}/statuses`);
10662
+ async postTaskComment() {
10663
+ throw new Error("Optima runtime does not post ClickUp task comments; use local logs for process failures.");
10477
10664
  },
10478
- async verifyVercelPullRequestDeployment({
10479
- pullNumber,
10480
- context = "Vercel \u2013 defend-preproduction",
10481
- environment = "Preview \u2013 defend-preproduction",
10482
- requireFunctionalUrl = true
10483
- } = {}) {
10484
- const pr = await this.getPullRequest(pullNumber);
10485
- const headSha = String(pr?.head?.sha || "").trim();
10486
- if (!headSha) return { ok: true, ready: false, reason: "pr_head_sha_missing", pull_request: { number: pullNumber } };
10487
- const combined = await this.getCombinedStatus(headSha);
10488
- const statuses = Array.isArray(combined?.statuses) ? combined.statuses : [];
10489
- const matchingStatuses = statuses.filter((status) => matchesVercelStatusContext(status?.context, context));
10490
- const selectedStatus = sortNewestFirst(matchingStatuses)[0] || null;
10491
- if (!selectedStatus) {
10492
- return {
10493
- ok: true,
10494
- ready: false,
10495
- reason: "vercel_status_missing",
10496
- pull_request: { number: pr.number, url: pr.html_url, head_sha: headSha },
10497
- required_context: context,
10498
- combined_state: combined?.state || null
10499
- };
10500
- }
10501
- if (String(selectedStatus.state || "").toLowerCase() !== "success") {
10502
- return {
10503
- ok: true,
10504
- ready: false,
10505
- reason: "vercel_status_not_success",
10506
- pull_request: { number: pr.number, url: pr.html_url, head_sha: headSha },
10507
- required_context: context,
10508
- status: selectedStatus,
10509
- combined_state: combined?.state || null
10510
- };
10511
- }
10512
- let deployments = await this.listDeployments({ sha: headSha, environment });
10513
- if (!Array.isArray(deployments) || deployments.length === 0) deployments = await this.listDeployments({ sha: headSha });
10514
- const selectedDeployment = sortNewestFirst(Array.isArray(deployments) ? deployments : []).find((deployment) => !environment || String(deployment?.environment || "") === environment) || sortNewestFirst(Array.isArray(deployments) ? deployments : [])[0] || null;
10515
- if (!selectedDeployment?.id) {
10516
- return {
10517
- ok: true,
10518
- ready: false,
10519
- reason: "vercel_deployment_missing",
10520
- pull_request: { number: pr.number, url: pr.html_url, head_sha: headSha },
10521
- required_environment: environment,
10522
- status: selectedStatus
10523
- };
10524
- }
10525
- const deploymentStatuses = await this.listDeploymentStatuses(selectedDeployment.id);
10526
- const selectedDeploymentStatus = sortNewestFirst(Array.isArray(deploymentStatuses) ? deploymentStatuses : [])[0] || null;
10527
- if (!selectedDeploymentStatus || String(selectedDeploymentStatus.state || "").toLowerCase() !== "success") {
10528
- return {
10529
- ok: true,
10530
- ready: false,
10531
- reason: "vercel_deployment_not_success",
10532
- pull_request: { number: pr.number, url: pr.html_url, head_sha: headSha },
10533
- required_environment: environment,
10534
- status: selectedStatus,
10535
- deployment: selectedDeployment,
10536
- deployment_status: selectedDeploymentStatus
10537
- };
10538
- }
10539
- const url = selectFunctionalDeploymentUrl(selectedDeploymentStatus, selectedDeployment);
10540
- const urlCheck = requireFunctionalUrl ? await checkFunctionalDeploymentUrl(url, fetchImpl) : { ok: Boolean(url), reason: url ? void 0 : "url_missing", url };
10541
- if (requireFunctionalUrl && !urlCheck.ok) {
10542
- return {
10543
- ok: true,
10544
- ready: false,
10545
- reason: "vercel_url_not_functional",
10546
- pull_request: { number: pr.number, url: pr.html_url, head_sha: headSha },
10547
- required_environment: environment,
10548
- status: selectedStatus,
10549
- deployment: selectedDeployment,
10550
- deployment_status: selectedDeploymentStatus,
10551
- url,
10552
- url_check: urlCheck
10553
- };
10554
- }
10555
- return {
10556
- ok: true,
10557
- ready: true,
10558
- reason: "vercel_pr_deployment_ready",
10559
- pull_request: { number: pr.number, url: pr.html_url, head_sha: headSha },
10560
- required_context: context,
10561
- required_environment: environment,
10562
- status: selectedStatus,
10563
- deployment: selectedDeployment,
10564
- deployment_status: selectedDeploymentStatus,
10565
- url,
10566
- url_check: urlCheck
10567
- };
10665
+ async addTaskTag() {
10666
+ throw new Error("Optima runtime does not add ClickUp task tags; use local logs for process failures.");
10568
10667
  },
10569
- async commitWorktree({ worktree, branch = "", message = "", runGitFn = runGit, syncLocal = false } = {}) {
10570
- const directory = path6.resolve(String(worktree || ""));
10571
- if (!directory || !fs5.existsSync(directory)) throw new Error("worktree does not exist");
10572
- const targetBranch = String(branch || currentGitBranch(directory, runGitFn)).trim();
10573
- if (!targetBranch || targetBranch === "HEAD") throw new Error("target branch is required for GitHub API commit");
10574
- const commitMessage = String(message || "").trim();
10575
- if (!commitMessage) throw new Error("commit message is required");
10576
- const changedPaths = listWorktreeChangedPaths(directory, runGitFn);
10577
- if (changedPaths.length === 0) return { ok: true, action: "no_changes", branch: targetBranch, changedPaths: [] };
10578
- const ref = await getRef(targetBranch);
10579
- const headSha = ref?.object?.sha;
10580
- if (!headSha) throw new Error(`GitHub ref for ${targetBranch} did not include a head sha`);
10581
- const headCommit = await getCommitObject(headSha);
10582
- const baseTree = headCommit?.tree?.sha;
10583
- if (!baseTree) throw new Error(`GitHub commit ${headSha} did not include a tree sha`);
10584
- const tree = [];
10585
- for (const gitPath of changedPaths) {
10586
- const entry = treeEntryForWorktreePath(directory, gitPath);
10587
- if (!entry) continue;
10588
- if (entry.deleted) {
10589
- tree.push({ path: entry.path, mode: entry.mode, type: entry.type, sha: null });
10590
- continue;
10591
- }
10592
- const blob = await createBlob({ content: entry.content, encoding: entry.encoding });
10593
- if (!blob?.sha) throw new Error(`GitHub blob creation failed for ${gitPath}`);
10594
- tree.push({ path: entry.path, mode: entry.mode, type: entry.type, sha: blob.sha });
10595
- }
10596
- if (tree.length === 0) return { ok: true, action: "no_changes", branch: targetBranch, changedPaths: [] };
10597
- const nextTree = await createTree({ baseTree, tree });
10598
- const nextCommit = await createCommit({ message: commitMessage, treeSha: nextTree.sha, parents: [headSha] });
10599
- if (!nextCommit?.sha) throw new Error("GitHub commit creation did not return a sha");
10600
- const updatedRef = await updateRef({ branch: targetBranch, sha: nextCommit.sha, force: false });
10601
- if (syncLocal) {
10602
- runGitFn(directory, ["fetch", "origin", targetBranch]);
10603
- runGitFn(directory, ["reset", "--hard", "FETCH_HEAD"]);
10604
- }
10605
- return {
10606
- ok: true,
10607
- action: "committed",
10608
- branch: targetBranch,
10609
- before: headSha,
10610
- after: nextCommit.sha,
10611
- changedPaths,
10612
- treeEntries: tree.length,
10613
- verification: nextCommit.verification || null,
10614
- ref: updatedRef
10615
- };
10668
+ async listAssignedTasks({ assigneeId, statuses = [], limit = CLICKUP_WEBHOOK_STARTUP_TASK_LIMIT } = {}) {
10669
+ const params = new URLSearchParams();
10670
+ if (assigneeId) params.append("assignees[]", assigneeId);
10671
+ for (const status of statuses) if (status) params.append("statuses[]", status);
10672
+ if (limit) params.append("limit", String(limit));
10673
+ return request(`https://api.clickup.com/api/v2/team/${encodeURIComponent(config.teamId)}/task?${params.toString()}`);
10616
10674
  },
10617
- async authMode() {
10618
- if (appEnabled) return { mode: "github_app", appId, installationId };
10619
- if (staticToken) return { mode: "token" };
10620
- return { mode: "anonymous" };
10675
+ async getTaskComments({ taskId, start, limit = CLICKUP_WEBHOOK_STARTUP_COMMENT_LIMIT } = {}) {
10676
+ const params = new URLSearchParams();
10677
+ if (start) params.set("start", String(start));
10678
+ if (limit) params.set("limit", String(limit));
10679
+ const suffix = params.toString() ? `?${params.toString()}` : "";
10680
+ return request(`https://api.clickup.com/api/v2/task/${encodeURIComponent(taskId)}/comment${suffix}`);
10621
10681
  }
10622
10682
  };
10623
10683
  }
@@ -10846,10 +10906,10 @@ async function ensureClickUpWebhookSubscription({ validation, worktree, clickupC
10846
10906
  function verifyClickUpSignature(rawBody, signatureHeader, secret) {
10847
10907
  const signature = String(signatureHeader || "").replace(/^sha256=/i, "").trim();
10848
10908
  if (!signature || !secret) return false;
10849
- const expected = crypto.createHmac("sha256", secret).update(Buffer.isBuffer(rawBody) ? rawBody : String(rawBody || ""), "utf8").digest("hex");
10909
+ const expected = crypto2.createHmac("sha256", secret).update(Buffer.isBuffer(rawBody) ? rawBody : String(rawBody || ""), "utf8").digest("hex");
10850
10910
  const given = Buffer.from(signature, "hex");
10851
10911
  const wanted = Buffer.from(expected, "hex");
10852
- return given.length === wanted.length && crypto.timingSafeEqual(given, wanted);
10912
+ return given.length === wanted.length && crypto2.timingSafeEqual(given, wanted);
10853
10913
  }
10854
10914
  function verifyGitHubSignature(rawBody, signatureHeader, secret) {
10855
10915
  return verifyClickUpSignature(rawBody, signatureHeader, secret);
@@ -10903,9 +10963,9 @@ function rememberClickUpWebhookEvent(state = {}, eventKey, limit = 200) {
10903
10963
  return { duplicate: false, state: { ...state, recentEventKeys: [...recent, eventKey].slice(-limit) } };
10904
10964
  }
10905
10965
  function readClickUpCommentLedgerEntries(ledgerPath) {
10906
- if (!ledgerPath || !fs5.existsSync(ledgerPath)) return [];
10966
+ if (!ledgerPath || !fs8.existsSync(ledgerPath)) return [];
10907
10967
  try {
10908
- const raw = fs5.readFileSync(ledgerPath, "utf8");
10968
+ const raw = fs8.readFileSync(ledgerPath, "utf8");
10909
10969
  const entries = [];
10910
10970
  for (const [index, line] of raw.split(/\r?\n/).entries()) {
10911
10971
  if (!line.trim()) continue;
@@ -10929,11 +10989,11 @@ function readClickUpCommentLedger(ledgerPath) {
10929
10989
  }
10930
10990
  function appendClickUpCommentLedgerEntry(ledgerPath, entry = {}) {
10931
10991
  if (!ledgerPath || !entry.key) return;
10932
- fs5.mkdirSync(path6.dirname(ledgerPath), { recursive: true, mode: 448 });
10933
- fs5.appendFileSync(ledgerPath, `${JSON.stringify(entry)}
10992
+ fs8.mkdirSync(path8.dirname(ledgerPath), { recursive: true, mode: 448 });
10993
+ fs8.appendFileSync(ledgerPath, `${JSON.stringify(entry)}
10934
10994
  `, { encoding: "utf8", mode: 384 });
10935
10995
  try {
10936
- fs5.chmodSync(ledgerPath, 384);
10996
+ fs8.chmodSync(ledgerPath, 384);
10937
10997
  } catch {
10938
10998
  }
10939
10999
  }
@@ -10952,7 +11012,7 @@ function stableClickUpCommentVersionMarker(value) {
10952
11012
  const direct = value.version ?? value.date_updated ?? value.updated_at ?? value.revision ?? value.modified_at;
10953
11013
  const directMarker = stableClickUpCommentVersionMarker(direct);
10954
11014
  if (directMarker) return directMarker;
10955
- return `json:${crypto.createHash("sha256").update(JSON.stringify(value, Object.keys(value).sort())).digest("hex").slice(0, 16)}`;
11015
+ return `json:${crypto2.createHash("sha256").update(JSON.stringify(value, Object.keys(value).sort())).digest("hex").slice(0, 16)}`;
10956
11016
  }
10957
11017
  function clickUpCommentLedgerKey({ taskId, eventType, payload }) {
10958
11018
  const history = Array.isArray(payload?.history_items) ? payload.history_items[0] : payload?.history_item;
@@ -10962,7 +11022,7 @@ function clickUpCommentLedgerKey({ taskId, eventType, payload }) {
10962
11022
  const explicitVersion = stableClickUpCommentVersionMarker(
10963
11023
  comment?.date_updated || comment?.dateUpdated || comment?.updated_at || comment?.updatedAt || comment?._version_vector || comment?.version_vector || comment?.versionVector || comment?.version || comment?.revision || comment?.modified_at || comment?.modifiedAt || ""
10964
11024
  );
10965
- const contentVersion = crypto.createHash("sha256").update(JSON.stringify({ text: clickUpCommentText(comment), parts: Array.isArray(comment.comment) ? comment.comment : null })).digest("hex").slice(0, 16);
11025
+ const contentVersion = crypto2.createHash("sha256").update(JSON.stringify({ text: clickUpCommentText(comment), parts: Array.isArray(comment.comment) ? comment.comment : null })).digest("hex").slice(0, 16);
10966
11026
  return [String(taskId || "").trim(), "comment", commentId, explicitVersion || `sha256-${contentVersion}`].filter(Boolean).join(":");
10967
11027
  }
10968
11028
  function isClickUpCommentVersionProcessed({ ledgerPath, key, ledger = null, worktree = process.cwd() } = {}) {
@@ -11492,7 +11552,7 @@ function clampOpenCodeSessionText(text = "", maxLength = 12e3) {
11492
11552
  return value.length > maxLength ? value.slice(0, maxLength) : value;
11493
11553
  }
11494
11554
  function hashOpenCodeSessionText(text = "") {
11495
- return crypto.createHash("sha256").update(String(text ?? "")).digest("hex");
11555
+ return crypto2.createHash("sha256").update(String(text ?? "")).digest("hex");
11496
11556
  }
11497
11557
  async function readOpenCodeSessionMessages(client, { sessionId, directory, limit = 20 } = {}) {
11498
11558
  if (typeof client?.session?.messages !== "function") return null;
@@ -11730,7 +11790,7 @@ async function readOpenCodeSessionControl(client, { sessionId, directory, limit
11730
11790
  };
11731
11791
  }
11732
11792
  async function probeOpenCodeSessionControl(client, { directory, agent, omitAgentOnPrompt = false, text = "" } = {}) {
11733
- const requestedMarker = text || `optima-session-probe-${crypto.randomUUID()}`;
11793
+ const requestedMarker = text || `optima-session-probe-${crypto2.randomUUID()}`;
11734
11794
  const marker = clampOpenCodeSessionText(requestedMarker);
11735
11795
  const create = await createOpenCodeSessionControl(client, {
11736
11796
  directory,
@@ -11958,9 +12018,9 @@ function formatClickUpWebhookPrompt({ eventType, taskId, payload, branch = "", w
11958
12018
  }
11959
12019
  function appendClickUpWebhookLocalLog(worktree, entry) {
11960
12020
  const logPath = clickUpWebhookLogPath(worktree);
11961
- fs5.mkdirSync(path6.dirname(logPath), { recursive: true });
12021
+ fs8.mkdirSync(path8.dirname(logPath), { recursive: true });
11962
12022
  const safeEntry = { ...entry, at: entry.at || (/* @__PURE__ */ new Date()).toISOString() };
11963
- fs5.appendFileSync(logPath, `${JSON.stringify(safeEntry)}
12023
+ fs8.appendFileSync(logPath, `${JSON.stringify(safeEntry)}
11964
12024
  `, "utf8");
11965
12025
  }
11966
12026
  function clickUpWebhookLifecycleLog(worktree, entry) {
@@ -11989,7 +12049,7 @@ function closeClickUpWebhookServer(server) {
11989
12049
  });
11990
12050
  }
11991
12051
  function managedClickUpWebhookKey({ worktree, state, config } = {}) {
11992
- return [path6.resolve(worktree || process.cwd()), state?.webhookId || "", config?.webhook?.publicUrl || ""].join("|");
12052
+ return [path8.resolve(worktree || process.cwd()), state?.webhookId || "", config?.webhook?.publicUrl || ""].join("|");
11993
12053
  }
11994
12054
  async function deleteClickUpWebhookBestEffort({ webhookId, clickupClient, worktree, reason = "cleanup" } = {}) {
11995
12055
  const id = String(webhookId || "").trim();
@@ -12089,7 +12149,7 @@ function writeClickUpWebhookAuditLog({ method, url, headers = {}, rawBody = "",
12089
12149
  const failed = Boolean(error || !handled?.ok || (handled?.status || 500) >= 400);
12090
12150
  if (level === "error" && !failed) return;
12091
12151
  const logDir = clickUpWebhookAuditLogDir();
12092
- fs5.mkdirSync(logDir, { recursive: true });
12152
+ fs8.mkdirSync(logDir, { recursive: true });
12093
12153
  const secretValues = [
12094
12154
  resolveSecretReference(config?.apiToken),
12095
12155
  resolveSecretReference(config?.github?.apiToken),
@@ -12100,8 +12160,8 @@ function writeClickUpWebhookAuditLog({ method, url, headers = {}, rawBody = "",
12100
12160
  let requestFile;
12101
12161
  if (level === "verbose") {
12102
12162
  const absoluteRequestFile = clickUpWebhookRequestFilePath(at, logDir);
12103
- fs5.mkdirSync(path6.dirname(absoluteRequestFile), { recursive: true });
12104
- requestFile = path6.relative(logDir, absoluteRequestFile).split(path6.sep).join("/");
12163
+ fs8.mkdirSync(path8.dirname(absoluteRequestFile), { recursive: true });
12164
+ requestFile = path8.relative(logDir, absoluteRequestFile).split(path8.sep).join("/");
12105
12165
  const parsedBody = payload || (() => {
12106
12166
  try {
12107
12167
  return JSON.parse(Buffer.isBuffer(rawBody) ? rawBody.toString("utf8") : String(rawBody || ""));
@@ -12117,11 +12177,11 @@ function writeClickUpWebhookAuditLog({ method, url, headers = {}, rawBody = "",
12117
12177
  headers,
12118
12178
  body: parsedBody === void 0 ? Buffer.isBuffer(rawBody) ? rawBody.toString("utf8") : String(rawBody || "") : parsedBody
12119
12179
  }, secretValues);
12120
- fs5.writeFileSync(absoluteRequestFile, `${JSON.stringify(requestArtifact, null, 2)}
12180
+ fs8.writeFileSync(absoluteRequestFile, `${JSON.stringify(requestArtifact, null, 2)}
12121
12181
  `, "utf8");
12122
12182
  }
12123
12183
  const summary = redactClickUpWebhookAuditValue(buildClickUpWebhookAuditSummary({ method, url, config, handled, error, payload, requestFile, at }), secretValues);
12124
- fs5.appendFileSync(clickUpWebhookAuditLogPath(at, logDir), `${JSON.stringify(summary)}
12184
+ fs8.appendFileSync(clickUpWebhookAuditLogPath(at, logDir), `${JSON.stringify(summary)}
12125
12185
  `, "utf8");
12126
12186
  } catch {
12127
12187
  }
@@ -12139,7 +12199,7 @@ async function withClickUpTaskRouteLock(taskId, operation) {
12139
12199
  if (activeClickUpTaskRoutes.get(key) === current) activeClickUpTaskRoutes.delete(key);
12140
12200
  }
12141
12201
  }
12142
- async function routeClickUpWebhookEventUnlocked({ payload, config, state = {}, worktree = process.cwd(), clickupClient, openCodeClient, sessionExists = openCodeSessionExists, createSession = createOpenCodeSession, sendSessionEvent = sendOpenCodeSessionEvent, ensureTaskWorktree = ensureClickUpTaskWorktreeForWebhook, verifySessionEventDelivery = verifyOpenCodeSessionEventDelivery, saveState = null, now = () => /* @__PURE__ */ new Date(), host = os.hostname(), commentLedgerPath = clickUpCommentLedgerPath(worktree) } = {}) {
12202
+ async function routeClickUpWebhookEventUnlocked({ payload, config, state = {}, worktree = process.cwd(), clickupClient, openCodeClient, sessionExists = openCodeSessionExists, createSession = createOpenCodeSession, sendSessionEvent = sendOpenCodeSessionEvent, ensureTaskWorktree = ensureClickUpTaskWorktreeForWebhook, verifySessionEventDelivery = verifyOpenCodeSessionEventDelivery, saveState = null, now = () => /* @__PURE__ */ new Date(), host = os2.hostname(), commentLedgerPath = clickUpCommentLedgerPath(worktree) } = {}) {
12143
12203
  const eventType = clickUpEventType(payload);
12144
12204
  const eventKey = clickUpWebhookEventKey(payload);
12145
12205
  const isStartupAssignmentReconciliation = payload?.startup_reconciliation === true && eventType === "taskAssigneeUpdated";
@@ -12908,17 +12968,17 @@ function startClickUpWebhookListener({ config, state, worktree, clickupClient, g
12908
12968
  return result;
12909
12969
  }
12910
12970
  function legacyVariantPath(destinationPath) {
12911
- const parsed = path6.parse(destinationPath);
12971
+ const parsed = path8.parse(destinationPath);
12912
12972
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[-:TZ.]/g, "").slice(0, 14);
12913
- if (parsed.ext) return path6.join(parsed.dir, `${parsed.name}.legacy-${stamp}${parsed.ext}`);
12914
- return path6.join(parsed.dir, `${parsed.base}.legacy-${stamp}`);
12973
+ if (parsed.ext) return path8.join(parsed.dir, `${parsed.name}.legacy-${stamp}${parsed.ext}`);
12974
+ return path8.join(parsed.dir, `${parsed.base}.legacy-${stamp}`);
12915
12975
  }
12916
12976
  function normalizeWorkflowTaskPath(taskPath) {
12917
12977
  if (typeof taskPath !== "string") return { ok: false, message: "Error: task_path is required." };
12918
12978
  const trimmed = taskPath.trim();
12919
12979
  if (!trimmed) return { ok: false, message: "Error: task_path is required." };
12920
12980
  const normalized = trimmed.replace(/\\/g, "/");
12921
- if (path6.isAbsolute(trimmed)) return { ok: true, taskPath: trimmed };
12981
+ if (path8.isAbsolute(trimmed)) return { ok: true, taskPath: trimmed };
12922
12982
  if (normalized === "tasks" || normalized.startsWith("tasks/")) {
12923
12983
  return {
12924
12984
  ok: false,
@@ -12936,78 +12996,78 @@ function normalizeWorkflowTaskPath(taskPath) {
12936
12996
  function mergeFileIntoDestination(sourcePath, destinationPath, relativeSource, gitState = null) {
12937
12997
  const sourceWasTracked = isGitTracked(gitState, sourcePath);
12938
12998
  if (gitAwareMoveIfTracked(sourcePath, destinationPath, gitState)) return;
12939
- if (!fs5.existsSync(destinationPath)) {
12940
- fs5.mkdirSync(path6.dirname(destinationPath), { recursive: true });
12941
- fs5.renameSync(sourcePath, destinationPath);
12999
+ if (!fs8.existsSync(destinationPath)) {
13000
+ fs8.mkdirSync(path8.dirname(destinationPath), { recursive: true });
13001
+ fs8.renameSync(sourcePath, destinationPath);
12942
13002
  if (sourceWasTracked) stageGitAwareMerge(sourcePath, destinationPath, gitState);
12943
13003
  return;
12944
13004
  }
12945
- const ext = path6.extname(destinationPath).toLowerCase();
13005
+ const ext = path8.extname(destinationPath).toLowerCase();
12946
13006
  if ([".yaml", ".yml", ".json"].includes(ext)) {
12947
- const sourceRaw = fs5.readFileSync(sourcePath, "utf8");
12948
- const destRaw = fs5.readFileSync(destinationPath, "utf8");
13007
+ const sourceRaw = fs8.readFileSync(sourcePath, "utf8");
13008
+ const destRaw = fs8.readFileSync(destinationPath, "utf8");
12949
13009
  const parser = ext === ".json" ? JSON : import_yaml3.default;
12950
13010
  const sourceValue = parser.parse(sourceRaw) || {};
12951
13011
  const destValue = parser.parse(destRaw) || {};
12952
13012
  const merged = mergeStructuredValues(sourceValue, destValue);
12953
13013
  const serialized = ext === ".json" ? `${JSON.stringify(merged, null, 2)}
12954
13014
  ` : import_yaml3.default.stringify(merged);
12955
- fs5.writeFileSync(destinationPath, serialized, "utf8");
12956
- fs5.unlinkSync(sourcePath);
13015
+ fs8.writeFileSync(destinationPath, serialized, "utf8");
13016
+ fs8.unlinkSync(sourcePath);
12957
13017
  stageGitAwareMerge(sourcePath, destinationPath, gitState);
12958
13018
  return;
12959
13019
  }
12960
13020
  if (ext === ".md") {
12961
- const sourceRaw = fs5.readFileSync(sourcePath, "utf8").trimEnd();
12962
- const destRaw = fs5.readFileSync(destinationPath, "utf8").trimEnd();
13021
+ const sourceRaw = fs8.readFileSync(sourcePath, "utf8").trimEnd();
13022
+ const destRaw = fs8.readFileSync(destinationPath, "utf8").trimEnd();
12963
13023
  if (sourceRaw && !destRaw.includes(sourceRaw)) {
12964
13024
  const marker = `## Legacy Content From ${relativeSource}`;
12965
- fs5.writeFileSync(destinationPath, `${destRaw}
13025
+ fs8.writeFileSync(destinationPath, `${destRaw}
12966
13026
 
12967
13027
  ${marker}
12968
13028
 
12969
13029
  ${sourceRaw}
12970
13030
  `, "utf8");
12971
13031
  }
12972
- fs5.unlinkSync(sourcePath);
13032
+ fs8.unlinkSync(sourcePath);
12973
13033
  stageGitAwareMerge(sourcePath, destinationPath, gitState);
12974
13034
  return;
12975
13035
  }
12976
13036
  const preservedPath = legacyVariantPath(destinationPath);
12977
- fs5.renameSync(sourcePath, preservedPath);
13037
+ fs8.renameSync(sourcePath, preservedPath);
12978
13038
  stageGitAwareMerge(sourcePath, preservedPath, gitState);
12979
13039
  }
12980
- function mergePathIntoDestination(sourcePath, destinationPath, relativeSource = path6.basename(sourcePath), gitState = null) {
12981
- if (!fs5.existsSync(sourcePath)) return;
12982
- const stat = fs5.statSync(sourcePath);
13040
+ function mergePathIntoDestination(sourcePath, destinationPath, relativeSource = path8.basename(sourcePath), gitState = null) {
13041
+ if (!fs8.existsSync(sourcePath)) return;
13042
+ const stat = fs8.statSync(sourcePath);
12983
13043
  if (stat.isDirectory()) {
12984
13044
  const sourceWasTracked = isGitTracked(gitState, sourcePath) || hasGitTrackedChildren(gitState, sourcePath);
12985
13045
  if (gitAwareMoveIfTracked(sourcePath, destinationPath, gitState)) return;
12986
- if (!fs5.existsSync(destinationPath)) {
12987
- fs5.mkdirSync(path6.dirname(destinationPath), { recursive: true });
12988
- fs5.renameSync(sourcePath, destinationPath);
13046
+ if (!fs8.existsSync(destinationPath)) {
13047
+ fs8.mkdirSync(path8.dirname(destinationPath), { recursive: true });
13048
+ fs8.renameSync(sourcePath, destinationPath);
12989
13049
  if (sourceWasTracked) stageGitAwareMerge(sourcePath, destinationPath, gitState);
12990
13050
  return;
12991
13051
  }
12992
- fs5.mkdirSync(destinationPath, { recursive: true });
12993
- for (const entry of fs5.readdirSync(sourcePath)) {
13052
+ fs8.mkdirSync(destinationPath, { recursive: true });
13053
+ for (const entry of fs8.readdirSync(sourcePath)) {
12994
13054
  mergePathIntoDestination(
12995
- path6.join(sourcePath, entry),
12996
- path6.join(destinationPath, entry),
12997
- path6.join(relativeSource, entry),
13055
+ path8.join(sourcePath, entry),
13056
+ path8.join(destinationPath, entry),
13057
+ path8.join(relativeSource, entry),
12998
13058
  gitState
12999
13059
  );
13000
13060
  }
13001
- fs5.rmSync(sourcePath, { recursive: true, force: true });
13061
+ fs8.rmSync(sourcePath, { recursive: true, force: true });
13002
13062
  return;
13003
13063
  }
13004
13064
  mergeFileIntoDestination(sourcePath, destinationPath, relativeSource, gitState);
13005
13065
  }
13006
13066
  function isOptimaPluginPackageWorktree(worktree) {
13007
- const packageJsonPath = path6.join(worktree, "package.json");
13008
- if (!fs5.existsSync(packageJsonPath)) return false;
13067
+ const packageJsonPath = path8.join(worktree, "package.json");
13068
+ if (!fs8.existsSync(packageJsonPath)) return false;
13009
13069
  try {
13010
- const pkg = JSON.parse(fs5.readFileSync(packageJsonPath, "utf8"));
13070
+ const pkg = JSON.parse(fs8.readFileSync(packageJsonPath, "utf8"));
13011
13071
  return pkg?.name === "@defend-tech/opencode-optima";
13012
13072
  } catch {
13013
13073
  return false;
@@ -13016,59 +13076,59 @@ function isOptimaPluginPackageWorktree(worktree) {
13016
13076
  function migrateLegacyOptimaLayout(worktree) {
13017
13077
  const gitState = gitMigrationState(worktree);
13018
13078
  const migrations = [
13019
- [path6.join(legacyOrbitaDir(worktree), "orbita.yaml"), repoConfigPath(worktree), path6.join(".orbita", "orbita.yaml")],
13020
- [path6.join(legacyOrbitaDir(worktree), "staticeng.yaml"), repoConfigPath(worktree), path6.join(".orbita", "staticeng.yaml")],
13021
- [path6.join(legacyOrbitaDir(worktree), ".config"), optimaLocalConfigDir(worktree), path6.join(".orbita", ".config")],
13022
- [path6.join(legacyOrbitaDir(worktree), "config"), optimaLocalConfigDir(worktree), path6.join(".orbita", "config")],
13023
- [path6.join(legacyOrbitaDir(worktree), "runtime"), path6.join(optimaLocalConfigDir(worktree), "runtime"), path6.join(".orbita", "runtime")],
13024
- [path6.join(legacyOrbitaDir(worktree), "generated"), path6.join(optimaLocalConfigDir(worktree), "generated"), path6.join(".orbita", "generated")],
13079
+ [path8.join(legacyOrbitaDir(worktree), "orbita.yaml"), repoConfigPath(worktree), path8.join(".orbita", "orbita.yaml")],
13080
+ [path8.join(legacyOrbitaDir(worktree), "staticeng.yaml"), repoConfigPath(worktree), path8.join(".orbita", "staticeng.yaml")],
13081
+ [path8.join(legacyOrbitaDir(worktree), ".config"), optimaLocalConfigDir(worktree), path8.join(".orbita", ".config")],
13082
+ [path8.join(legacyOrbitaDir(worktree), "config"), optimaLocalConfigDir(worktree), path8.join(".orbita", "config")],
13083
+ [path8.join(legacyOrbitaDir(worktree), "runtime"), path8.join(optimaLocalConfigDir(worktree), "runtime"), path8.join(".orbita", "runtime")],
13084
+ [path8.join(legacyOrbitaDir(worktree), "generated"), path8.join(optimaLocalConfigDir(worktree), "generated"), path8.join(".orbita", "generated")],
13025
13085
  [legacyOrbitaDir(worktree), optimaDir(worktree), ".orbita"],
13026
- [path6.join(legacyStaticEngDir(worktree), "staticeng.yaml"), repoConfigPath(worktree), path6.join(".staticeng", "staticeng.yaml")],
13027
- [path6.join(legacyStaticEngDir(worktree), "orbita.yaml"), repoConfigPath(worktree), path6.join(".staticeng", "orbita.yaml")],
13028
- [path6.join(legacyStaticEngDir(worktree), ".config"), optimaLocalConfigDir(worktree), path6.join(".staticeng", ".config")],
13029
- [path6.join(legacyStaticEngDir(worktree), "config"), optimaLocalConfigDir(worktree), path6.join(".staticeng", "config")],
13030
- [path6.join(legacyStaticEngDir(worktree), "runtime"), path6.join(optimaLocalConfigDir(worktree), "runtime"), path6.join(".staticeng", "runtime")],
13031
- [path6.join(legacyStaticEngDir(worktree), "generated"), path6.join(optimaLocalConfigDir(worktree), "generated"), path6.join(".staticeng", "generated")],
13086
+ [path8.join(legacyStaticEngDir(worktree), "staticeng.yaml"), repoConfigPath(worktree), path8.join(".staticeng", "staticeng.yaml")],
13087
+ [path8.join(legacyStaticEngDir(worktree), "orbita.yaml"), repoConfigPath(worktree), path8.join(".staticeng", "orbita.yaml")],
13088
+ [path8.join(legacyStaticEngDir(worktree), ".config"), optimaLocalConfigDir(worktree), path8.join(".staticeng", ".config")],
13089
+ [path8.join(legacyStaticEngDir(worktree), "config"), optimaLocalConfigDir(worktree), path8.join(".staticeng", "config")],
13090
+ [path8.join(legacyStaticEngDir(worktree), "runtime"), path8.join(optimaLocalConfigDir(worktree), "runtime"), path8.join(".staticeng", "runtime")],
13091
+ [path8.join(legacyStaticEngDir(worktree), "generated"), path8.join(optimaLocalConfigDir(worktree), "generated"), path8.join(".staticeng", "generated")],
13032
13092
  [legacyStaticEngDir(worktree), optimaDir(worktree), ".staticeng"],
13033
- [path6.join(legacyNomadworkDir(worktree), "nomadworks.yaml"), repoConfigPath(worktree), path6.join(".nomadwork", "nomadworks.yaml")],
13034
- [path6.join(legacyNomadworksDir(worktree), "nomadworks.yaml"), repoConfigPath(worktree), path6.join(".nomadworks", "nomadworks.yaml")],
13035
- [path6.join(legacyNomadworkDir(worktree), "staticeng.yaml"), repoConfigPath(worktree), path6.join(".nomadwork", "staticeng.yaml")],
13036
- [path6.join(legacyNomadworksDir(worktree), "staticeng.yaml"), repoConfigPath(worktree), path6.join(".nomadworks", "staticeng.yaml")],
13037
- [path6.join(legacyNomadworkDir(worktree), "orbita.yaml"), repoConfigPath(worktree), path6.join(".nomadwork", "orbita.yaml")],
13038
- [path6.join(legacyNomadworksDir(worktree), "orbita.yaml"), repoConfigPath(worktree), path6.join(".nomadworks", "orbita.yaml")],
13039
- [path6.join(legacyNomadworkDir(worktree), "runtime"), path6.join(optimaLocalConfigDir(worktree), "runtime"), path6.join(".nomadwork", "runtime")],
13040
- [path6.join(legacyNomadworksDir(worktree), "runtime"), path6.join(optimaLocalConfigDir(worktree), "runtime"), path6.join(".nomadworks", "runtime")],
13041
- [path6.join(legacyNomadworkDir(worktree), "generated"), path6.join(optimaLocalConfigDir(worktree), "generated"), path6.join(".nomadwork", "generated")],
13042
- [path6.join(legacyNomadworksDir(worktree), "generated"), path6.join(optimaLocalConfigDir(worktree), "generated"), path6.join(".nomadworks", "generated")],
13043
- [path6.join(legacyNomadworkDir(worktree), "config"), optimaLocalConfigDir(worktree), path6.join(".nomadwork", "config")],
13044
- [path6.join(legacyNomadworksDir(worktree), "config"), optimaLocalConfigDir(worktree), path6.join(".nomadworks", "config")],
13093
+ [path8.join(legacyNomadworkDir(worktree), "nomadworks.yaml"), repoConfigPath(worktree), path8.join(".nomadwork", "nomadworks.yaml")],
13094
+ [path8.join(legacyNomadworksDir(worktree), "nomadworks.yaml"), repoConfigPath(worktree), path8.join(".nomadworks", "nomadworks.yaml")],
13095
+ [path8.join(legacyNomadworkDir(worktree), "staticeng.yaml"), repoConfigPath(worktree), path8.join(".nomadwork", "staticeng.yaml")],
13096
+ [path8.join(legacyNomadworksDir(worktree), "staticeng.yaml"), repoConfigPath(worktree), path8.join(".nomadworks", "staticeng.yaml")],
13097
+ [path8.join(legacyNomadworkDir(worktree), "orbita.yaml"), repoConfigPath(worktree), path8.join(".nomadwork", "orbita.yaml")],
13098
+ [path8.join(legacyNomadworksDir(worktree), "orbita.yaml"), repoConfigPath(worktree), path8.join(".nomadworks", "orbita.yaml")],
13099
+ [path8.join(legacyNomadworkDir(worktree), "runtime"), path8.join(optimaLocalConfigDir(worktree), "runtime"), path8.join(".nomadwork", "runtime")],
13100
+ [path8.join(legacyNomadworksDir(worktree), "runtime"), path8.join(optimaLocalConfigDir(worktree), "runtime"), path8.join(".nomadworks", "runtime")],
13101
+ [path8.join(legacyNomadworkDir(worktree), "generated"), path8.join(optimaLocalConfigDir(worktree), "generated"), path8.join(".nomadwork", "generated")],
13102
+ [path8.join(legacyNomadworksDir(worktree), "generated"), path8.join(optimaLocalConfigDir(worktree), "generated"), path8.join(".nomadworks", "generated")],
13103
+ [path8.join(legacyNomadworkDir(worktree), "config"), optimaLocalConfigDir(worktree), path8.join(".nomadwork", "config")],
13104
+ [path8.join(legacyNomadworksDir(worktree), "config"), optimaLocalConfigDir(worktree), path8.join(".nomadworks", "config")],
13045
13105
  [legacyNomadworkDir(worktree), optimaDir(worktree), ".nomadwork"],
13046
13106
  [legacyNomadworksDir(worktree), optimaDir(worktree), ".nomadworks"],
13047
- [path6.join(worktree, "tasks"), optimaTasksDir(worktree), "tasks"],
13048
- [path6.join(worktree, "evidences"), optimaEvidencesDir(worktree), "evidences"],
13049
- [path6.join(worktree, "docs", "scrs"), optimaScrsDir(worktree), path6.join("docs", "scrs")],
13050
- [path6.join(worktree, "codemap.yml"), optimaCodemapPath(worktree), "codemap.yml"],
13051
- [path6.join(worktree, "codemap.yaml"), optimaCodemapPath(worktree), "codemap.yaml"]
13107
+ [path8.join(worktree, "tasks"), optimaTasksDir(worktree), "tasks"],
13108
+ [path8.join(worktree, "evidences"), optimaEvidencesDir(worktree), "evidences"],
13109
+ [path8.join(worktree, "docs", "scrs"), optimaScrsDir(worktree), path8.join("docs", "scrs")],
13110
+ [path8.join(worktree, "codemap.yml"), optimaCodemapPath(worktree), "codemap.yml"],
13111
+ [path8.join(worktree, "codemap.yaml"), optimaCodemapPath(worktree), "codemap.yaml"]
13052
13112
  ];
13053
13113
  if (!isOptimaPluginPackageWorktree(worktree)) {
13054
- migrations.push([path6.join(worktree, "policies"), repoPoliciesDir(worktree), "policies"]);
13114
+ migrations.push([path8.join(worktree, "policies"), repoPoliciesDir(worktree), "policies"]);
13055
13115
  }
13056
13116
  for (const [source, destination, relativeSource] of migrations) {
13057
- if (fs5.existsSync(source)) mergePathIntoDestination(source, destination, relativeSource, gitState);
13117
+ if (fs8.existsSync(source)) mergePathIntoDestination(source, destination, relativeSource, gitState);
13058
13118
  }
13059
13119
  for (const [source, destination, relativeSource] of [
13060
- [path6.join(optimaDir(worktree), "optima.yaml"), repoConfigPath(worktree), path6.join(".optima", "optima.yaml")],
13061
- [path6.join(optimaDir(worktree), "config"), optimaLocalConfigDir(worktree), path6.join(".optima", "config")],
13062
- [path6.join(optimaDir(worktree), "runtime"), path6.join(optimaLocalConfigDir(worktree), "runtime"), path6.join(".optima", "runtime")],
13063
- [path6.join(optimaDir(worktree), "generated"), path6.join(optimaLocalConfigDir(worktree), "generated"), path6.join(".optima", "generated")]
13120
+ [path8.join(optimaDir(worktree), "optima.yaml"), repoConfigPath(worktree), path8.join(".optima", "optima.yaml")],
13121
+ [path8.join(optimaDir(worktree), "config"), optimaLocalConfigDir(worktree), path8.join(".optima", "config")],
13122
+ [path8.join(optimaDir(worktree), "runtime"), path8.join(optimaLocalConfigDir(worktree), "runtime"), path8.join(".optima", "runtime")],
13123
+ [path8.join(optimaDir(worktree), "generated"), path8.join(optimaLocalConfigDir(worktree), "generated"), path8.join(".optima", "generated")]
13064
13124
  ]) {
13065
- if (fs5.existsSync(source)) mergePathIntoDestination(source, destination, relativeSource, gitState);
13125
+ if (fs8.existsSync(source)) mergePathIntoDestination(source, destination, relativeSource, gitState);
13066
13126
  }
13067
13127
  }
13068
13128
  function listMarkdownFiles(dirPath) {
13069
- if (!fs5.existsSync(dirPath)) return [];
13129
+ if (!fs8.existsSync(dirPath)) return [];
13070
13130
  try {
13071
- return fs5.readdirSync(dirPath).filter((file) => file.endsWith(".md") && file.toLowerCase() !== "readme.md");
13131
+ return fs8.readdirSync(dirPath).filter((file) => file.endsWith(".md") && file.toLowerCase() !== "readme.md");
13072
13132
  } catch (e) {
13073
13133
  console.error(`[Optima] Failed to read markdown files from ${dirPath}:`, e);
13074
13134
  return [];
@@ -13109,10 +13169,10 @@ function toModelString(provider, model) {
13109
13169
  }
13110
13170
  function readTaskMetadata(taskPath, worktree) {
13111
13171
  if (!taskPath) return {};
13112
- const absoluteTaskPath = path6.isAbsolute(taskPath) ? taskPath : path6.join(worktree, taskPath);
13113
- if (!fs5.existsSync(absoluteTaskPath)) return {};
13172
+ const absoluteTaskPath = path8.isAbsolute(taskPath) ? taskPath : path8.join(worktree, taskPath);
13173
+ if (!fs8.existsSync(absoluteTaskPath)) return {};
13114
13174
  try {
13115
- const raw = fs5.readFileSync(absoluteTaskPath, "utf8");
13175
+ const raw = fs8.readFileSync(absoluteTaskPath, "utf8");
13116
13176
  const { data } = parseFrontmatter(raw);
13117
13177
  return {
13118
13178
  complexity: typeof data.complexity === "string" ? data.complexity.trim().toLowerCase() : void 0,
@@ -13137,11 +13197,11 @@ function slugifyTitle(input) {
13137
13197
  }
13138
13198
  function loadDiscussionRegistry(worktree) {
13139
13199
  const registryPath = runtimeDiscussionRegistryPath(worktree);
13140
- if (!fs5.existsSync(registryPath)) {
13200
+ if (!fs8.existsSync(registryPath)) {
13141
13201
  return { version: 1, active: {} };
13142
13202
  }
13143
13203
  try {
13144
- const parsed = JSON.parse(fs5.readFileSync(registryPath, "utf8"));
13204
+ const parsed = JSON.parse(fs8.readFileSync(registryPath, "utf8"));
13145
13205
  const registry = {
13146
13206
  version: 1,
13147
13207
  active: Object.fromEntries(Object.entries(parsed.active || {}).map(([key, value]) => [key, normalizeLegacyDiscussionEntry(value)]))
@@ -13154,34 +13214,34 @@ function loadDiscussionRegistry(worktree) {
13154
13214
  }
13155
13215
  function saveDiscussionRegistry(worktree, registry) {
13156
13216
  const registryPath = runtimeDiscussionRegistryPath(worktree);
13157
- const runtimeDir = path6.dirname(registryPath);
13158
- if (!fs5.existsSync(runtimeDir)) fs5.mkdirSync(runtimeDir, { recursive: true });
13159
- fs5.writeFileSync(registryPath, JSON.stringify(registry, null, 2), "utf8");
13217
+ const runtimeDir = path8.dirname(registryPath);
13218
+ if (!fs8.existsSync(runtimeDir)) fs8.mkdirSync(runtimeDir, { recursive: true });
13219
+ fs8.writeFileSync(registryPath, JSON.stringify(registry, null, 2), "utf8");
13160
13220
  }
13161
13221
  function runtimeDiscussionsDir(worktree) {
13162
- return path6.join(optimaLocalConfigDir(worktree), "runtime", "discussions");
13222
+ return path8.join(optimaLocalConfigDir(worktree), "runtime", "discussions");
13163
13223
  }
13164
13224
  function archivedRuntimeDiscussionsDir(worktree) {
13165
- return path6.join(runtimeDiscussionsDir(worktree), "archive");
13225
+ return path8.join(runtimeDiscussionsDir(worktree), "archive");
13166
13226
  }
13167
13227
  function finalDiscussionsDir(worktree) {
13168
- return path6.join(optimaTasksDir(worktree), "discussions");
13228
+ return path8.join(optimaTasksDir(worktree), "discussions");
13169
13229
  }
13170
13230
  function nextDiscussionIdentity(worktree, title) {
13171
13231
  const discussionsDir = finalDiscussionsDir(worktree);
13172
13232
  const runtimeDir = runtimeDiscussionsDir(worktree);
13173
- if (!fs5.existsSync(discussionsDir)) fs5.mkdirSync(discussionsDir, { recursive: true });
13174
- if (!fs5.existsSync(runtimeDir)) fs5.mkdirSync(runtimeDir, { recursive: true });
13233
+ if (!fs8.existsSync(discussionsDir)) fs8.mkdirSync(discussionsDir, { recursive: true });
13234
+ if (!fs8.existsSync(runtimeDir)) fs8.mkdirSync(runtimeDir, { recursive: true });
13175
13235
  let sequence = 1;
13176
13236
  while (true) {
13177
13237
  const id = `DISCUSSION-${String(sequence).padStart(3, "0")}`;
13178
13238
  const filename = `${id}-${slugifyTitle(title)}.md`;
13179
- const summaryRelativePath = path6.join(".optima", "tasks", "discussions", filename);
13180
- const summaryAbsolutePath = path6.join(worktree, summaryRelativePath);
13239
+ const summaryRelativePath = path8.join(".optima", "tasks", "discussions", filename);
13240
+ const summaryAbsolutePath = path8.join(worktree, summaryRelativePath);
13181
13241
  const transcriptFilename = `${id}-transcript.md`;
13182
- const transcriptRelativePath = path6.join(".optima", ".config", "runtime", "discussions", transcriptFilename);
13183
- const transcriptAbsolutePath = path6.join(worktree, transcriptRelativePath);
13184
- if (!fs5.existsSync(summaryAbsolutePath) && !fs5.existsSync(transcriptAbsolutePath)) {
13242
+ const transcriptRelativePath = path8.join(".optima", ".config", "runtime", "discussions", transcriptFilename);
13243
+ const transcriptAbsolutePath = path8.join(worktree, transcriptRelativePath);
13244
+ if (!fs8.existsSync(summaryAbsolutePath) && !fs8.existsSync(transcriptAbsolutePath)) {
13185
13245
  return {
13186
13246
  id,
13187
13247
  filename,
@@ -13197,23 +13257,23 @@ function nextDiscussionIdentity(worktree, title) {
13197
13257
  }
13198
13258
  function findDiscussionById(worktree, discussionID) {
13199
13259
  const discussionsDir = finalDiscussionsDir(worktree);
13200
- if (!fs5.existsSync(discussionsDir)) return null;
13201
- const entries = fs5.readdirSync(discussionsDir).filter((name) => name.startsWith(`${discussionID}-`) && name.endsWith(".md"));
13260
+ if (!fs8.existsSync(discussionsDir)) return null;
13261
+ const entries = fs8.readdirSync(discussionsDir).filter((name) => name.startsWith(`${discussionID}-`) && name.endsWith(".md"));
13202
13262
  if (entries.length === 0) return null;
13203
13263
  const filename = entries.sort()[0];
13204
13264
  const transcriptFilename = `${discussionID}-transcript.md`;
13205
13265
  return {
13206
13266
  id: discussionID,
13207
13267
  filename,
13208
- summaryRelativePath: path6.join(".optima", "tasks", "discussions", filename),
13209
- summaryAbsolutePath: path6.join(discussionsDir, filename),
13268
+ summaryRelativePath: path8.join(".optima", "tasks", "discussions", filename),
13269
+ summaryAbsolutePath: path8.join(discussionsDir, filename),
13210
13270
  transcriptFilename,
13211
- transcriptRelativePath: path6.join(".optima", ".config", "runtime", "discussions", transcriptFilename),
13212
- transcriptAbsolutePath: path6.join(runtimeDiscussionsDir(worktree), transcriptFilename)
13271
+ transcriptRelativePath: path8.join(".optima", ".config", "runtime", "discussions", transcriptFilename),
13272
+ transcriptAbsolutePath: path8.join(runtimeDiscussionsDir(worktree), transcriptFilename)
13213
13273
  };
13214
13274
  }
13215
13275
  function parseDiscussionFile(filePath) {
13216
- const raw = fs5.readFileSync(filePath, "utf8");
13276
+ const raw = fs8.readFileSync(filePath, "utf8");
13217
13277
  const { data, body } = parseFrontmatter(raw);
13218
13278
  return { data, body: body.trimStart() };
13219
13279
  }
@@ -13224,10 +13284,10 @@ ${import_yaml3.default.stringify(frontmatter).trim()}
13224
13284
 
13225
13285
  ${body.trimEnd()}
13226
13286
  `;
13227
- fs5.writeFileSync(filePath, serialized, "utf8");
13287
+ fs8.writeFileSync(filePath, serialized, "utf8");
13228
13288
  }
13229
13289
  function setDiscussionStatus(filePath, status) {
13230
- if (!fs5.existsSync(filePath)) return;
13290
+ if (!fs8.existsSync(filePath)) return;
13231
13291
  const { data, body } = parseDiscussionFile(filePath);
13232
13292
  writeDiscussionFile(filePath, { ...data, status }, body);
13233
13293
  }
@@ -13292,18 +13352,18 @@ async function appendMessageIfNeeded(client, worktree, registry, sessionID, mess
13292
13352
  });
13293
13353
  const text = extractTextParts(response.data.parts || []);
13294
13354
  if (!text) return;
13295
- appendDiscussionMessage(path6.join(worktree, discussion.transcriptPath), speaker, text, messageID);
13355
+ appendDiscussionMessage(path8.join(worktree, discussion.transcriptPath), speaker, text, messageID);
13296
13356
  discussion.appendedMessageIDs ??= [];
13297
13357
  discussion.appendedMessageIDs.push(messageID);
13298
13358
  saveDiscussionRegistry(worktree, registry);
13299
13359
  }
13300
13360
  async function summarizeDiscussionWithBA(client, worktree, discussion) {
13301
- const transcriptPath = path6.join(worktree, discussion.transcriptPath);
13302
- const summaryPath = path6.join(worktree, discussion.summaryPath);
13303
- const summaryDir = path6.dirname(summaryPath);
13304
- if (!fs5.existsSync(summaryDir)) fs5.mkdirSync(summaryDir, { recursive: true });
13305
- const hasExistingSummary = fs5.existsSync(summaryPath);
13306
- const priorMtimeMs = hasExistingSummary ? fs5.statSync(summaryPath).mtimeMs : null;
13361
+ const transcriptPath = path8.join(worktree, discussion.transcriptPath);
13362
+ const summaryPath = path8.join(worktree, discussion.summaryPath);
13363
+ const summaryDir = path8.dirname(summaryPath);
13364
+ if (!fs8.existsSync(summaryDir)) fs8.mkdirSync(summaryDir, { recursive: true });
13365
+ const hasExistingSummary = fs8.existsSync(summaryPath);
13366
+ const priorMtimeMs = hasExistingSummary ? fs8.statSync(summaryPath).mtimeMs : null;
13307
13367
  const summarizerSession = await client.session.create({
13308
13368
  body: { title: `Discussion Summary: ${discussion.id}` }
13309
13369
  });
@@ -13403,30 +13463,30 @@ async function summarizeDiscussionWithBA(client, worktree, discussion) {
13403
13463
  return { confirmation, summaryPath, transcriptPath, hasExistingSummary, priorMtimeMs };
13404
13464
  }
13405
13465
  function archiveDiscussionTranscript(worktree, transcriptRelativePath) {
13406
- const sourcePath = path6.join(worktree, transcriptRelativePath);
13407
- if (!fs5.existsSync(sourcePath)) return null;
13466
+ const sourcePath = path8.join(worktree, transcriptRelativePath);
13467
+ if (!fs8.existsSync(sourcePath)) return null;
13408
13468
  const archiveDir = archivedRuntimeDiscussionsDir(worktree);
13409
- if (!fs5.existsSync(archiveDir)) fs5.mkdirSync(archiveDir, { recursive: true });
13410
- const targetPath = path6.join(archiveDir, path6.basename(sourcePath));
13411
- fs5.renameSync(sourcePath, targetPath);
13469
+ if (!fs8.existsSync(archiveDir)) fs8.mkdirSync(archiveDir, { recursive: true });
13470
+ const targetPath = path8.join(archiveDir, path8.basename(sourcePath));
13471
+ fs8.renameSync(sourcePath, targetPath);
13412
13472
  return targetPath;
13413
13473
  }
13414
13474
  async function finalizeClosingDiscussion(client, worktree, registry, sessionID, discussion) {
13415
13475
  const { confirmation, summaryPath, hasExistingSummary, priorMtimeMs } = await summarizeDiscussionWithBA(client, worktree, discussion);
13416
- if (!fs5.existsSync(summaryPath)) {
13476
+ if (!fs8.existsSync(summaryPath)) {
13417
13477
  throw new Error(`Discussion summary was not written to ${discussion.summaryPath}`);
13418
13478
  }
13419
13479
  if (hasExistingSummary) {
13420
- const currentMtimeMs = fs5.statSync(summaryPath).mtimeMs;
13480
+ const currentMtimeMs = fs8.statSync(summaryPath).mtimeMs;
13421
13481
  if (currentMtimeMs <= priorMtimeMs) {
13422
13482
  throw new Error(`Discussion summary file was not updated at ${discussion.summaryPath}`);
13423
13483
  }
13424
13484
  }
13425
- const summaryContent = fs5.readFileSync(summaryPath, "utf8").trim();
13485
+ const summaryContent = fs8.readFileSync(summaryPath, "utf8").trim();
13426
13486
  if (!summaryContent) {
13427
13487
  throw new Error(`Discussion summary file is empty at ${discussion.summaryPath}`);
13428
13488
  }
13429
- const transcriptPath = path6.join(worktree, discussion.transcriptPath);
13489
+ const transcriptPath = path8.join(worktree, discussion.transcriptPath);
13430
13490
  setDiscussionStatus(transcriptPath, "closed");
13431
13491
  const archivedTranscriptPath = archiveDiscussionTranscript(worktree, discussion.transcriptPath);
13432
13492
  delete registry.active[sessionID];
@@ -13434,7 +13494,7 @@ async function finalizeClosingDiscussion(client, worktree, registry, sessionID,
13434
13494
  return {
13435
13495
  confirmation,
13436
13496
  summaryPath: discussion.summaryPath,
13437
- archivedTranscriptPath: archivedTranscriptPath ? path6.relative(worktree, archivedTranscriptPath) : path6.join(".optima", ".config", "runtime", "discussions", "archive", path6.basename(discussion.transcriptPath))
13497
+ archivedTranscriptPath: archivedTranscriptPath ? path8.relative(worktree, archivedTranscriptPath) : path8.join(".optima", ".config", "runtime", "discussions", "archive", path8.basename(discussion.transcriptPath))
13438
13498
  };
13439
13499
  }
13440
13500
  function normalizeTeamMode(value) {
@@ -13473,13 +13533,13 @@ function getOperatingTeamMode(repoCfg) {
13473
13533
  }
13474
13534
  function readResolvedFile(relativePath, worktree, options = {}) {
13475
13535
  const filePath = resolveIncludeFile(`plugin:${relativePath}`, worktree, PKG_ROOT, options);
13476
- if (!filePath || !fs5.existsSync(filePath)) return "";
13477
- return resolveIncludes(fs5.readFileSync(filePath, "utf8"), worktree, PKG_ROOT, options).trim();
13536
+ if (!filePath || !fs8.existsSync(filePath)) return "";
13537
+ return resolveIncludes(fs8.readFileSync(filePath, "utf8"), worktree, PKG_ROOT, options).trim();
13478
13538
  }
13479
13539
  function loadMarkdownFragment(filePath, worktree) {
13480
- if (!fs5.existsSync(filePath)) return "";
13540
+ if (!fs8.existsSync(filePath)) return "";
13481
13541
  try {
13482
- const raw = fs5.readFileSync(filePath, "utf8");
13542
+ const raw = fs8.readFileSync(filePath, "utf8");
13483
13543
  const { body } = parseFrontmatter(raw);
13484
13544
  return resolveIncludes(body.trim(), worktree, PKG_ROOT);
13485
13545
  } catch (e) {
@@ -13488,9 +13548,9 @@ function loadMarkdownFragment(filePath, worktree) {
13488
13548
  }
13489
13549
  }
13490
13550
  function loadAgentDefinition(filePath, worktree, options = {}) {
13491
- if (!fs5.existsSync(filePath)) return null;
13551
+ if (!fs8.existsSync(filePath)) return null;
13492
13552
  try {
13493
- const rawContent = fs5.readFileSync(filePath, "utf8");
13553
+ const rawContent = fs8.readFileSync(filePath, "utf8");
13494
13554
  const { data, body } = parseFrontmatter(rawContent);
13495
13555
  const prompt = resolveIncludes(body.trim(), worktree, PKG_ROOT, options);
13496
13556
  return { data, prompt };
@@ -13501,13 +13561,13 @@ function loadAgentDefinition(filePath, worktree, options = {}) {
13501
13561
  }
13502
13562
  function syncGeneratedPolicies(worktree, repoCfg) {
13503
13563
  if (repoCfg.policies?.extract_defaults !== "all") return;
13504
- if (!fs5.existsSync(BUNDLE_POLICIES_DIR)) return;
13564
+ if (!fs8.existsSync(BUNDLE_POLICIES_DIR)) return;
13505
13565
  const generatedDir = generatedPoliciesDir(worktree);
13506
- if (!fs5.existsSync(generatedDir)) fs5.mkdirSync(generatedDir, { recursive: true });
13507
- const policyFiles = fs5.readdirSync(BUNDLE_POLICIES_DIR).filter((file) => file.endsWith(".md") && file !== "README.md");
13566
+ if (!fs8.existsSync(generatedDir)) fs8.mkdirSync(generatedDir, { recursive: true });
13567
+ const policyFiles = fs8.readdirSync(BUNDLE_POLICIES_DIR).filter((file) => file.endsWith(".md") && file !== "README.md");
13508
13568
  for (const file of policyFiles) {
13509
- const sourcePath = path6.join(BUNDLE_POLICIES_DIR, file);
13510
- const source = fs5.readFileSync(sourcePath, "utf8").trimEnd();
13569
+ const sourcePath = path8.join(BUNDLE_POLICIES_DIR, file);
13570
+ const source = fs8.readFileSync(sourcePath, "utf8").trimEnd();
13511
13571
  const generated = [
13512
13572
  "<!--",
13513
13573
  "Generated from Optima plugin defaults.",
@@ -13518,19 +13578,19 @@ function syncGeneratedPolicies(worktree, repoCfg) {
13518
13578
  source,
13519
13579
  ""
13520
13580
  ].join("\n");
13521
- fs5.writeFileSync(path6.join(generatedDir, file), generated, "utf8");
13581
+ fs8.writeFileSync(path8.join(generatedDir, file), generated, "utf8");
13522
13582
  }
13523
13583
  }
13524
13584
  function ensureReadmeFile(dirPath, content) {
13525
- if (!fs5.existsSync(dirPath)) fs5.mkdirSync(dirPath, { recursive: true });
13526
- const readmePath = path6.join(dirPath, "README.md");
13527
- if (!fs5.existsSync(readmePath)) {
13528
- fs5.writeFileSync(readmePath, content, "utf8");
13585
+ if (!fs8.existsSync(dirPath)) fs8.mkdirSync(dirPath, { recursive: true });
13586
+ const readmePath = path8.join(dirPath, "README.md");
13587
+ if (!fs8.existsSync(readmePath)) {
13588
+ fs8.writeFileSync(readmePath, content, "utf8");
13529
13589
  }
13530
13590
  }
13531
13591
  function ensureFileIfMissing(filePath, content) {
13532
- if (!fs5.existsSync(path6.dirname(filePath))) fs5.mkdirSync(path6.dirname(filePath), { recursive: true });
13533
- if (!fs5.existsSync(filePath)) fs5.writeFileSync(filePath, content, "utf8");
13592
+ if (!fs8.existsSync(path8.dirname(filePath))) fs8.mkdirSync(path8.dirname(filePath), { recursive: true });
13593
+ if (!fs8.existsSync(filePath)) fs8.writeFileSync(filePath, content, "utf8");
13534
13594
  }
13535
13595
  function currentTasksRegistryContent() {
13536
13596
  return "# Current Tasks (Backlog)\n\n## \u{1F4AC} Active Discussions\n- (None)\n\n## \u{1F680} Active\n- (None)\n\n## \u{1F4CB} Todo\n- (None)\n\n## \u{1F6D1} Blocked\n- (None)\n";
@@ -13616,16 +13676,16 @@ Never place implementation evidence under root \`evidences/\`.
13616
13676
  }
13617
13677
  function ensureOptimaTaskTemplates(worktree) {
13618
13678
  const tasksDir = optimaTasksDir(worktree);
13619
- ensureFileIfMissing(path6.join(tasksDir, "task-template.md"), taskTemplateContent());
13620
- ensureFileIfMissing(path6.join(tasksDir, "subtask-template.md"), subtaskTemplateContent());
13679
+ ensureFileIfMissing(path8.join(tasksDir, "task-template.md"), taskTemplateContent());
13680
+ ensureFileIfMissing(path8.join(tasksDir, "subtask-template.md"), subtaskTemplateContent());
13621
13681
  }
13622
13682
  function scaffoldOptimaConfig(worktree, teamMode = "full") {
13623
13683
  const configPath = repoConfigPath(worktree);
13624
- if (fs5.existsSync(configPath)) return false;
13625
- const templatePath = path6.join(TEMPLATES_DIR, "optima.yaml.template");
13626
- if (!fs5.existsSync(templatePath)) return false;
13627
- const agentIds = fs5.existsSync(BUNDLE_AGENTS_DIR) ? fs5.readdirSync(BUNDLE_AGENTS_DIR).filter((f) => f.endsWith(".md")).map((f) => f.replace(".md", "")) : [];
13628
- let optimaConfig = fs5.readFileSync(templatePath, "utf8");
13684
+ if (fs8.existsSync(configPath)) return false;
13685
+ const templatePath = path8.join(TEMPLATES_DIR, "optima.yaml.template");
13686
+ if (!fs8.existsSync(templatePath)) return false;
13687
+ const agentIds = fs8.existsSync(BUNDLE_AGENTS_DIR) ? fs8.readdirSync(BUNDLE_AGENTS_DIR).filter((f) => f.endsWith(".md")).map((f) => f.replace(".md", "")) : [];
13688
+ let optimaConfig = fs8.readFileSync(templatePath, "utf8");
13629
13689
  optimaConfig = optimaConfig.replace("{{teamMode}}", normalizeTeamMode(teamMode));
13630
13690
  let agentsSection = "";
13631
13691
  for (const id of agentIds) {
@@ -13636,26 +13696,26 @@ function scaffoldOptimaConfig(worktree, teamMode = "full") {
13636
13696
  }
13637
13697
  optimaConfig = optimaConfig.replace(/^agents:/m, "agents:\n" + agentsSection);
13638
13698
  ensureFileIfMissing(configPath, optimaConfig);
13639
- return fs5.existsSync(configPath);
13699
+ return fs8.existsSync(configPath);
13640
13700
  }
13641
13701
  function scaffoldOptimaRootCodemap(worktree) {
13642
13702
  const rootCodemapPath = optimaCodemapPath(worktree);
13643
- if (fs5.existsSync(rootCodemapPath)) return false;
13644
- const templatePath = path6.join(TEMPLATES_DIR, "codemap.yml.template");
13645
- if (!fs5.existsSync(templatePath)) return false;
13646
- const codemapConfig = fs5.readFileSync(templatePath, "utf8").replace("{{projectName}}", path6.basename(worktree));
13703
+ if (fs8.existsSync(rootCodemapPath)) return false;
13704
+ const templatePath = path8.join(TEMPLATES_DIR, "codemap.yml.template");
13705
+ if (!fs8.existsSync(templatePath)) return false;
13706
+ const codemapConfig = fs8.readFileSync(templatePath, "utf8").replace("{{projectName}}", path8.basename(worktree));
13647
13707
  ensureFileIfMissing(rootCodemapPath, codemapConfig);
13648
- return fs5.existsSync(rootCodemapPath);
13708
+ return fs8.existsSync(rootCodemapPath);
13649
13709
  }
13650
13710
  function ensureOptimaRegistries(worktree) {
13651
13711
  const tasksDir = optimaTasksDir(worktree);
13652
13712
  const scrsDir = optimaScrsDir(worktree);
13653
- if (!fs5.existsSync(tasksDir)) fs5.mkdirSync(tasksDir, { recursive: true });
13654
- if (!fs5.existsSync(scrsDir)) fs5.mkdirSync(scrsDir, { recursive: true });
13655
- ensureFileIfMissing(path6.join(tasksDir, "current.md"), currentTasksRegistryContent());
13656
- ensureFileIfMissing(path6.join(tasksDir, "done.md"), doneTasksRegistryContent());
13657
- ensureFileIfMissing(path6.join(scrsDir, "current.md"), currentScrRegistryContent());
13658
- ensureFileIfMissing(path6.join(scrsDir, "done.md"), doneScrRegistryContent());
13713
+ if (!fs8.existsSync(tasksDir)) fs8.mkdirSync(tasksDir, { recursive: true });
13714
+ if (!fs8.existsSync(scrsDir)) fs8.mkdirSync(scrsDir, { recursive: true });
13715
+ ensureFileIfMissing(path8.join(tasksDir, "current.md"), currentTasksRegistryContent());
13716
+ ensureFileIfMissing(path8.join(tasksDir, "done.md"), doneTasksRegistryContent());
13717
+ ensureFileIfMissing(path8.join(scrsDir, "current.md"), currentScrRegistryContent());
13718
+ ensureFileIfMissing(path8.join(scrsDir, "done.md"), doneScrRegistryContent());
13659
13719
  }
13660
13720
  function scaffoldOptimaReadmes(worktree) {
13661
13721
  ensureReadmeFile(repoPoliciesDir(worktree), REPO_LOCAL_POLICIES_README);
@@ -13817,12 +13877,12 @@ function shouldRegisterWorkflowProductManager(options = {}, worktree = process.c
13817
13877
  }
13818
13878
  function isClickUpDerivedWorktreeSibling(candidate, basePath) {
13819
13879
  if (typeof candidate !== "string" || typeof basePath !== "string" || !candidate.trim() || !basePath.trim()) return false;
13820
- const resolvedCandidate = path6.resolve(candidate);
13821
- const resolvedBase = path6.resolve(basePath);
13822
- const baseParent = path6.dirname(resolvedBase);
13823
- if (path6.dirname(resolvedCandidate) !== baseParent) return false;
13824
- const baseName = path6.basename(resolvedBase);
13825
- const candidateName = path6.basename(resolvedCandidate);
13880
+ const resolvedCandidate = path8.resolve(candidate);
13881
+ const resolvedBase = path8.resolve(basePath);
13882
+ const baseParent = path8.dirname(resolvedBase);
13883
+ if (path8.dirname(resolvedCandidate) !== baseParent) return false;
13884
+ const baseName = path8.basename(resolvedBase);
13885
+ const candidateName = path8.basename(resolvedCandidate);
13826
13886
  if (!candidateName.startsWith(`${baseName}-`)) return false;
13827
13887
  const branchSlug = candidateName.slice(baseName.length + 1);
13828
13888
  const parts = branchSlug.split("-").filter(Boolean);
@@ -13830,11 +13890,11 @@ function isClickUpDerivedWorktreeSibling(candidate, basePath) {
13830
13890
  if (!(/* @__PURE__ */ new Set(["tarea", "bug", "doc", "poc", "idea"])).has(parts[0])) return false;
13831
13891
  if (!parts.slice(1).every((part) => /^[a-z0-9][a-z0-9-]*$/.test(part))) return false;
13832
13892
  try {
13833
- const candidateStat = fs5.lstatSync(resolvedCandidate);
13893
+ const candidateStat = fs8.lstatSync(resolvedCandidate);
13834
13894
  if (!candidateStat.isDirectory() || candidateStat.isSymbolicLink()) return false;
13835
- const realCandidate = fs5.realpathSync.native(resolvedCandidate);
13836
- const realBaseParent = fs5.realpathSync.native(baseParent);
13837
- return path6.dirname(realCandidate) === realBaseParent && path6.basename(realCandidate) === candidateName;
13895
+ const realCandidate = fs8.realpathSync.native(resolvedCandidate);
13896
+ const realBaseParent = fs8.realpathSync.native(baseParent);
13897
+ return path8.dirname(realCandidate) === realBaseParent && path8.basename(realCandidate) === candidateName;
13838
13898
  } catch {
13839
13899
  return false;
13840
13900
  }
@@ -13842,15 +13902,15 @@ function isClickUpDerivedWorktreeSibling(candidate, basePath) {
13842
13902
  function resolveSessionToolDirectory({ requestedDirectory, context, pluginWorktree, clickUpWebhookValidation } = {}) {
13843
13903
  const safe = safeWorktreeOrFailure(context, pluginWorktree);
13844
13904
  if (!safe.ok) return { ok: false, error: safe.message };
13845
- const requested = String(requestedDirectory || "").trim() ? path6.resolve(safe.worktree, String(requestedDirectory).trim()) : safe.worktree;
13905
+ const requested = String(requestedDirectory || "").trim() ? path8.resolve(safe.worktree, String(requestedDirectory).trim()) : safe.worktree;
13846
13906
  if (!isSafeWritableDirectory(requested)) return { ok: false, error: `Directory is not a safe writable directory: ${requested}` };
13847
13907
  if (isSameOrNestedPath(requested, safe.worktree)) return { ok: true, directory: requested, safeWorktree: safe.worktree, scope: "context_worktree" };
13848
13908
  const clickUpBasePath = clickUpWebhookValidation?.complete === true && clickUpWebhookValidation?.ok !== false ? clickUpWebhookValidation.config?.basePath : "";
13849
13909
  if (clickUpBasePath && isSameOrNestedPath(requested, clickUpBasePath)) {
13850
- return { ok: true, directory: requested, safeWorktree: safe.worktree, scope: "clickup_base_path", clickupBasePath: path6.resolve(clickUpBasePath) };
13910
+ return { ok: true, directory: requested, safeWorktree: safe.worktree, scope: "clickup_base_path", clickupBasePath: path8.resolve(clickUpBasePath) };
13851
13911
  }
13852
13912
  if (clickUpBasePath && isClickUpDerivedWorktreeSibling(requested, clickUpBasePath)) {
13853
- return { ok: true, directory: requested, safeWorktree: safe.worktree, scope: "clickup_derived_worktree", clickupBasePath: path6.resolve(clickUpBasePath) };
13913
+ return { ok: true, directory: requested, safeWorktree: safe.worktree, scope: "clickup_derived_worktree", clickupBasePath: path8.resolve(clickUpBasePath) };
13854
13914
  }
13855
13915
  return {
13856
13916
  ok: false,
@@ -13884,8 +13944,8 @@ function buildOptimaAgents(repoCfg, operatingTeamMode, worktree, debugDir, optio
13884
13944
  if (!enabled) continue;
13885
13945
  }
13886
13946
  const promptOptions = { preferCompactPromptDocs: repoCfg.features?.compact_prompt_docs !== false };
13887
- const bundledDefinition = loadAgentDefinition(path6.join(BUNDLE_AGENTS_DIR, file), worktree, promptOptions);
13888
- const repoDefinition = loadAgentDefinition(path6.join(repoAgentDefinitions, file), worktree, promptOptions) || loadAgentDefinition(path6.join(legacyAgentsDir, file), worktree, promptOptions);
13947
+ const bundledDefinition = loadAgentDefinition(path8.join(BUNDLE_AGENTS_DIR, file), worktree, promptOptions);
13948
+ const repoDefinition = loadAgentDefinition(path8.join(repoAgentDefinitions, file), worktree, promptOptions) || loadAgentDefinition(path8.join(legacyAgentsDir, file), worktree, promptOptions);
13889
13949
  const activeDefinition = repoDefinition || bundledDefinition;
13890
13950
  if (!activeDefinition) continue;
13891
13951
  const { data } = activeDefinition;
@@ -13894,7 +13954,7 @@ function buildOptimaAgents(repoCfg, operatingTeamMode, worktree, debugDir, optio
13894
13954
  if (modePromptFragment) finalPrompt = `${finalPrompt}
13895
13955
 
13896
13956
  ${modePromptFragment}`;
13897
- const additionFragment = loadMarkdownFragment(path6.join(repoAgentAdditions, file), worktree);
13957
+ const additionFragment = loadMarkdownFragment(path8.join(repoAgentAdditions, file), worktree);
13898
13958
  if (additionFragment) {
13899
13959
  finalPrompt = `${finalPrompt}
13900
13960
 
@@ -13947,14 +14007,14 @@ Use this Optima-provided fallback when the current task worktree lacks docs/core
13947
14007
  }
13948
14008
  ourAgents[id] = agentConfig;
13949
14009
  if (repoCfg.features?.debug_dumps !== false) {
13950
- const debugPath = path6.join(debugDir, `${id}.md`);
14010
+ const debugPath = path8.join(debugDir, `${id}.md`);
13951
14011
  const { prompt, ...dumpConfig } = agentConfig;
13952
14012
  const debugHeader = `---
13953
14013
  ${import_yaml3.default.stringify(dumpConfig).trim()}
13954
14014
  ---`;
13955
14015
  try {
13956
- if (!fs5.existsSync(debugDir)) fs5.mkdirSync(debugDir, { recursive: true });
13957
- fs5.writeFileSync(debugPath, `${debugHeader}
14016
+ if (!fs8.existsSync(debugDir)) fs8.mkdirSync(debugDir, { recursive: true });
14017
+ fs8.writeFileSync(debugPath, `${debugHeader}
13958
14018
 
13959
14019
  ${prompt}`, "utf8");
13960
14020
  } catch (e) {
@@ -13978,9 +14038,9 @@ async function OptimaPlugin(input = {}, pluginOptions = {}) {
13978
14038
  const configPath = resolveConfigPath(worktree);
13979
14039
  const discussionRegistry = loadDiscussionRegistry(worktree);
13980
14040
  let repoCfg = { agents: {}, defaults: {}, features: {} };
13981
- if (fs5.existsSync(configPath)) {
14041
+ if (fs8.existsSync(configPath)) {
13982
14042
  try {
13983
- repoCfg = import_yaml3.default.parse(fs5.readFileSync(configPath, "utf8")) || repoCfg;
14043
+ repoCfg = import_yaml3.default.parse(fs8.readFileSync(configPath, "utf8")) || repoCfg;
13984
14044
  } catch (e) {
13985
14045
  console.error(`[Optima] Failed to parse config at ${configPath}:`, e);
13986
14046
  }
@@ -14108,10 +14168,10 @@ async function OptimaPlugin(input = {}, pluginOptions = {}) {
14108
14168
  }
14109
14169
  migrateLegacyOptimaLayout(toolWorktree);
14110
14170
  const cfgDir = optimaConfigDir(toolWorktree);
14111
- if (!fs5.existsSync(cfgDir)) fs5.mkdirSync(cfgDir, { recursive: true });
14112
- const optimaTmplPath = path6.join(TEMPLATES_DIR, "optima.yaml.template");
14113
- const codemapTmplPath = path6.join(TEMPLATES_DIR, "codemap.yml.template");
14114
- if (!fs5.existsSync(optimaTmplPath) || !fs5.existsSync(codemapTmplPath)) {
14171
+ if (!fs8.existsSync(cfgDir)) fs8.mkdirSync(cfgDir, { recursive: true });
14172
+ const optimaTmplPath = path8.join(TEMPLATES_DIR, "optima.yaml.template");
14173
+ const codemapTmplPath = path8.join(TEMPLATES_DIR, "codemap.yml.template");
14174
+ if (!fs8.existsSync(optimaTmplPath) || !fs8.existsSync(codemapTmplPath)) {
14115
14175
  return "Error: Initialization templates not found in plugin.";
14116
14176
  }
14117
14177
  scaffoldOptimaConfig(toolWorktree, requestedTeamMode);
@@ -14232,14 +14292,14 @@ Restart or reload OpenCode manually if the newly scaffolded config or agents are
14232
14292
  async execute(args, context) {
14233
14293
  const safe = safeWorktreeOrFailure(context, worktree);
14234
14294
  if (!safe.ok) return safe.message;
14235
- const summaryPath = path6.resolve(safe.worktree, args.summary_path || "");
14236
- if (!fs5.existsSync(summaryPath)) return `FAIL: summary_path not found: ${summaryPath}`;
14237
- const taskPath = args.task_path ? path6.resolve(safe.worktree, args.task_path) : "";
14295
+ const summaryPath = path8.resolve(safe.worktree, args.summary_path || "");
14296
+ if (!fs8.existsSync(summaryPath)) return `FAIL: summary_path not found: ${summaryPath}`;
14297
+ const taskPath = args.task_path ? path8.resolve(safe.worktree, args.task_path) : "";
14238
14298
  const payload = buildClickUpSummaryPayload({
14239
- summaryMarkdown: fs5.readFileSync(summaryPath, "utf8"),
14240
- summaryPath: path6.relative(safe.worktree, summaryPath),
14241
- taskMarkdown: taskPath && fs5.existsSync(taskPath) ? fs5.readFileSync(taskPath, "utf8") : "",
14242
- taskPath: taskPath ? path6.relative(safe.worktree, taskPath) : "",
14299
+ summaryMarkdown: fs8.readFileSync(summaryPath, "utf8"),
14300
+ summaryPath: path8.relative(safe.worktree, summaryPath),
14301
+ taskMarkdown: taskPath && fs8.existsSync(taskPath) ? fs8.readFileSync(taskPath, "utf8") : "",
14302
+ taskPath: taskPath ? path8.relative(safe.worktree, taskPath) : "",
14243
14303
  branch: args.branch,
14244
14304
  worktree: args.worktree,
14245
14305
  pr: args.pr
@@ -14318,12 +14378,12 @@ Restart or reload OpenCode manually if the newly scaffolded config or agents are
14318
14378
  async execute(args, context) {
14319
14379
  const safe = safeWorktreeOrFailure(context, worktree);
14320
14380
  if (!safe.ok) return safe.message;
14321
- const markdownPath = path6.resolve(safe.worktree, args.markdown_path || "");
14322
- if (!fs5.existsSync(markdownPath)) return `FAIL: markdown_path not found: ${markdownPath}`;
14381
+ const markdownPath = path8.resolve(safe.worktree, args.markdown_path || "");
14382
+ if (!fs8.existsSync(markdownPath)) return `FAIL: markdown_path not found: ${markdownPath}`;
14323
14383
  const payload = buildClickUpCreateSubtasksPayload({
14324
14384
  parentTaskId: args.parent_task_id,
14325
- markdown: fs5.readFileSync(markdownPath, "utf8"),
14326
- sourcePath: path6.relative(safe.worktree, markdownPath),
14385
+ markdown: fs8.readFileSync(markdownPath, "utf8"),
14386
+ sourcePath: path8.relative(safe.worktree, markdownPath),
14327
14387
  parentBranch: args.parent_branch,
14328
14388
  parentTaskType: args.parent_task_type || "Tarea",
14329
14389
  apply: String(args.apply || "").toLowerCase() === "true"
@@ -14693,7 +14753,7 @@ Backfilled messages: ${backfilled}`;
14693
14753
  if (!existing) {
14694
14754
  return "FAIL: No active discussion exists for this session.";
14695
14755
  }
14696
- const discussionPath = path6.join(toolWorktree, existing.transcriptPath);
14756
+ const discussionPath = path8.join(toolWorktree, existing.transcriptPath);
14697
14757
  setDiscussionStatus(discussionPath, "summarizing");
14698
14758
  existing.status = "summarizing";
14699
14759
  saveDiscussionRegistry(toolWorktree, toolRegistry);
@@ -14745,7 +14805,7 @@ Reason: ${err.message}`;
14745
14805
  try {
14746
14806
  const sessionResult = await client.session.create({
14747
14807
  query: { directory: workflowDirectory },
14748
- body: { title: `Workflow Run: ${path6.basename(workflowTaskPath)}` }
14808
+ body: { title: `Workflow Run: ${path8.basename(workflowTaskPath)}` }
14749
14809
  });
14750
14810
  const sessionId = sessionResult.data.id;
14751
14811
  activeWorkflows.set(sessionId, { pmaSessionId, taskPath: workflowTaskPath, track: workflowTrack, directory: workflowDirectory });