@defend-tech/opencode-optima 0.1.55 → 0.1.57

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.
@@ -109,17 +109,17 @@ var require_visit = __commonJS({
109
109
  visit.BREAK = BREAK;
110
110
  visit.SKIP = SKIP;
111
111
  visit.REMOVE = REMOVE;
112
- function visit_(key, node, visitor, path4) {
113
- const ctrl = callVisitor(key, node, visitor, path4);
112
+ function visit_(key, node, visitor, path7) {
113
+ const ctrl = callVisitor(key, node, visitor, path7);
114
114
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
115
- replaceNode(key, path4, ctrl);
116
- return visit_(key, ctrl, visitor, path4);
115
+ replaceNode(key, path7, ctrl);
116
+ return visit_(key, ctrl, visitor, path7);
117
117
  }
118
118
  if (typeof ctrl !== "symbol") {
119
119
  if (identity.isCollection(node)) {
120
- path4 = Object.freeze(path4.concat(node));
120
+ path7 = Object.freeze(path7.concat(node));
121
121
  for (let i = 0; i < node.items.length; ++i) {
122
- const ci = visit_(i, node.items[i], visitor, path4);
122
+ const ci = visit_(i, node.items[i], visitor, path7);
123
123
  if (typeof ci === "number")
124
124
  i = ci - 1;
125
125
  else if (ci === BREAK)
@@ -130,13 +130,13 @@ var require_visit = __commonJS({
130
130
  }
131
131
  }
132
132
  } else if (identity.isPair(node)) {
133
- path4 = Object.freeze(path4.concat(node));
134
- const ck = visit_("key", node.key, visitor, path4);
133
+ path7 = Object.freeze(path7.concat(node));
134
+ const ck = visit_("key", node.key, visitor, path7);
135
135
  if (ck === BREAK)
136
136
  return BREAK;
137
137
  else if (ck === REMOVE)
138
138
  node.key = null;
139
- const cv = visit_("value", node.value, visitor, path4);
139
+ const cv = visit_("value", node.value, visitor, path7);
140
140
  if (cv === BREAK)
141
141
  return BREAK;
142
142
  else if (cv === REMOVE)
@@ -157,17 +157,17 @@ var require_visit = __commonJS({
157
157
  visitAsync.BREAK = BREAK;
158
158
  visitAsync.SKIP = SKIP;
159
159
  visitAsync.REMOVE = REMOVE;
160
- async function visitAsync_(key, node, visitor, path4) {
161
- const ctrl = await callVisitor(key, node, visitor, path4);
160
+ async function visitAsync_(key, node, visitor, path7) {
161
+ const ctrl = await callVisitor(key, node, visitor, path7);
162
162
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
163
- replaceNode(key, path4, ctrl);
164
- return visitAsync_(key, ctrl, visitor, path4);
163
+ replaceNode(key, path7, ctrl);
164
+ return visitAsync_(key, ctrl, visitor, path7);
165
165
  }
166
166
  if (typeof ctrl !== "symbol") {
167
167
  if (identity.isCollection(node)) {
168
- path4 = Object.freeze(path4.concat(node));
168
+ path7 = Object.freeze(path7.concat(node));
169
169
  for (let i = 0; i < node.items.length; ++i) {
170
- const ci = await visitAsync_(i, node.items[i], visitor, path4);
170
+ const ci = await visitAsync_(i, node.items[i], visitor, path7);
171
171
  if (typeof ci === "number")
172
172
  i = ci - 1;
173
173
  else if (ci === BREAK)
@@ -178,13 +178,13 @@ var require_visit = __commonJS({
178
178
  }
179
179
  }
180
180
  } else if (identity.isPair(node)) {
181
- path4 = Object.freeze(path4.concat(node));
182
- const ck = await visitAsync_("key", node.key, visitor, path4);
181
+ path7 = Object.freeze(path7.concat(node));
182
+ const ck = await visitAsync_("key", node.key, visitor, path7);
183
183
  if (ck === BREAK)
184
184
  return BREAK;
185
185
  else if (ck === REMOVE)
186
186
  node.key = null;
187
- const cv = await visitAsync_("value", node.value, visitor, path4);
187
+ const cv = await visitAsync_("value", node.value, visitor, path7);
188
188
  if (cv === BREAK)
189
189
  return BREAK;
190
190
  else if (cv === REMOVE)
@@ -211,23 +211,23 @@ var require_visit = __commonJS({
211
211
  }
212
212
  return visitor;
213
213
  }
214
- function callVisitor(key, node, visitor, path4) {
214
+ function callVisitor(key, node, visitor, path7) {
215
215
  if (typeof visitor === "function")
216
- return visitor(key, node, path4);
216
+ return visitor(key, node, path7);
217
217
  if (identity.isMap(node))
218
- return visitor.Map?.(key, node, path4);
218
+ return visitor.Map?.(key, node, path7);
219
219
  if (identity.isSeq(node))
220
- return visitor.Seq?.(key, node, path4);
220
+ return visitor.Seq?.(key, node, path7);
221
221
  if (identity.isPair(node))
222
- return visitor.Pair?.(key, node, path4);
222
+ return visitor.Pair?.(key, node, path7);
223
223
  if (identity.isScalar(node))
224
- return visitor.Scalar?.(key, node, path4);
224
+ return visitor.Scalar?.(key, node, path7);
225
225
  if (identity.isAlias(node))
226
- return visitor.Alias?.(key, node, path4);
226
+ return visitor.Alias?.(key, node, path7);
227
227
  return void 0;
228
228
  }
229
- function replaceNode(key, path4, node) {
230
- const parent = path4[path4.length - 1];
229
+ function replaceNode(key, path7, node) {
230
+ const parent = path7[path7.length - 1];
231
231
  if (identity.isCollection(parent)) {
232
232
  parent.items[key] = node;
233
233
  } else if (identity.isPair(parent)) {
@@ -633,6 +633,8 @@ var require_Alias = __commonJS({
633
633
  * instance of the `source` anchor before this node.
634
634
  */
635
635
  resolve(doc, ctx) {
636
+ if (ctx?.maxAliasCount === 0)
637
+ throw new ReferenceError("Alias resolution is disabled");
636
638
  let nodes;
637
639
  if (ctx?.aliasResolveCache) {
638
640
  nodes = ctx.aliasResolveCache;
@@ -835,10 +837,10 @@ var require_Collection = __commonJS({
835
837
  var createNode = require_createNode();
836
838
  var identity = require_identity();
837
839
  var Node = require_Node();
838
- function collectionFromPath(schema, path4, value) {
840
+ function collectionFromPath(schema, path7, value) {
839
841
  let v = value;
840
- for (let i = path4.length - 1; i >= 0; --i) {
841
- const k = path4[i];
842
+ for (let i = path7.length - 1; i >= 0; --i) {
843
+ const k = path7[i];
842
844
  if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
843
845
  const a = [];
844
846
  a[k] = v;
@@ -857,7 +859,7 @@ var require_Collection = __commonJS({
857
859
  sourceObjects: /* @__PURE__ */ new Map()
858
860
  });
859
861
  }
860
- var isEmptyPath = (path4) => path4 == null || typeof path4 === "object" && !!path4[Symbol.iterator]().next().done;
862
+ var isEmptyPath = (path7) => path7 == null || typeof path7 === "object" && !!path7[Symbol.iterator]().next().done;
861
863
  var Collection = class extends Node.NodeBase {
862
864
  constructor(type, schema) {
863
865
  super(type);
@@ -887,11 +889,11 @@ var require_Collection = __commonJS({
887
889
  * be a Pair instance or a `{ key, value }` object, which may not have a key
888
890
  * that already exists in the map.
889
891
  */
890
- addIn(path4, value) {
891
- if (isEmptyPath(path4))
892
+ addIn(path7, value) {
893
+ if (isEmptyPath(path7))
892
894
  this.add(value);
893
895
  else {
894
- const [key, ...rest] = path4;
896
+ const [key, ...rest] = path7;
895
897
  const node = this.get(key, true);
896
898
  if (identity.isCollection(node))
897
899
  node.addIn(rest, value);
@@ -905,8 +907,8 @@ var require_Collection = __commonJS({
905
907
  * Removes a value from the collection.
906
908
  * @returns `true` if the item was found and removed.
907
909
  */
908
- deleteIn(path4) {
909
- const [key, ...rest] = path4;
910
+ deleteIn(path7) {
911
+ const [key, ...rest] = path7;
910
912
  if (rest.length === 0)
911
913
  return this.delete(key);
912
914
  const node = this.get(key, true);
@@ -920,8 +922,8 @@ var require_Collection = __commonJS({
920
922
  * scalar values from their surrounding node; to disable set `keepScalar` to
921
923
  * `true` (collections are always returned intact).
922
924
  */
923
- getIn(path4, keepScalar) {
924
- const [key, ...rest] = path4;
925
+ getIn(path7, keepScalar) {
926
+ const [key, ...rest] = path7;
925
927
  const node = this.get(key, true);
926
928
  if (rest.length === 0)
927
929
  return !keepScalar && identity.isScalar(node) ? node.value : node;
@@ -939,8 +941,8 @@ var require_Collection = __commonJS({
939
941
  /**
940
942
  * Checks if the collection includes a value with the key `key`.
941
943
  */
942
- hasIn(path4) {
943
- const [key, ...rest] = path4;
944
+ hasIn(path7) {
945
+ const [key, ...rest] = path7;
944
946
  if (rest.length === 0)
945
947
  return this.has(key);
946
948
  const node = this.get(key, true);
@@ -950,8 +952,8 @@ var require_Collection = __commonJS({
950
952
  * Sets a value in this collection. For `!!set`, `value` needs to be a
951
953
  * boolean to add/remove the item from the set.
952
954
  */
953
- setIn(path4, value) {
954
- const [key, ...rest] = path4;
955
+ setIn(path7, value) {
956
+ const [key, ...rest] = path7;
955
957
  if (rest.length === 0) {
956
958
  this.set(key, value);
957
959
  } else {
@@ -1432,6 +1434,7 @@ var require_stringify = __commonJS({
1432
1434
  nullStr: "null",
1433
1435
  simpleKeys: false,
1434
1436
  singleQuote: null,
1437
+ trailingComma: false,
1435
1438
  trueStr: "true",
1436
1439
  verifyAliasOrder: true
1437
1440
  }, doc.schema.toStringOptions, options);
@@ -1704,18 +1707,18 @@ var require_merge = __commonJS({
1704
1707
  };
1705
1708
  var isMergeKey = (ctx, key) => (merge.identify(key) || identity.isScalar(key) && (!key.type || key.type === Scalar.Scalar.PLAIN) && merge.identify(key.value)) && ctx?.doc.schema.tags.some((tag) => tag.tag === merge.tag && tag.default);
1706
1709
  function addMergeToJSMap(ctx, map, value) {
1707
- value = ctx && identity.isAlias(value) ? value.resolve(ctx.doc) : value;
1708
- if (identity.isSeq(value))
1709
- for (const it of value.items)
1710
+ const source = resolveAliasValue(ctx, value);
1711
+ if (identity.isSeq(source))
1712
+ for (const it of source.items)
1710
1713
  mergeValue(ctx, map, it);
1711
- else if (Array.isArray(value))
1712
- for (const it of value)
1714
+ else if (Array.isArray(source))
1715
+ for (const it of source)
1713
1716
  mergeValue(ctx, map, it);
1714
1717
  else
1715
- mergeValue(ctx, map, value);
1718
+ mergeValue(ctx, map, source);
1716
1719
  }
1717
1720
  function mergeValue(ctx, map, value) {
1718
- const source = ctx && identity.isAlias(value) ? value.resolve(ctx.doc) : value;
1721
+ const source = resolveAliasValue(ctx, value);
1719
1722
  if (!identity.isMap(source))
1720
1723
  throw new Error("Merge sources must be maps or map aliases");
1721
1724
  const srcMap = source.toJSON(null, ctx, Map);
@@ -1736,6 +1739,9 @@ var require_merge = __commonJS({
1736
1739
  }
1737
1740
  return map;
1738
1741
  }
1742
+ function resolveAliasValue(ctx, value) {
1743
+ return ctx && identity.isAlias(value) ? value.resolve(ctx.doc, ctx) : value;
1744
+ }
1739
1745
  exports.addMergeToJSMap = addMergeToJSMap;
1740
1746
  exports.isMergeKey = isMergeKey;
1741
1747
  exports.merge = merge;
@@ -1949,12 +1955,19 @@ ${indent}${line}` : "\n";
1949
1955
  if (comment)
1950
1956
  reqNewline = true;
1951
1957
  let str = stringify.stringify(item, itemCtx, () => comment = null);
1952
- if (i < items.length - 1)
1958
+ reqNewline || (reqNewline = lines.length > linesAtValue || str.includes("\n"));
1959
+ if (i < items.length - 1) {
1953
1960
  str += ",";
1961
+ } else if (ctx.options.trailingComma) {
1962
+ if (ctx.options.lineWidth > 0) {
1963
+ reqNewline || (reqNewline = lines.reduce((sum, line) => sum + line.length + 2, 2) + (str.length + 2) > ctx.options.lineWidth);
1964
+ }
1965
+ if (reqNewline) {
1966
+ str += ",";
1967
+ }
1968
+ }
1954
1969
  if (comment)
1955
1970
  str += stringifyComment.lineComment(str, itemIndent, commentString(comment));
1956
- if (!reqNewline && (lines.length > linesAtValue || str.includes("\n")))
1957
- reqNewline = true;
1958
1971
  lines.push(str);
1959
1972
  linesAtValue = lines.length;
1960
1973
  }
@@ -2366,7 +2379,7 @@ var require_stringifyNumber = __commonJS({
2366
2379
  if (!isFinite(num))
2367
2380
  return isNaN(num) ? ".nan" : num < 0 ? "-.inf" : ".inf";
2368
2381
  let n = Object.is(value, -0) ? "-0" : JSON.stringify(value);
2369
- if (!format && minFractionDigits && (!tag || tag === "tag:yaml.org,2002:float") && /^\d/.test(n)) {
2382
+ if (!format && minFractionDigits && (!tag || tag === "tag:yaml.org,2002:float") && /^-?\d/.test(n) && !n.includes("e")) {
2370
2383
  let i = n.indexOf(".");
2371
2384
  if (i < 0) {
2372
2385
  i = n.length;
@@ -3455,9 +3468,9 @@ var require_Document = __commonJS({
3455
3468
  this.contents.add(value);
3456
3469
  }
3457
3470
  /** Adds a value to the document. */
3458
- addIn(path4, value) {
3471
+ addIn(path7, value) {
3459
3472
  if (assertCollection(this.contents))
3460
- this.contents.addIn(path4, value);
3473
+ this.contents.addIn(path7, value);
3461
3474
  }
3462
3475
  /**
3463
3476
  * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
@@ -3532,14 +3545,14 @@ var require_Document = __commonJS({
3532
3545
  * Removes a value from the document.
3533
3546
  * @returns `true` if the item was found and removed.
3534
3547
  */
3535
- deleteIn(path4) {
3536
- if (Collection.isEmptyPath(path4)) {
3548
+ deleteIn(path7) {
3549
+ if (Collection.isEmptyPath(path7)) {
3537
3550
  if (this.contents == null)
3538
3551
  return false;
3539
3552
  this.contents = null;
3540
3553
  return true;
3541
3554
  }
3542
- return assertCollection(this.contents) ? this.contents.deleteIn(path4) : false;
3555
+ return assertCollection(this.contents) ? this.contents.deleteIn(path7) : false;
3543
3556
  }
3544
3557
  /**
3545
3558
  * Returns item at `key`, or `undefined` if not found. By default unwraps
@@ -3554,10 +3567,10 @@ var require_Document = __commonJS({
3554
3567
  * scalar values from their surrounding node; to disable set `keepScalar` to
3555
3568
  * `true` (collections are always returned intact).
3556
3569
  */
3557
- getIn(path4, keepScalar) {
3558
- if (Collection.isEmptyPath(path4))
3570
+ getIn(path7, keepScalar) {
3571
+ if (Collection.isEmptyPath(path7))
3559
3572
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
3560
- return identity.isCollection(this.contents) ? this.contents.getIn(path4, keepScalar) : void 0;
3573
+ return identity.isCollection(this.contents) ? this.contents.getIn(path7, keepScalar) : void 0;
3561
3574
  }
3562
3575
  /**
3563
3576
  * Checks if the document includes a value with the key `key`.
@@ -3568,10 +3581,10 @@ var require_Document = __commonJS({
3568
3581
  /**
3569
3582
  * Checks if the document includes a value at `path`.
3570
3583
  */
3571
- hasIn(path4) {
3572
- if (Collection.isEmptyPath(path4))
3584
+ hasIn(path7) {
3585
+ if (Collection.isEmptyPath(path7))
3573
3586
  return this.contents !== void 0;
3574
- return identity.isCollection(this.contents) ? this.contents.hasIn(path4) : false;
3587
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path7) : false;
3575
3588
  }
3576
3589
  /**
3577
3590
  * Sets a value in this document. For `!!set`, `value` needs to be a
@@ -3588,13 +3601,13 @@ var require_Document = __commonJS({
3588
3601
  * Sets a value in this document. For `!!set`, `value` needs to be a
3589
3602
  * boolean to add/remove the item from the set.
3590
3603
  */
3591
- setIn(path4, value) {
3592
- if (Collection.isEmptyPath(path4)) {
3604
+ setIn(path7, value) {
3605
+ if (Collection.isEmptyPath(path7)) {
3593
3606
  this.contents = value;
3594
3607
  } else if (this.contents == null) {
3595
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path4), value);
3608
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path7), value);
3596
3609
  } else if (assertCollection(this.contents)) {
3597
- this.contents.setIn(path4, value);
3610
+ this.contents.setIn(path7, value);
3598
3611
  }
3599
3612
  }
3600
3613
  /**
@@ -4738,7 +4751,7 @@ var require_resolve_flow_scalar = __commonJS({
4738
4751
  while (next === " " || next === " ")
4739
4752
  next = source[++i + 1];
4740
4753
  } else if (next === "x" || next === "u" || next === "U") {
4741
- const length = { x: 2, u: 4, U: 8 }[next];
4754
+ const length = next === "x" ? 2 : next === "u" ? 4 : 8;
4742
4755
  res += parseCharCode(source, i + 1, length, onError);
4743
4756
  i += length;
4744
4757
  } else {
@@ -4813,12 +4826,13 @@ var require_resolve_flow_scalar = __commonJS({
4813
4826
  const cc = source.substr(offset, length);
4814
4827
  const ok = cc.length === length && /^[0-9a-fA-F]+$/.test(cc);
4815
4828
  const code = ok ? parseInt(cc, 16) : NaN;
4816
- if (isNaN(code)) {
4829
+ try {
4830
+ return String.fromCodePoint(code);
4831
+ } catch {
4817
4832
  const raw = source.substr(offset - 2, length + 2);
4818
4833
  onError(offset - 2, "BAD_DQ_ESCAPE", `Invalid escape sequence ${raw}`);
4819
4834
  return raw;
4820
4835
  }
4821
- return String.fromCodePoint(code);
4822
4836
  }
4823
4837
  exports.resolveFlowScalar = resolveFlowScalar;
4824
4838
  }
@@ -4968,17 +4982,22 @@ var require_compose_node = __commonJS({
4968
4982
  case "block-map":
4969
4983
  case "block-seq":
4970
4984
  case "flow-collection":
4971
- node = composeCollection.composeCollection(CN, ctx, token, props, onError);
4972
- if (anchor)
4973
- node.anchor = anchor.source.substring(1);
4985
+ try {
4986
+ node = composeCollection.composeCollection(CN, ctx, token, props, onError);
4987
+ if (anchor)
4988
+ node.anchor = anchor.source.substring(1);
4989
+ } catch (error) {
4990
+ const message = error instanceof Error ? error.message : String(error);
4991
+ onError(token, "RESOURCE_EXHAUSTION", message);
4992
+ }
4974
4993
  break;
4975
4994
  default: {
4976
4995
  const message = token.type === "error" ? token.message : `Unsupported token (type: ${token.type})`;
4977
4996
  onError(token, "UNEXPECTED_TOKEN", message);
4978
- node = composeEmptyNode(ctx, token.offset, void 0, null, props, onError);
4979
4997
  isSrcToken = false;
4980
4998
  }
4981
4999
  }
5000
+ node ?? (node = composeEmptyNode(ctx, token.offset, void 0, null, props, onError));
4982
5001
  if (anchor && node.anchor === "")
4983
5002
  onError(anchor, "BAD_ALIAS", "Anchor cannot be an empty string");
4984
5003
  if (atKey && ctx.options.stringKeys && (!identity.isScalar(node) || typeof node.value !== "string" || node.tag && node.tag !== "tag:yaml.org,2002:str")) {
@@ -5163,8 +5182,10 @@ ${cb}` : comment;
5163
5182
  }
5164
5183
  }
5165
5184
  if (afterDoc) {
5166
- Array.prototype.push.apply(doc.errors, this.errors);
5167
- Array.prototype.push.apply(doc.warnings, this.warnings);
5185
+ for (let i = 0; i < this.errors.length; ++i)
5186
+ doc.errors.push(this.errors[i]);
5187
+ for (let i = 0; i < this.warnings.length; ++i)
5188
+ doc.warnings.push(this.warnings[i]);
5168
5189
  } else {
5169
5190
  doc.errors = this.errors;
5170
5191
  doc.warnings = this.warnings;
@@ -5546,9 +5567,9 @@ var require_cst_visit = __commonJS({
5546
5567
  visit.BREAK = BREAK;
5547
5568
  visit.SKIP = SKIP;
5548
5569
  visit.REMOVE = REMOVE;
5549
- visit.itemAtPath = (cst, path4) => {
5570
+ visit.itemAtPath = (cst, path7) => {
5550
5571
  let item = cst;
5551
- for (const [field, index] of path4) {
5572
+ for (const [field, index] of path7) {
5552
5573
  const tok = item?.[field];
5553
5574
  if (tok && "items" in tok) {
5554
5575
  item = tok.items[index];
@@ -5557,23 +5578,23 @@ var require_cst_visit = __commonJS({
5557
5578
  }
5558
5579
  return item;
5559
5580
  };
5560
- visit.parentCollection = (cst, path4) => {
5561
- const parent = visit.itemAtPath(cst, path4.slice(0, -1));
5562
- const field = path4[path4.length - 1][0];
5581
+ visit.parentCollection = (cst, path7) => {
5582
+ const parent = visit.itemAtPath(cst, path7.slice(0, -1));
5583
+ const field = path7[path7.length - 1][0];
5563
5584
  const coll = parent?.[field];
5564
5585
  if (coll && "items" in coll)
5565
5586
  return coll;
5566
5587
  throw new Error("Parent collection not found");
5567
5588
  };
5568
- function _visit(path4, item, visitor) {
5569
- let ctrl = visitor(item, path4);
5589
+ function _visit(path7, item, visitor) {
5590
+ let ctrl = visitor(item, path7);
5570
5591
  if (typeof ctrl === "symbol")
5571
5592
  return ctrl;
5572
5593
  for (const field of ["key", "value"]) {
5573
5594
  const token = item[field];
5574
5595
  if (token && "items" in token) {
5575
5596
  for (let i = 0; i < token.items.length; ++i) {
5576
- const ci = _visit(Object.freeze(path4.concat([[field, i]])), token.items[i], visitor);
5597
+ const ci = _visit(Object.freeze(path7.concat([[field, i]])), token.items[i], visitor);
5577
5598
  if (typeof ci === "number")
5578
5599
  i = ci - 1;
5579
5600
  else if (ci === BREAK)
@@ -5584,10 +5605,10 @@ var require_cst_visit = __commonJS({
5584
5605
  }
5585
5606
  }
5586
5607
  if (typeof ctrl === "function" && field === "key")
5587
- ctrl = ctrl(item, path4);
5608
+ ctrl = ctrl(item, path7);
5588
5609
  }
5589
5610
  }
5590
- return typeof ctrl === "function" ? ctrl(item, path4) : ctrl;
5611
+ return typeof ctrl === "function" ? ctrl(item, path7) : ctrl;
5591
5612
  }
5592
5613
  exports.visit = visit;
5593
5614
  }
@@ -5897,7 +5918,7 @@ var require_lexer = __commonJS({
5897
5918
  const n = (yield* this.pushCount(1)) + (yield* this.pushSpaces(true));
5898
5919
  this.indentNext = this.indentValue + 1;
5899
5920
  this.indentValue += n;
5900
- return yield* this.parseBlockStart();
5921
+ return "block-start";
5901
5922
  }
5902
5923
  return "doc";
5903
5924
  }
@@ -6196,28 +6217,38 @@ var require_lexer = __commonJS({
6196
6217
  return 0;
6197
6218
  }
6198
6219
  *pushIndicators() {
6199
- switch (this.charAt(0)) {
6200
- case "!":
6201
- return (yield* this.pushTag()) + (yield* this.pushSpaces(true)) + (yield* this.pushIndicators());
6202
- case "&":
6203
- return (yield* this.pushUntil(isNotAnchorChar)) + (yield* this.pushSpaces(true)) + (yield* this.pushIndicators());
6204
- case "-":
6205
- // this is an error
6206
- case "?":
6207
- // this is an error outside flow collections
6208
- case ":": {
6209
- const inFlow = this.flowLevel > 0;
6210
- const ch1 = this.charAt(1);
6211
- if (isEmpty(ch1) || inFlow && flowIndicatorChars.has(ch1)) {
6212
- if (!inFlow)
6213
- this.indentNext = this.indentValue + 1;
6214
- else if (this.flowKey)
6215
- this.flowKey = false;
6216
- return (yield* this.pushCount(1)) + (yield* this.pushSpaces(true)) + (yield* this.pushIndicators());
6220
+ let n = 0;
6221
+ loop: while (true) {
6222
+ switch (this.charAt(0)) {
6223
+ case "!":
6224
+ n += yield* this.pushTag();
6225
+ n += yield* this.pushSpaces(true);
6226
+ continue loop;
6227
+ case "&":
6228
+ n += yield* this.pushUntil(isNotAnchorChar);
6229
+ n += yield* this.pushSpaces(true);
6230
+ continue loop;
6231
+ case "-":
6232
+ // this is an error
6233
+ case "?":
6234
+ // this is an error outside flow collections
6235
+ case ":": {
6236
+ const inFlow = this.flowLevel > 0;
6237
+ const ch1 = this.charAt(1);
6238
+ if (isEmpty(ch1) || inFlow && flowIndicatorChars.has(ch1)) {
6239
+ if (!inFlow)
6240
+ this.indentNext = this.indentValue + 1;
6241
+ else if (this.flowKey)
6242
+ this.flowKey = false;
6243
+ n += yield* this.pushCount(1);
6244
+ n += yield* this.pushSpaces(true);
6245
+ continue loop;
6246
+ }
6217
6247
  }
6218
6248
  }
6249
+ break loop;
6219
6250
  }
6220
- return 0;
6251
+ return n;
6221
6252
  }
6222
6253
  *pushTag() {
6223
6254
  if (this.charAt(1) === "<") {
@@ -6376,6 +6407,13 @@ var require_parser = __commonJS({
6376
6407
  }
6377
6408
  return prev.splice(i, prev.length);
6378
6409
  }
6410
+ function arrayPushArray(target, source) {
6411
+ if (source.length < 1e5)
6412
+ Array.prototype.push.apply(target, source);
6413
+ else
6414
+ for (let i = 0; i < source.length; ++i)
6415
+ target.push(source[i]);
6416
+ }
6379
6417
  function fixFlowSeqItems(fc) {
6380
6418
  if (fc.start.type === "flow-seq-start") {
6381
6419
  for (const it of fc.items) {
@@ -6385,11 +6423,11 @@ var require_parser = __commonJS({
6385
6423
  delete it.key;
6386
6424
  if (isFlowToken(it.value)) {
6387
6425
  if (it.value.end)
6388
- Array.prototype.push.apply(it.value.end, it.sep);
6426
+ arrayPushArray(it.value.end, it.sep);
6389
6427
  else
6390
6428
  it.value.end = it.sep;
6391
6429
  } else
6392
- Array.prototype.push.apply(it.start, it.sep);
6430
+ arrayPushArray(it.start, it.sep);
6393
6431
  delete it.sep;
6394
6432
  }
6395
6433
  }
@@ -6744,7 +6782,7 @@ var require_parser = __commonJS({
6744
6782
  const prev = map.items[map.items.length - 2];
6745
6783
  const end = prev?.value?.end;
6746
6784
  if (Array.isArray(end)) {
6747
- Array.prototype.push.apply(end, it.start);
6785
+ arrayPushArray(end, it.start);
6748
6786
  end.push(this.sourceToken);
6749
6787
  map.items.pop();
6750
6788
  return;
@@ -6872,14 +6910,14 @@ var require_parser = __commonJS({
6872
6910
  case "scalar":
6873
6911
  case "single-quoted-scalar":
6874
6912
  case "double-quoted-scalar": {
6875
- const fs4 = this.flowScalar(this.type);
6913
+ const fs7 = this.flowScalar(this.type);
6876
6914
  if (atNextItem || it.value) {
6877
- map.items.push({ start, key: fs4, sep: [] });
6915
+ map.items.push({ start, key: fs7, sep: [] });
6878
6916
  this.onKeyLine = true;
6879
6917
  } else if (it.sep) {
6880
- this.stack.push(fs4);
6918
+ this.stack.push(fs7);
6881
6919
  } else {
6882
- Object.assign(it, { key: fs4, sep: [] });
6920
+ Object.assign(it, { key: fs7, sep: [] });
6883
6921
  this.onKeyLine = true;
6884
6922
  }
6885
6923
  return;
@@ -6932,7 +6970,7 @@ var require_parser = __commonJS({
6932
6970
  const prev = seq.items[seq.items.length - 2];
6933
6971
  const end = prev?.value?.end;
6934
6972
  if (Array.isArray(end)) {
6935
- Array.prototype.push.apply(end, it.start);
6973
+ arrayPushArray(end, it.start);
6936
6974
  end.push(this.sourceToken);
6937
6975
  seq.items.pop();
6938
6976
  return;
@@ -7007,13 +7045,13 @@ var require_parser = __commonJS({
7007
7045
  case "scalar":
7008
7046
  case "single-quoted-scalar":
7009
7047
  case "double-quoted-scalar": {
7010
- const fs4 = this.flowScalar(this.type);
7048
+ const fs7 = this.flowScalar(this.type);
7011
7049
  if (!it || it.value)
7012
- fc.items.push({ start: [], key: fs4, sep: [] });
7050
+ fc.items.push({ start: [], key: fs7, sep: [] });
7013
7051
  else if (it.sep)
7014
- this.stack.push(fs4);
7052
+ this.stack.push(fs7);
7015
7053
  else
7016
- Object.assign(it, { key: fs4, sep: [] });
7054
+ Object.assign(it, { key: fs7, sep: [] });
7017
7055
  return;
7018
7056
  }
7019
7057
  case "flow-map-end":
@@ -7551,17 +7589,17 @@ var require_ignore = __commonJS({
7551
7589
  var throwError = (message, Ctor) => {
7552
7590
  throw new Ctor(message);
7553
7591
  };
7554
- var checkPath = (path4, originalPath, doThrow) => {
7555
- if (!isString(path4)) {
7592
+ var checkPath = (path7, originalPath, doThrow) => {
7593
+ if (!isString(path7)) {
7556
7594
  return doThrow(
7557
7595
  `path must be a string, but got \`${originalPath}\``,
7558
7596
  TypeError
7559
7597
  );
7560
7598
  }
7561
- if (!path4) {
7599
+ if (!path7) {
7562
7600
  return doThrow(`path must not be empty`, TypeError);
7563
7601
  }
7564
- if (checkPath.isNotRelative(path4)) {
7602
+ if (checkPath.isNotRelative(path7)) {
7565
7603
  const r = "`path.relative()`d";
7566
7604
  return doThrow(
7567
7605
  `path should be a ${r} string, but got "${originalPath}"`,
@@ -7570,7 +7608,7 @@ var require_ignore = __commonJS({
7570
7608
  }
7571
7609
  return true;
7572
7610
  };
7573
- var isNotRelative = (path4) => REGEX_TEST_INVALID_PATH.test(path4);
7611
+ var isNotRelative = (path7) => REGEX_TEST_INVALID_PATH.test(path7);
7574
7612
  checkPath.isNotRelative = isNotRelative;
7575
7613
  checkPath.convert = (p) => p;
7576
7614
  var Ignore = class {
@@ -7629,7 +7667,7 @@ var require_ignore = __commonJS({
7629
7667
  // setting `checkUnignored` to `false` could reduce additional
7630
7668
  // path matching.
7631
7669
  // @returns {TestResult} true if a file is ignored
7632
- _testOne(path4, checkUnignored) {
7670
+ _testOne(path7, checkUnignored) {
7633
7671
  let ignored = false;
7634
7672
  let unignored = false;
7635
7673
  this._rules.forEach((rule) => {
@@ -7637,7 +7675,7 @@ var require_ignore = __commonJS({
7637
7675
  if (unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored) {
7638
7676
  return;
7639
7677
  }
7640
- const matched = rule.regex.test(path4);
7678
+ const matched = rule.regex.test(path7);
7641
7679
  if (matched) {
7642
7680
  ignored = !negative;
7643
7681
  unignored = negative;
@@ -7650,24 +7688,24 @@ var require_ignore = __commonJS({
7650
7688
  }
7651
7689
  // @returns {TestResult}
7652
7690
  _test(originalPath, cache, checkUnignored, slices) {
7653
- const path4 = originalPath && checkPath.convert(originalPath);
7691
+ const path7 = originalPath && checkPath.convert(originalPath);
7654
7692
  checkPath(
7655
- path4,
7693
+ path7,
7656
7694
  originalPath,
7657
7695
  this._allowRelativePaths ? RETURN_FALSE : throwError
7658
7696
  );
7659
- return this._t(path4, cache, checkUnignored, slices);
7697
+ return this._t(path7, cache, checkUnignored, slices);
7660
7698
  }
7661
- _t(path4, cache, checkUnignored, slices) {
7662
- if (path4 in cache) {
7663
- return cache[path4];
7699
+ _t(path7, cache, checkUnignored, slices) {
7700
+ if (path7 in cache) {
7701
+ return cache[path7];
7664
7702
  }
7665
7703
  if (!slices) {
7666
- slices = path4.split(SLASH);
7704
+ slices = path7.split(SLASH);
7667
7705
  }
7668
7706
  slices.pop();
7669
7707
  if (!slices.length) {
7670
- return cache[path4] = this._testOne(path4, checkUnignored);
7708
+ return cache[path7] = this._testOne(path7, checkUnignored);
7671
7709
  }
7672
7710
  const parent = this._t(
7673
7711
  slices.join(SLASH) + SLASH,
@@ -7675,24 +7713,24 @@ var require_ignore = __commonJS({
7675
7713
  checkUnignored,
7676
7714
  slices
7677
7715
  );
7678
- return cache[path4] = parent.ignored ? parent : this._testOne(path4, checkUnignored);
7716
+ return cache[path7] = parent.ignored ? parent : this._testOne(path7, checkUnignored);
7679
7717
  }
7680
- ignores(path4) {
7681
- return this._test(path4, this._ignoreCache, false).ignored;
7718
+ ignores(path7) {
7719
+ return this._test(path7, this._ignoreCache, false).ignored;
7682
7720
  }
7683
7721
  createFilter() {
7684
- return (path4) => !this.ignores(path4);
7722
+ return (path7) => !this.ignores(path7);
7685
7723
  }
7686
7724
  filter(paths) {
7687
7725
  return makeArray(paths).filter(this.createFilter());
7688
7726
  }
7689
7727
  // @returns {TestResult}
7690
- test(path4) {
7691
- return this._test(path4, this._testCache, true);
7728
+ test(path7) {
7729
+ return this._test(path7, this._testCache, true);
7692
7730
  }
7693
7731
  };
7694
7732
  var factory = (options) => new Ignore(options);
7695
- var isPathValid = (path4) => checkPath(path4 && checkPath.convert(path4), path4, RETURN_FALSE);
7733
+ var isPathValid = (path7) => checkPath(path7 && checkPath.convert(path7), path7, RETURN_FALSE);
7696
7734
  factory.isPathValid = isPathValid;
7697
7735
  factory.default = factory;
7698
7736
  module.exports = factory;
@@ -7703,44 +7741,632 @@ var require_ignore = __commonJS({
7703
7741
  const makePosix = (str) => /^\\\\\?\\/.test(str) || /["<>|\u0000-\u001F]+/u.test(str) ? str : str.replace(/\\/g, "/");
7704
7742
  checkPath.convert = makePosix;
7705
7743
  const REGIX_IS_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i;
7706
- checkPath.isNotRelative = (path4) => REGIX_IS_WINDOWS_PATH_ABSOLUTE.test(path4) || isNotRelative(path4);
7744
+ checkPath.isNotRelative = (path7) => REGIX_IS_WINDOWS_PATH_ABSOLUTE.test(path7) || isNotRelative(path7);
7707
7745
  }
7708
7746
  }
7709
7747
  });
7710
7748
 
7711
7749
  // src/sanitize_cli.js
7712
- import fs3 from "node:fs";
7750
+ import fs6 from "node:fs";
7713
7751
  import os2 from "node:os";
7714
- import path3 from "node:path";
7752
+ import path6 from "node:path";
7715
7753
  import { execFileSync as execFileSync2, spawnSync } from "node:child_process";
7716
7754
 
7717
7755
  // src/index.js
7718
- var import_yaml2 = __toESM(require_dist(), 1);
7719
- var import_ignore2 = __toESM(require_ignore(), 1);
7756
+ var import_yaml3 = __toESM(require_dist(), 1);
7757
+ var import_ignore3 = __toESM(require_ignore(), 1);
7720
7758
  import crypto from "node:crypto";
7721
- import fs2 from "node:fs";
7759
+ import fs5 from "node:fs";
7722
7760
  import http from "node:http";
7723
7761
  import os from "node:os";
7724
- import path2 from "node:path";
7725
- import { execFileSync } from "node:child_process";
7762
+ import path5 from "node:path";
7726
7763
  import { fileURLToPath } from "node:url";
7727
7764
  import { tool } from "@opencode-ai/plugin/tool";
7728
7765
 
7729
- // src/validate_logic.js
7730
- var import_yaml = __toESM(require_dist(), 1);
7731
- var import_ignore = __toESM(require_ignore(), 1);
7766
+ // src/git_utils.js
7732
7767
  import fs from "node:fs";
7733
7768
  import path from "node:path";
7769
+ import { execFileSync } from "node:child_process";
7770
+ function toGitPath(worktree, targetPath) {
7771
+ const relativePath = path.relative(worktree, targetPath);
7772
+ if (!relativePath || relativePath.startsWith("..") || path.isAbsolute(relativePath)) return null;
7773
+ return relativePath.split(path.sep).join("/");
7774
+ }
7775
+ function runGit(worktree, args) {
7776
+ return execFileSync("git", args, {
7777
+ cwd: worktree,
7778
+ encoding: "utf8",
7779
+ stdio: ["ignore", "pipe", "pipe"]
7780
+ });
7781
+ }
7782
+ function sameFilesystemPath(left, right) {
7783
+ try {
7784
+ return fs.realpathSync(left) === fs.realpathSync(right);
7785
+ } catch {
7786
+ return path.resolve(left) === path.resolve(right);
7787
+ }
7788
+ }
7789
+ function gitMigrationState(worktree) {
7790
+ try {
7791
+ const root = runGit(worktree, ["rev-parse", "--show-toplevel"]).trim();
7792
+ if (!sameFilesystemPath(root, worktree)) return null;
7793
+ return { worktree };
7794
+ } catch {
7795
+ return null;
7796
+ }
7797
+ }
7798
+ function isGitTracked(gitState, targetPath) {
7799
+ if (!gitState) return false;
7800
+ const gitPath = toGitPath(gitState.worktree, targetPath);
7801
+ if (!gitPath) return false;
7802
+ try {
7803
+ runGit(gitState.worktree, ["ls-files", "--error-unmatch", "--", gitPath]);
7804
+ return true;
7805
+ } catch {
7806
+ return false;
7807
+ }
7808
+ }
7809
+ function hasGitTrackedChildren(gitState, targetPath) {
7810
+ if (!gitState) return false;
7811
+ const gitPath = toGitPath(gitState.worktree, targetPath);
7812
+ if (!gitPath) return false;
7813
+ try {
7814
+ return runGit(gitState.worktree, ["ls-files", "--", `${gitPath}/`]).trim().length > 0;
7815
+ } catch {
7816
+ return false;
7817
+ }
7818
+ }
7819
+ function gitAwareMoveIfTracked(sourcePath, destinationPath, gitState) {
7820
+ const sourceIsTracked = isGitTracked(gitState, sourcePath) || hasGitTrackedChildren(gitState, sourcePath);
7821
+ if (!gitState || !sourceIsTracked || fs.existsSync(destinationPath)) return false;
7822
+ const sourceGitPath = toGitPath(gitState.worktree, sourcePath);
7823
+ const destinationGitPath = toGitPath(gitState.worktree, destinationPath);
7824
+ if (!sourceGitPath || !destinationGitPath) return false;
7825
+ fs.mkdirSync(path.dirname(destinationPath), { recursive: true });
7826
+ try {
7827
+ runGit(gitState.worktree, ["mv", "--", sourceGitPath, destinationGitPath]);
7828
+ return true;
7829
+ } catch {
7830
+ return false;
7831
+ }
7832
+ }
7833
+ function stageGitAwareMerge(sourcePath, destinationPath, gitState) {
7834
+ if (!gitState) return;
7835
+ const sourceGitPath = toGitPath(gitState.worktree, sourcePath);
7836
+ const destinationGitPath = toGitPath(gitState.worktree, destinationPath);
7837
+ if (!sourceGitPath || !destinationGitPath) return;
7838
+ try {
7839
+ runGit(gitState.worktree, ["add", "-A", "--", sourceGitPath, destinationGitPath]);
7840
+ } catch {
7841
+ }
7842
+ }
7843
+
7844
+ // src/include_resolver.js
7845
+ import fs2 from "node:fs";
7846
+ import path2 from "node:path";
7847
+ function compactPromptPath(filePath) {
7848
+ if (!filePath.endsWith(".md") || filePath.endsWith(".prompt.md")) return null;
7849
+ return filePath.replace(/\.md$/, ".prompt.md");
7850
+ }
7851
+ function isSameOrNestedPath(candidate, root) {
7852
+ if (typeof candidate !== "string" || typeof root !== "string" || !candidate.trim() || !root.trim()) return false;
7853
+ const resolvedCandidate = path2.resolve(candidate);
7854
+ const resolvedRoot = path2.resolve(root);
7855
+ const relative = path2.relative(resolvedRoot, resolvedCandidate);
7856
+ return relative === "" || !!relative && !relative.startsWith("..") && !path2.isAbsolute(relative);
7857
+ }
7858
+ function resolveWithin(baseDir, relativePath) {
7859
+ if (!relativePath) return null;
7860
+ if (path2.isAbsolute(relativePath)) return null;
7861
+ const resolved = path2.resolve(baseDir, relativePath);
7862
+ return isSameOrNestedPath(resolved, baseDir) ? resolved : null;
7863
+ }
7864
+ function withCompactPreference(paths, options = {}) {
7865
+ if (!options.preferCompactPromptDocs) return paths;
7866
+ const compactPaths = paths.map((filePath) => filePath ? compactPromptPath(filePath) : null).filter(Boolean);
7867
+ return [...compactPaths, ...paths];
7868
+ }
7869
+ function resolveIncludeFile(includeRef, repoRoot, bundleRoot, options = {}) {
7870
+ const trimmed = String(includeRef || "").trim();
7871
+ const scopedMatch = trimmed.match(/^([a-z]+):(.*)$/i);
7872
+ const scope = scopedMatch?.[1]?.toLowerCase();
7873
+ const target = scopedMatch ? scopedMatch[2].trim() : trimmed;
7874
+ const optimaRoot = options.optimaRoot || path2.join(repoRoot, ".optima");
7875
+ const repoPolicyRoot = options.repoPolicyRoot || path2.join(optimaRoot, "policies");
7876
+ const bundlePolicyRoot = options.bundlePolicyRoot || path2.join(bundleRoot, "assets", "policies");
7877
+ if (scope === "plugin") {
7878
+ for (const filePath of withCompactPreference([resolveWithin(bundleRoot, target)], options)) {
7879
+ if (filePath && fs2.existsSync(filePath)) return filePath;
7880
+ }
7881
+ return null;
7882
+ }
7883
+ if (scope === "repo") {
7884
+ for (const filePath of withCompactPreference([resolveWithin(optimaRoot, target)], options)) {
7885
+ if (filePath && fs2.existsSync(filePath)) return filePath;
7886
+ }
7887
+ return null;
7888
+ }
7889
+ if (scope === "policy") {
7890
+ const candidates2 = withCompactPreference([
7891
+ resolveWithin(repoPolicyRoot, target),
7892
+ resolveWithin(bundlePolicyRoot, target)
7893
+ ], options);
7894
+ for (const filePath of candidates2) {
7895
+ if (filePath && fs2.existsSync(filePath)) return filePath;
7896
+ }
7897
+ return null;
7898
+ }
7899
+ const candidates = withCompactPreference([
7900
+ resolveWithin(repoRoot, target),
7901
+ resolveWithin(bundleRoot, target)
7902
+ ], options);
7903
+ for (const filePath of candidates) {
7904
+ if (filePath && fs2.existsSync(filePath)) return filePath;
7905
+ }
7906
+ return null;
7907
+ }
7908
+ function resolveIncludes(text, repoRoot, bundleRoot, options = {}) {
7909
+ const includeDepth = Number(options.includeDepth || 0);
7910
+ const maxIncludeDepth = Number(options.maxIncludeDepth || 20);
7911
+ if (includeDepth > maxIncludeDepth) {
7912
+ return "\n\n# ERROR: Include recursion limit exceeded.\n\n";
7913
+ }
7914
+ const includeRegex = /<include:(.*?)>/g;
7915
+ return String(text || "").replace(includeRegex, (match, includeRef) => {
7916
+ const filePath = resolveIncludeFile(includeRef, repoRoot, bundleRoot, options);
7917
+ if (!filePath) {
7918
+ console.warn(`[Optima] Include file not found: ${includeRef}`);
7919
+ return `
7920
+
7921
+ # ERROR: Include file not found: ${includeRef}
7922
+
7923
+ `;
7924
+ }
7925
+ const content = fs2.readFileSync(filePath, "utf8");
7926
+ return resolveIncludes(content, repoRoot, bundleRoot, { ...options, includeDepth: includeDepth + 1, maxIncludeDepth });
7927
+ });
7928
+ }
7929
+
7930
+ // src/repair.js
7931
+ var import_yaml = __toESM(require_dist(), 1);
7932
+ var import_ignore = __toESM(require_ignore(), 1);
7933
+ import fs3 from "node:fs";
7934
+ import path3 from "node:path";
7935
+ var CODEMAP_SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
7936
+ ".js",
7937
+ ".ts",
7938
+ ".tsx",
7939
+ ".jsx",
7940
+ ".dart",
7941
+ ".py",
7942
+ ".go",
7943
+ ".rs",
7944
+ ".java",
7945
+ ".c",
7946
+ ".cpp",
7947
+ ".cs",
7948
+ ".php",
7949
+ ".rb",
7950
+ ".swift",
7951
+ ".kt",
7952
+ ".m",
7953
+ ".sh",
7954
+ ".sql",
7955
+ ".yaml",
7956
+ ".yml",
7957
+ ".json",
7958
+ ".md"
7959
+ ]);
7960
+ var LEGACY_OPERATIONAL_ROOTS = /* @__PURE__ */ new Set([
7961
+ "tasks",
7962
+ "evidences",
7963
+ ".orbita",
7964
+ ".staticeng",
7965
+ ".nomadworks",
7966
+ ".nomadwork",
7967
+ "nomadworks",
7968
+ ".codenomad"
7969
+ ]);
7970
+ var OPTIMA_OPERATIONAL_FOLDERS = [".optima", "templates", "dist"];
7971
+ function relPath(worktree, targetPath) {
7972
+ return path3.relative(worktree, targetPath).split(path3.sep).join("/") || ".";
7973
+ }
7974
+ function normalizeCodemapRelPath(relPathValue) {
7975
+ return path3.normalize(relPathValue).replace(/\\/g, "/").replace(/\/$/, "");
7976
+ }
7977
+ function firstPathSegment(relPathValue) {
7978
+ return normalizeCodemapRelPath(relPathValue).split("/").filter(Boolean)[0] || "";
7979
+ }
7980
+ function isOperationalRelPath(relPathValue) {
7981
+ if (!relPathValue) return false;
7982
+ const normalized = normalizeCodemapRelPath(relPathValue);
7983
+ const firstSegment = firstPathSegment(normalized);
7984
+ if (LEGACY_OPERATIONAL_ROOTS.has(firstSegment)) return true;
7985
+ return OPTIMA_OPERATIONAL_FOLDERS.some((folder) => normalized === folder || normalized.startsWith(`${folder}/`));
7986
+ }
7987
+ function isHiddenTree(relPathValue) {
7988
+ if (!relPathValue) return false;
7989
+ return normalizeCodemapRelPath(relPathValue).split("/").some((part) => part.startsWith("."));
7990
+ }
7991
+ function loadGitIgnoreMatcher(worktree) {
7992
+ const ig = (0, import_ignore.default)();
7993
+ ig.add(".git");
7994
+ const gitignorePath = path3.join(worktree, ".gitignore");
7995
+ if (fs3.existsSync(gitignorePath)) ig.add(fs3.readFileSync(gitignorePath, "utf8"));
7996
+ return ig;
7997
+ }
7998
+ function codemapSectionEntries(value) {
7999
+ if (Array.isArray(value)) return value;
8000
+ if (value && typeof value === "object") return Object.values(value);
8001
+ return [];
8002
+ }
8003
+ function codemapIndexedPaths(map) {
8004
+ const indexed = /* @__PURE__ */ new Set();
8005
+ for (const section of ["modules", "entrypoints", "sources_of_truth", "links", "internals"]) {
8006
+ for (const item of codemapSectionEntries(map?.[section])) {
8007
+ if (item?.path) indexed.add(normalizeCodemapRelPath(item.path));
8008
+ }
8009
+ }
8010
+ return indexed;
8011
+ }
8012
+ function readCodemap(filePath, unresolved, worktree) {
8013
+ try {
8014
+ const parsed = import_yaml.default.parse(fs3.readFileSync(filePath, "utf8"));
8015
+ if (!parsed || typeof parsed !== "object") {
8016
+ unresolved.push({ category: "codemap", path: relPath(worktree, filePath), message: "CodeMap is empty or invalid; manual repair required." });
8017
+ return null;
8018
+ }
8019
+ return parsed;
8020
+ } catch {
8021
+ unresolved.push({ category: "codemap", path: relPath(worktree, filePath), message: "CodeMap has invalid YAML; manual repair required." });
8022
+ return null;
8023
+ }
8024
+ }
8025
+ function writeCodemap(filePath, map) {
8026
+ fs3.writeFileSync(filePath, import_yaml.default.stringify(map), "utf8");
8027
+ }
8028
+ function isIgnoredPath(ig, relativePath) {
8029
+ const normalized = normalizeCodemapRelPath(relativePath);
8030
+ return Boolean(normalized) && ig.ignores(normalized);
8031
+ }
8032
+ function hasImmediateSourceFile(dirPath, ig, worktree) {
8033
+ if (!fs3.existsSync(dirPath)) return false;
8034
+ for (const item of fs3.readdirSync(dirPath, { withFileTypes: true })) {
8035
+ const childPath = path3.join(dirPath, item.name);
8036
+ const relative = path3.relative(worktree, childPath);
8037
+ if (isIgnoredPath(ig, relative) || isOperationalRelPath(relative)) continue;
8038
+ if (item.isFile() && CODEMAP_SOURCE_EXTENSIONS.has(path3.extname(item.name))) return true;
8039
+ }
8040
+ return false;
8041
+ }
8042
+ function containsSource(dirPath, ig, worktree) {
8043
+ if (!fs3.existsSync(dirPath)) return false;
8044
+ const dirRelPath = path3.relative(worktree, dirPath);
8045
+ if (isOperationalRelPath(dirRelPath) || isHiddenTree(dirRelPath)) return false;
8046
+ for (const item of fs3.readdirSync(dirPath, { withFileTypes: true })) {
8047
+ const childPath = path3.join(dirPath, item.name);
8048
+ const relative = path3.relative(worktree, childPath);
8049
+ if (isIgnoredPath(ig, relative) || isOperationalRelPath(relative) || isHiddenTree(relative)) continue;
8050
+ if (item.isFile() && CODEMAP_SOURCE_EXTENSIONS.has(path3.extname(item.name))) return true;
8051
+ if (item.isDirectory() && containsSource(childPath, ig, worktree)) return true;
8052
+ }
8053
+ return false;
8054
+ }
8055
+ function createModuleCodemap(dirPath, worktree, deps) {
8056
+ const entries = fs3.readdirSync(dirPath, { withFileTypes: true });
8057
+ const entrypoints = [];
8058
+ const internals = [];
8059
+ const relToRoot = path3.relative(dirPath, deps.optimaCodemapPath(worktree)).split(path3.sep).join("/");
8060
+ for (const item of entries) {
8061
+ if (!item.isFile() || item.name === "codemap.yml" || !CODEMAP_SOURCE_EXTENSIONS.has(path3.extname(item.name))) continue;
8062
+ const bucket = /^index\.(js|ts|tsx|jsx)$|^main\.(js|ts|tsx|jsx|py|go|rs|java)$/.test(item.name) ? entrypoints : internals;
8063
+ bucket.push({ path: item.name });
8064
+ }
8065
+ const map = { scope: "module", parent: relToRoot };
8066
+ if (entrypoints.length > 0) map.entrypoints = entrypoints;
8067
+ map.internals = internals;
8068
+ return map;
8069
+ }
8070
+ function repairSingleCodemap(codemapPath, worktree, apply, registerAction, unresolved, deps) {
8071
+ const map = readCodemap(codemapPath, unresolved, worktree);
8072
+ if (!map) return;
8073
+ const isRootMap = codemapPath === deps.optimaCodemapPath(worktree);
8074
+ const mapDir = path3.dirname(codemapPath);
8075
+ const pathBase = isRootMap ? worktree : mapDir;
8076
+ let changed = false;
8077
+ for (const section of ["modules", "entrypoints", "sources_of_truth", "links", "internals"]) {
8078
+ const originalEntries = codemapSectionEntries(map[section]);
8079
+ if (!Array.isArray(map[section]) && originalEntries.length > 0) {
8080
+ unresolved.push({ category: "codemap", path: relPath(worktree, codemapPath), message: `Section '${section}' is object-shaped; repair leaves it unchanged to avoid changing user structure.` });
8081
+ continue;
8082
+ }
8083
+ const nextEntries = [];
8084
+ for (const entry of originalEntries) {
8085
+ if (!entry?.path || entry.path.startsWith("http://") || entry.path.startsWith("https://") || path3.isAbsolute(entry.path)) {
8086
+ nextEntries.push(entry);
8087
+ continue;
8088
+ }
8089
+ const normalizedPath = normalizeCodemapRelPath(entry.path);
8090
+ const absPath = path3.join(pathBase, normalizedPath);
8091
+ if (!fs3.existsSync(absPath)) {
8092
+ registerAction({ category: "codemap", action: apply ? "removed" : "would_remove", path: relPath(worktree, codemapPath), detail: `Remove broken ${section.slice(0, -1)} reference '${entry.path}'.` });
8093
+ changed = true;
8094
+ continue;
8095
+ }
8096
+ const parts = normalizedPath.split("/").filter((part) => part && part !== ".");
8097
+ const maxParts = isRootMap ? 2 : 1;
8098
+ if (parts.length > maxParts) {
8099
+ const localPath = isRootMap ? parts.slice(0, 2).join("/") : parts[0];
8100
+ const localAbs = path3.join(pathBase, localPath);
8101
+ if (fs3.existsSync(localAbs)) {
8102
+ nextEntries.push({ ...entry, path: localPath });
8103
+ changed = true;
8104
+ registerAction({ category: "codemap", action: apply ? "updated" : "would_update", path: relPath(worktree, codemapPath), detail: `Shorten '${entry.path}' to local path '${localPath}'.` });
8105
+ continue;
8106
+ }
8107
+ unresolved.push({ category: "codemap", path: relPath(worktree, codemapPath), message: `Path '${entry.path}' violates Rule of Local Knowledge and no safe local replacement exists.` });
8108
+ nextEntries.push(entry);
8109
+ continue;
8110
+ }
8111
+ nextEntries.push(entry);
8112
+ }
8113
+ if (Array.isArray(map[section])) map[section] = nextEntries;
8114
+ }
8115
+ if (map.scope === "module" && !isOperationalRelPath(path3.relative(worktree, mapDir))) {
8116
+ const indexed = codemapIndexedPaths(map);
8117
+ const internals = Array.isArray(map.internals) ? map.internals : [];
8118
+ for (const item of fs3.readdirSync(mapDir, { withFileTypes: true })) {
8119
+ if (!item.isFile() || item.name === "codemap.yml" || !CODEMAP_SOURCE_EXTENSIONS.has(path3.extname(item.name))) continue;
8120
+ if (indexed.has(item.name)) continue;
8121
+ internals.push({ path: item.name });
8122
+ indexed.add(item.name);
8123
+ changed = true;
8124
+ registerAction({ category: "codemap", action: apply ? "updated" : "would_update", path: relPath(worktree, codemapPath), detail: `Categorize immediate source file '${item.name}' as internal.` });
8125
+ }
8126
+ if (internals.length > 0) map.internals = internals;
8127
+ }
8128
+ if (changed && apply) writeCodemap(codemapPath, map);
8129
+ }
8130
+ function repairCodemaps(worktree, apply, actions, unresolved, deps) {
8131
+ const ig = loadGitIgnoreMatcher(worktree);
8132
+ const rootCodemapPath = deps.optimaCodemapPath(worktree);
8133
+ const rootCodemapMissing = !fs3.existsSync(rootCodemapPath);
8134
+ if (rootCodemapMissing) {
8135
+ actions.push({ category: "codemap", action: apply ? "created" : "would_create", path: ".optima/codemap.yml", detail: "Create missing root CodeMap from template." });
8136
+ if (apply) deps.scaffoldOptimaRootCodemap(worktree);
8137
+ }
8138
+ if (fs3.existsSync(rootCodemapPath)) repairSingleCodemap(rootCodemapPath, worktree, apply, (action) => actions.push(action), unresolved, deps);
8139
+ const rootMap = fs3.existsSync(rootCodemapPath) ? readCodemap(rootCodemapPath, unresolved, worktree) : null;
8140
+ let rootChanged = false;
8141
+ const rootModulesRepairable = rootMap && (rootMap.modules === void 0 || Array.isArray(rootMap.modules));
8142
+ if (rootMap) {
8143
+ rootMap.scope ||= "repo";
8144
+ if (rootModulesRepairable) {
8145
+ rootMap.modules = Array.isArray(rootMap.modules) ? rootMap.modules : [];
8146
+ } else {
8147
+ unresolved.push({ category: "codemap", path: ".optima/codemap.yml", message: "Root modules section is object-shaped; repair will not add module entries to avoid changing user structure." });
8148
+ }
8149
+ }
8150
+ function walk(dirPath) {
8151
+ const relative = path3.relative(worktree, dirPath);
8152
+ if (relative && (isIgnoredPath(ig, relative) || isOperationalRelPath(relative) || isHiddenTree(relative))) return;
8153
+ const codemapPath = path3.join(dirPath, "codemap.yml");
8154
+ const hasCodemap = fs3.existsSync(codemapPath);
8155
+ const sourceDir = relative && containsSource(dirPath, ig, worktree);
8156
+ if (sourceDir && !hasCodemap && dirPath !== worktree) {
8157
+ if (hasImmediateSourceFile(dirPath, ig, worktree)) {
8158
+ actions.push({ category: "codemap", action: apply ? "created" : "would_create", path: relPath(worktree, codemapPath), detail: "Create missing module CodeMap for source directory." });
8159
+ if (apply) writeCodemap(codemapPath, createModuleCodemap(dirPath, worktree, deps));
8160
+ } else {
8161
+ unresolved.push({ category: "codemap", path: relPath(worktree, dirPath), message: "Directory contains source only in nested directories; create a local CodeMap after deciding module boundaries." });
8162
+ }
8163
+ }
8164
+ if (rootMap && rootModulesRepairable && relative && sourceDir && normalizeCodemapRelPath(relative).split("/").length === 1) {
8165
+ const modules = codemapSectionEntries(rootMap.modules);
8166
+ if (!modules.some((entry) => normalizeCodemapRelPath(entry.path) === normalizeCodemapRelPath(relative))) {
8167
+ rootMap.modules = modules;
8168
+ rootMap.modules.push({ path: normalizeCodemapRelPath(relative), summary: "Maintained source module." });
8169
+ rootChanged = true;
8170
+ actions.push({ category: "codemap", action: apply ? "updated" : "would_update", path: ".optima/codemap.yml", detail: `Register top-level source module '${normalizeCodemapRelPath(relative)}'.` });
8171
+ }
8172
+ }
8173
+ if (fs3.existsSync(codemapPath) && codemapPath !== rootCodemapPath) repairSingleCodemap(codemapPath, worktree, apply, (action) => actions.push(action), unresolved, deps);
8174
+ for (const item of fs3.readdirSync(dirPath, { withFileTypes: true })) {
8175
+ if (item.isDirectory()) walk(path3.join(dirPath, item.name));
8176
+ }
8177
+ }
8178
+ if (fs3.existsSync(worktree)) walk(worktree);
8179
+ if (rootMap && rootChanged && apply) writeCodemap(rootCodemapPath, rootMap);
8180
+ }
8181
+ function walkMarkdownFiles(dirPath) {
8182
+ if (!fs3.existsSync(dirPath)) return [];
8183
+ const files = [];
8184
+ for (const entry of fs3.readdirSync(dirPath, { withFileTypes: true })) {
8185
+ const entryPath = path3.join(dirPath, entry.name);
8186
+ if (entry.isDirectory()) {
8187
+ files.push(...walkMarkdownFiles(entryPath));
8188
+ } else if (entry.isFile() && entry.name.endsWith(".md")) {
8189
+ files.push(entryPath);
8190
+ }
8191
+ }
8192
+ return files;
8193
+ }
8194
+ function isMarkdownReferenceNormalizationExempt(line) {
8195
+ const normalized = line.toLowerCase().replace(/[`*_~]/g, "");
8196
+ const pathToken = "(?:tasks/|evidences/|docs/scrs/|codemap\\.yml|logs/|screenshots/)";
8197
+ if (new RegExp(`\\b(root|legacy)\\s+${pathToken}`).test(normalized)) return true;
8198
+ if (new RegExp(`\\b(do not|don't|never|must not|should not|avoid|forbid|prohibit)\\b[^\\n]*${pathToken}`).test(normalized)) return true;
8199
+ if (/\b(historical|problem|prohibition)\b[^\n]*(tasks\/|evidences\/|docs\/scrs\/|codemap\.yml|logs\/|screenshots\/)/.test(normalized)) return true;
8200
+ return false;
8201
+ }
8202
+ function rewriteReferenceToken(text, fromPrefix, toPrefix) {
8203
+ const escapedPrefix = fromPrefix.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
8204
+ const pattern = new RegExp("(^|[\\s([{\"'<`])" + escapedPrefix + `(?=[^\\s)\\]}>"']+)`, "g");
8205
+ return text.replace(pattern, `$1${toPrefix}`);
8206
+ }
8207
+ function rewriteOptimaMarkdownReferences(content, evidenceBasePath = null) {
8208
+ return content.split(/(\r?\n)/).map((part) => {
8209
+ if (part === "\n" || part === "\r\n" || isMarkdownReferenceNormalizationExempt(part)) return part;
8210
+ let next = part;
8211
+ next = rewriteReferenceToken(next, "tasks/", ".optima/tasks/");
8212
+ next = rewriteReferenceToken(next, "evidences/", ".optima/evidences/");
8213
+ next = rewriteReferenceToken(next, "docs/scrs/", ".optima/docs/scrs/");
8214
+ next = next.replace(/(^|[\s([{"'<`])codemap\.yml\b/g, "$1.optima/codemap.yml");
8215
+ if (evidenceBasePath) {
8216
+ next = rewriteReferenceToken(next, "logs/", `${evidenceBasePath}/logs/`);
8217
+ next = rewriteReferenceToken(next, "screenshots/", `${evidenceBasePath}/screenshots/`);
8218
+ }
8219
+ return next;
8220
+ }).join("");
8221
+ }
8222
+ function optimaEvidenceBaseForFile(worktree, filePath, deps) {
8223
+ const evidenceRoot = deps.optimaEvidencesDir(worktree);
8224
+ const relative = path3.relative(evidenceRoot, filePath).split(path3.sep).join("/");
8225
+ const [taskId] = relative.split("/");
8226
+ if (!taskId || taskId === ".." || relative.startsWith("../")) return null;
8227
+ return `.optima/evidences/${taskId}`;
8228
+ }
8229
+ function normalizeOptimaMarkdownReferences(worktree, deps) {
8230
+ const scanRoots = [
8231
+ deps.optimaTasksDir(worktree),
8232
+ deps.optimaEvidencesDir(worktree),
8233
+ deps.optimaScrsDir(worktree)
8234
+ ];
8235
+ const changed = [];
8236
+ for (const filePath of scanRoots.flatMap(walkMarkdownFiles)) {
8237
+ const raw = fs3.readFileSync(filePath, "utf8");
8238
+ const evidenceBasePath = filePath.startsWith(deps.optimaEvidencesDir(worktree) + path3.sep) ? optimaEvidenceBaseForFile(worktree, filePath, deps) : null;
8239
+ const rewritten = rewriteOptimaMarkdownReferences(raw, evidenceBasePath);
8240
+ if (rewritten !== raw) {
8241
+ fs3.writeFileSync(filePath, rewritten, "utf8");
8242
+ changed.push(relPath(worktree, filePath));
8243
+ }
8244
+ }
8245
+ return changed;
8246
+ }
8247
+ function missingOptimaGitignoreRules(worktree, deps) {
8248
+ if (!deps.isGitRepository(worktree)) return [];
8249
+ const gitignorePath = path3.join(worktree, ".gitignore");
8250
+ const existing = fs3.existsSync(gitignorePath) ? fs3.readFileSync(gitignorePath, "utf8") : "";
8251
+ const existingRules = new Set(existing.split(/\r?\n/).map((line) => line.trim()).filter(Boolean));
8252
+ return deps.optimaGitignoreRules.filter((rule) => !existingRules.has(rule));
8253
+ }
8254
+ function repairMode(args = {}) {
8255
+ const value = args.apply ?? args.mode;
8256
+ if (value === true || value === "apply") return "apply";
8257
+ return "dry-run";
8258
+ }
8259
+ function pushRepairAction(actions, category, action, pathValue, detail) {
8260
+ actions.push({ category, action, path: pathValue, detail });
8261
+ }
8262
+ function planOptimaRepair(worktree, args = {}, deps) {
8263
+ const mode = repairMode(args);
8264
+ const apply = mode === "apply";
8265
+ const actions = [];
8266
+ const unresolved = [];
8267
+ const hadOptima = fs3.existsSync(deps.optimaDir(worktree));
8268
+ const missingGitignoreRules = missingOptimaGitignoreRules(worktree, deps);
8269
+ const markdownBefore = apply ? [] : walkMarkdownFiles(deps.optimaDir(worktree)).filter((filePath) => {
8270
+ const raw = fs3.readFileSync(filePath, "utf8");
8271
+ const evidenceBasePath = filePath.startsWith(deps.optimaEvidencesDir(worktree) + path3.sep) ? optimaEvidenceBaseForFile(worktree, filePath, deps) : null;
8272
+ return rewriteOptimaMarkdownReferences(raw, evidenceBasePath) !== raw;
8273
+ }).map((filePath) => relPath(worktree, filePath));
8274
+ if (!hadOptima) pushRepairAction(actions, "operational", apply ? "created" : "would_create", ".optima/", "Create Optima operational root.");
8275
+ const legacySources = [
8276
+ [".orbita/", deps.legacyOrbitaDir(worktree)],
8277
+ [".staticeng/", deps.legacyStaticEngDir(worktree)],
8278
+ [".nomadwork/", deps.legacyNomadworkDir(worktree)],
8279
+ [".nomadworks/", deps.legacyNomadworksDir(worktree)],
8280
+ ["tasks/", path3.join(worktree, "tasks")],
8281
+ ["evidences/", path3.join(worktree, "evidences")],
8282
+ ["docs/scrs/", path3.join(worktree, "docs", "scrs")],
8283
+ ["codemap.yml", path3.join(worktree, "codemap.yml")],
8284
+ ["codemap.yaml", path3.join(worktree, "codemap.yaml")]
8285
+ ];
8286
+ if (!deps.isOptimaPluginPackageWorktree(worktree)) legacySources.push(["policies/", path3.join(worktree, "policies")]);
8287
+ for (const [display, sourcePath] of legacySources) {
8288
+ if (fs3.existsSync(sourcePath)) pushRepairAction(actions, "legacy", apply ? "migrated" : "would_migrate", display, "Move or merge legacy/root Optima artifact into .optima using preservation safeguards.");
8289
+ }
8290
+ if (apply) deps.migrateLegacyOptimaLayout(worktree);
8291
+ const configMissing = !fs3.existsSync(deps.repoConfigPath(worktree));
8292
+ if (configMissing) pushRepairAction(actions, "config", apply ? "created" : "would_create", ".optima/.config/optima.yaml", "Create missing local Optima config from template.");
8293
+ if (apply) deps.scaffoldOptimaConfig(worktree, args.team_mode || "full");
8294
+ const requiredFiles = [
8295
+ [path3.join(deps.optimaTasksDir(worktree), "current.md"), "registry", ".optima/tasks/current.md", deps.currentTasksRegistryContent()],
8296
+ [path3.join(deps.optimaTasksDir(worktree), "done.md"), "registry", ".optima/tasks/done.md", deps.doneTasksRegistryContent()],
8297
+ [path3.join(deps.optimaScrsDir(worktree), "current.md"), "registry", ".optima/docs/scrs/current.md", deps.currentScrRegistryContent()],
8298
+ [path3.join(deps.optimaScrsDir(worktree), "done.md"), "registry", ".optima/docs/scrs/done.md", deps.doneScrRegistryContent()],
8299
+ [path3.join(deps.optimaTasksDir(worktree), "task-template.md"), "template", ".optima/tasks/task-template.md", deps.taskTemplateContent()],
8300
+ [path3.join(deps.optimaTasksDir(worktree), "subtask-template.md"), "template", ".optima/tasks/subtask-template.md", deps.subtaskTemplateContent()],
8301
+ [path3.join(deps.repoPoliciesDir(worktree), "README.md"), "policy", ".optima/policies/README.md", deps.repoLocalPoliciesReadme]
8302
+ ];
8303
+ for (const [filePath, category, displayPath, content] of requiredFiles) {
8304
+ if (!fs3.existsSync(filePath)) {
8305
+ pushRepairAction(actions, category, apply ? "created" : "would_create", displayPath, "Create missing Optima scaffold file without overwriting existing content.");
8306
+ if (apply) deps.ensureFileIfMissing(filePath, content);
8307
+ }
8308
+ }
8309
+ if (apply) {
8310
+ deps.scaffoldOptimaReadmes(worktree);
8311
+ deps.ensureOptimaRegistries(worktree);
8312
+ normalizeOptimaMarkdownReferences(worktree, deps).forEach((filePath) => {
8313
+ pushRepairAction(actions, "markdown", "normalized", filePath, "Normalize Optima artifact paths in Markdown.");
8314
+ });
8315
+ } else {
8316
+ markdownBefore.forEach((filePath) => pushRepairAction(actions, "markdown", "would_normalize", filePath, "Normalize Optima artifact paths in Markdown."));
8317
+ }
8318
+ if (missingGitignoreRules.length > 0) {
8319
+ pushRepairAction(actions, "gitignore", apply ? "updated" : "would_update", ".gitignore", `Add ${missingGitignoreRules.length} Optima local/private rule(s).`);
8320
+ if (apply) deps.ensureOptimaGitignoreRules(worktree);
8321
+ }
8322
+ repairCodemaps(worktree, apply, actions, unresolved, deps);
8323
+ return { mode, actions, unresolved };
8324
+ }
8325
+ function formatRepairResult(plan, validationResult = null, formatValidationResult2 = (res) => JSON.stringify(res, null, 2)) {
8326
+ const lines = [
8327
+ `Optima repair ${plan.mode === "apply" ? "applied" : "dry-run"}.`,
8328
+ "Scope inspected: config, registries, templates, policy scaffolding, legacy/root artifact leakage, Markdown path normalization, gitignore rules, and CodeMap integrity.",
8329
+ "",
8330
+ "Planned/Applied fixes:"
8331
+ ];
8332
+ if (plan.actions.length === 0) {
8333
+ lines.push("- None");
8334
+ } else {
8335
+ for (const action of plan.actions) {
8336
+ lines.push(`- [${action.category}] ${action.action} ${action.path}: ${action.detail}`);
8337
+ }
8338
+ }
8339
+ lines.push("", "Unresolved issues:");
8340
+ if (plan.unresolved.length === 0) {
8341
+ lines.push("- None");
8342
+ } else {
8343
+ for (const issue of plan.unresolved) {
8344
+ lines.push(`- [${issue.category}] ${issue.path}: ${issue.message}`);
8345
+ }
8346
+ }
8347
+ if (validationResult) {
8348
+ lines.push("", "Validation after apply:", formatValidationResult2(validationResult));
8349
+ } else {
8350
+ lines.push("", "Validation after apply: not run in dry-run mode.");
8351
+ }
8352
+ return lines.join("\n");
8353
+ }
8354
+
8355
+ // src/validate_logic.js
8356
+ var import_yaml2 = __toESM(require_dist(), 1);
8357
+ var import_ignore2 = __toESM(require_ignore(), 1);
8358
+ import fs4 from "node:fs";
8359
+ import path4 from "node:path";
7734
8360
  async function optima_validate_logic(worktree) {
7735
- const rootCodemapPath = path.join(worktree, ".optima", "codemap.yml");
7736
- if (!fs.existsSync(rootCodemapPath)) return { ok: false, errors: [".optima/codemap.yml not found."], warnings: [] };
8361
+ const rootCodemapPath = path4.join(worktree, ".optima", "codemap.yml");
8362
+ if (!fs4.existsSync(rootCodemapPath)) return { ok: false, errors: [".optima/codemap.yml not found."], warnings: [] };
7737
8363
  const errors = [];
7738
8364
  const warnings = [];
7739
- const ig = (0, import_ignore.default)();
8365
+ const ig = (0, import_ignore2.default)();
7740
8366
  ig.add(".git");
7741
- const gitignorePath = path.join(worktree, ".gitignore");
7742
- if (fs.existsSync(gitignorePath)) {
7743
- ig.add(fs.readFileSync(gitignorePath, "utf8"));
8367
+ const gitignorePath = path4.join(worktree, ".gitignore");
8368
+ if (fs4.existsSync(gitignorePath)) {
8369
+ ig.add(fs4.readFileSync(gitignorePath, "utf8"));
7744
8370
  }
7745
8371
  const sourceExtensions = [
7746
8372
  ".js",
@@ -7778,32 +8404,32 @@ async function optima_validate_logic(worktree) {
7778
8404
  ".codenomad"
7779
8405
  ]);
7780
8406
  const operationalFolders = [".optima", "templates", "dist"];
7781
- const isHiddenTree = (relPath) => {
7782
- if (!relPath) return false;
7783
- return relPath.split(path.sep).some((part) => part.startsWith("."));
8407
+ const isHiddenTree2 = (relPath2) => {
8408
+ if (!relPath2) return false;
8409
+ return relPath2.split(path4.sep).some((part) => part.startsWith("."));
7784
8410
  };
7785
- const firstPathSegment = (relPath) => relPath.split(path.sep).filter(Boolean)[0] || "";
7786
- const isOperationalRelPath = (relPath) => {
7787
- if (!relPath) return false;
7788
- const firstSegment = firstPathSegment(relPath);
8411
+ const firstPathSegment2 = (relPath2) => relPath2.split(path4.sep).filter(Boolean)[0] || "";
8412
+ const isOperationalRelPath2 = (relPath2) => {
8413
+ if (!relPath2) return false;
8414
+ const firstSegment = firstPathSegment2(relPath2);
7789
8415
  if (legacyOperationalRoots.has(firstSegment)) return true;
7790
- return operationalFolders.some((f) => relPath === f || relPath.startsWith(f + path.sep));
8416
+ return operationalFolders.some((f) => relPath2 === f || relPath2.startsWith(f + path4.sep));
7791
8417
  };
7792
8418
  const getSectionEntries = (value) => {
7793
8419
  if (Array.isArray(value)) return value;
7794
8420
  if (value && typeof value === "object") return Object.values(value);
7795
8421
  return [];
7796
8422
  };
7797
- const normalizeRelativePath = (relPath) => path.normalize(relPath).replace(/\\/g, "/").replace(/\/$/, "");
8423
+ const normalizeRelativePath = (relPath2) => path4.normalize(relPath2).replace(/\\/g, "/").replace(/\/$/, "");
7798
8424
  const isSourceDir = (dirPath) => {
7799
- const dirRelPath = path.relative(worktree, dirPath);
7800
- if (isOperationalRelPath(dirRelPath)) return false;
7801
- const items = fs.readdirSync(dirPath, { withFileTypes: true });
8425
+ const dirRelPath = path4.relative(worktree, dirPath);
8426
+ if (isOperationalRelPath2(dirRelPath)) return false;
8427
+ const items = fs4.readdirSync(dirPath, { withFileTypes: true });
7802
8428
  for (const item of items) {
7803
- const childPath = path.join(dirPath, item.name);
7804
- const relPath = path.relative(worktree, childPath);
7805
- if (ig.ignores(relPath) || isOperationalRelPath(relPath)) continue;
7806
- if (item.isFile() && sourceExtensions.includes(path.extname(item.name))) return true;
8429
+ const childPath = path4.join(dirPath, item.name);
8430
+ const relPath2 = path4.relative(worktree, childPath);
8431
+ if (ig.ignores(relPath2) || isOperationalRelPath2(relPath2)) continue;
8432
+ if (item.isFile() && sourceExtensions.includes(path4.extname(item.name))) return true;
7807
8433
  if (item.isDirectory()) {
7808
8434
  if (isSourceDir(childPath)) return true;
7809
8435
  }
@@ -7811,10 +8437,10 @@ async function optima_validate_logic(worktree) {
7811
8437
  return false;
7812
8438
  };
7813
8439
  function validateMap(filePath) {
7814
- const content = fs.readFileSync(filePath, "utf8");
8440
+ const content = fs4.readFileSync(filePath, "utf8");
7815
8441
  let map;
7816
8442
  try {
7817
- map = import_yaml.default.parse(content);
8443
+ map = import_yaml2.default.parse(content);
7818
8444
  if (!map || typeof map !== "object") {
7819
8445
  errors.push(`${filePath}: CodeMap is empty or invalid.`);
7820
8446
  return;
@@ -7823,32 +8449,32 @@ async function optima_validate_logic(worktree) {
7823
8449
  errors.push(`${filePath}: Invalid YAML.`);
7824
8450
  return;
7825
8451
  }
7826
- const dir = path.dirname(filePath);
8452
+ const dir = path4.dirname(filePath);
7827
8453
  const pathBase = filePath === rootCodemapPath ? worktree : dir;
7828
8454
  const indexedPaths = /* @__PURE__ */ new Set();
7829
8455
  const sectionsToVerify = ["modules", "entrypoints", "sources_of_truth", "links", "internals"];
7830
8456
  for (const section of sectionsToVerify) {
7831
8457
  for (const item of getSectionEntries(map[section])) {
7832
8458
  if (item?.path) {
7833
- indexedPaths.add(path.normalize(item.path));
8459
+ indexedPaths.add(path4.normalize(item.path));
7834
8460
  if (section === "links" && (item.path.startsWith("http://") || item.path.startsWith("https://"))) {
7835
8461
  continue;
7836
8462
  }
7837
- const absPath = path.isAbsolute(item.path) ? item.path : path.join(pathBase, item.path);
7838
- if (!fs.existsSync(absPath)) {
8463
+ const absPath = path4.isAbsolute(item.path) ? item.path : path4.join(pathBase, item.path);
8464
+ if (!fs4.existsSync(absPath)) {
7839
8465
  errors.push(`${filePath}: ${section.slice(0, -1)} path does not exist: ${item.path}`);
7840
8466
  }
7841
8467
  }
7842
8468
  }
7843
8469
  }
7844
- const relDir = path.relative(worktree, dir);
7845
- const isOperational = isOperationalRelPath(relDir);
8470
+ const relDir = path4.relative(worktree, dir);
8471
+ const isOperational = isOperationalRelPath2(relDir);
7846
8472
  if (map.scope === "module" && !isOperational) {
7847
- const items = fs.readdirSync(dir, { withFileTypes: true });
8473
+ const items = fs4.readdirSync(dir, { withFileTypes: true });
7848
8474
  for (const item of items) {
7849
- if (item.isFile() && sourceExtensions.includes(path.extname(item.name))) {
8475
+ if (item.isFile() && sourceExtensions.includes(path4.extname(item.name))) {
7850
8476
  if (item.name === "codemap.yml") continue;
7851
- if (!indexedPaths.has(path.normalize(item.name))) {
8477
+ if (!indexedPaths.has(path4.normalize(item.name))) {
7852
8478
  errors.push(`${filePath}: Unindexed source file found: '${item.name}'. Every source file must be categorized in a section (e.g., 'internals').`);
7853
8479
  }
7854
8480
  }
@@ -7858,7 +8484,7 @@ async function optima_validate_logic(worktree) {
7858
8484
  for (const key of pathKeys) {
7859
8485
  for (const entry of getSectionEntries(map[key])) {
7860
8486
  if (!entry?.path || entry.path.startsWith("http://") || entry.path.startsWith("https://")) continue;
7861
- if (path.isAbsolute(entry.path)) continue;
8487
+ if (path4.isAbsolute(entry.path)) continue;
7862
8488
  const normalizedPath = normalizeRelativePath(entry.path);
7863
8489
  if (!normalizedPath || normalizedPath === ".") continue;
7864
8490
  const parts = normalizedPath.split("/").filter((p) => p && p !== ".");
@@ -7870,30 +8496,30 @@ async function optima_validate_logic(worktree) {
7870
8496
  }
7871
8497
  }
7872
8498
  const walk = (dir) => {
7873
- const relDir = path.relative(worktree, dir);
8499
+ const relDir = path4.relative(worktree, dir);
7874
8500
  if (relDir && ig.ignores(relDir)) return;
7875
- if (isOperationalRelPath(relDir)) return;
7876
- if (isHiddenTree(relDir)) return;
7877
- const hasCodemap = fs.existsSync(path.join(dir, "codemap.yml"));
7878
- const items = fs.readdirSync(dir, { withFileTypes: true });
7879
- if (!relDir.startsWith(path.join(".optima", "tasks", "done"))) {
8501
+ if (isOperationalRelPath2(relDir)) return;
8502
+ if (isHiddenTree2(relDir)) return;
8503
+ const hasCodemap = fs4.existsSync(path4.join(dir, "codemap.yml"));
8504
+ const items = fs4.readdirSync(dir, { withFileTypes: true });
8505
+ if (!relDir.startsWith(path4.join(".optima", "tasks", "done"))) {
7880
8506
  for (const item of items) {
7881
8507
  if (item.isFile() && item.name.endsWith(".md")) {
7882
- const content = fs.readFileSync(path.join(dir, item.name), "utf8");
8508
+ const content = fs4.readFileSync(path4.join(dir, item.name), "utf8");
7883
8509
  if (content.includes("[To be defined]") || content.includes("[Insert ")) {
7884
- const relFilePath = path.join(relDir, item.name);
8510
+ const relFilePath = path4.join(relDir, item.name);
7885
8511
  errors.push(`Documentation Placeholder found: '${relFilePath}' still contains [To be defined] or [Insert ...] placeholders.`);
7886
8512
  }
7887
8513
  }
7888
8514
  }
7889
8515
  }
7890
- const isOperational = isOperationalRelPath(relDir);
8516
+ const isOperational = isOperationalRelPath2(relDir);
7891
8517
  if (relDir !== "" && !hasCodemap && isSourceDir(dir) && !isOperational) {
7892
8518
  errors.push(`Missing CodeMap: Directory '${relDir}' contains source but has no codemap.yml.`);
7893
8519
  }
7894
- if (hasCodemap) validateMap(path.join(dir, "codemap.yml"));
8520
+ if (hasCodemap) validateMap(path4.join(dir, "codemap.yml"));
7895
8521
  for (const item of items) {
7896
- if (item.isDirectory()) walk(path.join(dir, item.name));
8522
+ if (item.isDirectory()) walk(path4.join(dir, item.name));
7897
8523
  }
7898
8524
  };
7899
8525
  validateMap(rootCodemapPath);
@@ -7906,12 +8532,12 @@ async function optima_validate_logic(worktree) {
7906
8532
  }
7907
8533
 
7908
8534
  // src/index.js
7909
- var PKG_ROOT = path2.resolve(path2.dirname(fileURLToPath(import.meta.url)), "..");
7910
- var BUNDLE_ASSETS_DIR = path2.join(PKG_ROOT, "assets");
7911
- var BUNDLE_AGENTS_DIR = path2.join(BUNDLE_ASSETS_DIR, "agents");
7912
- var BUNDLE_POLICIES_DIR = path2.join(BUNDLE_ASSETS_DIR, "policies");
7913
- var TEMPLATES_DIR = path2.join(PKG_ROOT, "templates");
7914
- var HUMANS_REGISTRY_PATH = path2.join(PKG_ROOT, "docs", "core", "humans.md");
8535
+ var PKG_ROOT = path5.resolve(path5.dirname(fileURLToPath(import.meta.url)), "..");
8536
+ var BUNDLE_ASSETS_DIR = path5.join(PKG_ROOT, "assets");
8537
+ var BUNDLE_AGENTS_DIR = path5.join(BUNDLE_ASSETS_DIR, "agents");
8538
+ var BUNDLE_POLICIES_DIR = path5.join(BUNDLE_ASSETS_DIR, "policies");
8539
+ var TEMPLATES_DIR = path5.join(PKG_ROOT, "templates");
8540
+ var HUMANS_REGISTRY_PATH = path5.join(PKG_ROOT, "docs", "core", "humans.md");
7915
8541
  var MANDATORY_AGENTS = /* @__PURE__ */ new Set(["product_manager", "business_analyst", "tech_lead"]);
7916
8542
  var MINI_MODE_AGENTS = /* @__PURE__ */ new Set(["product_manager", "business_analyst", "tech_lead"]);
7917
8543
  var CLICKUP_IGNORED_TASK_TYPES = ["Idea", "Backlog", "Hito", "Nota de reuni\xF3n", "Respuesta del formulario"];
@@ -8047,18 +8673,18 @@ function objectIdentity(value) {
8047
8673
  return objectIdentityMap.get(value);
8048
8674
  }
8049
8675
  function isRootDirectory(candidate) {
8050
- const resolved = path2.resolve(candidate);
8051
- return resolved === path2.parse(resolved).root;
8676
+ const resolved = path5.resolve(candidate);
8677
+ return resolved === path5.parse(resolved).root;
8052
8678
  }
8053
8679
  function isSafeWritableDirectory(candidate) {
8054
8680
  if (typeof candidate !== "string" || !candidate.trim()) return false;
8055
- if (!path2.isAbsolute(candidate)) return false;
8056
- const resolved = path2.resolve(candidate);
8681
+ if (!path5.isAbsolute(candidate)) return false;
8682
+ const resolved = path5.resolve(candidate);
8057
8683
  if (isRootDirectory(resolved)) return false;
8058
8684
  try {
8059
- const stat = fs2.statSync(resolved);
8685
+ const stat = fs5.statSync(resolved);
8060
8686
  if (!stat.isDirectory()) return false;
8061
- fs2.accessSync(resolved, fs2.constants.W_OK);
8687
+ fs5.accessSync(resolved, fs5.constants.W_OK);
8062
8688
  return true;
8063
8689
  } catch {
8064
8690
  return false;
@@ -8074,7 +8700,7 @@ function resolveSafeWorktree(context = {}, pluginWorktree = null) {
8074
8700
  ];
8075
8701
  for (const candidate of candidates) {
8076
8702
  if (typeof candidate !== "string" || !candidate.trim()) continue;
8077
- const resolved = path2.resolve(candidate);
8703
+ const resolved = path5.resolve(candidate);
8078
8704
  if (isSafeWritableDirectory(resolved)) return resolved;
8079
8705
  }
8080
8706
  throw new Error(SAFE_WORKTREE_FAILURE);
@@ -8089,13 +8715,13 @@ function safeWorktreeOrFailure(context, pluginWorktree) {
8089
8715
  function explicitSafeInputWorktree(input = {}) {
8090
8716
  for (const candidate of [input?.worktree, input?.directory]) {
8091
8717
  if (typeof candidate !== "string" || !candidate.trim()) continue;
8092
- const resolved = path2.resolve(candidate);
8718
+ const resolved = path5.resolve(candidate);
8093
8719
  if (isSafeWritableDirectory(resolved)) return resolved;
8094
8720
  }
8095
8721
  return null;
8096
8722
  }
8097
8723
  function isGitRepository(worktree) {
8098
- return fs2.existsSync(path2.join(worktree, ".git"));
8724
+ return fs5.existsSync(path5.join(worktree, ".git"));
8099
8725
  }
8100
8726
  function normalizeLooseToken(value) {
8101
8727
  return String(value ?? "").trim().normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
@@ -8129,8 +8755,8 @@ function parseHumansRegistry(markdown = "") {
8129
8755
  return roles;
8130
8756
  }
8131
8757
  function loadHumansRegistry(registryPath = HUMANS_REGISTRY_PATH) {
8132
- if (!fs2.existsSync(registryPath)) return {};
8133
- return parseHumansRegistry(fs2.readFileSync(registryPath, "utf8"));
8758
+ if (!fs5.existsSync(registryPath)) return {};
8759
+ return parseHumansRegistry(fs5.readFileSync(registryPath, "utf8"));
8134
8760
  }
8135
8761
  function resolveHumanRoles(roles = CLICKUP_FINAL_APPROVER_ROLES, registry = loadHumansRegistry()) {
8136
8762
  return [...new Set(roles.map((role) => registry[String(role ?? "").trim()] || "").filter(Boolean))];
@@ -8297,7 +8923,7 @@ function parseMarkdownArtifact(markdown = "", { requiredSections = [] } = {}) {
8297
8923
  };
8298
8924
  }
8299
8925
  function readMarkdownArtifact(filePath, options = {}) {
8300
- const markdown = fs2.readFileSync(filePath, "utf8");
8926
+ const markdown = fs5.readFileSync(filePath, "utf8");
8301
8927
  return parseMarkdownArtifact(markdown, options);
8302
8928
  }
8303
8929
  function stripRawLogSections(sections = {}) {
@@ -8583,7 +9209,7 @@ function buildClickUpSummaryPayload({ summaryMarkdown = "", summaryPath = "", ta
8583
9209
  function deriveClickUpWorktree({ baseWorktree = "", taskId, taskType, parentTaskId, subtaskId } = {}) {
8584
9210
  const branch = deriveClickUpBranchName({ taskType, parentTaskId, subtaskId, taskId });
8585
9211
  const root = baseWorktree || process.cwd();
8586
- return path2.join(path2.dirname(root), `${path2.basename(root)}-${branch.replace(/\//g, "-")}`);
9212
+ return path5.join(path5.dirname(root), `${path5.basename(root)}-${branch.replace(/\//g, "-")}`);
8587
9213
  }
8588
9214
  function clickUpCustomFieldValue(task = {}, names = []) {
8589
9215
  const fields = Array.isArray(task.custom_fields) ? task.custom_fields : [];
@@ -8607,12 +9233,12 @@ function safeExistingClickUpWorktree({ metadata = {}, branch = "" } = {}) {
8607
9233
  const taskMetadata = metadataTaskRouting(metadata);
8608
9234
  const existingWorktree = typeof taskMetadata.worktree === "string" ? taskMetadata.worktree.trim() : "";
8609
9235
  const existingBranch = typeof taskMetadata.branch === "string" ? taskMetadata.branch.trim() : "";
8610
- if (!existingWorktree || !path2.isAbsolute(existingWorktree) || !fs2.existsSync(existingWorktree)) return null;
9236
+ if (!existingWorktree || !path5.isAbsolute(existingWorktree) || !fs5.existsSync(existingWorktree)) return null;
8611
9237
  try {
8612
- const stat = fs2.statSync(existingWorktree);
9238
+ const stat = fs5.statSync(existingWorktree);
8613
9239
  if (!stat.isDirectory()) return null;
8614
9240
  if (branch && existingBranch && existingBranch !== branch) return null;
8615
- return { branch: existingBranch || branch, worktree: path2.resolve(existingWorktree), reused: true };
9241
+ return { branch: existingBranch || branch, worktree: path5.resolve(existingWorktree), reused: true };
8616
9242
  } catch {
8617
9243
  return null;
8618
9244
  }
@@ -8623,10 +9249,10 @@ function ensureClickUpTaskWorktree({ baseWorktree = "", taskId, taskType = "Tare
8623
9249
  const existing = safeExistingClickUpWorktree({ metadata: existingMetadata, branch });
8624
9250
  if (existing) return { ...existing, branch };
8625
9251
  const worktreePath = deriveClickUpWorktree({ baseWorktree, taskId, taskType, parentTaskId: effectiveParent, subtaskId });
8626
- if (fs2.existsSync(worktreePath)) return { branch, worktree: path2.resolve(worktreePath), reused: true };
9252
+ if (fs5.existsSync(worktreePath)) return { branch, worktree: path5.resolve(worktreePath), reused: true };
8627
9253
  if (allowNonGitFallback) {
8628
- fs2.mkdirSync(worktreePath, { recursive: true });
8629
- return { branch, worktree: path2.resolve(worktreePath), reused: false, fallback: "non_git" };
9254
+ fs5.mkdirSync(worktreePath, { recursive: true });
9255
+ return { branch, worktree: path5.resolve(worktreePath), reused: false, fallback: "non_git" };
8630
9256
  }
8631
9257
  const startPoint = (() => {
8632
9258
  try {
@@ -8637,7 +9263,7 @@ function ensureClickUpTaskWorktree({ baseWorktree = "", taskId, taskType = "Tare
8637
9263
  }
8638
9264
  })();
8639
9265
  runGitFn(baseWorktree, ["worktree", "add", "-b", branch, worktreePath, startPoint]);
8640
- return { branch, worktree: path2.resolve(worktreePath), reused: false, startPoint };
9266
+ return { branch, worktree: path5.resolve(worktreePath), reused: false, startPoint };
8641
9267
  }
8642
9268
  function normalizeClickUpDefinitionDocParent(parent = {}) {
8643
9269
  const docId = String(parent.doc_id || parent.docId || CLICKUP_DEFINITION_DOC_PARENT.doc_id).trim();
@@ -8772,76 +9398,10 @@ function buildClickUpTransitionPayload({ fromStatus, toStatus, validationPassed
8772
9398
  }
8773
9399
  };
8774
9400
  }
8775
- function toGitPath(worktree, targetPath) {
8776
- const relativePath = path2.relative(worktree, targetPath);
8777
- if (!relativePath || relativePath.startsWith("..") || path2.isAbsolute(relativePath)) return null;
8778
- return relativePath.split(path2.sep).join("/");
8779
- }
8780
- function runGit(worktree, args) {
8781
- return execFileSync("git", args, {
8782
- cwd: worktree,
8783
- encoding: "utf8",
8784
- stdio: ["ignore", "pipe", "pipe"]
8785
- });
8786
- }
8787
- function gitMigrationState(worktree) {
8788
- try {
8789
- const root = runGit(worktree, ["rev-parse", "--show-toplevel"]).trim();
8790
- if (path2.resolve(root) !== path2.resolve(worktree)) return null;
8791
- return { worktree };
8792
- } catch {
8793
- return null;
8794
- }
8795
- }
8796
- function isGitTracked(gitState, targetPath) {
8797
- if (!gitState) return false;
8798
- const gitPath = toGitPath(gitState.worktree, targetPath);
8799
- if (!gitPath) return false;
8800
- try {
8801
- runGit(gitState.worktree, ["ls-files", "--error-unmatch", "--", gitPath]);
8802
- return true;
8803
- } catch {
8804
- return false;
8805
- }
8806
- }
8807
- function hasGitTrackedChildren(gitState, targetPath) {
8808
- if (!gitState) return false;
8809
- const gitPath = toGitPath(gitState.worktree, targetPath);
8810
- if (!gitPath) return false;
8811
- try {
8812
- return runGit(gitState.worktree, ["ls-files", "--", `${gitPath}/`]).trim().length > 0;
8813
- } catch {
8814
- return false;
8815
- }
8816
- }
8817
- function gitAwareMoveIfTracked(sourcePath, destinationPath, gitState) {
8818
- const sourceIsTracked = isGitTracked(gitState, sourcePath) || hasGitTrackedChildren(gitState, sourcePath);
8819
- if (!gitState || !sourceIsTracked || fs2.existsSync(destinationPath)) return false;
8820
- const sourceGitPath = toGitPath(gitState.worktree, sourcePath);
8821
- const destinationGitPath = toGitPath(gitState.worktree, destinationPath);
8822
- if (!sourceGitPath || !destinationGitPath) return false;
8823
- fs2.mkdirSync(path2.dirname(destinationPath), { recursive: true });
8824
- try {
8825
- runGit(gitState.worktree, ["mv", "--", sourceGitPath, destinationGitPath]);
8826
- return true;
8827
- } catch {
8828
- return false;
8829
- }
8830
- }
8831
- function stageGitAwareMerge(sourcePath, destinationPath, gitState) {
8832
- if (!gitState || !isGitTracked(gitState, sourcePath)) return;
8833
- const sourceGitPath = toGitPath(gitState.worktree, sourcePath);
8834
- const destinationGitPath = toGitPath(gitState.worktree, destinationPath);
8835
- if (!sourceGitPath || !destinationGitPath) return;
8836
- try {
8837
- runGit(gitState.worktree, ["add", "-A", "--", sourceGitPath, destinationGitPath]);
8838
- } catch {
8839
- }
8840
- }
8841
9401
  function ensureOptimaGitignoreRules(worktree) {
8842
9402
  if (!isGitRepository(worktree)) return { touched: false, added: [] };
8843
- const gitignorePath = path2.join(worktree, ".gitignore");
8844
- const existing = fs2.existsSync(gitignorePath) ? fs2.readFileSync(gitignorePath, "utf8") : "";
9403
+ const gitignorePath = path5.join(worktree, ".gitignore");
9404
+ const existing = fs5.existsSync(gitignorePath) ? fs5.readFileSync(gitignorePath, "utf8") : "";
8845
9405
  const existingRules = new Set(existing.split(/\r?\n/).map((line) => line.trim()).filter(Boolean));
8846
9406
  const missingRules = OPTIMA_GITIGNORE_RULES.filter((rule) => !existingRules.has(rule));
8847
9407
  if (missingRules.length === 0) return { touched: false, added: [] };
@@ -8851,49 +9411,45 @@ function ensureOptimaGitignoreRules(worktree) {
8851
9411
  "# Optima local/private state",
8852
9412
  ...missingRules
8853
9413
  ].join("\n");
8854
- fs2.writeFileSync(gitignorePath, `${existing}${prefix}${separator}${block}
9414
+ fs5.writeFileSync(gitignorePath, `${existing}${prefix}${separator}${block}
8855
9415
  `, "utf8");
8856
9416
  return { touched: true, added: missingRules };
8857
9417
  }
8858
- function compactPromptPath(filePath) {
8859
- if (!filePath.endsWith(".md") || filePath.endsWith(".prompt.md")) return null;
8860
- return filePath.replace(/\.md$/, ".prompt.md");
8861
- }
8862
9418
  function optimaDir(worktree) {
8863
- return path2.join(worktree, OPTIMA_DIRNAME);
9419
+ return path5.join(worktree, OPTIMA_DIRNAME);
8864
9420
  }
8865
9421
  function optimaLocalConfigDir(worktree) {
8866
- return path2.join(optimaDir(worktree), ".config");
9422
+ return path5.join(optimaDir(worktree), ".config");
8867
9423
  }
8868
9424
  function optimaConfigDir(worktree) {
8869
9425
  return optimaLocalConfigDir(worktree);
8870
9426
  }
8871
9427
  function optimaCodemapPath(worktree) {
8872
- return path2.join(optimaDir(worktree), "codemap.yml");
9428
+ return path5.join(optimaDir(worktree), "codemap.yml");
8873
9429
  }
8874
9430
  function optimaTasksDir(worktree) {
8875
- return path2.join(optimaDir(worktree), "tasks");
9431
+ return path5.join(optimaDir(worktree), "tasks");
8876
9432
  }
8877
9433
  function optimaEvidencesDir(worktree) {
8878
- return path2.join(optimaDir(worktree), "evidences");
9434
+ return path5.join(optimaDir(worktree), "evidences");
8879
9435
  }
8880
9436
  function optimaScrsDir(worktree) {
8881
- return path2.join(optimaDir(worktree), "docs", "scrs");
9437
+ return path5.join(optimaDir(worktree), "docs", "scrs");
8882
9438
  }
8883
9439
  function legacyNomadworkDir(worktree) {
8884
- return path2.join(worktree, LEGACY_NOMADWORK_DIRNAME);
9440
+ return path5.join(worktree, LEGACY_NOMADWORK_DIRNAME);
8885
9441
  }
8886
9442
  function legacyNomadworksDir(worktree) {
8887
- return path2.join(worktree, LEGACY_NOMADWORKS_DIRNAME);
9443
+ return path5.join(worktree, LEGACY_NOMADWORKS_DIRNAME);
8888
9444
  }
8889
9445
  function legacyOrbitaDir(worktree) {
8890
- return path2.join(worktree, LEGACY_ORBITA_DIRNAME);
9446
+ return path5.join(worktree, LEGACY_ORBITA_DIRNAME);
8891
9447
  }
8892
9448
  function legacyStaticEngDir(worktree) {
8893
- return path2.join(worktree, LEGACY_STATICENG_DIRNAME);
9449
+ return path5.join(worktree, LEGACY_STATICENG_DIRNAME);
8894
9450
  }
8895
9451
  function repoConfigPath(worktree) {
8896
- return path2.join(optimaConfigDir(worktree), "optima.yaml");
9452
+ return path5.join(optimaConfigDir(worktree), "optima.yaml");
8897
9453
  }
8898
9454
  function normalizeLegacyDiscussionEntry(entry) {
8899
9455
  if (!entry || typeof entry !== "object") return entry;
@@ -8906,25 +9462,25 @@ function normalizeLegacyDiscussionEntry(entry) {
8906
9462
  return next;
8907
9463
  }
8908
9464
  function repoPoliciesDir(worktree) {
8909
- return path2.join(optimaDir(worktree), "policies");
9465
+ return path5.join(optimaDir(worktree), "policies");
8910
9466
  }
8911
9467
  function generatedPoliciesDir(worktree) {
8912
- return path2.join(optimaLocalConfigDir(worktree), "generated", "policies");
9468
+ return path5.join(optimaLocalConfigDir(worktree), "generated", "policies");
8913
9469
  }
8914
9470
  function generatedAgentsDir(worktree) {
8915
- return path2.join(optimaLocalConfigDir(worktree), "generated", "agents");
9471
+ return path5.join(optimaLocalConfigDir(worktree), "generated", "agents");
8916
9472
  }
8917
9473
  function repoAgentsDir(worktree) {
8918
- return path2.join(optimaDir(worktree), "agents");
9474
+ return path5.join(optimaDir(worktree), "agents");
8919
9475
  }
8920
9476
  function repoAgentAdditionsDir(worktree) {
8921
- return path2.join(optimaDir(worktree), "agent-additions");
9477
+ return path5.join(optimaDir(worktree), "agent-additions");
8922
9478
  }
8923
9479
  function legacyRepoAgentsDir(worktree) {
8924
- return path2.join(legacyNomadworksDir(worktree), "agents");
9480
+ return path5.join(legacyNomadworksDir(worktree), "agents");
8925
9481
  }
8926
9482
  function runtimeDiscussionRegistryPath(worktree) {
8927
- return path2.join(optimaLocalConfigDir(worktree), "runtime", "discussions.json");
9483
+ return path5.join(optimaLocalConfigDir(worktree), "runtime", "discussions.json");
8928
9484
  }
8929
9485
  function resolveConfigPath(worktree) {
8930
9486
  return repoConfigPath(worktree);
@@ -8967,32 +9523,32 @@ function mergeClickUpAgentMetadata(existing, update = {}) {
8967
9523
  return JSON.stringify(sortJsonValue(merged), null, 2);
8968
9524
  }
8969
9525
  function optimaRuntimeDir(worktree) {
8970
- return path2.join(optimaLocalConfigDir(worktree), "runtime");
9526
+ return path5.join(optimaLocalConfigDir(worktree), "runtime");
8971
9527
  }
8972
9528
  function clickUpWebhookStatePath(worktree) {
8973
- return path2.join(optimaRuntimeDir(worktree), "clickup-webhook.json");
9529
+ return path5.join(optimaRuntimeDir(worktree), "clickup-webhook.json");
8974
9530
  }
8975
9531
  function clickUpCommentLedgerPath(worktree) {
8976
- return path2.join(optimaRuntimeDir(worktree), "clickup-comment-ledger.jsonl");
9532
+ return path5.join(optimaRuntimeDir(worktree), "clickup-comment-ledger.jsonl");
8977
9533
  }
8978
9534
  function clickUpWebhookLogPath(worktree) {
8979
- return path2.join(optimaRuntimeDir(worktree), "clickup-webhook.log.jsonl");
9535
+ return path5.join(optimaRuntimeDir(worktree), "clickup-webhook.log.jsonl");
8980
9536
  }
8981
9537
  function normalizeClickUpWebhookLogLevel(value) {
8982
9538
  const level = String(value || "info").trim().toLowerCase();
8983
9539
  return CLICKUP_WEBHOOK_LOG_LEVELS.has(level) ? level : "info";
8984
9540
  }
8985
9541
  function clickUpWebhookAuditLogDir() {
8986
- const dataHome = process.env.XDG_DATA_HOME && path2.isAbsolute(process.env.XDG_DATA_HOME) ? process.env.XDG_DATA_HOME : path2.join(os.homedir(), ".local", "share", "opencode");
8987
- return path2.join(dataHome, "opencode-optima");
9542
+ const dataHome = process.env.XDG_DATA_HOME && path5.isAbsolute(process.env.XDG_DATA_HOME) ? process.env.XDG_DATA_HOME : path5.join(os.homedir(), ".local", "share", "opencode");
9543
+ return path5.join(dataHome, "opencode-optima");
8988
9544
  }
8989
9545
  function clickUpWebhookAuditLogPath(at = /* @__PURE__ */ new Date(), logDir = clickUpWebhookAuditLogDir()) {
8990
- return path2.join(logDir, `clickup-webhook-${at.toISOString().slice(0, 10)}.jsonl`);
9546
+ return path5.join(logDir, `clickup-webhook-${at.toISOString().slice(0, 10)}.jsonl`);
8991
9547
  }
8992
9548
  function clickUpWebhookRequestFilePath(at = /* @__PURE__ */ new Date(), logDir = clickUpWebhookAuditLogDir()) {
8993
9549
  const stamp = at.toISOString().replace(/:/g, "-").replace(/\./g, "-");
8994
9550
  const shortId = crypto.randomBytes(4).toString("hex");
8995
- return path2.join(logDir, "requests", `clickup-webhook-${stamp}-${shortId}.json`);
9551
+ return path5.join(logDir, "requests", `clickup-webhook-${stamp}-${shortId}.json`);
8996
9552
  }
8997
9553
  function findOptimaPluginTupleOptions(pluginEntries = []) {
8998
9554
  if (!Array.isArray(pluginEntries)) return null;
@@ -9036,6 +9592,7 @@ function normalizeClickUpWebhookConfig(rawClickUp = null, worktree = process.cwd
9036
9592
  const ignoredStatuses = Array.isArray(routing.ignored_statuses) && routing.ignored_statuses.length > 0 ? routing.ignored_statuses : CLICKUP_WEBHOOK_TERMINAL_STATUSES;
9037
9593
  const config = {
9038
9594
  enabled: raw.enabled === true,
9595
+ test: raw.test === true || raw.test_mode === true || raw.testMode === true,
9039
9596
  basePath: String(raw.base_path || raw.basePath || worktree || "").trim(),
9040
9597
  teamId: String(raw.team_id || raw.teamId || "").trim(),
9041
9598
  apiToken: String(raw.api_token || raw.apiToken || "").trim(),
@@ -9074,7 +9631,7 @@ function normalizeClickUpWebhookConfig(rawClickUp = null, worktree = process.cwd
9074
9631
  };
9075
9632
  const errors = [];
9076
9633
  if (!config.enabled) errors.push("clickup.enabled must be true");
9077
- if (!config.basePath || !path2.isAbsolute(config.basePath)) errors.push("clickup.base_path must be an absolute path");
9634
+ if (!config.basePath || !path5.isAbsolute(config.basePath)) errors.push("clickup.base_path must be an absolute path");
9078
9635
  if (!config.teamId) errors.push("clickup.team_id is required");
9079
9636
  if (!config.apiToken) errors.push("clickup.api_token is required");
9080
9637
  if (!config.webhook.publicUrl) errors.push("clickup.webhook.public_url is required");
@@ -9116,21 +9673,21 @@ function sanitizeClickUpWebhookState(state = {}, config = null) {
9116
9673
  }
9117
9674
  function readClickUpWebhookState(worktree, config = null) {
9118
9675
  const statePath = clickUpWebhookStatePath(worktree);
9119
- if (!fs2.existsSync(statePath)) return sanitizeClickUpWebhookState({}, config);
9676
+ if (!fs5.existsSync(statePath)) return sanitizeClickUpWebhookState({}, config);
9120
9677
  try {
9121
- return sanitizeClickUpWebhookState(JSON.parse(fs2.readFileSync(statePath, "utf8")), config);
9678
+ return sanitizeClickUpWebhookState(JSON.parse(fs5.readFileSync(statePath, "utf8")), config);
9122
9679
  } catch {
9123
9680
  return sanitizeClickUpWebhookState({}, config);
9124
9681
  }
9125
9682
  }
9126
9683
  function writeClickUpWebhookState(worktree, state, config = null) {
9127
9684
  const statePath = clickUpWebhookStatePath(worktree);
9128
- fs2.mkdirSync(path2.dirname(statePath), { recursive: true, mode: 448 });
9685
+ fs5.mkdirSync(path5.dirname(statePath), { recursive: true, mode: 448 });
9129
9686
  const next = sanitizeClickUpWebhookState(state, config);
9130
- fs2.writeFileSync(statePath, `${JSON.stringify(next, null, 2)}
9687
+ fs5.writeFileSync(statePath, `${JSON.stringify(next, null, 2)}
9131
9688
  `, { encoding: "utf8", mode: 384 });
9132
9689
  try {
9133
- fs2.chmodSync(statePath, 384);
9690
+ fs5.chmodSync(statePath, 384);
9134
9691
  } catch {
9135
9692
  }
9136
9693
  return next;
@@ -9146,7 +9703,7 @@ function isClickUpWebhookStateActive(state, config) {
9146
9703
  function expandHomePath(value = "") {
9147
9704
  const input = String(value || "").trim();
9148
9705
  if (input === "~") return os.homedir();
9149
- if (input.startsWith("~/")) return path2.join(os.homedir(), input.slice(2));
9706
+ if (input.startsWith("~/")) return path5.join(os.homedir(), input.slice(2));
9150
9707
  return input;
9151
9708
  }
9152
9709
  function resolveSecretReference(value = "") {
@@ -9156,7 +9713,7 @@ function resolveSecretReference(value = "") {
9156
9713
  const fileMatch = raw.match(/^\{file:(.+)\}$/);
9157
9714
  if (fileMatch) {
9158
9715
  try {
9159
- return fs2.readFileSync(expandHomePath(fileMatch[1]), "utf8").trim();
9716
+ return fs5.readFileSync(expandHomePath(fileMatch[1]), "utf8").trim();
9160
9717
  } catch {
9161
9718
  return "";
9162
9719
  }
@@ -9233,6 +9790,40 @@ function createClickUpApiClient(config, fetchImpl = globalThis.fetch) {
9233
9790
  }
9234
9791
  };
9235
9792
  }
9793
+ function createTestClickUpApiClient(config) {
9794
+ const metadata = /* @__PURE__ */ new Map();
9795
+ return {
9796
+ async createWebhook({ endpoint, events, location } = {}) {
9797
+ return {
9798
+ webhook: {
9799
+ id: "optima-test-webhook",
9800
+ endpoint: endpoint || config.webhook.publicUrl,
9801
+ events: events || config.webhook.events,
9802
+ location: location || config.webhook.location,
9803
+ secret: "optima-test-secret",
9804
+ active: true
9805
+ }
9806
+ };
9807
+ },
9808
+ async getTask(taskId) {
9809
+ return null;
9810
+ },
9811
+ async updateTaskMetadata({ taskId, value }) {
9812
+ metadata.set(String(taskId || ""), value);
9813
+ return { ok: true };
9814
+ },
9815
+ async postTaskComment() {
9816
+ return { ok: true };
9817
+ },
9818
+ async addTaskTag() {
9819
+ return { ok: true };
9820
+ },
9821
+ async listAssignedTasks() {
9822
+ return { tasks: [] };
9823
+ },
9824
+ __metadata: metadata
9825
+ };
9826
+ }
9236
9827
  function normalizeClickUpWebhookApiResponse(response = {}, fallbackConfig = null) {
9237
9828
  const webhook = response?.webhook || response?.data || response || {};
9238
9829
  const healthStatus = String(webhook.health?.status || webhook.health_status || "").trim().toLowerCase();
@@ -9412,9 +10003,9 @@ function rememberClickUpWebhookEvent(state = {}, eventKey, limit = 200) {
9412
10003
  }
9413
10004
  function readClickUpCommentLedger(ledgerPath) {
9414
10005
  const processed = /* @__PURE__ */ new Set();
9415
- if (!ledgerPath || !fs2.existsSync(ledgerPath)) return processed;
10006
+ if (!ledgerPath || !fs5.existsSync(ledgerPath)) return processed;
9416
10007
  try {
9417
- const raw = fs2.readFileSync(ledgerPath, "utf8");
10008
+ const raw = fs5.readFileSync(ledgerPath, "utf8");
9418
10009
  for (const [index, line] of raw.split(/\r?\n/).entries()) {
9419
10010
  if (!line.trim()) continue;
9420
10011
  try {
@@ -9431,11 +10022,11 @@ function readClickUpCommentLedger(ledgerPath) {
9431
10022
  }
9432
10023
  function appendClickUpCommentLedgerEntry(ledgerPath, entry = {}) {
9433
10024
  if (!ledgerPath || !entry.key) return;
9434
- fs2.mkdirSync(path2.dirname(ledgerPath), { recursive: true, mode: 448 });
9435
- fs2.appendFileSync(ledgerPath, `${JSON.stringify(entry)}
10025
+ fs5.mkdirSync(path5.dirname(ledgerPath), { recursive: true, mode: 448 });
10026
+ fs5.appendFileSync(ledgerPath, `${JSON.stringify(entry)}
9436
10027
  `, { encoding: "utf8", mode: 384 });
9437
10028
  try {
9438
- fs2.chmodSync(ledgerPath, 384);
10029
+ fs5.chmodSync(ledgerPath, 384);
9439
10030
  } catch {
9440
10031
  }
9441
10032
  }
@@ -10151,9 +10742,9 @@ function formatClickUpWebhookPrompt({ eventType, taskId, payload, branch = "", w
10151
10742
  }
10152
10743
  function appendClickUpWebhookLocalLog(worktree, entry) {
10153
10744
  const logPath = clickUpWebhookLogPath(worktree);
10154
- fs2.mkdirSync(path2.dirname(logPath), { recursive: true });
10745
+ fs5.mkdirSync(path5.dirname(logPath), { recursive: true });
10155
10746
  const safeEntry = { ...entry, at: entry.at || (/* @__PURE__ */ new Date()).toISOString() };
10156
- fs2.appendFileSync(logPath, `${JSON.stringify(safeEntry)}
10747
+ fs5.appendFileSync(logPath, `${JSON.stringify(safeEntry)}
10157
10748
  `, "utf8");
10158
10749
  }
10159
10750
  function clickUpWebhookLifecycleLog(worktree, entry) {
@@ -10182,7 +10773,7 @@ function closeClickUpWebhookServer(server) {
10182
10773
  });
10183
10774
  }
10184
10775
  function managedClickUpWebhookKey({ worktree, state, config } = {}) {
10185
- return [path2.resolve(worktree || process.cwd()), state?.webhookId || "", config?.webhook?.publicUrl || ""].join("|");
10776
+ return [path5.resolve(worktree || process.cwd()), state?.webhookId || "", config?.webhook?.publicUrl || ""].join("|");
10186
10777
  }
10187
10778
  async function deleteClickUpWebhookBestEffort({ webhookId, clickupClient, worktree, reason = "cleanup" } = {}) {
10188
10779
  const id = String(webhookId || "").trim();
@@ -10281,13 +10872,13 @@ function writeClickUpWebhookAuditLog({ method, url, headers = {}, rawBody = "",
10281
10872
  const failed = Boolean(error || !handled?.ok || (handled?.status || 500) >= 400);
10282
10873
  if (level === "error" && !failed) return;
10283
10874
  const logDir = clickUpWebhookAuditLogDir();
10284
- fs2.mkdirSync(logDir, { recursive: true });
10875
+ fs5.mkdirSync(logDir, { recursive: true });
10285
10876
  const secretValues = [resolveSecretReference(config?.apiToken), state?.secret, config?.webhook?.secret].filter(Boolean);
10286
10877
  let requestFile;
10287
10878
  if (level === "verbose") {
10288
10879
  const absoluteRequestFile = clickUpWebhookRequestFilePath(at, logDir);
10289
- fs2.mkdirSync(path2.dirname(absoluteRequestFile), { recursive: true });
10290
- requestFile = path2.relative(logDir, absoluteRequestFile).split(path2.sep).join("/");
10880
+ fs5.mkdirSync(path5.dirname(absoluteRequestFile), { recursive: true });
10881
+ requestFile = path5.relative(logDir, absoluteRequestFile).split(path5.sep).join("/");
10291
10882
  const parsedBody = payload || (() => {
10292
10883
  try {
10293
10884
  return JSON.parse(Buffer.isBuffer(rawBody) ? rawBody.toString("utf8") : String(rawBody || ""));
@@ -10303,11 +10894,11 @@ function writeClickUpWebhookAuditLog({ method, url, headers = {}, rawBody = "",
10303
10894
  headers,
10304
10895
  body: parsedBody === void 0 ? Buffer.isBuffer(rawBody) ? rawBody.toString("utf8") : String(rawBody || "") : parsedBody
10305
10896
  }, secretValues);
10306
- fs2.writeFileSync(absoluteRequestFile, `${JSON.stringify(requestArtifact, null, 2)}
10897
+ fs5.writeFileSync(absoluteRequestFile, `${JSON.stringify(requestArtifact, null, 2)}
10307
10898
  `, "utf8");
10308
10899
  }
10309
10900
  const summary = redactClickUpWebhookAuditValue(buildClickUpWebhookAuditSummary({ method, url, config, handled, error, payload, requestFile, at }), secretValues);
10310
- fs2.appendFileSync(clickUpWebhookAuditLogPath(at, logDir), `${JSON.stringify(summary)}
10901
+ fs5.appendFileSync(clickUpWebhookAuditLogPath(at, logDir), `${JSON.stringify(summary)}
10311
10902
  `, "utf8");
10312
10903
  } catch {
10313
10904
  }
@@ -10381,7 +10972,7 @@ async function routeClickUpWebhookEventUnlocked({ payload, config, state = {}, w
10381
10972
  const subtaskId = parentTaskId && parentTaskId !== taskId ? taskId : "";
10382
10973
  let taskRoute;
10383
10974
  try {
10384
- taskRoute = ensureTaskWorktree({ baseWorktree: config.basePath, taskId, taskType, parentTaskId, subtaskId, existingMetadata: metadata, allowNonGitFallback: process.env.NODE_ENV === "test" });
10975
+ taskRoute = ensureTaskWorktree({ baseWorktree: config.basePath, taskId, taskType, parentTaskId, subtaskId, existingMetadata: metadata, allowNonGitFallback: process.env.NODE_ENV === "test" || config.test === true });
10385
10976
  } catch (error) {
10386
10977
  const message = `Optima webhook could not create or reuse a task worktree for ${taskId}: ${error.message}`;
10387
10978
  appendClickUpWebhookLocalLog(worktree, { type: "task_worktree_failed", taskId, message });
@@ -10663,7 +11254,7 @@ function clickUpListenerFingerprint({ config, state, worktree, clickupClient, op
10663
11254
  return JSON.stringify({
10664
11255
  publicUrl: config?.webhook?.publicUrl || "",
10665
11256
  path: clickUpWebhookExpectedPath(config),
10666
- worktree: path2.resolve(worktree || process.cwd()),
11257
+ worktree: path5.resolve(worktree || process.cwd()),
10667
11258
  webhookId: state?.webhookId || "",
10668
11259
  secret: state?.secret || "",
10669
11260
  events: config?.webhook?.events || [],
@@ -10760,17 +11351,17 @@ function startClickUpWebhookListener({ config, state, worktree, clickupClient, o
10760
11351
  return result;
10761
11352
  }
10762
11353
  function legacyVariantPath(destinationPath) {
10763
- const parsed = path2.parse(destinationPath);
11354
+ const parsed = path5.parse(destinationPath);
10764
11355
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[-:TZ.]/g, "").slice(0, 14);
10765
- if (parsed.ext) return path2.join(parsed.dir, `${parsed.name}.legacy-${stamp}${parsed.ext}`);
10766
- return path2.join(parsed.dir, `${parsed.base}.legacy-${stamp}`);
11356
+ if (parsed.ext) return path5.join(parsed.dir, `${parsed.name}.legacy-${stamp}${parsed.ext}`);
11357
+ return path5.join(parsed.dir, `${parsed.base}.legacy-${stamp}`);
10767
11358
  }
10768
11359
  function normalizeWorkflowTaskPath(taskPath) {
10769
11360
  if (typeof taskPath !== "string") return { ok: false, message: "Error: task_path is required." };
10770
11361
  const trimmed = taskPath.trim();
10771
11362
  if (!trimmed) return { ok: false, message: "Error: task_path is required." };
10772
11363
  const normalized = trimmed.replace(/\\/g, "/");
10773
- if (path2.isAbsolute(trimmed)) return { ok: true, taskPath: trimmed };
11364
+ if (path5.isAbsolute(trimmed)) return { ok: true, taskPath: trimmed };
10774
11365
  if (normalized === "tasks" || normalized.startsWith("tasks/")) {
10775
11366
  return {
10776
11367
  ok: false,
@@ -10786,76 +11377,80 @@ function normalizeWorkflowTaskPath(taskPath) {
10786
11377
  return { ok: true, taskPath: trimmed };
10787
11378
  }
10788
11379
  function mergeFileIntoDestination(sourcePath, destinationPath, relativeSource, gitState = null) {
11380
+ const sourceWasTracked = isGitTracked(gitState, sourcePath);
10789
11381
  if (gitAwareMoveIfTracked(sourcePath, destinationPath, gitState)) return;
10790
- if (!fs2.existsSync(destinationPath)) {
10791
- fs2.mkdirSync(path2.dirname(destinationPath), { recursive: true });
10792
- fs2.renameSync(sourcePath, destinationPath);
11382
+ if (!fs5.existsSync(destinationPath)) {
11383
+ fs5.mkdirSync(path5.dirname(destinationPath), { recursive: true });
11384
+ fs5.renameSync(sourcePath, destinationPath);
11385
+ if (sourceWasTracked) stageGitAwareMerge(sourcePath, destinationPath, gitState);
10793
11386
  return;
10794
11387
  }
10795
- const ext = path2.extname(destinationPath).toLowerCase();
11388
+ const ext = path5.extname(destinationPath).toLowerCase();
10796
11389
  if ([".yaml", ".yml", ".json"].includes(ext)) {
10797
- const sourceRaw = fs2.readFileSync(sourcePath, "utf8");
10798
- const destRaw = fs2.readFileSync(destinationPath, "utf8");
10799
- const parser = ext === ".json" ? JSON : import_yaml2.default;
11390
+ const sourceRaw = fs5.readFileSync(sourcePath, "utf8");
11391
+ const destRaw = fs5.readFileSync(destinationPath, "utf8");
11392
+ const parser = ext === ".json" ? JSON : import_yaml3.default;
10800
11393
  const sourceValue = parser.parse(sourceRaw) || {};
10801
11394
  const destValue = parser.parse(destRaw) || {};
10802
11395
  const merged = mergeStructuredValues(sourceValue, destValue);
10803
11396
  const serialized = ext === ".json" ? `${JSON.stringify(merged, null, 2)}
10804
- ` : import_yaml2.default.stringify(merged);
10805
- fs2.writeFileSync(destinationPath, serialized, "utf8");
10806
- fs2.unlinkSync(sourcePath);
11397
+ ` : import_yaml3.default.stringify(merged);
11398
+ fs5.writeFileSync(destinationPath, serialized, "utf8");
11399
+ fs5.unlinkSync(sourcePath);
10807
11400
  stageGitAwareMerge(sourcePath, destinationPath, gitState);
10808
11401
  return;
10809
11402
  }
10810
11403
  if (ext === ".md") {
10811
- const sourceRaw = fs2.readFileSync(sourcePath, "utf8").trimEnd();
10812
- const destRaw = fs2.readFileSync(destinationPath, "utf8").trimEnd();
11404
+ const sourceRaw = fs5.readFileSync(sourcePath, "utf8").trimEnd();
11405
+ const destRaw = fs5.readFileSync(destinationPath, "utf8").trimEnd();
10813
11406
  if (sourceRaw && !destRaw.includes(sourceRaw)) {
10814
11407
  const marker = `## Legacy Content From ${relativeSource}`;
10815
- fs2.writeFileSync(destinationPath, `${destRaw}
11408
+ fs5.writeFileSync(destinationPath, `${destRaw}
10816
11409
 
10817
11410
  ${marker}
10818
11411
 
10819
11412
  ${sourceRaw}
10820
11413
  `, "utf8");
10821
11414
  }
10822
- fs2.unlinkSync(sourcePath);
11415
+ fs5.unlinkSync(sourcePath);
10823
11416
  stageGitAwareMerge(sourcePath, destinationPath, gitState);
10824
11417
  return;
10825
11418
  }
10826
11419
  const preservedPath = legacyVariantPath(destinationPath);
10827
- fs2.renameSync(sourcePath, preservedPath);
11420
+ fs5.renameSync(sourcePath, preservedPath);
10828
11421
  stageGitAwareMerge(sourcePath, preservedPath, gitState);
10829
11422
  }
10830
- function mergePathIntoDestination(sourcePath, destinationPath, relativeSource = path2.basename(sourcePath), gitState = null) {
10831
- if (!fs2.existsSync(sourcePath)) return;
10832
- const stat = fs2.statSync(sourcePath);
11423
+ function mergePathIntoDestination(sourcePath, destinationPath, relativeSource = path5.basename(sourcePath), gitState = null) {
11424
+ if (!fs5.existsSync(sourcePath)) return;
11425
+ const stat = fs5.statSync(sourcePath);
10833
11426
  if (stat.isDirectory()) {
11427
+ const sourceWasTracked = isGitTracked(gitState, sourcePath) || hasGitTrackedChildren(gitState, sourcePath);
10834
11428
  if (gitAwareMoveIfTracked(sourcePath, destinationPath, gitState)) return;
10835
- if (!fs2.existsSync(destinationPath)) {
10836
- fs2.mkdirSync(path2.dirname(destinationPath), { recursive: true });
10837
- fs2.renameSync(sourcePath, destinationPath);
11429
+ if (!fs5.existsSync(destinationPath)) {
11430
+ fs5.mkdirSync(path5.dirname(destinationPath), { recursive: true });
11431
+ fs5.renameSync(sourcePath, destinationPath);
11432
+ if (sourceWasTracked) stageGitAwareMerge(sourcePath, destinationPath, gitState);
10838
11433
  return;
10839
11434
  }
10840
- fs2.mkdirSync(destinationPath, { recursive: true });
10841
- for (const entry of fs2.readdirSync(sourcePath)) {
11435
+ fs5.mkdirSync(destinationPath, { recursive: true });
11436
+ for (const entry of fs5.readdirSync(sourcePath)) {
10842
11437
  mergePathIntoDestination(
10843
- path2.join(sourcePath, entry),
10844
- path2.join(destinationPath, entry),
10845
- path2.join(relativeSource, entry),
11438
+ path5.join(sourcePath, entry),
11439
+ path5.join(destinationPath, entry),
11440
+ path5.join(relativeSource, entry),
10846
11441
  gitState
10847
11442
  );
10848
11443
  }
10849
- fs2.rmSync(sourcePath, { recursive: true, force: true });
11444
+ fs5.rmSync(sourcePath, { recursive: true, force: true });
10850
11445
  return;
10851
11446
  }
10852
11447
  mergeFileIntoDestination(sourcePath, destinationPath, relativeSource, gitState);
10853
11448
  }
10854
11449
  function isOptimaPluginPackageWorktree(worktree) {
10855
- const packageJsonPath = path2.join(worktree, "package.json");
10856
- if (!fs2.existsSync(packageJsonPath)) return false;
11450
+ const packageJsonPath = path5.join(worktree, "package.json");
11451
+ if (!fs5.existsSync(packageJsonPath)) return false;
10857
11452
  try {
10858
- const pkg = JSON.parse(fs2.readFileSync(packageJsonPath, "utf8"));
11453
+ const pkg = JSON.parse(fs5.readFileSync(packageJsonPath, "utf8"));
10859
11454
  return pkg?.name === "@defend-tech/opencode-optima";
10860
11455
  } catch {
10861
11456
  return false;
@@ -10864,59 +11459,59 @@ function isOptimaPluginPackageWorktree(worktree) {
10864
11459
  function migrateLegacyOptimaLayout(worktree) {
10865
11460
  const gitState = gitMigrationState(worktree);
10866
11461
  const migrations = [
10867
- [path2.join(legacyOrbitaDir(worktree), "orbita.yaml"), repoConfigPath(worktree), path2.join(".orbita", "orbita.yaml")],
10868
- [path2.join(legacyOrbitaDir(worktree), "staticeng.yaml"), repoConfigPath(worktree), path2.join(".orbita", "staticeng.yaml")],
10869
- [path2.join(legacyOrbitaDir(worktree), ".config"), optimaLocalConfigDir(worktree), path2.join(".orbita", ".config")],
10870
- [path2.join(legacyOrbitaDir(worktree), "config"), optimaLocalConfigDir(worktree), path2.join(".orbita", "config")],
10871
- [path2.join(legacyOrbitaDir(worktree), "runtime"), path2.join(optimaLocalConfigDir(worktree), "runtime"), path2.join(".orbita", "runtime")],
10872
- [path2.join(legacyOrbitaDir(worktree), "generated"), path2.join(optimaLocalConfigDir(worktree), "generated"), path2.join(".orbita", "generated")],
11462
+ [path5.join(legacyOrbitaDir(worktree), "orbita.yaml"), repoConfigPath(worktree), path5.join(".orbita", "orbita.yaml")],
11463
+ [path5.join(legacyOrbitaDir(worktree), "staticeng.yaml"), repoConfigPath(worktree), path5.join(".orbita", "staticeng.yaml")],
11464
+ [path5.join(legacyOrbitaDir(worktree), ".config"), optimaLocalConfigDir(worktree), path5.join(".orbita", ".config")],
11465
+ [path5.join(legacyOrbitaDir(worktree), "config"), optimaLocalConfigDir(worktree), path5.join(".orbita", "config")],
11466
+ [path5.join(legacyOrbitaDir(worktree), "runtime"), path5.join(optimaLocalConfigDir(worktree), "runtime"), path5.join(".orbita", "runtime")],
11467
+ [path5.join(legacyOrbitaDir(worktree), "generated"), path5.join(optimaLocalConfigDir(worktree), "generated"), path5.join(".orbita", "generated")],
10873
11468
  [legacyOrbitaDir(worktree), optimaDir(worktree), ".orbita"],
10874
- [path2.join(legacyStaticEngDir(worktree), "staticeng.yaml"), repoConfigPath(worktree), path2.join(".staticeng", "staticeng.yaml")],
10875
- [path2.join(legacyStaticEngDir(worktree), "orbita.yaml"), repoConfigPath(worktree), path2.join(".staticeng", "orbita.yaml")],
10876
- [path2.join(legacyStaticEngDir(worktree), ".config"), optimaLocalConfigDir(worktree), path2.join(".staticeng", ".config")],
10877
- [path2.join(legacyStaticEngDir(worktree), "config"), optimaLocalConfigDir(worktree), path2.join(".staticeng", "config")],
10878
- [path2.join(legacyStaticEngDir(worktree), "runtime"), path2.join(optimaLocalConfigDir(worktree), "runtime"), path2.join(".staticeng", "runtime")],
10879
- [path2.join(legacyStaticEngDir(worktree), "generated"), path2.join(optimaLocalConfigDir(worktree), "generated"), path2.join(".staticeng", "generated")],
11469
+ [path5.join(legacyStaticEngDir(worktree), "staticeng.yaml"), repoConfigPath(worktree), path5.join(".staticeng", "staticeng.yaml")],
11470
+ [path5.join(legacyStaticEngDir(worktree), "orbita.yaml"), repoConfigPath(worktree), path5.join(".staticeng", "orbita.yaml")],
11471
+ [path5.join(legacyStaticEngDir(worktree), ".config"), optimaLocalConfigDir(worktree), path5.join(".staticeng", ".config")],
11472
+ [path5.join(legacyStaticEngDir(worktree), "config"), optimaLocalConfigDir(worktree), path5.join(".staticeng", "config")],
11473
+ [path5.join(legacyStaticEngDir(worktree), "runtime"), path5.join(optimaLocalConfigDir(worktree), "runtime"), path5.join(".staticeng", "runtime")],
11474
+ [path5.join(legacyStaticEngDir(worktree), "generated"), path5.join(optimaLocalConfigDir(worktree), "generated"), path5.join(".staticeng", "generated")],
10880
11475
  [legacyStaticEngDir(worktree), optimaDir(worktree), ".staticeng"],
10881
- [path2.join(legacyNomadworkDir(worktree), "nomadworks.yaml"), repoConfigPath(worktree), path2.join(".nomadwork", "nomadworks.yaml")],
10882
- [path2.join(legacyNomadworksDir(worktree), "nomadworks.yaml"), repoConfigPath(worktree), path2.join(".nomadworks", "nomadworks.yaml")],
10883
- [path2.join(legacyNomadworkDir(worktree), "staticeng.yaml"), repoConfigPath(worktree), path2.join(".nomadwork", "staticeng.yaml")],
10884
- [path2.join(legacyNomadworksDir(worktree), "staticeng.yaml"), repoConfigPath(worktree), path2.join(".nomadworks", "staticeng.yaml")],
10885
- [path2.join(legacyNomadworkDir(worktree), "orbita.yaml"), repoConfigPath(worktree), path2.join(".nomadwork", "orbita.yaml")],
10886
- [path2.join(legacyNomadworksDir(worktree), "orbita.yaml"), repoConfigPath(worktree), path2.join(".nomadworks", "orbita.yaml")],
10887
- [path2.join(legacyNomadworkDir(worktree), "runtime"), path2.join(optimaLocalConfigDir(worktree), "runtime"), path2.join(".nomadwork", "runtime")],
10888
- [path2.join(legacyNomadworksDir(worktree), "runtime"), path2.join(optimaLocalConfigDir(worktree), "runtime"), path2.join(".nomadworks", "runtime")],
10889
- [path2.join(legacyNomadworkDir(worktree), "generated"), path2.join(optimaLocalConfigDir(worktree), "generated"), path2.join(".nomadwork", "generated")],
10890
- [path2.join(legacyNomadworksDir(worktree), "generated"), path2.join(optimaLocalConfigDir(worktree), "generated"), path2.join(".nomadworks", "generated")],
10891
- [path2.join(legacyNomadworkDir(worktree), "config"), optimaLocalConfigDir(worktree), path2.join(".nomadwork", "config")],
10892
- [path2.join(legacyNomadworksDir(worktree), "config"), optimaLocalConfigDir(worktree), path2.join(".nomadworks", "config")],
11476
+ [path5.join(legacyNomadworkDir(worktree), "nomadworks.yaml"), repoConfigPath(worktree), path5.join(".nomadwork", "nomadworks.yaml")],
11477
+ [path5.join(legacyNomadworksDir(worktree), "nomadworks.yaml"), repoConfigPath(worktree), path5.join(".nomadworks", "nomadworks.yaml")],
11478
+ [path5.join(legacyNomadworkDir(worktree), "staticeng.yaml"), repoConfigPath(worktree), path5.join(".nomadwork", "staticeng.yaml")],
11479
+ [path5.join(legacyNomadworksDir(worktree), "staticeng.yaml"), repoConfigPath(worktree), path5.join(".nomadworks", "staticeng.yaml")],
11480
+ [path5.join(legacyNomadworkDir(worktree), "orbita.yaml"), repoConfigPath(worktree), path5.join(".nomadwork", "orbita.yaml")],
11481
+ [path5.join(legacyNomadworksDir(worktree), "orbita.yaml"), repoConfigPath(worktree), path5.join(".nomadworks", "orbita.yaml")],
11482
+ [path5.join(legacyNomadworkDir(worktree), "runtime"), path5.join(optimaLocalConfigDir(worktree), "runtime"), path5.join(".nomadwork", "runtime")],
11483
+ [path5.join(legacyNomadworksDir(worktree), "runtime"), path5.join(optimaLocalConfigDir(worktree), "runtime"), path5.join(".nomadworks", "runtime")],
11484
+ [path5.join(legacyNomadworkDir(worktree), "generated"), path5.join(optimaLocalConfigDir(worktree), "generated"), path5.join(".nomadwork", "generated")],
11485
+ [path5.join(legacyNomadworksDir(worktree), "generated"), path5.join(optimaLocalConfigDir(worktree), "generated"), path5.join(".nomadworks", "generated")],
11486
+ [path5.join(legacyNomadworkDir(worktree), "config"), optimaLocalConfigDir(worktree), path5.join(".nomadwork", "config")],
11487
+ [path5.join(legacyNomadworksDir(worktree), "config"), optimaLocalConfigDir(worktree), path5.join(".nomadworks", "config")],
10893
11488
  [legacyNomadworkDir(worktree), optimaDir(worktree), ".nomadwork"],
10894
11489
  [legacyNomadworksDir(worktree), optimaDir(worktree), ".nomadworks"],
10895
- [path2.join(worktree, "tasks"), optimaTasksDir(worktree), "tasks"],
10896
- [path2.join(worktree, "evidences"), optimaEvidencesDir(worktree), "evidences"],
10897
- [path2.join(worktree, "docs", "scrs"), optimaScrsDir(worktree), path2.join("docs", "scrs")],
10898
- [path2.join(worktree, "codemap.yml"), optimaCodemapPath(worktree), "codemap.yml"],
10899
- [path2.join(worktree, "codemap.yaml"), optimaCodemapPath(worktree), "codemap.yaml"]
11490
+ [path5.join(worktree, "tasks"), optimaTasksDir(worktree), "tasks"],
11491
+ [path5.join(worktree, "evidences"), optimaEvidencesDir(worktree), "evidences"],
11492
+ [path5.join(worktree, "docs", "scrs"), optimaScrsDir(worktree), path5.join("docs", "scrs")],
11493
+ [path5.join(worktree, "codemap.yml"), optimaCodemapPath(worktree), "codemap.yml"],
11494
+ [path5.join(worktree, "codemap.yaml"), optimaCodemapPath(worktree), "codemap.yaml"]
10900
11495
  ];
10901
11496
  if (!isOptimaPluginPackageWorktree(worktree)) {
10902
- migrations.push([path2.join(worktree, "policies"), repoPoliciesDir(worktree), "policies"]);
11497
+ migrations.push([path5.join(worktree, "policies"), repoPoliciesDir(worktree), "policies"]);
10903
11498
  }
10904
11499
  for (const [source, destination, relativeSource] of migrations) {
10905
- if (fs2.existsSync(source)) mergePathIntoDestination(source, destination, relativeSource, gitState);
11500
+ if (fs5.existsSync(source)) mergePathIntoDestination(source, destination, relativeSource, gitState);
10906
11501
  }
10907
11502
  for (const [source, destination, relativeSource] of [
10908
- [path2.join(optimaDir(worktree), "optima.yaml"), repoConfigPath(worktree), path2.join(".optima", "optima.yaml")],
10909
- [path2.join(optimaDir(worktree), "config"), optimaLocalConfigDir(worktree), path2.join(".optima", "config")],
10910
- [path2.join(optimaDir(worktree), "runtime"), path2.join(optimaLocalConfigDir(worktree), "runtime"), path2.join(".optima", "runtime")],
10911
- [path2.join(optimaDir(worktree), "generated"), path2.join(optimaLocalConfigDir(worktree), "generated"), path2.join(".optima", "generated")]
11503
+ [path5.join(optimaDir(worktree), "optima.yaml"), repoConfigPath(worktree), path5.join(".optima", "optima.yaml")],
11504
+ [path5.join(optimaDir(worktree), "config"), optimaLocalConfigDir(worktree), path5.join(".optima", "config")],
11505
+ [path5.join(optimaDir(worktree), "runtime"), path5.join(optimaLocalConfigDir(worktree), "runtime"), path5.join(".optima", "runtime")],
11506
+ [path5.join(optimaDir(worktree), "generated"), path5.join(optimaLocalConfigDir(worktree), "generated"), path5.join(".optima", "generated")]
10912
11507
  ]) {
10913
- if (fs2.existsSync(source)) mergePathIntoDestination(source, destination, relativeSource, gitState);
11508
+ if (fs5.existsSync(source)) mergePathIntoDestination(source, destination, relativeSource, gitState);
10914
11509
  }
10915
11510
  }
10916
11511
  function listMarkdownFiles(dirPath) {
10917
- if (!fs2.existsSync(dirPath)) return [];
11512
+ if (!fs5.existsSync(dirPath)) return [];
10918
11513
  try {
10919
- return fs2.readdirSync(dirPath).filter((file) => file.endsWith(".md") && file.toLowerCase() !== "readme.md");
11514
+ return fs5.readdirSync(dirPath).filter((file) => file.endsWith(".md") && file.toLowerCase() !== "readme.md");
10920
11515
  } catch (e) {
10921
11516
  console.error(`[Optima] Failed to read markdown files from ${dirPath}:`, e);
10922
11517
  return [];
@@ -10926,67 +11521,6 @@ function normalizePolicyExtraction(value) {
10926
11521
  if (typeof value !== "string") return "none";
10927
11522
  return value.trim().toLowerCase() === "all" ? "all" : "none";
10928
11523
  }
10929
- function resolveIncludeFile(includeRef, repoRoot, bundleRoot, options = {}) {
10930
- const trimmed = includeRef.trim();
10931
- const scopedMatch = trimmed.match(/^([a-z]+):(.*)$/i);
10932
- const scope = scopedMatch?.[1]?.toLowerCase();
10933
- const target = scopedMatch ? scopedMatch[2].trim() : trimmed;
10934
- const resolveRelative = (baseDir, relativePath) => {
10935
- if (!relativePath) return null;
10936
- return path2.isAbsolute(relativePath) ? relativePath : path2.join(baseDir, relativePath);
10937
- };
10938
- const withCompactPreference = (paths) => {
10939
- if (!options.preferCompactPromptDocs) return paths;
10940
- const compactPaths = paths.map((filePath) => filePath ? compactPromptPath(filePath) : null).filter(Boolean);
10941
- return [...compactPaths, ...paths];
10942
- };
10943
- if (scope === "plugin") {
10944
- for (const filePath of withCompactPreference([resolveRelative(bundleRoot, target)])) {
10945
- if (filePath && fs2.existsSync(filePath)) return filePath;
10946
- }
10947
- return null;
10948
- }
10949
- if (scope === "repo") {
10950
- for (const filePath of withCompactPreference([resolveRelative(optimaDir(repoRoot), target)])) {
10951
- if (filePath && fs2.existsSync(filePath)) return filePath;
10952
- }
10953
- return null;
10954
- }
10955
- if (scope === "policy") {
10956
- const candidates2 = withCompactPreference([
10957
- resolveRelative(repoPoliciesDir(repoRoot), target),
10958
- resolveRelative(BUNDLE_POLICIES_DIR, target)
10959
- ]);
10960
- for (const filePath of candidates2) {
10961
- if (filePath && fs2.existsSync(filePath)) return filePath;
10962
- }
10963
- return null;
10964
- }
10965
- const candidates = withCompactPreference([
10966
- resolveRelative(repoRoot, target),
10967
- resolveRelative(bundleRoot, target)
10968
- ]);
10969
- for (const filePath of candidates) {
10970
- if (filePath && fs2.existsSync(filePath)) return filePath;
10971
- }
10972
- return null;
10973
- }
10974
- function resolveIncludes(text, repoRoot, bundleRoot, options = {}) {
10975
- const includeRegex = /<include:(.*?)>/g;
10976
- return text.replace(includeRegex, (match, includeRef) => {
10977
- const filePath = resolveIncludeFile(includeRef, repoRoot, bundleRoot, options);
10978
- if (!filePath) {
10979
- console.warn(`[Optima] Include file not found: ${includeRef}`);
10980
- return `
10981
-
10982
- # ERROR: Include file not found: ${includeRef}
10983
-
10984
- `;
10985
- }
10986
- const content = fs2.readFileSync(filePath, "utf8");
10987
- return resolveIncludes(content, repoRoot, bundleRoot, options);
10988
- });
10989
- }
10990
11524
  function parseFrontmatter(mdText) {
10991
11525
  const lines = mdText.split(/\r?\n/);
10992
11526
  if (lines[0]?.trim() !== "---") return { data: {}, body: mdText };
@@ -11001,7 +11535,7 @@ function parseFrontmatter(mdText) {
11001
11535
  const fmText = lines.slice(1, end).join("\n");
11002
11536
  const body = lines.slice(end + 1).join("\n");
11003
11537
  try {
11004
- return { data: import_yaml2.default.parse(fmText) || {}, body };
11538
+ return { data: import_yaml3.default.parse(fmText) || {}, body };
11005
11539
  } catch {
11006
11540
  return { data: {}, body };
11007
11541
  }
@@ -11018,10 +11552,10 @@ function toModelString(provider, model) {
11018
11552
  }
11019
11553
  function readTaskMetadata(taskPath, worktree) {
11020
11554
  if (!taskPath) return {};
11021
- const absoluteTaskPath = path2.isAbsolute(taskPath) ? taskPath : path2.join(worktree, taskPath);
11022
- if (!fs2.existsSync(absoluteTaskPath)) return {};
11555
+ const absoluteTaskPath = path5.isAbsolute(taskPath) ? taskPath : path5.join(worktree, taskPath);
11556
+ if (!fs5.existsSync(absoluteTaskPath)) return {};
11023
11557
  try {
11024
- const raw = fs2.readFileSync(absoluteTaskPath, "utf8");
11558
+ const raw = fs5.readFileSync(absoluteTaskPath, "utf8");
11025
11559
  const { data } = parseFrontmatter(raw);
11026
11560
  return {
11027
11561
  complexity: typeof data.complexity === "string" ? data.complexity.trim().toLowerCase() : void 0,
@@ -11046,11 +11580,11 @@ function slugifyTitle(input) {
11046
11580
  }
11047
11581
  function loadDiscussionRegistry(worktree) {
11048
11582
  const registryPath = runtimeDiscussionRegistryPath(worktree);
11049
- if (!fs2.existsSync(registryPath)) {
11583
+ if (!fs5.existsSync(registryPath)) {
11050
11584
  return { version: 1, active: {} };
11051
11585
  }
11052
11586
  try {
11053
- const parsed = JSON.parse(fs2.readFileSync(registryPath, "utf8"));
11587
+ const parsed = JSON.parse(fs5.readFileSync(registryPath, "utf8"));
11054
11588
  const registry = {
11055
11589
  version: 1,
11056
11590
  active: Object.fromEntries(Object.entries(parsed.active || {}).map(([key, value]) => [key, normalizeLegacyDiscussionEntry(value)]))
@@ -11063,34 +11597,34 @@ function loadDiscussionRegistry(worktree) {
11063
11597
  }
11064
11598
  function saveDiscussionRegistry(worktree, registry) {
11065
11599
  const registryPath = runtimeDiscussionRegistryPath(worktree);
11066
- const runtimeDir = path2.dirname(registryPath);
11067
- if (!fs2.existsSync(runtimeDir)) fs2.mkdirSync(runtimeDir, { recursive: true });
11068
- fs2.writeFileSync(registryPath, JSON.stringify(registry, null, 2), "utf8");
11600
+ const runtimeDir = path5.dirname(registryPath);
11601
+ if (!fs5.existsSync(runtimeDir)) fs5.mkdirSync(runtimeDir, { recursive: true });
11602
+ fs5.writeFileSync(registryPath, JSON.stringify(registry, null, 2), "utf8");
11069
11603
  }
11070
11604
  function runtimeDiscussionsDir(worktree) {
11071
- return path2.join(optimaLocalConfigDir(worktree), "runtime", "discussions");
11605
+ return path5.join(optimaLocalConfigDir(worktree), "runtime", "discussions");
11072
11606
  }
11073
11607
  function archivedRuntimeDiscussionsDir(worktree) {
11074
- return path2.join(runtimeDiscussionsDir(worktree), "archive");
11608
+ return path5.join(runtimeDiscussionsDir(worktree), "archive");
11075
11609
  }
11076
11610
  function finalDiscussionsDir(worktree) {
11077
- return path2.join(optimaTasksDir(worktree), "discussions");
11611
+ return path5.join(optimaTasksDir(worktree), "discussions");
11078
11612
  }
11079
11613
  function nextDiscussionIdentity(worktree, title) {
11080
11614
  const discussionsDir = finalDiscussionsDir(worktree);
11081
11615
  const runtimeDir = runtimeDiscussionsDir(worktree);
11082
- if (!fs2.existsSync(discussionsDir)) fs2.mkdirSync(discussionsDir, { recursive: true });
11083
- if (!fs2.existsSync(runtimeDir)) fs2.mkdirSync(runtimeDir, { recursive: true });
11616
+ if (!fs5.existsSync(discussionsDir)) fs5.mkdirSync(discussionsDir, { recursive: true });
11617
+ if (!fs5.existsSync(runtimeDir)) fs5.mkdirSync(runtimeDir, { recursive: true });
11084
11618
  let sequence = 1;
11085
11619
  while (true) {
11086
11620
  const id = `DISCUSSION-${String(sequence).padStart(3, "0")}`;
11087
11621
  const filename = `${id}-${slugifyTitle(title)}.md`;
11088
- const summaryRelativePath = path2.join(".optima", "tasks", "discussions", filename);
11089
- const summaryAbsolutePath = path2.join(worktree, summaryRelativePath);
11622
+ const summaryRelativePath = path5.join(".optima", "tasks", "discussions", filename);
11623
+ const summaryAbsolutePath = path5.join(worktree, summaryRelativePath);
11090
11624
  const transcriptFilename = `${id}-transcript.md`;
11091
- const transcriptRelativePath = path2.join(".optima", ".config", "runtime", "discussions", transcriptFilename);
11092
- const transcriptAbsolutePath = path2.join(worktree, transcriptRelativePath);
11093
- if (!fs2.existsSync(summaryAbsolutePath) && !fs2.existsSync(transcriptAbsolutePath)) {
11625
+ const transcriptRelativePath = path5.join(".optima", ".config", "runtime", "discussions", transcriptFilename);
11626
+ const transcriptAbsolutePath = path5.join(worktree, transcriptRelativePath);
11627
+ if (!fs5.existsSync(summaryAbsolutePath) && !fs5.existsSync(transcriptAbsolutePath)) {
11094
11628
  return {
11095
11629
  id,
11096
11630
  filename,
@@ -11106,37 +11640,37 @@ function nextDiscussionIdentity(worktree, title) {
11106
11640
  }
11107
11641
  function findDiscussionById(worktree, discussionID) {
11108
11642
  const discussionsDir = finalDiscussionsDir(worktree);
11109
- if (!fs2.existsSync(discussionsDir)) return null;
11110
- const entries = fs2.readdirSync(discussionsDir).filter((name) => name.startsWith(`${discussionID}-`) && name.endsWith(".md"));
11643
+ if (!fs5.existsSync(discussionsDir)) return null;
11644
+ const entries = fs5.readdirSync(discussionsDir).filter((name) => name.startsWith(`${discussionID}-`) && name.endsWith(".md"));
11111
11645
  if (entries.length === 0) return null;
11112
11646
  const filename = entries.sort()[0];
11113
11647
  const transcriptFilename = `${discussionID}-transcript.md`;
11114
11648
  return {
11115
11649
  id: discussionID,
11116
11650
  filename,
11117
- summaryRelativePath: path2.join(".optima", "tasks", "discussions", filename),
11118
- summaryAbsolutePath: path2.join(discussionsDir, filename),
11651
+ summaryRelativePath: path5.join(".optima", "tasks", "discussions", filename),
11652
+ summaryAbsolutePath: path5.join(discussionsDir, filename),
11119
11653
  transcriptFilename,
11120
- transcriptRelativePath: path2.join(".optima", ".config", "runtime", "discussions", transcriptFilename),
11121
- transcriptAbsolutePath: path2.join(runtimeDiscussionsDir(worktree), transcriptFilename)
11654
+ transcriptRelativePath: path5.join(".optima", ".config", "runtime", "discussions", transcriptFilename),
11655
+ transcriptAbsolutePath: path5.join(runtimeDiscussionsDir(worktree), transcriptFilename)
11122
11656
  };
11123
11657
  }
11124
11658
  function parseDiscussionFile(filePath) {
11125
- const raw = fs2.readFileSync(filePath, "utf8");
11659
+ const raw = fs5.readFileSync(filePath, "utf8");
11126
11660
  const { data, body } = parseFrontmatter(raw);
11127
11661
  return { data, body: body.trimStart() };
11128
11662
  }
11129
11663
  function writeDiscussionFile(filePath, frontmatter, body) {
11130
11664
  const serialized = `---
11131
- ${import_yaml2.default.stringify(frontmatter).trim()}
11665
+ ${import_yaml3.default.stringify(frontmatter).trim()}
11132
11666
  ---
11133
11667
 
11134
11668
  ${body.trimEnd()}
11135
11669
  `;
11136
- fs2.writeFileSync(filePath, serialized, "utf8");
11670
+ fs5.writeFileSync(filePath, serialized, "utf8");
11137
11671
  }
11138
11672
  function setDiscussionStatus(filePath, status) {
11139
- if (!fs2.existsSync(filePath)) return;
11673
+ if (!fs5.existsSync(filePath)) return;
11140
11674
  const { data, body } = parseDiscussionFile(filePath);
11141
11675
  writeDiscussionFile(filePath, { ...data, status }, body);
11142
11676
  }
@@ -11201,18 +11735,18 @@ async function appendMessageIfNeeded(client, worktree, registry, sessionID, mess
11201
11735
  });
11202
11736
  const text = extractTextParts(response.data.parts || []);
11203
11737
  if (!text) return;
11204
- appendDiscussionMessage(path2.join(worktree, discussion.transcriptPath), speaker, text, messageID);
11738
+ appendDiscussionMessage(path5.join(worktree, discussion.transcriptPath), speaker, text, messageID);
11205
11739
  discussion.appendedMessageIDs ??= [];
11206
11740
  discussion.appendedMessageIDs.push(messageID);
11207
11741
  saveDiscussionRegistry(worktree, registry);
11208
11742
  }
11209
11743
  async function summarizeDiscussionWithBA(client, worktree, discussion) {
11210
- const transcriptPath = path2.join(worktree, discussion.transcriptPath);
11211
- const summaryPath = path2.join(worktree, discussion.summaryPath);
11212
- const summaryDir = path2.dirname(summaryPath);
11213
- if (!fs2.existsSync(summaryDir)) fs2.mkdirSync(summaryDir, { recursive: true });
11214
- const hasExistingSummary = fs2.existsSync(summaryPath);
11215
- const priorMtimeMs = hasExistingSummary ? fs2.statSync(summaryPath).mtimeMs : null;
11744
+ const transcriptPath = path5.join(worktree, discussion.transcriptPath);
11745
+ const summaryPath = path5.join(worktree, discussion.summaryPath);
11746
+ const summaryDir = path5.dirname(summaryPath);
11747
+ if (!fs5.existsSync(summaryDir)) fs5.mkdirSync(summaryDir, { recursive: true });
11748
+ const hasExistingSummary = fs5.existsSync(summaryPath);
11749
+ const priorMtimeMs = hasExistingSummary ? fs5.statSync(summaryPath).mtimeMs : null;
11216
11750
  const summarizerSession = await client.session.create({
11217
11751
  body: { title: `Discussion Summary: ${discussion.id}` }
11218
11752
  });
@@ -11312,30 +11846,30 @@ async function summarizeDiscussionWithBA(client, worktree, discussion) {
11312
11846
  return { confirmation, summaryPath, transcriptPath, hasExistingSummary, priorMtimeMs };
11313
11847
  }
11314
11848
  function archiveDiscussionTranscript(worktree, transcriptRelativePath) {
11315
- const sourcePath = path2.join(worktree, transcriptRelativePath);
11316
- if (!fs2.existsSync(sourcePath)) return null;
11849
+ const sourcePath = path5.join(worktree, transcriptRelativePath);
11850
+ if (!fs5.existsSync(sourcePath)) return null;
11317
11851
  const archiveDir = archivedRuntimeDiscussionsDir(worktree);
11318
- if (!fs2.existsSync(archiveDir)) fs2.mkdirSync(archiveDir, { recursive: true });
11319
- const targetPath = path2.join(archiveDir, path2.basename(sourcePath));
11320
- fs2.renameSync(sourcePath, targetPath);
11852
+ if (!fs5.existsSync(archiveDir)) fs5.mkdirSync(archiveDir, { recursive: true });
11853
+ const targetPath = path5.join(archiveDir, path5.basename(sourcePath));
11854
+ fs5.renameSync(sourcePath, targetPath);
11321
11855
  return targetPath;
11322
11856
  }
11323
11857
  async function finalizeClosingDiscussion(client, worktree, registry, sessionID, discussion) {
11324
11858
  const { confirmation, summaryPath, hasExistingSummary, priorMtimeMs } = await summarizeDiscussionWithBA(client, worktree, discussion);
11325
- if (!fs2.existsSync(summaryPath)) {
11859
+ if (!fs5.existsSync(summaryPath)) {
11326
11860
  throw new Error(`Discussion summary was not written to ${discussion.summaryPath}`);
11327
11861
  }
11328
11862
  if (hasExistingSummary) {
11329
- const currentMtimeMs = fs2.statSync(summaryPath).mtimeMs;
11863
+ const currentMtimeMs = fs5.statSync(summaryPath).mtimeMs;
11330
11864
  if (currentMtimeMs <= priorMtimeMs) {
11331
11865
  throw new Error(`Discussion summary file was not updated at ${discussion.summaryPath}`);
11332
11866
  }
11333
11867
  }
11334
- const summaryContent = fs2.readFileSync(summaryPath, "utf8").trim();
11868
+ const summaryContent = fs5.readFileSync(summaryPath, "utf8").trim();
11335
11869
  if (!summaryContent) {
11336
11870
  throw new Error(`Discussion summary file is empty at ${discussion.summaryPath}`);
11337
11871
  }
11338
- const transcriptPath = path2.join(worktree, discussion.transcriptPath);
11872
+ const transcriptPath = path5.join(worktree, discussion.transcriptPath);
11339
11873
  setDiscussionStatus(transcriptPath, "closed");
11340
11874
  const archivedTranscriptPath = archiveDiscussionTranscript(worktree, discussion.transcriptPath);
11341
11875
  delete registry.active[sessionID];
@@ -11343,7 +11877,7 @@ async function finalizeClosingDiscussion(client, worktree, registry, sessionID,
11343
11877
  return {
11344
11878
  confirmation,
11345
11879
  summaryPath: discussion.summaryPath,
11346
- archivedTranscriptPath: archivedTranscriptPath ? path2.relative(worktree, archivedTranscriptPath) : path2.join(".optima", ".config", "runtime", "discussions", "archive", path2.basename(discussion.transcriptPath))
11880
+ archivedTranscriptPath: archivedTranscriptPath ? path5.relative(worktree, archivedTranscriptPath) : path5.join(".optima", ".config", "runtime", "discussions", "archive", path5.basename(discussion.transcriptPath))
11347
11881
  };
11348
11882
  }
11349
11883
  function normalizeTeamMode(value) {
@@ -11382,13 +11916,13 @@ function getOperatingTeamMode(repoCfg) {
11382
11916
  }
11383
11917
  function readResolvedFile(relativePath, worktree, options = {}) {
11384
11918
  const filePath = resolveIncludeFile(`plugin:${relativePath}`, worktree, PKG_ROOT, options);
11385
- if (!filePath || !fs2.existsSync(filePath)) return "";
11386
- return resolveIncludes(fs2.readFileSync(filePath, "utf8"), worktree, PKG_ROOT, options).trim();
11919
+ if (!filePath || !fs5.existsSync(filePath)) return "";
11920
+ return resolveIncludes(fs5.readFileSync(filePath, "utf8"), worktree, PKG_ROOT, options).trim();
11387
11921
  }
11388
11922
  function loadMarkdownFragment(filePath, worktree) {
11389
- if (!fs2.existsSync(filePath)) return "";
11923
+ if (!fs5.existsSync(filePath)) return "";
11390
11924
  try {
11391
- const raw = fs2.readFileSync(filePath, "utf8");
11925
+ const raw = fs5.readFileSync(filePath, "utf8");
11392
11926
  const { body } = parseFrontmatter(raw);
11393
11927
  return resolveIncludes(body.trim(), worktree, PKG_ROOT);
11394
11928
  } catch (e) {
@@ -11397,9 +11931,9 @@ function loadMarkdownFragment(filePath, worktree) {
11397
11931
  }
11398
11932
  }
11399
11933
  function loadAgentDefinition(filePath, worktree, options = {}) {
11400
- if (!fs2.existsSync(filePath)) return null;
11934
+ if (!fs5.existsSync(filePath)) return null;
11401
11935
  try {
11402
- const rawContent = fs2.readFileSync(filePath, "utf8");
11936
+ const rawContent = fs5.readFileSync(filePath, "utf8");
11403
11937
  const { data, body } = parseFrontmatter(rawContent);
11404
11938
  const prompt = resolveIncludes(body.trim(), worktree, PKG_ROOT, options);
11405
11939
  return { data, prompt };
@@ -11410,13 +11944,13 @@ function loadAgentDefinition(filePath, worktree, options = {}) {
11410
11944
  }
11411
11945
  function syncGeneratedPolicies(worktree, repoCfg) {
11412
11946
  if (repoCfg.policies?.extract_defaults !== "all") return;
11413
- if (!fs2.existsSync(BUNDLE_POLICIES_DIR)) return;
11947
+ if (!fs5.existsSync(BUNDLE_POLICIES_DIR)) return;
11414
11948
  const generatedDir = generatedPoliciesDir(worktree);
11415
- if (!fs2.existsSync(generatedDir)) fs2.mkdirSync(generatedDir, { recursive: true });
11416
- const policyFiles = fs2.readdirSync(BUNDLE_POLICIES_DIR).filter((file) => file.endsWith(".md") && file !== "README.md");
11949
+ if (!fs5.existsSync(generatedDir)) fs5.mkdirSync(generatedDir, { recursive: true });
11950
+ const policyFiles = fs5.readdirSync(BUNDLE_POLICIES_DIR).filter((file) => file.endsWith(".md") && file !== "README.md");
11417
11951
  for (const file of policyFiles) {
11418
- const sourcePath = path2.join(BUNDLE_POLICIES_DIR, file);
11419
- const source = fs2.readFileSync(sourcePath, "utf8").trimEnd();
11952
+ const sourcePath = path5.join(BUNDLE_POLICIES_DIR, file);
11953
+ const source = fs5.readFileSync(sourcePath, "utf8").trimEnd();
11420
11954
  const generated = [
11421
11955
  "<!--",
11422
11956
  "Generated from Optima plugin defaults.",
@@ -11427,19 +11961,31 @@ function syncGeneratedPolicies(worktree, repoCfg) {
11427
11961
  source,
11428
11962
  ""
11429
11963
  ].join("\n");
11430
- fs2.writeFileSync(path2.join(generatedDir, file), generated, "utf8");
11964
+ fs5.writeFileSync(path5.join(generatedDir, file), generated, "utf8");
11431
11965
  }
11432
11966
  }
11433
11967
  function ensureReadmeFile(dirPath, content) {
11434
- if (!fs2.existsSync(dirPath)) fs2.mkdirSync(dirPath, { recursive: true });
11435
- const readmePath = path2.join(dirPath, "README.md");
11436
- if (!fs2.existsSync(readmePath)) {
11437
- fs2.writeFileSync(readmePath, content, "utf8");
11968
+ if (!fs5.existsSync(dirPath)) fs5.mkdirSync(dirPath, { recursive: true });
11969
+ const readmePath = path5.join(dirPath, "README.md");
11970
+ if (!fs5.existsSync(readmePath)) {
11971
+ fs5.writeFileSync(readmePath, content, "utf8");
11438
11972
  }
11439
11973
  }
11440
11974
  function ensureFileIfMissing(filePath, content) {
11441
- if (!fs2.existsSync(path2.dirname(filePath))) fs2.mkdirSync(path2.dirname(filePath), { recursive: true });
11442
- if (!fs2.existsSync(filePath)) fs2.writeFileSync(filePath, content, "utf8");
11975
+ if (!fs5.existsSync(path5.dirname(filePath))) fs5.mkdirSync(path5.dirname(filePath), { recursive: true });
11976
+ if (!fs5.existsSync(filePath)) fs5.writeFileSync(filePath, content, "utf8");
11977
+ }
11978
+ function currentTasksRegistryContent() {
11979
+ 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";
11980
+ }
11981
+ function doneTasksRegistryContent() {
11982
+ return "# Completed Tasks (Registry)\n\n| Date | Task ID | SCR ID | Commit | Summary |\n| :--- | :--- | :--- | :--- | :--- |\n";
11983
+ }
11984
+ function currentScrRegistryContent() {
11985
+ return "# Current Spec Change Requests (Backlog)\n\n## \u{1F680} Active/Review\n- (None)\n\n## \u{1F4CB} Approved (Ready for Implementation)\n- (None)\n\n## \u{1F4A1} Proposed\n- (None)\n";
11986
+ }
11987
+ function doneScrRegistryContent() {
11988
+ return "# Implemented Spec Change Requests\n\n| Date | SCR ID | Title | Related Feature | Task ID |\n| :--- | :--- | :--- | :--- | :--- |\n";
11443
11989
  }
11444
11990
  function taskTemplateContent() {
11445
11991
  return `---
@@ -11513,19 +12059,58 @@ Never place implementation evidence under root \`evidences/\`.
11513
12059
  }
11514
12060
  function ensureOptimaTaskTemplates(worktree) {
11515
12061
  const tasksDir = optimaTasksDir(worktree);
11516
- ensureFileIfMissing(path2.join(tasksDir, "task-template.md"), taskTemplateContent());
11517
- ensureFileIfMissing(path2.join(tasksDir, "subtask-template.md"), subtaskTemplateContent());
12062
+ ensureFileIfMissing(path5.join(tasksDir, "task-template.md"), taskTemplateContent());
12063
+ ensureFileIfMissing(path5.join(tasksDir, "subtask-template.md"), subtaskTemplateContent());
12064
+ }
12065
+ function scaffoldOptimaConfig(worktree, teamMode = "full") {
12066
+ const configPath = repoConfigPath(worktree);
12067
+ if (fs5.existsSync(configPath)) return false;
12068
+ const templatePath = path5.join(TEMPLATES_DIR, "optima.yaml.template");
12069
+ if (!fs5.existsSync(templatePath)) return false;
12070
+ const agentIds = fs5.existsSync(BUNDLE_AGENTS_DIR) ? fs5.readdirSync(BUNDLE_AGENTS_DIR).filter((f) => f.endsWith(".md")).map((f) => f.replace(".md", "")) : [];
12071
+ let optimaConfig = fs5.readFileSync(templatePath, "utf8");
12072
+ optimaConfig = optimaConfig.replace("{{teamMode}}", normalizeTeamMode(teamMode));
12073
+ let agentsSection = "";
12074
+ for (const id of agentIds) {
12075
+ const enabled = isAgentEnabledForTeamMode(id, normalizeTeamMode(teamMode)) ? "true" : "false";
12076
+ agentsSection += ` ${id}:
12077
+ enabled: ${enabled}
12078
+ `;
12079
+ }
12080
+ optimaConfig = optimaConfig.replace(/^agents:/m, "agents:\n" + agentsSection);
12081
+ ensureFileIfMissing(configPath, optimaConfig);
12082
+ return fs5.existsSync(configPath);
12083
+ }
12084
+ function scaffoldOptimaRootCodemap(worktree) {
12085
+ const rootCodemapPath = optimaCodemapPath(worktree);
12086
+ if (fs5.existsSync(rootCodemapPath)) return false;
12087
+ const templatePath = path5.join(TEMPLATES_DIR, "codemap.yml.template");
12088
+ if (!fs5.existsSync(templatePath)) return false;
12089
+ const codemapConfig = fs5.readFileSync(templatePath, "utf8").replace("{{projectName}}", path5.basename(worktree));
12090
+ ensureFileIfMissing(rootCodemapPath, codemapConfig);
12091
+ return fs5.existsSync(rootCodemapPath);
12092
+ }
12093
+ function ensureOptimaRegistries(worktree) {
12094
+ const tasksDir = optimaTasksDir(worktree);
12095
+ const scrsDir = optimaScrsDir(worktree);
12096
+ if (!fs5.existsSync(tasksDir)) fs5.mkdirSync(tasksDir, { recursive: true });
12097
+ if (!fs5.existsSync(scrsDir)) fs5.mkdirSync(scrsDir, { recursive: true });
12098
+ ensureFileIfMissing(path5.join(tasksDir, "current.md"), currentTasksRegistryContent());
12099
+ ensureFileIfMissing(path5.join(tasksDir, "done.md"), doneTasksRegistryContent());
12100
+ ensureFileIfMissing(path5.join(scrsDir, "current.md"), currentScrRegistryContent());
12101
+ ensureFileIfMissing(path5.join(scrsDir, "done.md"), doneScrRegistryContent());
11518
12102
  }
11519
12103
  function scaffoldOptimaReadmes(worktree) {
11520
12104
  ensureReadmeFile(repoPoliciesDir(worktree), REPO_LOCAL_POLICIES_README);
11521
12105
  ensureReadmeFile(repoAgentsDir(worktree), [
11522
12106
  "# Repository Agents",
11523
12107
  "",
11524
- "Place full repository-local agent definitions here.",
12108
+ "Place full repository-local agent definitions here only when explicitly requested by the user.",
11525
12109
  "",
11526
- "- Use `.optima/agents/<agent>.md` to override a bundled agent's full base definition.",
11527
- "- Use `.optima/agents/<agent>.md` to define a brand new custom repository agent.",
11528
- "- Files in this folder are treated as full agent definitions.",
12110
+ "- Use `.optima/agents/<agent>.md` only to intentionally override a bundled agent's full base definition.",
12111
+ "- Use `.optima/agents/<agent>.md` only to define a brand new custom repository agent.",
12112
+ "- Files in this folder are treated as full agent definitions and block bundled prompt updates for that agent.",
12113
+ "- Prefer `.optima/agent-additions/<agent>.md` for normal repository-specific guidance.",
11529
12114
  "- `README.md` is ignored by agent discovery.",
11530
12115
  "",
11531
12116
  "## Include Types Available In Custom Agents",
@@ -11619,6 +12204,38 @@ function scaffoldOptimaReadmes(worktree) {
11619
12204
  ].join("\n"));
11620
12205
  ensureOptimaTaskTemplates(worktree);
11621
12206
  }
12207
+ function optimaRepairDependencies() {
12208
+ return {
12209
+ currentScrRegistryContent,
12210
+ currentTasksRegistryContent,
12211
+ doneScrRegistryContent,
12212
+ doneTasksRegistryContent,
12213
+ ensureFileIfMissing,
12214
+ ensureOptimaGitignoreRules,
12215
+ ensureOptimaRegistries,
12216
+ isGitRepository,
12217
+ isOptimaPluginPackageWorktree,
12218
+ legacyNomadworkDir,
12219
+ legacyNomadworksDir,
12220
+ legacyOrbitaDir,
12221
+ legacyStaticEngDir,
12222
+ migrateLegacyOptimaLayout,
12223
+ optimaCodemapPath,
12224
+ optimaDir,
12225
+ optimaEvidencesDir,
12226
+ optimaGitignoreRules: OPTIMA_GITIGNORE_RULES,
12227
+ optimaScrsDir,
12228
+ optimaTasksDir,
12229
+ repoConfigPath,
12230
+ repoLocalPoliciesReadme: REPO_LOCAL_POLICIES_README,
12231
+ repoPoliciesDir,
12232
+ scaffoldOptimaConfig,
12233
+ scaffoldOptimaReadmes,
12234
+ scaffoldOptimaRootCodemap,
12235
+ subtaskTemplateContent,
12236
+ taskTemplateContent
12237
+ };
12238
+ }
11622
12239
  function getModePromptFragment(agentId, operatingTeamMode, worktree) {
11623
12240
  const fragmentMap = {
11624
12241
  product_manager: {
@@ -11634,13 +12251,6 @@ function getModePromptFragment(agentId, operatingTeamMode, worktree) {
11634
12251
  if (!fragmentPath) return "";
11635
12252
  return readResolvedFile(fragmentPath, worktree, { preferCompactPromptDocs: true });
11636
12253
  }
11637
- function isSameOrNestedPath(candidate, root) {
11638
- if (typeof candidate !== "string" || typeof root !== "string" || !candidate.trim() || !root.trim()) return false;
11639
- const resolvedCandidate = path2.resolve(candidate);
11640
- const resolvedRoot = path2.resolve(root);
11641
- const relative = path2.relative(resolvedRoot, resolvedCandidate);
11642
- return relative === "" || !!relative && !relative.startsWith("..") && !path2.isAbsolute(relative);
11643
- }
11644
12254
  function shouldRegisterWorkflowProductManager(options = {}, worktree = process.cwd()) {
11645
12255
  if (options.clickUpWebhookActive === true) return true;
11646
12256
  const validation = options.clickUpWebhookValidation;
@@ -11649,12 +12259,12 @@ function shouldRegisterWorkflowProductManager(options = {}, worktree = process.c
11649
12259
  function resolveSessionToolDirectory({ requestedDirectory, context, pluginWorktree, clickUpWebhookValidation } = {}) {
11650
12260
  const safe = safeWorktreeOrFailure(context, pluginWorktree);
11651
12261
  if (!safe.ok) return { ok: false, error: safe.message };
11652
- const requested = String(requestedDirectory || "").trim() ? path2.resolve(safe.worktree, String(requestedDirectory).trim()) : safe.worktree;
12262
+ const requested = String(requestedDirectory || "").trim() ? path5.resolve(safe.worktree, String(requestedDirectory).trim()) : safe.worktree;
11653
12263
  if (!isSafeWritableDirectory(requested)) return { ok: false, error: `Directory is not a safe writable directory: ${requested}` };
11654
12264
  if (isSameOrNestedPath(requested, safe.worktree)) return { ok: true, directory: requested, safeWorktree: safe.worktree, scope: "context_worktree" };
11655
12265
  const clickUpBasePath = clickUpWebhookValidation?.complete === true && clickUpWebhookValidation?.ok !== false ? clickUpWebhookValidation.config?.basePath : "";
11656
12266
  if (clickUpBasePath && isSameOrNestedPath(requested, clickUpBasePath)) {
11657
- return { ok: true, directory: requested, safeWorktree: safe.worktree, scope: "clickup_base_path", clickupBasePath: path2.resolve(clickUpBasePath) };
12267
+ return { ok: true, directory: requested, safeWorktree: safe.worktree, scope: "clickup_base_path", clickupBasePath: path5.resolve(clickUpBasePath) };
11658
12268
  }
11659
12269
  return {
11660
12270
  ok: false,
@@ -11688,8 +12298,8 @@ function buildOptimaAgents(repoCfg, operatingTeamMode, worktree, debugDir, optio
11688
12298
  if (!enabled) continue;
11689
12299
  }
11690
12300
  const promptOptions = { preferCompactPromptDocs: repoCfg.features?.compact_prompt_docs !== false };
11691
- const bundledDefinition = loadAgentDefinition(path2.join(BUNDLE_AGENTS_DIR, file), worktree, promptOptions);
11692
- const repoDefinition = loadAgentDefinition(path2.join(repoAgentDefinitions, file), worktree, promptOptions) || loadAgentDefinition(path2.join(legacyAgentsDir, file), worktree, promptOptions);
12301
+ const bundledDefinition = loadAgentDefinition(path5.join(BUNDLE_AGENTS_DIR, file), worktree, promptOptions);
12302
+ const repoDefinition = loadAgentDefinition(path5.join(repoAgentDefinitions, file), worktree, promptOptions) || loadAgentDefinition(path5.join(legacyAgentsDir, file), worktree, promptOptions);
11693
12303
  const activeDefinition = repoDefinition || bundledDefinition;
11694
12304
  if (!activeDefinition) continue;
11695
12305
  const { data } = activeDefinition;
@@ -11698,7 +12308,7 @@ function buildOptimaAgents(repoCfg, operatingTeamMode, worktree, debugDir, optio
11698
12308
  if (modePromptFragment) finalPrompt = `${finalPrompt}
11699
12309
 
11700
12310
  ${modePromptFragment}`;
11701
- const additionFragment = loadMarkdownFragment(path2.join(repoAgentAdditions, file), worktree);
12311
+ const additionFragment = loadMarkdownFragment(path5.join(repoAgentAdditions, file), worktree);
11702
12312
  if (additionFragment) {
11703
12313
  finalPrompt = `${finalPrompt}
11704
12314
 
@@ -11751,14 +12361,14 @@ Use this Optima-provided fallback when the current task worktree lacks docs/core
11751
12361
  }
11752
12362
  ourAgents[id] = agentConfig;
11753
12363
  if (repoCfg.features?.debug_dumps !== false) {
11754
- const debugPath = path2.join(debugDir, `${id}.md`);
12364
+ const debugPath = path5.join(debugDir, `${id}.md`);
11755
12365
  const { prompt, ...dumpConfig } = agentConfig;
11756
12366
  const debugHeader = `---
11757
- ${import_yaml2.default.stringify(dumpConfig).trim()}
12367
+ ${import_yaml3.default.stringify(dumpConfig).trim()}
11758
12368
  ---`;
11759
12369
  try {
11760
- if (!fs2.existsSync(debugDir)) fs2.mkdirSync(debugDir, { recursive: true });
11761
- fs2.writeFileSync(debugPath, `${debugHeader}
12370
+ if (!fs5.existsSync(debugDir)) fs5.mkdirSync(debugDir, { recursive: true });
12371
+ fs5.writeFileSync(debugPath, `${debugHeader}
11762
12372
 
11763
12373
  ${prompt}`, "utf8");
11764
12374
  } catch (e) {
@@ -11782,9 +12392,9 @@ async function OptimaPlugin(input = {}, pluginOptions = {}) {
11782
12392
  const configPath = resolveConfigPath(worktree);
11783
12393
  const discussionRegistry = loadDiscussionRegistry(worktree);
11784
12394
  let repoCfg = { agents: {}, defaults: {}, features: {} };
11785
- if (fs2.existsSync(configPath)) {
12395
+ if (fs5.existsSync(configPath)) {
11786
12396
  try {
11787
- repoCfg = import_yaml2.default.parse(fs2.readFileSync(configPath, "utf8")) || repoCfg;
12397
+ repoCfg = import_yaml3.default.parse(fs5.readFileSync(configPath, "utf8")) || repoCfg;
11788
12398
  } catch (e) {
11789
12399
  console.error(`[Optima] Failed to parse config at ${configPath}:`, e);
11790
12400
  }
@@ -11797,13 +12407,14 @@ async function OptimaPlugin(input = {}, pluginOptions = {}) {
11797
12407
  syncGeneratedPolicies(worktree, repoCfg);
11798
12408
  const operatingTeamMode = getOperatingTeamMode(repoCfg);
11799
12409
  const clickUpWebhookValidation = normalizeClickUpWebhookConfig(pickConfiguredClickUp(input, repoCfg, resolvedPluginOptions), worktree);
12410
+ const runtimeClickUpClient = input.clickupClient || (clickUpWebhookValidation.config?.test === true ? createTestClickUpApiClient(clickUpWebhookValidation.config) : createClickUpApiClient(clickUpWebhookValidation.config, input.fetch));
11800
12411
  let clickUpWebhookRuntime = { active: false, valid: false, reason: "not_configured" };
11801
12412
  if (clickUpWebhookValidation.complete) {
11802
12413
  try {
11803
12414
  clickUpWebhookRuntime = await ensureClickUpWebhookSubscription({
11804
12415
  validation: clickUpWebhookValidation,
11805
12416
  worktree,
11806
- clickupClient: input.clickupClient || createClickUpApiClient(clickUpWebhookValidation.config, input.fetch)
12417
+ clickupClient: runtimeClickUpClient
11807
12418
  });
11808
12419
  } catch (error) {
11809
12420
  clickUpWebhookRuntime = { active: false, valid: false, reason: "subscription_failed", error: error.message };
@@ -11813,7 +12424,7 @@ async function OptimaPlugin(input = {}, pluginOptions = {}) {
11813
12424
  let clickUpWebhookActive = clickUpWebhookRuntime.active === true && clickUpWebhookRuntime.valid === true;
11814
12425
  if (clickUpWebhookActive && input.startClickUpWebhookListener !== false) {
11815
12426
  try {
11816
- const lifecycleClickUpClient = input.clickupClient || createClickUpApiClient(clickUpWebhookValidation.config, input.fetch);
12427
+ const lifecycleClickUpClient = runtimeClickUpClient;
11817
12428
  const listenerRegistry = input.clickUpWebhookListenerRegistry || activeClickUpWebhookListeners;
11818
12429
  const listenerState = clickUpWebhookRuntime.state || readClickUpWebhookState(worktree, clickUpWebhookValidation.config);
11819
12430
  const listener = startClickUpWebhookListener({
@@ -11891,54 +12502,16 @@ async function OptimaPlugin(input = {}, pluginOptions = {}) {
11891
12502
  }
11892
12503
  migrateLegacyOptimaLayout(toolWorktree);
11893
12504
  const cfgDir = optimaConfigDir(toolWorktree);
11894
- if (!fs2.existsSync(cfgDir)) fs2.mkdirSync(cfgDir, { recursive: true });
11895
- const agentIds = fs2.existsSync(BUNDLE_AGENTS_DIR) ? fs2.readdirSync(BUNDLE_AGENTS_DIR).filter((f) => f.endsWith(".md")).map((f) => f.replace(".md", "")) : [];
11896
- const optimaTmplPath = path2.join(TEMPLATES_DIR, "optima.yaml.template");
11897
- const codemapTmplPath = path2.join(TEMPLATES_DIR, "codemap.yml.template");
11898
- if (!fs2.existsSync(optimaTmplPath) || !fs2.existsSync(codemapTmplPath)) {
12505
+ if (!fs5.existsSync(cfgDir)) fs5.mkdirSync(cfgDir, { recursive: true });
12506
+ const optimaTmplPath = path5.join(TEMPLATES_DIR, "optima.yaml.template");
12507
+ const codemapTmplPath = path5.join(TEMPLATES_DIR, "codemap.yml.template");
12508
+ if (!fs5.existsSync(optimaTmplPath) || !fs5.existsSync(codemapTmplPath)) {
11899
12509
  return "Error: Initialization templates not found in plugin.";
11900
12510
  }
11901
- let optimaConfig = fs2.readFileSync(optimaTmplPath, "utf8");
11902
- optimaConfig = optimaConfig.replace("{{teamMode}}", requestedTeamMode);
11903
- let agentsSection = "";
11904
- for (const id of agentIds) {
11905
- const enabled = isAgentEnabledForTeamMode(id, requestedTeamMode) ? "true" : "false";
11906
- agentsSection += ` ${id}:
11907
- enabled: ${enabled}
11908
- `;
11909
- }
11910
- optimaConfig = optimaConfig.replace(/^agents:/m, "agents:\n" + agentsSection);
11911
- let codemapConfig = fs2.readFileSync(codemapTmplPath, "utf8");
11912
- codemapConfig = codemapConfig.replace("{{projectName}}", path2.basename(toolWorktree));
11913
- const cfgFilePath = repoConfigPath(toolWorktree);
11914
- const rootCodemapPath = optimaCodemapPath(toolWorktree);
11915
- if (!fs2.existsSync(cfgFilePath)) {
11916
- fs2.writeFileSync(cfgFilePath, optimaConfig, "utf8");
11917
- }
11918
- if (!fs2.existsSync(rootCodemapPath)) {
11919
- fs2.writeFileSync(rootCodemapPath, codemapConfig, "utf8");
11920
- }
12511
+ scaffoldOptimaConfig(toolWorktree, requestedTeamMode);
12512
+ scaffoldOptimaRootCodemap(toolWorktree);
11921
12513
  scaffoldOptimaReadmes(toolWorktree);
11922
- const tasksDir = optimaTasksDir(toolWorktree);
11923
- const scrsDir = optimaScrsDir(toolWorktree);
11924
- if (!fs2.existsSync(tasksDir)) fs2.mkdirSync(tasksDir, { recursive: true });
11925
- if (!fs2.existsSync(scrsDir)) fs2.mkdirSync(scrsDir, { recursive: true });
11926
- const currentPath = path2.join(tasksDir, "current.md");
11927
- const donePath = path2.join(tasksDir, "done.md");
11928
- const scrsCurrentPath = path2.join(scrsDir, "current.md");
11929
- const scrsDonePath = path2.join(scrsDir, "done.md");
11930
- if (!fs2.existsSync(currentPath)) {
11931
- fs2.writeFileSync(currentPath, "# 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", "utf8");
11932
- }
11933
- if (!fs2.existsSync(donePath)) {
11934
- fs2.writeFileSync(donePath, "# Completed Tasks (Registry)\n\n| Date | Task ID | SCR ID | Commit | Summary |\n| :--- | :--- | :--- | :--- | :--- |\n", "utf8");
11935
- }
11936
- if (!fs2.existsSync(scrsCurrentPath)) {
11937
- fs2.writeFileSync(scrsCurrentPath, "# Current Spec Change Requests (Backlog)\n\n## \u{1F680} Active/Review\n- (None)\n\n## \u{1F4CB} Approved (Ready for Implementation)\n- (None)\n\n## \u{1F4A1} Proposed\n- (None)\n", "utf8");
11938
- }
11939
- if (!fs2.existsSync(scrsDonePath)) {
11940
- fs2.writeFileSync(scrsDonePath, "# Implemented Spec Change Requests\n\n| Date | SCR ID | Title | Related Feature | Task ID |\n| :--- | :--- | :--- | :--- | :--- |\n", "utf8");
11941
- }
12514
+ ensureOptimaRegistries(toolWorktree);
11942
12515
  const gitignoreResult = ensureOptimaGitignoreRules(toolWorktree);
11943
12516
  const gitignoreNote = gitignoreResult.added.length > 0 ? ` Added ${gitignoreResult.added.length} Optima local/private .gitignore rule(s).` : "";
11944
12517
  const initSummary = `Optima initialized in '${requestedTeamMode}' team mode: .optima/.config/optima.yaml, repo policy/agent folders, registries, and .optima/codemap.yml created.${gitignoreNote}`;
@@ -12053,14 +12626,14 @@ Restart or reload OpenCode manually if the newly scaffolded config or agents are
12053
12626
  async execute(args, context) {
12054
12627
  const safe = safeWorktreeOrFailure(context, worktree);
12055
12628
  if (!safe.ok) return safe.message;
12056
- const summaryPath = path2.resolve(safe.worktree, args.summary_path || "");
12057
- if (!fs2.existsSync(summaryPath)) return `FAIL: summary_path not found: ${summaryPath}`;
12058
- const taskPath = args.task_path ? path2.resolve(safe.worktree, args.task_path) : "";
12629
+ const summaryPath = path5.resolve(safe.worktree, args.summary_path || "");
12630
+ if (!fs5.existsSync(summaryPath)) return `FAIL: summary_path not found: ${summaryPath}`;
12631
+ const taskPath = args.task_path ? path5.resolve(safe.worktree, args.task_path) : "";
12059
12632
  const payload = buildClickUpSummaryPayload({
12060
- summaryMarkdown: fs2.readFileSync(summaryPath, "utf8"),
12061
- summaryPath: path2.relative(safe.worktree, summaryPath),
12062
- taskMarkdown: taskPath && fs2.existsSync(taskPath) ? fs2.readFileSync(taskPath, "utf8") : "",
12063
- taskPath: taskPath ? path2.relative(safe.worktree, taskPath) : "",
12633
+ summaryMarkdown: fs5.readFileSync(summaryPath, "utf8"),
12634
+ summaryPath: path5.relative(safe.worktree, summaryPath),
12635
+ taskMarkdown: taskPath && fs5.existsSync(taskPath) ? fs5.readFileSync(taskPath, "utf8") : "",
12636
+ taskPath: taskPath ? path5.relative(safe.worktree, taskPath) : "",
12064
12637
  branch: args.branch,
12065
12638
  worktree: args.worktree,
12066
12639
  pr: args.pr
@@ -12139,12 +12712,12 @@ Restart or reload OpenCode manually if the newly scaffolded config or agents are
12139
12712
  async execute(args, context) {
12140
12713
  const safe = safeWorktreeOrFailure(context, worktree);
12141
12714
  if (!safe.ok) return safe.message;
12142
- const markdownPath = path2.resolve(safe.worktree, args.markdown_path || "");
12143
- if (!fs2.existsSync(markdownPath)) return `FAIL: markdown_path not found: ${markdownPath}`;
12715
+ const markdownPath = path5.resolve(safe.worktree, args.markdown_path || "");
12716
+ if (!fs5.existsSync(markdownPath)) return `FAIL: markdown_path not found: ${markdownPath}`;
12144
12717
  const payload = buildClickUpCreateSubtasksPayload({
12145
12718
  parentTaskId: args.parent_task_id,
12146
- markdown: fs2.readFileSync(markdownPath, "utf8"),
12147
- sourcePath: path2.relative(safe.worktree, markdownPath),
12719
+ markdown: fs5.readFileSync(markdownPath, "utf8"),
12720
+ sourcePath: path5.relative(safe.worktree, markdownPath),
12148
12721
  parentBranch: args.parent_branch,
12149
12722
  parentTaskType: args.parent_task_type || "Tarea",
12150
12723
  apply: String(args.apply || "").toLowerCase() === "true"
@@ -12176,6 +12749,21 @@ Restart or reload OpenCode manually if the newly scaffolded config or agents are
12176
12749
  return formatValidationResult(res);
12177
12750
  }
12178
12751
  }),
12752
+ optima_repair: tool({
12753
+ description: "Inspect and repair Optima operational errors across config, registries, templates, policies, legacy artifacts, Markdown paths, gitignore rules, and CodeMaps. Dry-run by default; set apply true to mutate safely.",
12754
+ args: {
12755
+ apply: tool.schema.boolean().optional().describe("Set true to apply deterministic Optima metadata repairs. Defaults to false dry-run."),
12756
+ mode: tool.schema.string().optional().describe("Optional mode: 'dry-run' or 'apply'. Dry-run is the default."),
12757
+ team_mode: tool.schema.string().optional().describe("Team mode for a newly created config when missing: mini or full. Defaults to full.")
12758
+ },
12759
+ async execute(args, context) {
12760
+ const safe = safeWorktreeOrFailure(context, worktree);
12761
+ if (!safe.ok) return safe.message;
12762
+ const plan = planOptimaRepair(safe.worktree, args, optimaRepairDependencies());
12763
+ const validationResult = plan.mode === "apply" ? await optima_validate_logic(safe.worktree) : null;
12764
+ return formatRepairResult(plan, validationResult, formatValidationResult);
12765
+ }
12766
+ }),
12179
12767
  optima_start_discussion: tool({
12180
12768
  description: "Start an automatic discussion transcript for this session",
12181
12769
  args: {
@@ -12328,7 +12916,7 @@ Backfilled messages: ${backfilled}`;
12328
12916
  if (!existing) {
12329
12917
  return "FAIL: No active discussion exists for this session.";
12330
12918
  }
12331
- const discussionPath = path2.join(toolWorktree, existing.transcriptPath);
12919
+ const discussionPath = path5.join(toolWorktree, existing.transcriptPath);
12332
12920
  setDiscussionStatus(discussionPath, "summarizing");
12333
12921
  existing.status = "summarizing";
12334
12922
  saveDiscussionRegistry(toolWorktree, toolRegistry);
@@ -12380,7 +12968,7 @@ Reason: ${err.message}`;
12380
12968
  try {
12381
12969
  const sessionResult = await client.session.create({
12382
12970
  query: { directory: workflowDirectory },
12383
- body: { title: `Workflow Run: ${path2.basename(workflowTaskPath)}` }
12971
+ body: { title: `Workflow Run: ${path5.basename(workflowTaskPath)}` }
12384
12972
  });
12385
12973
  const sessionId = sessionResult.data.id;
12386
12974
  activeWorkflows.set(sessionId, { pmaSessionId, taskPath: workflowTaskPath, track: workflowTrack, directory: workflowDirectory });
@@ -12509,7 +13097,7 @@ Follow-up: use optima_prompt_workflow with session_id '${sessionId}' to check in
12509
13097
  }
12510
13098
  };
12511
13099
  }
12512
- OptimaPlugin.__internals = { BUNDLE_AGENTS_DIR, BUNDLE_ASSETS_DIR, CLICKUP_DEFINITION_DOC_PARENT, activeClickUpWebhookLifecycleRegistry, cleanupManagedClickUpWebhook, deleteClickUpWebhookBestEffort, BUNDLE_POLICIES_DIR, buildClickUpApplyPayloadResult, buildClickUpCreateSubtasksPayload, buildClickUpStartTaskPayload, buildClickUpSummaryPayload, buildClickUpTransitionPayload, buildOptimaAgents, clickUpCommentLedgerKey, clickUpCommentMentionsProductManager, clickUpWebhookAuditLogDir, clickUpWebhookAuditLogPath, createClickUpApiClient, createOpenCodeSession, createOpenCodeSessionControl, deliveryEvidencePathForClickUpTask, ensureClickUpTaskWorktree, ensureClickUpWebhookSubscription, handleClickUpWebhookRequest, isClickUpWebhookStateActive, normalizeClickUpWebhookConfig, normalizeClickUpWebhookLogLevel, normalizeOpenCodeBaseUrl, openCodeSessionExists, promptOpenCodeSessionControl, probeOpenCodeSessionControl, readClickUpCommentLedger, readClickUpWebhookState, readOpenCodeSessionControl, readOpenCodeSessionMessages, reconcileClickUpStartup, scheduleClickUpStartupReconciliation, waitForOpenCodeReadiness, recordClickUpCommentVersionProcessed, resyncClickUpWebhookForSignatureDrift, resolveOptimaPluginOptions, resolveSecretReference, routeClickUpWebhookEvent, sendOpenCodeSessionEvent, sendOpenCodeSessionEventDirect, summarizeOpenCodeMessages, verifyOpenCodeSessionEventDelivery, stableClickUpCommentVersionMarker, startClickUpWebhookListener, validateClickUpWebhookState, verifyClickUpSignature, writeClickUpWebhookState, decideClickUpStatusAction, deriveClickUpBranchName, deriveClickUpPendingSubtaskBranch, deriveClickUpPrTarget, deriveClickUpWorktree, determineClickUpMergeAuthority, ensureOptimaGitignoreRules, explicitSafeInputWorktree, finalApprovalAssignees, formatValidationResult, isIgnoredClickUpTaskType, isOptimaPluginPackageWorktree, isSafeWritableDirectory, loadHumansRegistry, mergeClickUpAgentMetadata, mergeClickUpSessionMetadata, migrateLegacyOptimaLayout, normalizeAgentMetadataJson, normalizeClickUpStatus, normalizeClickUpTaskType, normalizePromptResponseParts, normalizeWorkflowTaskPath, parseClickUpSubtasksMarkdown, parseHumansRegistry, parseMarkdownArtifact, parseMarkdownSections, preEstimateClickUpWork, readMarkdownArtifact, resolveHumanRoles, resolveSafeWorktree, safeWorktreeOrFailure, stripRawLogSections, validateMainWorkspaceBranchSafety, workflowFinalMessageFromPromptResponse };
13100
+ OptimaPlugin.__internals = { BUNDLE_AGENTS_DIR, BUNDLE_ASSETS_DIR, CLICKUP_DEFINITION_DOC_PARENT, activeClickUpWebhookLifecycleRegistry, cleanupManagedClickUpWebhook, deleteClickUpWebhookBestEffort, BUNDLE_POLICIES_DIR, buildClickUpApplyPayloadResult, buildClickUpCreateSubtasksPayload, buildClickUpStartTaskPayload, buildClickUpSummaryPayload, buildClickUpTransitionPayload, buildOptimaAgents, clickUpCommentLedgerKey, clickUpCommentMentionsProductManager, clickUpWebhookAuditLogDir, clickUpWebhookAuditLogPath, compactPromptPath, createClickUpApiClient, createTestClickUpApiClient, createOpenCodeSession, createOpenCodeSessionControl, deliveryEvidencePathForClickUpTask, ensureClickUpTaskWorktree, ensureClickUpWebhookSubscription, handleClickUpWebhookRequest, isClickUpWebhookStateActive, isSameOrNestedPath, normalizeClickUpWebhookConfig, normalizeClickUpWebhookLogLevel, normalizeOpenCodeBaseUrl, openCodeSessionExists, promptOpenCodeSessionControl, probeOpenCodeSessionControl, readClickUpCommentLedger, readClickUpWebhookState, readOpenCodeSessionControl, readOpenCodeSessionMessages, reconcileClickUpStartup, scheduleClickUpStartupReconciliation, waitForOpenCodeReadiness, recordClickUpCommentVersionProcessed, resyncClickUpWebhookForSignatureDrift, resolveIncludeFile, resolveIncludes, resolveOptimaPluginOptions, resolveSecretReference, routeClickUpWebhookEvent, sendOpenCodeSessionEvent, sendOpenCodeSessionEventDirect, summarizeOpenCodeMessages, verifyOpenCodeSessionEventDelivery, stableClickUpCommentVersionMarker, startClickUpWebhookListener, validateClickUpWebhookState, verifyClickUpSignature, writeClickUpWebhookState, decideClickUpStatusAction, deriveClickUpBranchName, deriveClickUpPendingSubtaskBranch, deriveClickUpPrTarget, deriveClickUpWorktree, determineClickUpMergeAuthority, ensureOptimaGitignoreRules, explicitSafeInputWorktree, finalApprovalAssignees, formatRepairResult, formatValidationResult, isIgnoredClickUpTaskType, isOptimaPluginPackageWorktree, isSafeWritableDirectory, loadHumansRegistry, mergeClickUpAgentMetadata, mergeClickUpSessionMetadata, migrateLegacyOptimaLayout, normalizeAgentMetadataJson, normalizeClickUpStatus, normalizeClickUpTaskType, normalizePromptResponseParts, normalizeWorkflowTaskPath, optimaRepairDependencies, parseClickUpSubtasksMarkdown, parseHumansRegistry, parseMarkdownArtifact, parseMarkdownSections, planOptimaRepair, preEstimateClickUpWork, readMarkdownArtifact, resolveHumanRoles, resolveSafeWorktree, safeWorktreeOrFailure, stripRawLogSections, validateMainWorkspaceBranchSafety, workflowFinalMessageFromPromptResponse };
12513
13101
 
12514
13102
  // src/sanitize_cli.js
12515
13103
  var { migrateLegacyOptimaLayout: migrateLegacyOptimaLayout2 } = OptimaPlugin.__internals;
@@ -12565,13 +13153,13 @@ function usage() {
12565
13153
  }
12566
13154
  function expandHome(inputPath) {
12567
13155
  if (!inputPath || inputPath === "~") return os2.homedir();
12568
- if (inputPath.startsWith("~/")) return path3.join(os2.homedir(), inputPath.slice(2));
13156
+ if (inputPath.startsWith("~/")) return path6.join(os2.homedir(), inputPath.slice(2));
12569
13157
  return inputPath;
12570
13158
  }
12571
13159
  function resolveOpenCodeDbPath(inputPath = null) {
12572
13160
  const expanded = expandHome(inputPath || process.env.OPTIMA_OPENCODE_DB_PATH || DEFAULT_DB_PATH);
12573
13161
  try {
12574
- if (fs3.existsSync(expanded) && fs3.statSync(expanded).isDirectory()) return path3.join(expanded, "opencode.db");
13162
+ if (fs6.existsSync(expanded) && fs6.statSync(expanded).isDirectory()) return path6.join(expanded, "opencode.db");
12575
13163
  } catch {
12576
13164
  return expanded;
12577
13165
  }
@@ -12635,12 +13223,12 @@ function extractOpenedPathValue(value) {
12635
13223
  }
12636
13224
  function normalizePathCandidate(candidate) {
12637
13225
  const expanded = expandHome(candidate);
12638
- if (!path3.isAbsolute(expanded)) return null;
12639
- return path3.resolve(expanded);
13226
+ if (!path6.isAbsolute(expanded)) return null;
13227
+ return path6.resolve(expanded);
12640
13228
  }
12641
13229
  function discoverOpenCodePaths(dbPath) {
12642
13230
  const resolvedDb = resolveOpenCodeDbPath(dbPath);
12643
- if (!fs3.existsSync(resolvedDb)) throw new Error(`OpenCode database not found: ${resolvedDb}`);
13231
+ if (!fs6.existsSync(resolvedDb)) throw new Error(`OpenCode database not found: ${resolvedDb}`);
12644
13232
  const tables = sqliteJson(resolvedDb, "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name");
12645
13233
  const discovered = /* @__PURE__ */ new Set();
12646
13234
  for (const table of tables) {
@@ -12665,27 +13253,27 @@ function discoverOpenCodePaths(dbPath) {
12665
13253
  function collectMarkdownOverridesFrom(baseDir) {
12666
13254
  const files = [];
12667
13255
  for (const dirName of OVERRIDE_DIRS) {
12668
- const dirPath = path3.join(baseDir, dirName);
12669
- if (!fs3.existsSync(dirPath)) continue;
12670
- for (const entry of fs3.readdirSync(dirPath, { withFileTypes: true })) {
13256
+ const dirPath = path6.join(baseDir, dirName);
13257
+ if (!fs6.existsSync(dirPath)) continue;
13258
+ for (const entry of fs6.readdirSync(dirPath, { withFileTypes: true })) {
12671
13259
  if (!entry.isFile()) continue;
12672
13260
  if (!entry.name.endsWith(".md")) continue;
12673
13261
  if (entry.name.toLowerCase() === "readme.md") continue;
12674
- files.push(path3.join(dirPath, entry.name));
13262
+ files.push(path6.join(dirPath, entry.name));
12675
13263
  }
12676
13264
  }
12677
13265
  return files;
12678
13266
  }
12679
13267
  function collectOverrideFiles(worktree) {
12680
- return collectMarkdownOverridesFrom(path3.join(worktree, ".optima")).sort();
13268
+ return collectMarkdownOverridesFrom(path6.join(worktree, ".optima")).sort();
12681
13269
  }
12682
13270
  function collectPlannedOverrideFiles(worktree) {
12683
13271
  return [
12684
13272
  ...collectOverrideFiles(worktree),
12685
- ...collectMarkdownOverridesFrom(path3.join(worktree, ".staticeng")),
12686
- ...collectMarkdownOverridesFrom(path3.join(worktree, ".orbita")),
12687
- ...collectMarkdownOverridesFrom(path3.join(worktree, ".nomadwork")),
12688
- ...collectMarkdownOverridesFrom(path3.join(worktree, ".nomadworks"))
13273
+ ...collectMarkdownOverridesFrom(path6.join(worktree, ".staticeng")),
13274
+ ...collectMarkdownOverridesFrom(path6.join(worktree, ".orbita")),
13275
+ ...collectMarkdownOverridesFrom(path6.join(worktree, ".nomadwork")),
13276
+ ...collectMarkdownOverridesFrom(path6.join(worktree, ".nomadworks"))
12689
13277
  ].sort();
12690
13278
  }
12691
13279
  var CRC_TABLE = (() => {
@@ -12718,14 +13306,14 @@ function writeUInt16LE(value) {
12718
13306
  return buffer;
12719
13307
  }
12720
13308
  function createZipBackup(files, backupPath) {
12721
- fs3.mkdirSync(path3.dirname(backupPath), { recursive: true });
13309
+ fs6.mkdirSync(path6.dirname(backupPath), { recursive: true });
12722
13310
  const localParts = [];
12723
13311
  const centralParts = [];
12724
13312
  let offset = 0;
12725
13313
  const now = dosTimeDate();
12726
13314
  for (const filePath of files) {
12727
- const data = fs3.readFileSync(filePath);
12728
- const name = path3.resolve(filePath).replace(/^\//, "").split(path3.sep).join("/");
13315
+ const data = fs6.readFileSync(filePath);
13316
+ const name = path6.resolve(filePath).replace(/^\//, "").split(path6.sep).join("/");
12729
13317
  const nameBuffer = Buffer.from(name, "utf8");
12730
13318
  const crc = crc32(data);
12731
13319
  const local = Buffer.concat([
@@ -12777,7 +13365,7 @@ function createZipBackup(files, backupPath) {
12777
13365
  writeUInt32LE(offset),
12778
13366
  writeUInt16LE(0)
12779
13367
  ]);
12780
- fs3.writeFileSync(backupPath, Buffer.concat([...localParts, ...centralParts, end]));
13368
+ fs6.writeFileSync(backupPath, Buffer.concat([...localParts, ...centralParts, end]));
12781
13369
  }
12782
13370
  function timestamp() {
12783
13371
  return (/* @__PURE__ */ new Date()).toISOString().replace(/[-:]/g, "").replace(/\.\d{3}Z$/, "Z");
@@ -12787,17 +13375,17 @@ function validationStatus(result) {
12787
13375
  return result.ok ? "passed" : "failed";
12788
13376
  }
12789
13377
  function hasLegacyMarker(worktree) {
12790
- return fs3.existsSync(path3.join(worktree, ".staticeng")) || fs3.existsSync(path3.join(worktree, ".orbita")) || fs3.existsSync(path3.join(worktree, ".nomadwork")) || fs3.existsSync(path3.join(worktree, ".nomadworks"));
13378
+ return fs6.existsSync(path6.join(worktree, ".staticeng")) || fs6.existsSync(path6.join(worktree, ".orbita")) || fs6.existsSync(path6.join(worktree, ".nomadwork")) || fs6.existsSync(path6.join(worktree, ".nomadworks"));
12791
13379
  }
12792
13380
  function rootOptimaArtifacts(worktree) {
12793
13381
  const artifacts = [
12794
- ["tasks/", path3.join(worktree, "tasks")],
12795
- ["evidences/", path3.join(worktree, "evidences")],
12796
- ["docs/scrs/", path3.join(worktree, "docs", "scrs")],
12797
- ["codemap.yml", path3.join(worktree, "codemap.yml")],
12798
- ["codemap.yaml", path3.join(worktree, "codemap.yaml")]
13382
+ ["tasks/", path6.join(worktree, "tasks")],
13383
+ ["evidences/", path6.join(worktree, "evidences")],
13384
+ ["docs/scrs/", path6.join(worktree, "docs", "scrs")],
13385
+ ["codemap.yml", path6.join(worktree, "codemap.yml")],
13386
+ ["codemap.yaml", path6.join(worktree, "codemap.yaml")]
12799
13387
  ];
12800
- return artifacts.map(([display, artifactPath]) => ({ display, path: artifactPath })).filter((item) => fs3.existsSync(item.path));
13388
+ return artifacts.map(([display, artifactPath]) => ({ display, path: artifactPath })).filter((item) => fs6.existsSync(item.path));
12801
13389
  }
12802
13390
  function hasSanitizableOverrides(worktree) {
12803
13391
  return collectPlannedOverrideFiles(worktree).length > 0;
@@ -12823,7 +13411,7 @@ function planOptimaMigration(worktree, dryRun) {
12823
13411
  ...overrides.map((file) => ({
12824
13412
  category: "override",
12825
13413
  action: dryRun ? "would_remove_after_backup" : "removed_after_backup",
12826
- path: path3.relative(worktree, file).split(path3.sep).join("/"),
13414
+ path: path6.relative(worktree, file).split(path6.sep).join("/"),
12827
13415
  detail: "Remove implicit agent/policy override after host-level backup."
12828
13416
  }))
12829
13417
  ],
@@ -12844,12 +13432,12 @@ async function sanitizeHost(options = {}) {
12844
13432
  const repoStates = [];
12845
13433
  for (const candidate of paths) {
12846
13434
  try {
12847
- if (!fs3.existsSync(candidate)) {
13435
+ if (!fs6.existsSync(candidate)) {
12848
13436
  report.totals.skipped += 1;
12849
13437
  report.repos.push({ path: candidate, status: "skipped", reason: "missing" });
12850
13438
  continue;
12851
13439
  }
12852
- if (!fs3.statSync(candidate).isDirectory()) {
13440
+ if (!fs6.statSync(candidate).isDirectory()) {
12853
13441
  report.totals.skipped += 1;
12854
13442
  report.repos.push({ path: candidate, status: "skipped", reason: "not_directory" });
12855
13443
  continue;
@@ -12871,7 +13459,7 @@ async function sanitizeHost(options = {}) {
12871
13459
  const overrides = repoStates.flatMap((state) => state.overrideFiles.map((file) => ({ repo: state.repo, file })));
12872
13460
  report.totals.overrideFiles = overrides.length;
12873
13461
  if (!dryRun && overrides.length > 0) {
12874
- const backupPath = path3.join(os2.homedir(), BACKUP_DIRNAME, `${timestamp()}.zip`);
13462
+ const backupPath = path6.join(os2.homedir(), BACKUP_DIRNAME, `${timestamp()}.zip`);
12875
13463
  try {
12876
13464
  createZipBackup(overrides.map((item) => item.file), backupPath);
12877
13465
  report.backupPath = backupPath;
@@ -12887,7 +13475,7 @@ async function sanitizeHost(options = {}) {
12887
13475
  for (const state of repoStates) {
12888
13476
  try {
12889
13477
  if (!dryRun) {
12890
- for (const file of state.overrideFiles) fs3.rmSync(file, { force: true });
13478
+ for (const file of state.overrideFiles) fs6.rmSync(file, { force: true });
12891
13479
  }
12892
13480
  const validation = !dryRun && hasLegacyMarker(state.repo) ? await optima_validate_logic(state.repo) : null;
12893
13481
  const status = (!validation || validation.ok) && state.plan.unresolved.length === 0 ? "repaired" : "failed";
@@ -12900,7 +13488,7 @@ async function sanitizeHost(options = {}) {
12900
13488
  repairActions: state.plan.actions.length,
12901
13489
  repairSkipped: state.plan.skippedRepair === true,
12902
13490
  overrideFiles: state.overrideFiles.length,
12903
- overridePaths: state.overrideFiles.map((file) => path3.relative(state.repo, file).split(path3.sep).join("/")),
13491
+ overridePaths: state.overrideFiles.map((file) => path6.relative(state.repo, file).split(path6.sep).join("/")),
12904
13492
  validation: validation ? validationStatus(validation) : "skipped",
12905
13493
  unresolved: state.plan.unresolved
12906
13494
  });