@defend-tech/opencode-optima 0.1.58 → 0.1.60

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -632,8 +632,6 @@ var require_Alias = __commonJS({
632
632
  * instance of the `source` anchor before this node.
633
633
  */
634
634
  resolve(doc, ctx) {
635
- if (ctx?.maxAliasCount === 0)
636
- throw new ReferenceError("Alias resolution is disabled");
637
635
  let nodes;
638
636
  if (ctx?.aliasResolveCache) {
639
637
  nodes = ctx.aliasResolveCache;
@@ -1433,7 +1431,6 @@ var require_stringify = __commonJS({
1433
1431
  nullStr: "null",
1434
1432
  simpleKeys: false,
1435
1433
  singleQuote: null,
1436
- trailingComma: false,
1437
1434
  trueStr: "true",
1438
1435
  verifyAliasOrder: true
1439
1436
  }, doc.schema.toStringOptions, options);
@@ -1706,18 +1703,18 @@ var require_merge = __commonJS({
1706
1703
  };
1707
1704
  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);
1708
1705
  function addMergeToJSMap(ctx, map, value) {
1709
- const source = resolveAliasValue(ctx, value);
1710
- if (identity.isSeq(source))
1711
- for (const it of source.items)
1706
+ value = ctx && identity.isAlias(value) ? value.resolve(ctx.doc) : value;
1707
+ if (identity.isSeq(value))
1708
+ for (const it of value.items)
1712
1709
  mergeValue(ctx, map, it);
1713
- else if (Array.isArray(source))
1714
- for (const it of source)
1710
+ else if (Array.isArray(value))
1711
+ for (const it of value)
1715
1712
  mergeValue(ctx, map, it);
1716
1713
  else
1717
- mergeValue(ctx, map, source);
1714
+ mergeValue(ctx, map, value);
1718
1715
  }
1719
1716
  function mergeValue(ctx, map, value) {
1720
- const source = resolveAliasValue(ctx, value);
1717
+ const source = ctx && identity.isAlias(value) ? value.resolve(ctx.doc) : value;
1721
1718
  if (!identity.isMap(source))
1722
1719
  throw new Error("Merge sources must be maps or map aliases");
1723
1720
  const srcMap = source.toJSON(null, ctx, Map);
@@ -1738,9 +1735,6 @@ var require_merge = __commonJS({
1738
1735
  }
1739
1736
  return map;
1740
1737
  }
1741
- function resolveAliasValue(ctx, value) {
1742
- return ctx && identity.isAlias(value) ? value.resolve(ctx.doc, ctx) : value;
1743
- }
1744
1738
  exports.addMergeToJSMap = addMergeToJSMap;
1745
1739
  exports.isMergeKey = isMergeKey;
1746
1740
  exports.merge = merge;
@@ -1954,19 +1948,12 @@ ${indent}${line}` : "\n";
1954
1948
  if (comment)
1955
1949
  reqNewline = true;
1956
1950
  let str = stringify.stringify(item, itemCtx, () => comment = null);
1957
- reqNewline || (reqNewline = lines.length > linesAtValue || str.includes("\n"));
1958
- if (i < items.length - 1) {
1951
+ if (i < items.length - 1)
1959
1952
  str += ",";
1960
- } else if (ctx.options.trailingComma) {
1961
- if (ctx.options.lineWidth > 0) {
1962
- reqNewline || (reqNewline = lines.reduce((sum, line) => sum + line.length + 2, 2) + (str.length + 2) > ctx.options.lineWidth);
1963
- }
1964
- if (reqNewline) {
1965
- str += ",";
1966
- }
1967
- }
1968
1953
  if (comment)
1969
1954
  str += stringifyComment.lineComment(str, itemIndent, commentString(comment));
1955
+ if (!reqNewline && (lines.length > linesAtValue || str.includes("\n")))
1956
+ reqNewline = true;
1970
1957
  lines.push(str);
1971
1958
  linesAtValue = lines.length;
1972
1959
  }
@@ -2378,7 +2365,7 @@ var require_stringifyNumber = __commonJS({
2378
2365
  if (!isFinite(num))
2379
2366
  return isNaN(num) ? ".nan" : num < 0 ? "-.inf" : ".inf";
2380
2367
  let n = Object.is(value, -0) ? "-0" : JSON.stringify(value);
2381
- if (!format && minFractionDigits && (!tag || tag === "tag:yaml.org,2002:float") && /^-?\d/.test(n) && !n.includes("e")) {
2368
+ if (!format && minFractionDigits && (!tag || tag === "tag:yaml.org,2002:float") && /^\d/.test(n)) {
2382
2369
  let i = n.indexOf(".");
2383
2370
  if (i < 0) {
2384
2371
  i = n.length;
@@ -4750,7 +4737,7 @@ var require_resolve_flow_scalar = __commonJS({
4750
4737
  while (next === " " || next === " ")
4751
4738
  next = source[++i + 1];
4752
4739
  } else if (next === "x" || next === "u" || next === "U") {
4753
- const length = next === "x" ? 2 : next === "u" ? 4 : 8;
4740
+ const length = { x: 2, u: 4, U: 8 }[next];
4754
4741
  res += parseCharCode(source, i + 1, length, onError);
4755
4742
  i += length;
4756
4743
  } else {
@@ -4825,13 +4812,12 @@ var require_resolve_flow_scalar = __commonJS({
4825
4812
  const cc = source.substr(offset, length);
4826
4813
  const ok = cc.length === length && /^[0-9a-fA-F]+$/.test(cc);
4827
4814
  const code = ok ? parseInt(cc, 16) : NaN;
4828
- try {
4829
- return String.fromCodePoint(code);
4830
- } catch {
4815
+ if (isNaN(code)) {
4831
4816
  const raw = source.substr(offset - 2, length + 2);
4832
4817
  onError(offset - 2, "BAD_DQ_ESCAPE", `Invalid escape sequence ${raw}`);
4833
4818
  return raw;
4834
4819
  }
4820
+ return String.fromCodePoint(code);
4835
4821
  }
4836
4822
  exports.resolveFlowScalar = resolveFlowScalar;
4837
4823
  }
@@ -4981,22 +4967,17 @@ var require_compose_node = __commonJS({
4981
4967
  case "block-map":
4982
4968
  case "block-seq":
4983
4969
  case "flow-collection":
4984
- try {
4985
- node = composeCollection.composeCollection(CN, ctx, token, props, onError);
4986
- if (anchor)
4987
- node.anchor = anchor.source.substring(1);
4988
- } catch (error) {
4989
- const message = error instanceof Error ? error.message : String(error);
4990
- onError(token, "RESOURCE_EXHAUSTION", message);
4991
- }
4970
+ node = composeCollection.composeCollection(CN, ctx, token, props, onError);
4971
+ if (anchor)
4972
+ node.anchor = anchor.source.substring(1);
4992
4973
  break;
4993
4974
  default: {
4994
4975
  const message = token.type === "error" ? token.message : `Unsupported token (type: ${token.type})`;
4995
4976
  onError(token, "UNEXPECTED_TOKEN", message);
4977
+ node = composeEmptyNode(ctx, token.offset, void 0, null, props, onError);
4996
4978
  isSrcToken = false;
4997
4979
  }
4998
4980
  }
4999
- node ?? (node = composeEmptyNode(ctx, token.offset, void 0, null, props, onError));
5000
4981
  if (anchor && node.anchor === "")
5001
4982
  onError(anchor, "BAD_ALIAS", "Anchor cannot be an empty string");
5002
4983
  if (atKey && ctx.options.stringKeys && (!identity.isScalar(node) || typeof node.value !== "string" || node.tag && node.tag !== "tag:yaml.org,2002:str")) {
@@ -5181,10 +5162,8 @@ ${cb}` : comment;
5181
5162
  }
5182
5163
  }
5183
5164
  if (afterDoc) {
5184
- for (let i = 0; i < this.errors.length; ++i)
5185
- doc.errors.push(this.errors[i]);
5186
- for (let i = 0; i < this.warnings.length; ++i)
5187
- doc.warnings.push(this.warnings[i]);
5165
+ Array.prototype.push.apply(doc.errors, this.errors);
5166
+ Array.prototype.push.apply(doc.warnings, this.warnings);
5188
5167
  } else {
5189
5168
  doc.errors = this.errors;
5190
5169
  doc.warnings = this.warnings;
@@ -5917,7 +5896,7 @@ var require_lexer = __commonJS({
5917
5896
  const n = (yield* this.pushCount(1)) + (yield* this.pushSpaces(true));
5918
5897
  this.indentNext = this.indentValue + 1;
5919
5898
  this.indentValue += n;
5920
- return "block-start";
5899
+ return yield* this.parseBlockStart();
5921
5900
  }
5922
5901
  return "doc";
5923
5902
  }
@@ -6216,38 +6195,28 @@ var require_lexer = __commonJS({
6216
6195
  return 0;
6217
6196
  }
6218
6197
  *pushIndicators() {
6219
- let n = 0;
6220
- loop: while (true) {
6221
- switch (this.charAt(0)) {
6222
- case "!":
6223
- n += yield* this.pushTag();
6224
- n += yield* this.pushSpaces(true);
6225
- continue loop;
6226
- case "&":
6227
- n += yield* this.pushUntil(isNotAnchorChar);
6228
- n += yield* this.pushSpaces(true);
6229
- continue loop;
6230
- case "-":
6231
- // this is an error
6232
- case "?":
6233
- // this is an error outside flow collections
6234
- case ":": {
6235
- const inFlow = this.flowLevel > 0;
6236
- const ch1 = this.charAt(1);
6237
- if (isEmpty(ch1) || inFlow && flowIndicatorChars.has(ch1)) {
6238
- if (!inFlow)
6239
- this.indentNext = this.indentValue + 1;
6240
- else if (this.flowKey)
6241
- this.flowKey = false;
6242
- n += yield* this.pushCount(1);
6243
- n += yield* this.pushSpaces(true);
6244
- continue loop;
6245
- }
6198
+ switch (this.charAt(0)) {
6199
+ case "!":
6200
+ return (yield* this.pushTag()) + (yield* this.pushSpaces(true)) + (yield* this.pushIndicators());
6201
+ case "&":
6202
+ return (yield* this.pushUntil(isNotAnchorChar)) + (yield* this.pushSpaces(true)) + (yield* this.pushIndicators());
6203
+ case "-":
6204
+ // this is an error
6205
+ case "?":
6206
+ // this is an error outside flow collections
6207
+ case ":": {
6208
+ const inFlow = this.flowLevel > 0;
6209
+ const ch1 = this.charAt(1);
6210
+ if (isEmpty(ch1) || inFlow && flowIndicatorChars.has(ch1)) {
6211
+ if (!inFlow)
6212
+ this.indentNext = this.indentValue + 1;
6213
+ else if (this.flowKey)
6214
+ this.flowKey = false;
6215
+ return (yield* this.pushCount(1)) + (yield* this.pushSpaces(true)) + (yield* this.pushIndicators());
6246
6216
  }
6247
6217
  }
6248
- break loop;
6249
6218
  }
6250
- return n;
6219
+ return 0;
6251
6220
  }
6252
6221
  *pushTag() {
6253
6222
  if (this.charAt(1) === "<") {
@@ -6406,13 +6375,6 @@ var require_parser = __commonJS({
6406
6375
  }
6407
6376
  return prev.splice(i, prev.length);
6408
6377
  }
6409
- function arrayPushArray(target, source) {
6410
- if (source.length < 1e5)
6411
- Array.prototype.push.apply(target, source);
6412
- else
6413
- for (let i = 0; i < source.length; ++i)
6414
- target.push(source[i]);
6415
- }
6416
6378
  function fixFlowSeqItems(fc) {
6417
6379
  if (fc.start.type === "flow-seq-start") {
6418
6380
  for (const it of fc.items) {
@@ -6422,11 +6384,11 @@ var require_parser = __commonJS({
6422
6384
  delete it.key;
6423
6385
  if (isFlowToken(it.value)) {
6424
6386
  if (it.value.end)
6425
- arrayPushArray(it.value.end, it.sep);
6387
+ Array.prototype.push.apply(it.value.end, it.sep);
6426
6388
  else
6427
6389
  it.value.end = it.sep;
6428
6390
  } else
6429
- arrayPushArray(it.start, it.sep);
6391
+ Array.prototype.push.apply(it.start, it.sep);
6430
6392
  delete it.sep;
6431
6393
  }
6432
6394
  }
@@ -6781,7 +6743,7 @@ var require_parser = __commonJS({
6781
6743
  const prev = map.items[map.items.length - 2];
6782
6744
  const end = prev?.value?.end;
6783
6745
  if (Array.isArray(end)) {
6784
- arrayPushArray(end, it.start);
6746
+ Array.prototype.push.apply(end, it.start);
6785
6747
  end.push(this.sourceToken);
6786
6748
  map.items.pop();
6787
6749
  return;
@@ -6969,7 +6931,7 @@ var require_parser = __commonJS({
6969
6931
  const prev = seq.items[seq.items.length - 2];
6970
6932
  const end = prev?.value?.end;
6971
6933
  if (Array.isArray(end)) {
6972
- arrayPushArray(end, it.start);
6934
+ Array.prototype.push.apply(end, it.start);
6973
6935
  end.push(this.sourceToken);
6974
6936
  seq.items.pop();
6975
6937
  return;
@@ -8841,7 +8803,13 @@ function deriveClickUpBranchName({ taskType, parentTaskId, subtaskId, taskId } =
8841
8803
  throw new Error("taskType and parentTaskId/taskId are required to derive a ClickUp branch name.");
8842
8804
  }
8843
8805
  if (typeSlug === "poc") return ["poc", parentSlug].join("/");
8844
- return [typeSlug, parentSlug, subtaskSlug].filter(Boolean).join("/");
8806
+ if (subtaskSlug) return `${typeSlug}/${parentSlug}-subtask-${subtaskSlug}`;
8807
+ return [typeSlug, parentSlug].join("/");
8808
+ }
8809
+ function isClickUpSubtaskRoute({ taskType, parentTaskId, subtaskId, taskId } = {}) {
8810
+ return Boolean(
8811
+ normalizeClickUpTaskType(taskType) !== "poc" && subtaskId && parentTaskId && String(parentTaskId) !== String(taskId || subtaskId)
8812
+ );
8845
8813
  }
8846
8814
  function deriveClickUpPrTarget({ isRelease = false, parentTaskId, parentBranch, parentTaskType, taskType, devBranch = "dev", mainBranch = "main" } = {}) {
8847
8815
  if (isRelease) return mainBranch;
@@ -9030,15 +8998,17 @@ function deriveClickUpPendingSubtaskBranch({ taskType, parentTaskId, title } = {
9030
8998
  const parentSlug = branchSafeClickUpId(parentTaskId);
9031
8999
  if (!typeSlug || !parentSlug) throw new Error("taskType and parentTaskId are required to derive a pending subtask branch name.");
9032
9000
  if (typeSlug === "poc") return ["poc", parentSlug].join("/");
9033
- return [typeSlug, parentSlug, `pending-${normalizeLooseToken(title) || "subtask"}`].join("/");
9001
+ return `${typeSlug}/${parentSlug}-pending-${normalizeLooseToken(title) || "subtask"}`;
9034
9002
  }
9035
- function buildClickUpSubtaskAgentMetadata({ parentTaskId, subtask, branch, prTarget, titleSlug } = {}) {
9003
+ function buildClickUpSubtaskAgentMetadata({ parentTaskId, subtask, branch, prTarget, titleSlug, parentBranch } = {}) {
9036
9004
  return mergeClickUpAgentMetadata("", {
9037
9005
  subtask: {
9038
9006
  parent_task_id: parentTaskId,
9007
+ parent_branch: parentBranch || prTarget,
9039
9008
  title: subtask.title,
9040
9009
  title_slug: titleSlug,
9041
9010
  branch,
9011
+ subtask_branch: branch,
9042
9012
  pr_target: prTarget,
9043
9013
  pending_clickup_subtask_id: true,
9044
9014
  owner_role: subtask.ownerRole,
@@ -9058,7 +9028,7 @@ function buildClickUpCreateSubtasksPayload({ parentTaskId, markdown = "", source
9058
9028
  const titleSlug = normalizeLooseToken(subtask.title) || "subtask";
9059
9029
  const branch = subtask.branch || deriveClickUpPendingSubtaskBranch({ taskType: subtask.type, parentTaskId: parentId, title: subtask.title });
9060
9030
  const prTarget = normalizeClickUpTaskType(subtask.type) === "poc" ? "dev" : parentBranchValue;
9061
- const agentMetadata = buildClickUpSubtaskAgentMetadata({ parentTaskId: parentId, subtask, branch, prTarget, titleSlug });
9031
+ const agentMetadata = buildClickUpSubtaskAgentMetadata({ parentTaskId: parentId, subtask, branch, prTarget, titleSlug, parentBranch: parentBranchValue });
9062
9032
  const descriptionParts = [
9063
9033
  subtask.description,
9064
9034
  subtask.acceptanceCriteria.length ? ["Acceptance Criteria:", ...subtask.acceptanceCriteria.map((item) => `- ${item}`)].join("\n") : ""
@@ -9236,27 +9206,261 @@ function safeExistingClickUpWorktree({ metadata = {}, branch = "" } = {}) {
9236
9206
  return null;
9237
9207
  }
9238
9208
  }
9209
+ function clickUpGitRefExists(baseWorktree, ref, runGitFn = runGit) {
9210
+ try {
9211
+ runGitFn(baseWorktree, ["rev-parse", "--verify", ref]);
9212
+ return true;
9213
+ } catch {
9214
+ return false;
9215
+ }
9216
+ }
9217
+ function resolveClickUpDevStartPoint(baseWorktree, runGitFn = runGit) {
9218
+ return clickUpGitRefExists(baseWorktree, "dev", runGitFn) ? "dev" : "origin/dev";
9219
+ }
9220
+ function addClickUpWorktreeForBranch({ baseWorktree, branch, worktreePath, startPoint, runGitFn = runGit } = {}) {
9221
+ if (clickUpGitRefExists(baseWorktree, branch, runGitFn)) {
9222
+ runGitFn(baseWorktree, ["worktree", "add", worktreePath, branch]);
9223
+ } else {
9224
+ runGitFn(baseWorktree, ["worktree", "add", "-b", branch, worktreePath, startPoint]);
9225
+ }
9226
+ }
9227
+ function clickUpOpenChamberWorktreeName(branch = "") {
9228
+ return String(branch || "").trim().replace(/\//g, "-");
9229
+ }
9230
+ function openChamberUrl(baseUrl, pathname, query = {}) {
9231
+ const url = new URL(pathname, normalizeOpenCodeBaseUrl(baseUrl));
9232
+ for (const [key, value] of Object.entries(query)) {
9233
+ if (value !== void 0 && value !== null && String(value).trim()) url.searchParams.set(key, String(value));
9234
+ }
9235
+ return url.toString();
9236
+ }
9237
+ async function readOpenChamberJson(response, endpoint) {
9238
+ const text = await response.text();
9239
+ let data = null;
9240
+ if (text.trim()) {
9241
+ try {
9242
+ data = JSON.parse(text);
9243
+ } catch {
9244
+ throw new Error(`OpenChamber ${endpoint} returned non-JSON response.`);
9245
+ }
9246
+ }
9247
+ if (!response.ok) {
9248
+ const message = data?.error?.message || data?.message || data?.data?.message || text.slice(0, 200) || `HTTP ${response.status}`;
9249
+ throw new Error(`OpenChamber ${endpoint} failed: ${response.status} ${message}`);
9250
+ }
9251
+ return data;
9252
+ }
9253
+ async function requestOpenChamberJson({ baseUrl, endpoint, method = "GET", directory, body, fetchImpl = globalThis.fetch } = {}) {
9254
+ if (typeof fetchImpl !== "function") throw new Error("OpenChamber worktree provisioning requires fetch.");
9255
+ const response = await fetchImpl(openChamberUrl(baseUrl, endpoint, { directory }), {
9256
+ method,
9257
+ headers: body ? { "content-type": "application/json" } : void 0,
9258
+ body: body ? JSON.stringify(body) : void 0
9259
+ });
9260
+ return readOpenChamberJson(response, endpoint);
9261
+ }
9262
+ function normalizeOpenChamberCollection(value) {
9263
+ if (Array.isArray(value)) return value;
9264
+ if (!isPlainObject(value)) return [];
9265
+ for (const key of ["worktrees", "items", "data", "result", "results", "directories", "sandboxes"]) {
9266
+ const nested = value[key];
9267
+ if (Array.isArray(nested)) return nested;
9268
+ if (isPlainObject(nested)) {
9269
+ const normalized = normalizeOpenChamberCollection(nested);
9270
+ if (normalized.length > 0) return normalized;
9271
+ }
9272
+ }
9273
+ return [];
9274
+ }
9275
+ function openChamberEntryDirectory(entry) {
9276
+ if (typeof entry === "string") return entry;
9277
+ return String(entry?.directory || entry?.path || entry?.worktreePath || entry?.worktree_path || entry?.worktree?.path || entry?.worktree?.directory || "");
9278
+ }
9279
+ function openChamberEntryBranch(entry) {
9280
+ if (typeof entry === "string") return "";
9281
+ return String(entry?.branch || entry?.branchName || entry?.branch_name || entry?.worktree?.branch || "").replace(/^refs\/heads\//, "");
9282
+ }
9283
+ function openChamberListIncludesDirectory(list, directory) {
9284
+ const resolved = path5.resolve(directory);
9285
+ return normalizeOpenChamberCollection(list).some((entry) => {
9286
+ const entryDirectory = openChamberEntryDirectory(entry);
9287
+ return entryDirectory && path5.resolve(entryDirectory) === resolved;
9288
+ });
9289
+ }
9290
+ function openChamberListIncludesBranch(list, directory, branch) {
9291
+ const resolved = path5.resolve(directory);
9292
+ return normalizeOpenChamberCollection(list).some((entry) => {
9293
+ const entryDirectory = openChamberEntryDirectory(entry);
9294
+ if (!entryDirectory || path5.resolve(entryDirectory) !== resolved) return false;
9295
+ const entryBranch = openChamberEntryBranch(entry);
9296
+ return !entryBranch || entryBranch === branch;
9297
+ });
9298
+ }
9299
+ async function findOpenChamberProject({ baseUrl, baseWorktree, fetchImpl = globalThis.fetch } = {}) {
9300
+ const projects = await requestOpenChamberJson({ baseUrl, endpoint: "/project", directory: baseWorktree, fetchImpl });
9301
+ if (!Array.isArray(projects)) return null;
9302
+ const resolvedBase = path5.resolve(baseWorktree);
9303
+ return projects.find((project) => path5.resolve(String(project?.worktree || project?.path || "")) === resolvedBase) || null;
9304
+ }
9305
+ async function refreshOpenChamberProjectCopy({ baseUrl, baseWorktree, projectId, fetchImpl = globalThis.fetch } = {}) {
9306
+ if (!projectId) return { refreshed: false, reason: "project_id_unavailable" };
9307
+ const response = await fetchImpl(openChamberUrl(baseUrl, `/experimental/project/${encodeURIComponent(projectId)}/copy/refresh`, {}), { method: "POST" });
9308
+ await readOpenChamberJson(response, "/experimental/project/{projectID}/copy/refresh");
9309
+ return { refreshed: true, projectId };
9310
+ }
9311
+ async function listOpenChamberGitWorktrees({ baseUrl, baseWorktree, fetchImpl = globalThis.fetch } = {}) {
9312
+ return requestOpenChamberJson({ baseUrl, endpoint: "/api/git/worktrees", directory: baseWorktree, fetchImpl });
9313
+ }
9314
+ async function verifyOpenChamberGitWorktree({ baseUrl, baseWorktree, worktreePath, branch, fetchImpl = globalThis.fetch } = {}) {
9315
+ const worktrees = await listOpenChamberGitWorktrees({ baseUrl, baseWorktree, fetchImpl });
9316
+ const verified = openChamberListIncludesBranch(worktrees, worktreePath, branch);
9317
+ if (!verified) {
9318
+ throw new Error(`OpenChamber Git worktree verification failed for ${worktreePath} on ${branch}.`);
9319
+ }
9320
+ return { worktree: true, branch: true };
9321
+ }
9322
+ async function syncOpenChamberWorktreeVisibility({ baseUrl, baseWorktree, worktreePath, branch, fetchImpl = globalThis.fetch } = {}) {
9323
+ const gitWorktree = await verifyOpenChamberGitWorktree({ baseUrl, baseWorktree, worktreePath, branch, fetchImpl });
9324
+ await requestOpenChamberJson({ baseUrl, endpoint: "/experimental/workspace/sync-list", method: "POST", directory: baseWorktree, fetchImpl });
9325
+ const project = await findOpenChamberProject({ baseUrl, baseWorktree, fetchImpl });
9326
+ if (!project?.id) throw new Error("OpenChamber project was not found after workspace sync; refusing to treat worktree as visible.");
9327
+ await refreshOpenChamberProjectCopy({ baseUrl, baseWorktree, projectId: project.id, fetchImpl });
9328
+ const [worktrees, workspaces, directories] = await Promise.all([
9329
+ listOpenChamberGitWorktrees({ baseUrl, baseWorktree, fetchImpl }),
9330
+ requestOpenChamberJson({ baseUrl, endpoint: "/experimental/workspace", directory: baseWorktree, fetchImpl }),
9331
+ requestOpenChamberJson({ baseUrl, endpoint: `/project/${encodeURIComponent(project.id)}/directories`, directory: baseWorktree, fetchImpl })
9332
+ ]);
9333
+ const visibility = {
9334
+ worktree: openChamberListIncludesBranch(worktrees, worktreePath, branch),
9335
+ workspace: openChamberListIncludesBranch(workspaces, worktreePath, branch),
9336
+ projectDirectory: openChamberListIncludesDirectory(directories, worktreePath),
9337
+ gitWorktree,
9338
+ projectId: project.id
9339
+ };
9340
+ if (!visibility.worktree || !visibility.workspace || !visibility.projectDirectory) {
9341
+ throw new Error(`OpenChamber visibility verification failed for ${worktreePath}: ${JSON.stringify(visibility)}`);
9342
+ }
9343
+ return visibility;
9344
+ }
9345
+ function assertOpenChamberClickUpWorktreePath({ baseWorktree, worktreePath } = {}) {
9346
+ if (!isClickUpDerivedWorktreeSibling(worktreePath, baseWorktree)) {
9347
+ throw new Error(`OpenChamber worktree path is outside the configured ClickUp sibling scope: ${worktreePath}`);
9348
+ }
9349
+ }
9350
+ async function createOpenChamberClickUpWorktree({ baseUrl, baseWorktree, branch, worktreePath, startPoint, branchExists = false, fetchImpl = globalThis.fetch } = {}) {
9351
+ const worktreeName = clickUpOpenChamberWorktreeName(branch);
9352
+ const body = { name: worktreeName, mode: branchExists ? "existing" : "new", worktreeName, branchName: branch, startRef: branchExists ? branch : startPoint };
9353
+ let created;
9354
+ try {
9355
+ created = await requestOpenChamberJson({ baseUrl, endpoint: "/api/git/worktrees", method: "POST", directory: baseWorktree, body, fetchImpl });
9356
+ } catch (error) {
9357
+ throw new Error(`OpenChamber could not create ${branch} from ${branchExists ? branch : startPoint}; API may not support required branch/startRef semantics. Fail-closed: ${error.message}`);
9358
+ }
9359
+ const createdDirectory = openChamberEntryDirectory(created);
9360
+ const createdBranch = openChamberEntryBranch(created);
9361
+ if (!createdDirectory || !path5.isAbsolute(createdDirectory)) {
9362
+ throw new Error(`OpenChamber did not return an absolute worktree path for ${branch}.`);
9363
+ }
9364
+ if (createdBranch !== branch) {
9365
+ throw new Error(`OpenChamber created unexpected branch ${createdBranch || "<unknown>"}; expected ${branch}.`);
9366
+ }
9367
+ const verified = await verifyOpenChamberGitWorktree({ baseUrl, baseWorktree, worktreePath: createdDirectory, branch, fetchImpl });
9368
+ return { created, worktree: path5.resolve(createdDirectory), branch: createdBranch, verified };
9369
+ }
9370
+ async function registerOpenChamberClickUpWorktree({ baseUrl, baseWorktree, branch, worktreePath, fetchImpl = globalThis.fetch, source = "reuse" } = {}) {
9371
+ assertOpenChamberClickUpWorktreePath({ baseWorktree, worktreePath });
9372
+ const visibility = await syncOpenChamberWorktreeVisibility({ baseUrl, baseWorktree, worktreePath, branch, fetchImpl });
9373
+ return { branch, worktree: path5.resolve(worktreePath), reused: true, provider: "openchamber", openChamber: { source, visibility } };
9374
+ }
9375
+ async function ensureClickUpTaskWorktreeOpenChamber({ baseWorktree = "", taskId, taskType = "Tarea", parentTaskId = "", subtaskId = "", existingMetadata = {}, runGitFn = runGit, baseUrl = "", fetchImpl = globalThis.fetch, log = null } = {}) {
9376
+ const effectiveParent = parentTaskId || taskId;
9377
+ const isSubtask = isClickUpSubtaskRoute({ taskType, parentTaskId: effectiveParent, subtaskId, taskId });
9378
+ const parentBranch = isSubtask ? deriveClickUpBranchName({ taskType, parentTaskId: effectiveParent }) : "";
9379
+ const branch = deriveClickUpBranchName({ taskType, parentTaskId: effectiveParent, subtaskId, taskId });
9380
+ const prTarget = parentBranch || "dev";
9381
+ const existing = safeExistingClickUpWorktree({ metadata: existingMetadata, branch });
9382
+ if (existing) {
9383
+ const registered = await registerOpenChamberClickUpWorktree({ baseUrl, baseWorktree, branch, worktreePath: existing.worktree, fetchImpl, source: "metadata_reuse" });
9384
+ log?.({ type: "openchamber_worktree_registered", taskId, branch, worktree: registered.worktree, source: "metadata_reuse", visibility: registered.openChamber.visibility });
9385
+ return { ...registered, parentBranch: parentBranch || void 0, prTarget };
9386
+ }
9387
+ const worktreePath = deriveClickUpWorktree({ baseWorktree, taskId, taskType, parentTaskId: effectiveParent, subtaskId });
9388
+ if (fs5.existsSync(worktreePath)) {
9389
+ const registered = await registerOpenChamberClickUpWorktree({ baseUrl, baseWorktree, branch, worktreePath, fetchImpl, source: "existing_directory" });
9390
+ log?.({ type: "openchamber_worktree_registered", taskId, branch, worktree: registered.worktree, source: "existing_directory", visibility: registered.openChamber.visibility });
9391
+ return { ...registered, parentBranch: parentBranch || void 0, prTarget };
9392
+ }
9393
+ let parentBootstrap = null;
9394
+ if (isSubtask) {
9395
+ const parentWorktree = deriveClickUpWorktree({ baseWorktree, taskId: effectiveParent, taskType, parentTaskId: effectiveParent });
9396
+ if (fs5.existsSync(parentWorktree)) {
9397
+ const registeredParent = await registerOpenChamberClickUpWorktree({ baseUrl, baseWorktree, branch: parentBranch, worktreePath: parentWorktree, fetchImpl, source: "parent_existing_directory" });
9398
+ parentBootstrap = { branch: parentBranch, worktree: registeredParent.worktree, reused: true, provider: "openchamber", visibility: registeredParent.openChamber.visibility };
9399
+ } else {
9400
+ const parentStartPoint = resolveClickUpDevStartPoint(baseWorktree, runGitFn);
9401
+ const parentBranchExists = clickUpGitRefExists(baseWorktree, parentBranch, runGitFn);
9402
+ const createdParent = await createOpenChamberClickUpWorktree({ baseUrl, baseWorktree, branch: parentBranch, worktreePath: parentWorktree, startPoint: parentStartPoint, branchExists: parentBranchExists, fetchImpl });
9403
+ const parentVisibility = await syncOpenChamberWorktreeVisibility({ baseUrl, baseWorktree, worktreePath: createdParent.worktree, branch: parentBranch, fetchImpl });
9404
+ parentBootstrap = { branch: parentBranch, worktree: createdParent.worktree, startPoint: parentBranchExists ? parentBranch : parentStartPoint, reused: parentBranchExists, provider: "openchamber", visibility: parentVisibility };
9405
+ log?.({ type: "openchamber_worktree_created", taskId: effectiveParent, branch: parentBranch, worktree: parentBootstrap.worktree, startPoint: parentBootstrap.startPoint, visibility: parentVisibility });
9406
+ }
9407
+ }
9408
+ const startPoint = isSubtask ? parentBranch : resolveClickUpDevStartPoint(baseWorktree, runGitFn);
9409
+ const branchExists = clickUpGitRefExists(baseWorktree, branch, runGitFn);
9410
+ const created = await createOpenChamberClickUpWorktree({ baseUrl, baseWorktree, branch, worktreePath, startPoint, branchExists, fetchImpl });
9411
+ const visibility = await syncOpenChamberWorktreeVisibility({ baseUrl, baseWorktree, worktreePath: created.worktree, branch, fetchImpl });
9412
+ log?.({ type: "openchamber_worktree_created", taskId, branch, worktree: created.worktree, startPoint: branchExists ? branch : startPoint, visibility });
9413
+ return { branch, worktree: created.worktree, reused: false, startPoint, parentBranch: parentBranch || void 0, prTarget, parentBootstrap: parentBootstrap || void 0, provider: "openchamber", openChamber: { source: "created", visibility } };
9414
+ }
9415
+ async function ensureClickUpTaskWorktreeForWebhook({ opencodeBaseUrl = "", opencodeBaseUrlConfigured = false, openchamberBaseUrl = "", openchamberBaseUrlConfigured = false, clickupClient = null, webhookWorktree = process.cwd(), fetchImpl = globalThis.fetch, ...options } = {}) {
9416
+ void opencodeBaseUrl;
9417
+ void opencodeBaseUrlConfigured;
9418
+ if (!openchamberBaseUrlConfigured || !openchamberBaseUrl) return ensureClickUpTaskWorktree(options);
9419
+ try {
9420
+ return await ensureClickUpTaskWorktreeOpenChamber({ ...options, baseUrl: openchamberBaseUrl, fetchImpl, log: (entry) => appendClickUpWebhookLocalLog(webhookWorktree, entry) });
9421
+ } catch (error) {
9422
+ const message = `OpenChamber worktree provisioning failed for ${options.taskId || "unknown task"}; raw git fallback is disabled to avoid invisible worktrees. ${error.message}`;
9423
+ appendClickUpWebhookLocalLog(webhookWorktree, { type: "openchamber_worktree_failed", taskId: options.taskId || null, message });
9424
+ if (typeof clickupClient?.postTaskComment === "function") {
9425
+ try {
9426
+ await clickupClient.postTaskComment({ taskId: options.taskId, comment: `${message}
9427
+
9428
+ Optima did not run raw git worktree fallback. Please verify clickup.openchamber.base_url and OpenChamber Git API compatibility.` });
9429
+ } catch (commentError) {
9430
+ appendClickUpWebhookLocalLog(webhookWorktree, { type: "openchamber_worktree_blocker_comment_failed", taskId: options.taskId || null, message: commentError.message });
9431
+ }
9432
+ }
9433
+ throw new Error(message);
9434
+ }
9435
+ }
9239
9436
  function ensureClickUpTaskWorktree({ baseWorktree = "", taskId, taskType = "Tarea", parentTaskId = "", subtaskId = "", existingMetadata = {}, runGitFn = runGit, allowNonGitFallback = false } = {}) {
9240
9437
  const effectiveParent = parentTaskId || taskId;
9438
+ const isSubtask = isClickUpSubtaskRoute({ taskType, parentTaskId: effectiveParent, subtaskId, taskId });
9439
+ const parentBranch = isSubtask ? deriveClickUpBranchName({ taskType, parentTaskId: effectiveParent }) : "";
9241
9440
  const branch = deriveClickUpBranchName({ taskType, parentTaskId: effectiveParent, subtaskId, taskId });
9242
9441
  const existing = safeExistingClickUpWorktree({ metadata: existingMetadata, branch });
9243
- if (existing) return { ...existing, branch };
9442
+ if (existing) return { ...existing, branch, parentBranch: parentBranch || void 0, prTarget: parentBranch || "dev" };
9244
9443
  const worktreePath = deriveClickUpWorktree({ baseWorktree, taskId, taskType, parentTaskId: effectiveParent, subtaskId });
9245
- if (fs5.existsSync(worktreePath)) return { branch, worktree: path5.resolve(worktreePath), reused: true };
9444
+ if (fs5.existsSync(worktreePath)) return { branch, worktree: path5.resolve(worktreePath), reused: true, parentBranch: parentBranch || void 0, prTarget: parentBranch || "dev" };
9246
9445
  if (allowNonGitFallback) {
9247
9446
  fs5.mkdirSync(worktreePath, { recursive: true });
9248
- return { branch, worktree: path5.resolve(worktreePath), reused: false, fallback: "non_git" };
9447
+ return { branch, worktree: path5.resolve(worktreePath), reused: false, fallback: "non_git", parentBranch: parentBranch || void 0, prTarget: parentBranch || "dev", startPoint: parentBranch || "dev" };
9249
9448
  }
9250
- const startPoint = (() => {
9251
- try {
9252
- runGitFn(baseWorktree, ["rev-parse", "--verify", "dev"]);
9253
- return "dev";
9254
- } catch {
9255
- return "origin/dev";
9449
+ let parentBootstrap = null;
9450
+ if (isSubtask) {
9451
+ const parentWorktree = deriveClickUpWorktree({ baseWorktree, taskId: effectiveParent, taskType, parentTaskId: effectiveParent });
9452
+ if (!fs5.existsSync(parentWorktree)) {
9453
+ const parentStartPoint = resolveClickUpDevStartPoint(baseWorktree, runGitFn);
9454
+ const parentBranchExists = clickUpGitRefExists(baseWorktree, parentBranch, runGitFn);
9455
+ addClickUpWorktreeForBranch({ baseWorktree, branch: parentBranch, worktreePath: parentWorktree, startPoint: parentStartPoint, runGitFn });
9456
+ parentBootstrap = { branch: parentBranch, worktree: path5.resolve(parentWorktree), startPoint: parentBranchExists ? parentBranch : parentStartPoint, reused: parentBranchExists };
9457
+ } else {
9458
+ parentBootstrap = { branch: parentBranch, worktree: path5.resolve(parentWorktree), reused: true };
9256
9459
  }
9257
- })();
9258
- runGitFn(baseWorktree, ["worktree", "add", "-b", branch, worktreePath, startPoint]);
9259
- return { branch, worktree: path5.resolve(worktreePath), reused: false, startPoint };
9460
+ }
9461
+ const startPoint = isSubtask ? parentBranch : resolveClickUpDevStartPoint(baseWorktree, runGitFn);
9462
+ addClickUpWorktreeForBranch({ baseWorktree, branch, worktreePath, startPoint, runGitFn });
9463
+ return { branch, worktree: path5.resolve(worktreePath), reused: false, startPoint, parentBranch: parentBranch || void 0, prTarget: parentBranch || "dev", parentBootstrap: parentBootstrap || void 0 };
9260
9464
  }
9261
9465
  function normalizeClickUpDefinitionDocParent(parent = {}) {
9262
9466
  const docId = String(parent.doc_id || parent.docId || CLICKUP_DEFINITION_DOC_PARENT.doc_id).trim();
@@ -9278,13 +9482,22 @@ function buildClickUpStartTaskPayload({ taskId, taskType = "Tarea", parentTaskId
9278
9482
  if (!description) errors.push("taskDescription is required for the initial ClickUp task description rewrite.");
9279
9483
  if (errors.length > 0) return clickUpPayloadValidationError(errors);
9280
9484
  const effectiveParent = parentTaskId || taskId;
9485
+ const isSubtask = isClickUpSubtaskRoute({ taskType, parentTaskId: effectiveParent, subtaskId, taskId });
9486
+ const parentBranch = isSubtask ? deriveClickUpBranchName({ taskType, parentTaskId: effectiveParent }) : "";
9281
9487
  const branch = deriveClickUpBranchName({ taskType, parentTaskId: effectiveParent, subtaskId, taskId });
9282
9488
  const worktree = deriveClickUpWorktree({ baseWorktree, taskId, taskType, parentTaskId: effectiveParent, subtaskId });
9489
+ const prTarget = isSubtask ? parentBranch : "dev";
9490
+ const startFrom = isSubtask ? parentBranch : "dev";
9283
9491
  const estimate = preEstimateClickUpWork({ complexity, filesChanged, acceptanceCriteria, unknowns });
9284
9492
  const metadata = mergeClickUpAgentMetadata(existingAgentMetadata, {
9285
9493
  task: {
9494
+ parent_task_id: isSubtask ? effectiveParent : void 0,
9495
+ parent_branch: parentBranch || void 0,
9286
9496
  branch,
9497
+ subtask_branch: isSubtask ? branch : void 0,
9287
9498
  worktree,
9499
+ subtask_worktree: isSubtask ? worktree : void 0,
9500
+ pr_target: prTarget,
9288
9501
  mirror_task_path: `.optima/tasks/${branchSafeClickUpId(taskId || subtaskId || effectiveParent)}.md`,
9289
9502
  evidence_path: `.optima/evidences/${branchSafeClickUpId(taskId || subtaskId || effectiveParent)}/SUMMARY.md`,
9290
9503
  delivery_evidence_path: deliveryEvidencePathForClickUpTask(taskId || subtaskId || effectiveParent),
@@ -9297,17 +9510,18 @@ function buildClickUpStartTaskPayload({ taskId, taskType = "Tarea", parentTaskId
9297
9510
  dryRun: true,
9298
9511
  required_first_actions: [
9299
9512
  "Create or reuse the task-specific branch/worktree before planning or writing local .optima mirrors.",
9300
- `Use branch ${branch} from dev and worktree ${worktree} for this task workspace.`,
9513
+ `Use branch ${branch} from ${startFrom} and worktree ${worktree} for this task workspace.`,
9301
9514
  "Write planning state, .optima/tasks/current.md, task mirrors, and local evidence only inside the task worktree.",
9302
9515
  `Write merge-trackable final evidence under ${deliveryEvidencePathForClickUpTask(taskId || subtaskId || effectiveParent)}; .optima remains local mirror/staging.`,
9303
9516
  "Do not update the principal dev workspace .optima/tasks/current.md for ClickUp task planning.",
9304
9517
  "If another active task is present in current.md, move to or create this task worktree instead of stopping."
9305
9518
  ],
9306
9519
  git: {
9307
- startFrom: "dev",
9520
+ startFrom,
9308
9521
  branch,
9309
9522
  worktree,
9310
- prTarget: subtaskId && normalizeClickUpTaskType(taskType) !== "poc" ? deriveClickUpPrTarget({ parentTaskId: effectiveParent, parentTaskType: taskType }) : "dev"
9523
+ parentBranch: parentBranch || void 0,
9524
+ prTarget
9311
9525
  },
9312
9526
  mirror: {
9313
9527
  taskPath: `.optima/tasks/${branchSafeClickUpId(taskId || subtaskId || effectiveParent)}.md`,
@@ -9319,7 +9533,7 @@ function buildClickUpStartTaskPayload({ taskId, taskType = "Tarea", parentTaskId
9319
9533
  wouldCreate: true
9320
9534
  },
9321
9535
  clickup: {
9322
- comment: `Starting task from dev. Branch: ${branch}. Worktree: ${worktree}. Delivery evidence: ${deliveryEvidencePathForClickUpTask(taskId || subtaskId || effectiveParent)}.`,
9536
+ comment: `Starting task from ${startFrom}. Branch: ${branch}. Worktree: ${worktree}. Delivery evidence: ${deliveryEvidencePathForClickUpTask(taskId || subtaskId || effectiveParent)}.`,
9323
9537
  description,
9324
9538
  fields: {
9325
9539
  Definition: definitionContent,
@@ -9580,6 +9794,11 @@ function normalizeClickUpWebhookConfig(rawClickUp = null, worktree = process.cwd
9580
9794
  const webhook = isPlainObject(raw.webhook) ? raw.webhook : {};
9581
9795
  const routing = isPlainObject(raw.routing) ? raw.routing : {};
9582
9796
  const opencode = isPlainObject(raw.opencode) ? raw.opencode : {};
9797
+ const openchamber = isPlainObject(raw.openchamber) ? raw.openchamber : {};
9798
+ const rawOpenCodeBaseUrl = opencode.base_url ?? opencode.baseUrl ?? raw.opencode_base_url ?? raw.opencodeBaseUrl;
9799
+ const rawOpenChamberBaseUrl = openchamber.base_url ?? openchamber.baseUrl ?? raw.openchamber_base_url ?? raw.openchamberBaseUrl;
9800
+ const openCodeBaseUrlConfigured = rawOpenCodeBaseUrl !== void 0 && rawOpenCodeBaseUrl !== null && String(rawOpenCodeBaseUrl).trim() !== "";
9801
+ const openChamberBaseUrlConfigured = rawOpenChamberBaseUrl !== void 0 && rawOpenChamberBaseUrl !== null && String(rawOpenChamberBaseUrl).trim() !== "";
9583
9802
  const location = isPlainObject(webhook.location) ? webhook.location : {};
9584
9803
  const events = Array.isArray(webhook.events) && webhook.events.length > 0 ? [...new Set(webhook.events.map((event) => String(event || "").trim()).filter(Boolean))] : [...CLICKUP_WEBHOOK_EVENTS];
9585
9804
  const ignoredStatuses = Array.isArray(routing.ignored_statuses) && routing.ignored_statuses.length > 0 ? routing.ignored_statuses : CLICKUP_WEBHOOK_TERMINAL_STATUSES;
@@ -9591,7 +9810,8 @@ function normalizeClickUpWebhookConfig(rawClickUp = null, worktree = process.cwd
9591
9810
  apiToken: String(raw.api_token || raw.apiToken || "").trim(),
9592
9811
  log: normalizeClickUpWebhookLogLevel(raw.log),
9593
9812
  opencode: {
9594
- baseUrl: normalizeOpenCodeBaseUrl(opencode.base_url || opencode.baseUrl || raw.opencode_base_url || raw.opencodeBaseUrl),
9813
+ baseUrl: normalizeOpenCodeBaseUrl(rawOpenCodeBaseUrl),
9814
+ baseUrlConfigured: openCodeBaseUrlConfigured,
9595
9815
  promptDelivery: ["http", "direct"].includes(String(opencode.prompt_delivery || opencode.promptDelivery || raw.prompt_delivery || raw.promptDelivery || "").trim().toLowerCase()) ? "http" : "sdk",
9596
9816
  acceptPromptAdmission: opencode.accept_prompt_admission === true || opencode.acceptPromptAdmission === true || raw.accept_prompt_admission === true || raw.acceptPromptAdmission === true,
9597
9817
  startupReconciliationDelayMs: normalizeNonNegativeInteger(
@@ -9599,6 +9819,10 @@ function normalizeClickUpWebhookConfig(rawClickUp = null, worktree = process.cwd
9599
9819
  CLICKUP_WEBHOOK_STARTUP_RECONCILIATION_DELAY_MS
9600
9820
  )
9601
9821
  },
9822
+ openchamber: {
9823
+ baseUrl: normalizeOpenCodeBaseUrl(rawOpenChamberBaseUrl, ""),
9824
+ baseUrlConfigured: openChamberBaseUrlConfigured
9825
+ },
9602
9826
  webhook: {
9603
9827
  publicUrl: String(webhook.public_url || webhook.publicUrl || "").trim(),
9604
9828
  bindHost: String(webhook.bind_host || webhook.bindHost || "127.0.0.1").trim(),
@@ -9640,6 +9864,13 @@ function normalizeClickUpWebhookConfig(rawClickUp = null, worktree = process.cwd
9640
9864
  errors.push("clickup.opencode.base_url must be a valid URL");
9641
9865
  }
9642
9866
  }
9867
+ if (config.openchamber.baseUrl) {
9868
+ try {
9869
+ new URL(config.openchamber.baseUrl);
9870
+ } catch {
9871
+ errors.push("clickup.openchamber.base_url must be a valid URL");
9872
+ }
9873
+ }
9643
9874
  const missingEvents = CLICKUP_WEBHOOK_EVENTS.filter((event) => !config.webhook.events.includes(event));
9644
9875
  if (missingEvents.length > 0) errors.push(`clickup.webhook.events missing: ${missingEvents.join(", ")}`);
9645
9876
  if (config.routing.targetAgent !== "workflow_product_manager") errors.push("clickup.routing.target_agent must be workflow_product_manager");
@@ -10563,6 +10794,16 @@ async function probeOpenCodeSessionControl(client, { directory, agent, omitAgent
10563
10794
  const rawMessages = await readOpenCodeSessionMessages(client, { sessionId: create.session_id, directory, limit: 50 });
10564
10795
  if (!rawMessages) throw new Error("OpenCode client does not expose session.messages.");
10565
10796
  const fullMessageText = rawMessages.map(openCodeMessageText).join("\n");
10797
+ const respondingAgents = [...new Set(rawMessages.filter((message) => normalizeLooseToken(normalizeOpenCodeMessageRole(message)) === "assistant").flatMap((message) => [normalizeOpenCodeMessageAgent(message), normalizeOpenCodeMessageMode(message)]).map((value) => String(value || "").trim()).filter(Boolean))];
10798
+ const requestedAgent = normalizeLooseToken(agent);
10799
+ const assistantVisible = rawMessages.some((message) => normalizeLooseToken(normalizeOpenCodeMessageRole(message)) === "assistant");
10800
+ const markerVisible = fullMessageText.includes(marker);
10801
+ const deliveryVerified = markerVisible && assistantVisible;
10802
+ const requestedAgentVerified = requestedAgent ? deliveryVerified && rawMessages.some((message) => {
10803
+ const messageAgent = normalizeLooseToken(normalizeOpenCodeMessageAgent(message));
10804
+ const messageMode = normalizeLooseToken(normalizeOpenCodeMessageMode(message));
10805
+ return normalizeLooseToken(normalizeOpenCodeMessageRole(message)) === "assistant" && (messageAgent === requestedAgent || messageMode === requestedAgent);
10806
+ }) : null;
10566
10807
  const messages = {
10567
10808
  ok: true,
10568
10809
  session_id: create.session_id,
@@ -10580,8 +10821,11 @@ async function probeOpenCodeSessionControl(client, { directory, agent, omitAgent
10580
10821
  marker_length: marker.length,
10581
10822
  marker_truncated: requestedMarker.length > marker.length,
10582
10823
  marker_hash: hashOpenCodeSessionText(marker),
10583
- marker_visible: fullMessageText.includes(marker),
10584
- assistant_visible: rawMessages.some((message) => normalizeLooseToken(normalizeOpenCodeMessageRole(message)) === "assistant" || Boolean(normalizeOpenCodeMessageAgent(message) && openCodeMessageText(message))),
10824
+ marker_visible: markerVisible,
10825
+ assistant_visible: assistantVisible,
10826
+ delivery_verified: deliveryVerified,
10827
+ requested_agent_verified: requestedAgentVerified,
10828
+ responding_agents: respondingAgents,
10585
10829
  create,
10586
10830
  prompt,
10587
10831
  messages
@@ -10916,7 +11160,7 @@ async function withClickUpTaskRouteLock(taskId, operation) {
10916
11160
  if (activeClickUpTaskRoutes.get(key) === current) activeClickUpTaskRoutes.delete(key);
10917
11161
  }
10918
11162
  }
10919
- async function routeClickUpWebhookEventUnlocked({ payload, config, state = {}, worktree = process.cwd(), clickupClient, openCodeClient, sessionExists = openCodeSessionExists, createSession = createOpenCodeSession, sendSessionEvent = sendOpenCodeSessionEvent, ensureTaskWorktree = ensureClickUpTaskWorktree, verifySessionEventDelivery = verifyOpenCodeSessionEventDelivery, saveState = null, now = () => /* @__PURE__ */ new Date(), host = os.hostname(), commentLedgerPath = clickUpCommentLedgerPath(worktree) } = {}) {
11163
+ async function routeClickUpWebhookEventUnlocked({ payload, config, state = {}, worktree = process.cwd(), clickupClient, openCodeClient, sessionExists = openCodeSessionExists, createSession = createOpenCodeSession, sendSessionEvent = sendOpenCodeSessionEvent, ensureTaskWorktree = ensureClickUpTaskWorktreeForWebhook, verifySessionEventDelivery = verifyOpenCodeSessionEventDelivery, saveState = null, now = () => /* @__PURE__ */ new Date(), host = os.hostname(), commentLedgerPath = clickUpCommentLedgerPath(worktree) } = {}) {
10920
11164
  const eventType = clickUpEventType(payload);
10921
11165
  const eventKey = clickUpWebhookEventKey(payload);
10922
11166
  const isStartupAssignmentReconciliation = payload?.startup_reconciliation === true && eventType === "taskAssigneeUpdated";
@@ -10972,7 +11216,7 @@ async function routeClickUpWebhookEventUnlocked({ payload, config, state = {}, w
10972
11216
  const subtaskId = parentTaskId && parentTaskId !== taskId ? taskId : "";
10973
11217
  let taskRoute;
10974
11218
  try {
10975
- taskRoute = ensureTaskWorktree({ baseWorktree: config.basePath, taskId, taskType, parentTaskId, subtaskId, existingMetadata: metadata, allowNonGitFallback: process.env.NODE_ENV === "test" || config.test === true });
11219
+ taskRoute = await ensureTaskWorktree({ baseWorktree: config.basePath, taskId, taskType, parentTaskId, subtaskId, existingMetadata: metadata, allowNonGitFallback: process.env.NODE_ENV === "test" || config.test === true, opencodeBaseUrl: config.opencode?.baseUrl, opencodeBaseUrlConfigured: config.opencode?.baseUrlConfigured === true, openchamberBaseUrl: config.openchamber?.baseUrl, openchamberBaseUrlConfigured: config.openchamber?.baseUrlConfigured === true, clickupClient, webhookWorktree: worktree });
10976
11220
  } catch (error) {
10977
11221
  const message = `Optima webhook could not create or reuse a task worktree for ${taskId}: ${error.message}`;
10978
11222
  appendClickUpWebhookLocalLog(worktree, { type: "task_worktree_failed", taskId, message });
@@ -10981,8 +11225,13 @@ async function routeClickUpWebhookEventUnlocked({ payload, config, state = {}, w
10981
11225
  }
10982
11226
  const deliveryEvidencePath = deliveryEvidencePathForClickUpTask(taskId);
10983
11227
  const routingMetadata = {
11228
+ parent_task_id: subtaskId ? parentTaskId : void 0,
11229
+ parent_branch: taskRoute.parentBranch,
10984
11230
  branch: taskRoute.branch,
11231
+ subtask_branch: subtaskId ? taskRoute.branch : void 0,
10985
11232
  worktree: taskRoute.worktree,
11233
+ subtask_worktree: subtaskId ? taskRoute.worktree : void 0,
11234
+ pr_target: taskRoute.prTarget || (subtaskId ? taskRoute.parentBranch : "dev"),
10986
11235
  delivery_evidence_path: deliveryEvidencePath,
10987
11236
  evidence_path: `.optima/evidences/${branchSafeClickUpId(taskId)}/SUMMARY.md`
10988
11237
  };
@@ -12254,7 +12503,33 @@ function getModePromptFragment(agentId, operatingTeamMode, worktree) {
12254
12503
  function shouldRegisterWorkflowProductManager(options = {}, worktree = process.cwd()) {
12255
12504
  if (options.clickUpWebhookActive === true) return true;
12256
12505
  const validation = options.clickUpWebhookValidation;
12257
- return validation?.complete === true && validation?.ok !== false && isSameOrNestedPath(worktree, validation.config?.basePath);
12506
+ if (validation?.complete !== true || validation?.ok === false) return false;
12507
+ const basePath = validation.config?.basePath;
12508
+ return isSameOrNestedPath(worktree, basePath) || isClickUpDerivedWorktreeSibling(worktree, basePath);
12509
+ }
12510
+ function isClickUpDerivedWorktreeSibling(candidate, basePath) {
12511
+ if (typeof candidate !== "string" || typeof basePath !== "string" || !candidate.trim() || !basePath.trim()) return false;
12512
+ const resolvedCandidate = path5.resolve(candidate);
12513
+ const resolvedBase = path5.resolve(basePath);
12514
+ const baseParent = path5.dirname(resolvedBase);
12515
+ if (path5.dirname(resolvedCandidate) !== baseParent) return false;
12516
+ const baseName = path5.basename(resolvedBase);
12517
+ const candidateName = path5.basename(resolvedCandidate);
12518
+ if (!candidateName.startsWith(`${baseName}-`)) return false;
12519
+ const branchSlug = candidateName.slice(baseName.length + 1);
12520
+ const parts = branchSlug.split("-").filter(Boolean);
12521
+ if (parts.length < 2) return false;
12522
+ if (!(/* @__PURE__ */ new Set(["tarea", "bug", "doc", "poc", "idea"])).has(parts[0])) return false;
12523
+ if (!parts.slice(1).every((part) => /^[a-z0-9][a-z0-9-]*$/.test(part))) return false;
12524
+ try {
12525
+ const candidateStat = fs5.lstatSync(resolvedCandidate);
12526
+ if (!candidateStat.isDirectory() || candidateStat.isSymbolicLink()) return false;
12527
+ const realCandidate = fs5.realpathSync.native(resolvedCandidate);
12528
+ const realBaseParent = fs5.realpathSync.native(baseParent);
12529
+ return path5.dirname(realCandidate) === realBaseParent && path5.basename(realCandidate) === candidateName;
12530
+ } catch {
12531
+ return false;
12532
+ }
12258
12533
  }
12259
12534
  function resolveSessionToolDirectory({ requestedDirectory, context, pluginWorktree, clickUpWebhookValidation } = {}) {
12260
12535
  const safe = safeWorktreeOrFailure(context, pluginWorktree);
@@ -12266,6 +12541,9 @@ function resolveSessionToolDirectory({ requestedDirectory, context, pluginWorktr
12266
12541
  if (clickUpBasePath && isSameOrNestedPath(requested, clickUpBasePath)) {
12267
12542
  return { ok: true, directory: requested, safeWorktree: safe.worktree, scope: "clickup_base_path", clickupBasePath: path5.resolve(clickUpBasePath) };
12268
12543
  }
12544
+ if (clickUpBasePath && isClickUpDerivedWorktreeSibling(requested, clickUpBasePath)) {
12545
+ return { ok: true, directory: requested, safeWorktree: safe.worktree, scope: "clickup_derived_worktree", clickupBasePath: path5.resolve(clickUpBasePath) };
12546
+ }
12269
12547
  return {
12270
12548
  ok: false,
12271
12549
  error: `Directory '${requested}' is outside the safe worktree '${safe.worktree}' and configured ClickUp base path.`
@@ -13097,7 +13375,7 @@ Follow-up: use optima_prompt_workflow with session_id '${sessionId}' to check in
13097
13375
  }
13098
13376
  };
13099
13377
  }
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 };
13378
+ OptimaPlugin.__internals = { BUNDLE_AGENTS_DIR, BUNDLE_ASSETS_DIR, CLICKUP_DEFINITION_DOC_PARENT, activeClickUpWebhookLifecycleRegistry, cleanupManagedClickUpWebhook, deleteClickUpWebhookBestEffort, BUNDLE_POLICIES_DIR, buildClickUpApplyPayloadResult, buildClickUpCreateSubtasksPayload, buildClickUpStartTaskPayload, buildClickUpSummaryPayload, buildClickUpTransitionPayload, buildOptimaAgents, clickUpCommentLedgerKey, clickUpCommentMentionsProductManager, clickUpWebhookAuditLogDir, clickUpWebhookAuditLogPath, compactPromptPath, createClickUpApiClient, createTestClickUpApiClient, createOpenCodeSession, createOpenCodeSessionControl, deliveryEvidencePathForClickUpTask, ensureClickUpTaskWorktree, ensureClickUpTaskWorktreeForWebhook, ensureClickUpTaskWorktreeOpenChamber, ensureClickUpWebhookSubscription, handleClickUpWebhookRequest, isClickUpDerivedWorktreeSibling, isClickUpSubtaskRoute, isClickUpWebhookStateActive, isSameOrNestedPath, normalizeClickUpWebhookConfig, normalizeClickUpWebhookLogLevel, normalizeOpenCodeBaseUrl, openCodeSessionExists, promptOpenCodeSessionControl, probeOpenCodeSessionControl, readClickUpCommentLedger, readClickUpWebhookState, readOpenCodeSessionControl, readOpenCodeSessionMessages, reconcileClickUpStartup, registerOpenChamberClickUpWorktree, scheduleClickUpStartupReconciliation, syncOpenChamberWorktreeVisibility, waitForOpenCodeReadiness, recordClickUpCommentVersionProcessed, resyncClickUpWebhookForSignatureDrift, resolveIncludeFile, resolveIncludes, resolveOptimaPluginOptions, resolveSecretReference, routeClickUpWebhookEvent, sendOpenCodeSessionEvent, sendOpenCodeSessionEventDirect, summarizeOpenCodeMessages, verifyOpenCodeSessionEventDelivery, stableClickUpCommentVersionMarker, startClickUpWebhookListener, validateClickUpWebhookState, verifyClickUpSignature, writeClickUpWebhookState, decideClickUpStatusAction, deriveClickUpBranchName, deriveClickUpPendingSubtaskBranch, deriveClickUpPrTarget, deriveClickUpWorktree, determineClickUpMergeAuthority, ensureOptimaGitignoreRules, explicitSafeInputWorktree, finalApprovalAssignees, formatRepairResult, formatValidationResult, isIgnoredClickUpTaskType, isOptimaPluginPackageWorktree, isSafeWritableDirectory, loadHumansRegistry, mergeClickUpAgentMetadata, mergeClickUpSessionMetadata, migrateLegacyOptimaLayout, normalizeAgentMetadataJson, normalizeClickUpStatus, normalizeClickUpTaskType, normalizePromptResponseParts, normalizeWorkflowTaskPath, optimaRepairDependencies, parseClickUpSubtasksMarkdown, parseHumansRegistry, parseMarkdownArtifact, parseMarkdownSections, planOptimaRepair, preEstimateClickUpWork, readMarkdownArtifact, resolveHumanRoles, resolveSafeWorktree, safeWorktreeOrFailure, stripRawLogSections, validateMainWorkspaceBranchSafety, workflowFinalMessageFromPromptResponse };
13101
13379
  export {
13102
13380
  OptimaPlugin as default
13103
13381
  };